1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef jsgcmark_h___
8 : #define jsgcmark_h___
9 :
10 : #include "jsgc.h"
11 : #include "jscntxt.h"
12 : #include "jscompartment.h"
13 : #include "jslock.h"
14 :
15 : #include "gc/Barrier.h"
16 : #include "js/TemplateLib.h"
17 :
18 : namespace js {
19 : namespace gc {
20 :
21 : /*** Object Marking ***/
22 :
23 : /*
24 : * These functions expose marking functionality for all of the different GC
25 : * thing kinds. For each GC thing, there are several variants. As an example,
26 : * these are the variants generated for JSObject. They are listed from most to
27 : * least desirable for use:
28 : *
29 : * MarkObject(JSTracer *trc, const HeapPtr<JSObject> &thing, const char *name);
30 : * This function should be used for marking JSObjects, in preference to all
31 : * others below. Use it when you have HeapPtr<JSObject>, which
32 : * automatically implements write barriers.
33 : *
34 : * MarkObjectRoot(JSTracer *trc, JSObject *thing, const char *name);
35 : * This function is only valid during the root marking phase of GC (i.e.,
36 : * when MarkRuntime is on the stack).
37 : *
38 : * MarkObjectUnbarriered(JSTracer *trc, JSObject *thing, const char *name);
39 : * Like MarkObject, this function can be called at any time. It is more
40 : * forgiving, since it doesn't demand a HeapPtr as an argument. Its use
41 : * should always be accompanied by a comment explaining how write barriers
42 : * are implemented for the given field.
43 : *
44 : * Additionally, the functions MarkObjectRange and MarkObjectRootRange are
45 : * defined for marking arrays of object pointers.
46 : */
47 : #define DeclMarker(base, type) \
48 : void Mark##base(JSTracer *trc, HeapPtr<type> *thing, const char *name); \
49 : void Mark##base##Root(JSTracer *trc, type **thingp, const char *name); \
50 : void Mark##base##Unbarriered(JSTracer *trc, type **thingp, const char *name); \
51 : void Mark##base##Range(JSTracer *trc, size_t len, HeapPtr<type> *thing, const char *name); \
52 : void Mark##base##RootRange(JSTracer *trc, size_t len, type **thing, const char *name);
53 :
54 : DeclMarker(BaseShape, BaseShape)
55 : DeclMarker(BaseShape, UnownedBaseShape)
56 : DeclMarker(Object, ArgumentsObject)
57 : DeclMarker(Object, GlobalObject)
58 : DeclMarker(Object, JSObject)
59 : DeclMarker(Object, JSFunction)
60 : DeclMarker(Script, JSScript)
61 : DeclMarker(Shape, Shape)
62 : DeclMarker(String, JSAtom)
63 : DeclMarker(String, JSString)
64 : DeclMarker(String, JSFlatString)
65 : DeclMarker(String, JSLinearString)
66 : DeclMarker(TypeObject, types::TypeObject)
67 : #if JS_HAS_XML_SUPPORT
68 : DeclMarker(XML, JSXML)
69 : #endif
70 :
71 : /*** Externally Typed Marking ***/
72 :
73 : /*
74 : * Note: this must only be called by the GC and only when we are tracing through
75 : * MarkRoots. It is explicitly for ConservativeStackMarking and should go away
76 : * after we transition to exact rooting.
77 : */
78 : void
79 : MarkKind(JSTracer *trc, void **thingp, JSGCTraceKind kind);
80 :
81 : void
82 : MarkGCThingRoot(JSTracer *trc, void **thingp, const char *name);
83 :
84 : /*** ID Marking ***/
85 :
86 : void
87 : MarkId(JSTracer *trc, HeapId *id, const char *name);
88 :
89 : void
90 : MarkIdRoot(JSTracer *trc, jsid *id, const char *name);
91 :
92 : void
93 : MarkIdRange(JSTracer *trc, size_t len, js::HeapId *vec, const char *name);
94 :
95 : void
96 : MarkIdRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name);
97 :
98 : /*** Value Marking ***/
99 :
100 : void
101 : MarkValue(JSTracer *trc, HeapValue *v, const char *name);
102 :
103 : void
104 : MarkValueRange(JSTracer *trc, size_t len, HeapValue *vec, const char *name);
105 :
106 : void
107 : MarkValueRoot(JSTracer *trc, Value *v, const char *name);
108 :
109 : void
110 : MarkValueRootRange(JSTracer *trc, size_t len, Value *vec, const char *name);
111 :
112 : inline void
113 630592 : MarkValueRootRange(JSTracer *trc, Value *begin, Value *end, const char *name)
114 : {
115 630592 : MarkValueRootRange(trc, end - begin, begin, name);
116 630592 : }
117 :
118 : /*** Slot Marking ***/
119 :
120 : void
121 : MarkSlot(JSTracer *trc, HeapSlot *s, const char *name);
122 :
123 : void
124 : MarkArraySlots(JSTracer *trc, size_t len, HeapSlot *vec, const char *name);
125 :
126 : void
127 : MarkObjectSlots(JSTracer *trc, JSObject *obj, uint32_t start, uint32_t nslots);
128 :
129 : void
130 : MarkCrossCompartmentObjectUnbarriered(JSTracer *trc, JSObject **obj, const char *name);
131 :
132 : void
133 : MarkCrossCompartmentScriptUnbarriered(JSTracer *trc, JSScript **script, const char *name);
134 :
135 : /*
136 : * Mark a value that may be in a different compartment from the compartment
137 : * being GC'd. (Although it won't be marked if it's in the wrong compartment.)
138 : */
139 : void
140 : MarkCrossCompartmentSlot(JSTracer *trc, HeapSlot *s, const char *name);
141 :
142 :
143 : /*** Special Cases ***/
144 :
145 : /*
146 : * The unioned HeapPtr stored in script->globalObj needs special treatment to
147 : * typecheck correctly.
148 : */
149 : void
150 : MarkObject(JSTracer *trc, HeapPtr<GlobalObject, JSScript *> *thingp, const char *name);
151 :
152 : /* Direct value access used by the write barriers and the methodjit. */
153 : void
154 : MarkValueUnbarriered(JSTracer *trc, Value *v, const char *name);
155 :
156 : /*
157 : * MarkChildren<JSObject> is exposed solely for preWriteBarrier on
158 : * JSObject::TradeGuts. It should not be considered external interface.
159 : */
160 : void
161 : MarkChildren(JSTracer *trc, JSObject *obj);
162 :
163 : /*
164 : * Trace through the shape and any shapes it contains to mark
165 : * non-shape children. This is exposed to the JS API as
166 : * JS_TraceShapeCycleCollectorChildren.
167 : */
168 : void
169 : MarkCycleCollectorChildren(JSTracer *trc, Shape *shape);
170 :
171 : void
172 : PushArena(GCMarker *gcmarker, ArenaHeader *aheader);
173 :
174 : /*** Generic ***/
175 :
176 : /*
177 : * The Mark() functions interface should only be used by code that must be
178 : * templated. Other uses should use the more specific, type-named functions.
179 : */
180 :
181 : inline void
182 : Mark(JSTracer *trc, HeapValue *v, const char *name)
183 : {
184 : MarkValue(trc, v, name);
185 : }
186 :
187 : inline void
188 : Mark(JSTracer *trc, HeapPtr<JSObject> *o, const char *name)
189 : {
190 : MarkObject(trc, o, name);
191 : }
192 :
193 : inline void
194 : Mark(JSTracer *trc, HeapPtr<JSXML> *xml, const char *name)
195 : {
196 : MarkXML(trc, xml, name);
197 : }
198 :
199 : inline bool
200 : IsMarked(const Value &v)
201 : {
202 : if (v.isMarkable())
203 : return !IsAboutToBeFinalized(v);
204 : return true;
205 : }
206 :
207 : inline bool
208 : IsMarked(Cell *cell)
209 : {
210 : return !IsAboutToBeFinalized(cell);
211 : }
212 :
213 : } /* namespace gc */
214 :
215 : void
216 : TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind);
217 :
218 : void
219 : CallTracer(JSTracer *trc, void *thing, JSGCTraceKind kind);
220 :
221 : } /* namespace js */
222 :
223 : #endif
|