1 /* 2 AngelCode Scripting Library 3 Copyright (c) 2003-2015 Andreas Jonsson 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any 7 damages arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any 10 purpose, including commercial applications, and to alter it and 11 redistribute it freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you 14 must not claim that you wrote the original software. If you use 15 this software in a product, an acknowledgment in the product 16 documentation would be appreciated but is not required. 17 18 2. Altered source versions must be plainly marked as such, and 19 must not be misrepresented as being the original software. 20 21 3. This notice may not be removed or altered from any source 22 distribution. 23 24 The original version of this library can be located at: 25 http://www.angelcode.com/angelscript/ 26 27 Andreas Jonsson 28 andreas@angelcode.com 29 */ 30 31 32 // 33 // as_gc.h 34 // 35 // The garbage collector is used to resolve cyclic references 36 // 37 38 39 40 #ifndef AS_GC_H 41 #define AS_GC_H 42 43 #include "as_config.h" 44 #include "as_array.h" 45 #include "as_map.h" 46 #include "as_thread.h" 47 48 BEGIN_AS_NAMESPACE 49 50 class asCScriptEngine; 51 class asCObjectType; 52 53 class asCGarbageCollector 54 { 55 public: 56 asCGarbageCollector(); 57 ~asCGarbageCollector(); 58 59 int GarbageCollect(asDWORD flags, asUINT iterations); 60 void GetStatistics(asUINT *currentSize, asUINT *totalDestroyed, asUINT *totalDetected, asUINT *newObjects, asUINT *totalNewDestroyed) const; 61 void GCEnumCallback(void *reference); 62 int AddScriptObjectToGC(void *obj, asCObjectType *objType); 63 int GetObjectInGC(asUINT idx, asUINT *seqNbr, void **obj, asITypeInfo **type); 64 65 int ReportAndReleaseUndestroyedObjects(); 66 67 asCScriptEngine *engine; 68 69 protected: 70 struct asSObjTypePair {void *obj; asCObjectType *type; asUINT seqNbr;}; 71 struct asSIntTypePair {int i; asCObjectType *type;}; 72 typedef asSMapNode<void*, asSIntTypePair> asSMapNode_t; 73 74 enum egcDestroyState 75 { 76 destroyGarbage_init = 0, 77 destroyGarbage_loop, 78 destroyGarbage_haveMore 79 }; 80 81 enum egcDetectState 82 { 83 clearCounters_init = 0, 84 clearCounters_loop, 85 buildMap_init, 86 buildMap_loop, 87 countReferences_init, 88 countReferences_loop, 89 detectGarbage_init, 90 detectGarbage_loop1, 91 detectGarbage_loop2, 92 verifyUnmarked_init, 93 verifyUnmarked_loop, 94 breakCircles_init, 95 breakCircles_loop, 96 breakCircles_haveGarbage 97 }; 98 99 int DestroyNewGarbage(); 100 int DestroyOldGarbage(); 101 int IdentifyGarbageWithCyclicRefs(); 102 asSObjTypePair GetNewObjectAtIdx(int idx); 103 asSObjTypePair GetOldObjectAtIdx(int idx); 104 void RemoveNewObjectAtIdx(int idx); 105 void RemoveOldObjectAtIdx(int idx); 106 void MoveObjectToOldList(int idx); 107 void MoveAllObjectsToOldList(); 108 109 // Holds all the objects known by the garbage collector 110 asCArray<asSObjTypePair> gcNewObjects; 111 asCArray<asSObjTypePair> gcOldObjects; 112 113 // This array temporarily holds references to objects known to be live objects 114 asCArray<void*> liveObjects; 115 116 // This map holds objects currently being searched for cyclic references, it also holds a 117 // counter that gives the number of references to the object that the GC can't reach 118 asCMap<void*, asSIntTypePair> gcMap; 119 120 // State variables 121 egcDestroyState destroyNewState; 122 egcDestroyState destroyOldState; 123 asUINT destroyNewIdx; 124 asUINT destroyOldIdx; 125 asUINT numDestroyed; 126 asUINT numNewDestroyed; 127 egcDetectState detectState; 128 asUINT detectIdx; 129 asUINT numDetected; 130 asUINT numAdded; 131 asUINT seqAtSweepStart[3]; 132 asSMapNode_t *gcMapCursor; 133 bool isProcessing; 134 135 // We'll keep a pool of nodes to avoid allocating memory all the time 136 asSMapNode_t *GetNode(void *obj, asSIntTypePair it); 137 void ReturnNode(asSMapNode_t *node); 138 asCArray<asSMapNode_t*> freeNodes; 139 140 // Critical section for multithreaded access 141 DECLARECRITICALSECTION(gcCritical) // Used for adding/removing objects 142 DECLARECRITICALSECTION(gcCollecting) // Used for processing 143 }; 144 145 END_AS_NAMESPACE 146 147 #endif 148