| 76 | } |
| 77 | |
| 78 | int asCGarbageCollector::AddScriptObjectToGC(void *obj, asCObjectType *objType) |
| 79 | { |
| 80 | if( obj == 0 || objType == 0 ) |
| 81 | { |
| 82 | engine->WriteMessage("", 0, 0, asMSGTYPE_ERROR, TXT_GC_RECEIVED_NULL_PTR); |
| 83 | return asINVALID_ARG; |
| 84 | } |
| 85 | |
| 86 | engine->CallObjectMethod(obj, objType->beh.addref); |
| 87 | asSObjTypePair ot = {obj, objType, 0}; |
| 88 | |
| 89 | // Invoke the garbage collector to destroy a little garbage as new comes in |
| 90 | // This will maintain the number of objects in the GC at a maintainable level without |
| 91 | // halting the application, and without burdening the application with manually invoking the |
| 92 | // garbage collector. |
| 93 | if( engine->ep.autoGarbageCollect && gcNewObjects.GetLength() ) |
| 94 | { |
| 95 | // If the GC is already processing in another thread, then don't try this again |
| 96 | if( TRYENTERCRITICALSECTION(gcCollecting) ) |
| 97 | { |
| 98 | // Skip this if the GC is already running in this thread |
| 99 | if( !isProcessing ) |
| 100 | { |
| 101 | isProcessing = true; |
| 102 | |
| 103 | // TODO: The number of iterations should be dynamic, and increase |
| 104 | // if the number of objects in the garbage collector grows high |
| 105 | |
| 106 | // Run one step of DetectGarbage |
| 107 | if( gcOldObjects.GetLength() ) |
| 108 | { |
| 109 | IdentifyGarbageWithCyclicRefs(); |
| 110 | DestroyOldGarbage(); |
| 111 | } |
| 112 | |
| 113 | // Run a few steps of DestroyGarbage |
| 114 | int iter = (int)gcNewObjects.GetLength(); |
| 115 | if( iter > 10 ) iter = 10; |
| 116 | while( iter-- > 0 ) |
| 117 | DestroyNewGarbage(); |
| 118 | |
| 119 | isProcessing = false; |
| 120 | } |
| 121 | |
| 122 | LEAVECRITICALSECTION(gcCollecting); |
| 123 | } |
| 124 | } |
| 125 | |
| 126 | // Add the data to the gcObjects array in a critical section as |
| 127 | // another thread might be calling this method at the same time |
| 128 | ENTERCRITICALSECTION(gcCritical); |
| 129 | ot.seqNbr = numAdded++; |
| 130 | gcNewObjects.PushLast(ot); |
| 131 | LEAVECRITICALSECTION(gcCritical); |
| 132 | |
| 133 | return ot.seqNbr; |
| 134 | } |
| 135 |
no test coverage detected