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