js/src/gc/Marking.h

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:53a9bb6f442e
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
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
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #ifndef gc_Marking_h
8 #define gc_Marking_h
9
10 #include "gc/Barrier.h"
11
12 class JSAtom;
13 class JSLinearString;
14
15 namespace js {
16
17 class ArgumentsObject;
18 class ArrayBufferObject;
19 class ArrayBufferViewObject;
20 class SharedArrayBufferObject;
21 class BaseShape;
22 class DebugScopeObject;
23 struct GCMarker;
24 class GlobalObject;
25 class LazyScript;
26 class ScopeObject;
27 class Shape;
28 class UnownedBaseShape;
29
30 template<class, typename> class HeapPtr;
31
32 namespace jit {
33 class JitCode;
34 class IonScript;
35 class VMFunction;
36 }
37
38 namespace types {
39 class Type;
40 }
41
42 namespace gc {
43
44 /*** Object Marking ***/
45
46 /*
47 * These functions expose marking functionality for all of the different GC
48 * thing kinds. For each GC thing, there are several variants. As an example,
49 * these are the variants generated for JSObject. They are listed from most to
50 * least desirable for use:
51 *
52 * MarkObject(JSTracer *trc, const HeapPtr<JSObject> &thing, const char *name);
53 * This function should be used for marking JSObjects, in preference to all
54 * others below. Use it when you have HeapPtr<JSObject>, which
55 * automatically implements write barriers.
56 *
57 * MarkObjectRoot(JSTracer *trc, JSObject *thing, const char *name);
58 * This function is only valid during the root marking phase of GC (i.e.,
59 * when MarkRuntime is on the stack).
60 *
61 * MarkObjectUnbarriered(JSTracer *trc, JSObject *thing, const char *name);
62 * Like MarkObject, this function can be called at any time. It is more
63 * forgiving, since it doesn't demand a HeapPtr as an argument. Its use
64 * should always be accompanied by a comment explaining how write barriers
65 * are implemented for the given field.
66 *
67 * Additionally, the functions MarkObjectRange and MarkObjectRootRange are
68 * defined for marking arrays of object pointers.
69 *
70 * The following functions are provided to test whether a GC thing is marked
71 * under different circumstances:
72 *
73 * IsObjectAboutToBeFinalized(JSObject **thing);
74 * This function is indended to be used in code used to sweep GC things. It
75 * indicates whether the object will will be finialized in the current group
76 * of compartments being swept. Note that this will return false for any
77 * object not in the group of compartments currently being swept, as even if
78 * it is unmarked it may still become marked before it is swept.
79 *
80 * IsObjectMarked(JSObject **thing);
81 * This function is indended to be used in rare cases in code used to mark
82 * GC things. It indicates whether the object is currently marked.
83 *
84 * UpdateObjectIfRelocated(JSObject **thingp);
85 * In some circumstances -- e.g. optional weak marking -- it is necessary
86 * to look at the pointer before marking it strongly or weakly. In these
87 * cases, the following must be called to update the pointer before use.
88 */
89
90 #define DeclMarker(base, type) \
91 void Mark##base(JSTracer *trc, BarrieredPtr<type> *thing, const char *name); \
92 void Mark##base##Root(JSTracer *trc, type **thingp, const char *name); \
93 void Mark##base##Unbarriered(JSTracer *trc, type **thingp, const char *name); \
94 void Mark##base##Range(JSTracer *trc, size_t len, HeapPtr<type> *thing, const char *name); \
95 void Mark##base##RootRange(JSTracer *trc, size_t len, type **thing, const char *name); \
96 bool Is##base##Marked(type **thingp); \
97 bool Is##base##Marked(BarrieredPtr<type> *thingp); \
98 bool Is##base##AboutToBeFinalized(type **thingp); \
99 bool Is##base##AboutToBeFinalized(BarrieredPtr<type> *thingp); \
100 type *Update##base##IfRelocated(JSRuntime *rt, BarrieredPtr<type> *thingp); \
101 type *Update##base##IfRelocated(JSRuntime *rt, type **thingp);
102
103 DeclMarker(BaseShape, BaseShape)
104 DeclMarker(BaseShape, UnownedBaseShape)
105 DeclMarker(JitCode, jit::JitCode)
106 DeclMarker(Object, ArgumentsObject)
107 DeclMarker(Object, ArrayBufferObject)
108 DeclMarker(Object, ArrayBufferViewObject)
109 DeclMarker(Object, SharedArrayBufferObject)
110 DeclMarker(Object, DebugScopeObject)
111 DeclMarker(Object, GlobalObject)
112 DeclMarker(Object, JSObject)
113 DeclMarker(Object, JSFunction)
114 DeclMarker(Object, ScopeObject)
115 DeclMarker(Script, JSScript)
116 DeclMarker(LazyScript, LazyScript)
117 DeclMarker(Shape, Shape)
118 DeclMarker(String, JSAtom)
119 DeclMarker(String, JSString)
120 DeclMarker(String, JSFlatString)
121 DeclMarker(String, JSLinearString)
122 DeclMarker(String, PropertyName)
123 DeclMarker(TypeObject, types::TypeObject)
124
125 #undef DeclMarker
126
127 void
128 MarkPermanentAtom(JSTracer *trc, JSAtom *atom, const char *name);
129
130 /* Return true if the pointer is nullptr, or if it is a tagged pointer to
131 * nullptr.
132 */
133 MOZ_ALWAYS_INLINE bool
134 IsNullTaggedPointer(void *p)
135 {
136 return uintptr_t(p) < 32;
137 }
138
139 /*** Externally Typed Marking ***/
140
141 /*
142 * Note: this must only be called by the GC and only when we are tracing through
143 * MarkRoots. It is explicitly for ConservativeStackMarking and should go away
144 * after we transition to exact rooting.
145 */
146 void
147 MarkKind(JSTracer *trc, void **thingp, JSGCTraceKind kind);
148
149 void
150 MarkGCThingRoot(JSTracer *trc, void **thingp, const char *name);
151
152 void
153 MarkGCThingUnbarriered(JSTracer *trc, void **thingp, const char *name);
154
155 /*** ID Marking ***/
156
157 void
158 MarkId(JSTracer *trc, BarrieredId *id, const char *name);
159
160 void
161 MarkIdRoot(JSTracer *trc, jsid *id, const char *name);
162
163 void
164 MarkIdUnbarriered(JSTracer *trc, jsid *id, const char *name);
165
166 void
167 MarkIdRange(JSTracer *trc, size_t len, HeapId *vec, const char *name);
168
169 void
170 MarkIdRootRange(JSTracer *trc, size_t len, jsid *vec, const char *name);
171
172 /*** Value Marking ***/
173
174 void
175 MarkValue(JSTracer *trc, BarrieredValue *v, const char *name);
176
177 void
178 MarkValueRange(JSTracer *trc, size_t len, BarrieredValue *vec, const char *name);
179
180 inline void
181 MarkValueRange(JSTracer *trc, HeapValue *begin, HeapValue *end, const char *name)
182 {
183 return MarkValueRange(trc, end - begin, begin, name);
184 }
185
186 void
187 MarkValueRoot(JSTracer *trc, Value *v, const char *name);
188
189 void
190 MarkThingOrValueUnbarriered(JSTracer *trc, uintptr_t *word, const char *name);
191
192 void
193 MarkValueRootRange(JSTracer *trc, size_t len, Value *vec, const char *name);
194
195 inline void
196 MarkValueRootRange(JSTracer *trc, Value *begin, Value *end, const char *name)
197 {
198 MarkValueRootRange(trc, end - begin, begin, name);
199 }
200
201 void
202 MarkTypeRoot(JSTracer *trc, types::Type *v, const char *name);
203
204 bool
205 IsValueMarked(Value *v);
206
207 bool
208 IsValueAboutToBeFinalized(Value *v);
209
210 /*** Slot Marking ***/
211
212 bool
213 IsSlotMarked(HeapSlot *s);
214
215 void
216 MarkSlot(JSTracer *trc, HeapSlot *s, const char *name);
217
218 void
219 MarkArraySlots(JSTracer *trc, size_t len, HeapSlot *vec, const char *name);
220
221 void
222 MarkObjectSlots(JSTracer *trc, JSObject *obj, uint32_t start, uint32_t nslots);
223
224 void
225 MarkCrossCompartmentObjectUnbarriered(JSTracer *trc, JSObject *src, JSObject **dst_obj,
226 const char *name);
227
228 void
229 MarkCrossCompartmentScriptUnbarriered(JSTracer *trc, JSObject *src, JSScript **dst_script,
230 const char *name);
231
232 /*
233 * Mark a value that may be in a different compartment from the compartment
234 * being GC'd. (Although it won't be marked if it's in the wrong compartment.)
235 */
236 void
237 MarkCrossCompartmentSlot(JSTracer *trc, JSObject *src, HeapSlot *dst_slot, const char *name);
238
239
240 /*** Special Cases ***/
241
242 /*
243 * The unioned HeapPtr stored in script->globalObj needs special treatment to
244 * typecheck correctly.
245 */
246 void
247 MarkObject(JSTracer *trc, HeapPtr<GlobalObject, JSScript *> *thingp, const char *name);
248
249 /*
250 * MarkChildren<JSObject> is exposed solely for preWriteBarrier on
251 * JSObject::TradeGuts. It should not be considered external interface.
252 */
253 void
254 MarkChildren(JSTracer *trc, JSObject *obj);
255
256 /*
257 * Trace through the shape and any shapes it contains to mark
258 * non-shape children. This is exposed to the JS API as
259 * JS_TraceShapeCycleCollectorChildren.
260 */
261 void
262 MarkCycleCollectorChildren(JSTracer *trc, Shape *shape);
263
264 void
265 PushArena(GCMarker *gcmarker, ArenaHeader *aheader);
266
267 /*** Generic ***/
268
269 /*
270 * The Mark() functions interface should only be used by code that must be
271 * templated. Other uses should use the more specific, type-named functions.
272 */
273
274 inline void
275 Mark(JSTracer *trc, BarrieredValue *v, const char *name)
276 {
277 MarkValue(trc, v, name);
278 }
279
280 inline void
281 Mark(JSTracer *trc, BarrieredPtrObject *o, const char *name)
282 {
283 MarkObject(trc, o, name);
284 }
285
286 inline void
287 Mark(JSTracer *trc, BarrieredPtrScript *o, const char *name)
288 {
289 MarkScript(trc, o, name);
290 }
291
292 inline void
293 Mark(JSTracer *trc, HeapPtr<jit::JitCode> *code, const char *name)
294 {
295 MarkJitCode(trc, code, name);
296 }
297
298 /* For use by WeakMap's HashKeyRef instantiation. */
299 inline void
300 Mark(JSTracer *trc, JSObject **objp, const char *name)
301 {
302 MarkObjectUnbarriered(trc, objp, name);
303 }
304
305 /* For use by Debugger::WeakMap's proxiedScopes HashKeyRef instantiation. */
306 inline void
307 Mark(JSTracer *trc, ScopeObject **obj, const char *name)
308 {
309 MarkObjectUnbarriered(trc, obj, name);
310 }
311
312 bool
313 IsCellMarked(Cell **thingp);
314
315 bool
316 IsCellAboutToBeFinalized(Cell **thing);
317
318 inline bool
319 IsMarked(BarrieredValue *v)
320 {
321 if (!v->isMarkable())
322 return true;
323 return IsValueMarked(v->unsafeGet());
324 }
325
326 inline bool
327 IsMarked(BarrieredPtrObject *objp)
328 {
329 return IsObjectMarked(objp);
330 }
331
332 inline bool
333 IsMarked(BarrieredPtrScript *scriptp)
334 {
335 return IsScriptMarked(scriptp);
336 }
337
338 inline bool
339 IsAboutToBeFinalized(BarrieredValue *v)
340 {
341 if (!v->isMarkable())
342 return false;
343 return IsValueAboutToBeFinalized(v->unsafeGet());
344 }
345
346 inline bool
347 IsAboutToBeFinalized(BarrieredPtrObject *objp)
348 {
349 return IsObjectAboutToBeFinalized(objp);
350 }
351
352 inline bool
353 IsAboutToBeFinalized(BarrieredPtrScript *scriptp)
354 {
355 return IsScriptAboutToBeFinalized(scriptp);
356 }
357
358 #ifdef JS_ION
359 /* Nonsense to get WeakCache to work with new Marking semantics. */
360
361 inline bool
362 IsAboutToBeFinalized(const js::jit::VMFunction **vmfunc)
363 {
364 /*
365 * Preserves entries in the WeakCache<VMFunction, JitCode>
366 * iff the JitCode has been marked.
367 */
368 return true;
369 }
370
371 inline bool
372 IsAboutToBeFinalized(ReadBarriered<js::jit::JitCode> code)
373 {
374 return IsJitCodeAboutToBeFinalized(code.unsafeGet());
375 }
376 #endif
377
378 inline Cell *
379 ToMarkable(const Value &v)
380 {
381 if (v.isMarkable())
382 return (Cell *)v.toGCThing();
383 return nullptr;
384 }
385
386 inline Cell *
387 ToMarkable(Cell *cell)
388 {
389 return cell;
390 }
391
392 inline JSGCTraceKind
393 TraceKind(const Value &v)
394 {
395 JS_ASSERT(v.isMarkable());
396 if (v.isObject())
397 return JSTRACE_OBJECT;
398 return JSTRACE_STRING;
399 }
400
401 inline JSGCTraceKind
402 TraceKind(JSObject *obj)
403 {
404 return JSTRACE_OBJECT;
405 }
406
407 inline JSGCTraceKind
408 TraceKind(JSScript *script)
409 {
410 return JSTRACE_SCRIPT;
411 }
412
413 inline JSGCTraceKind
414 TraceKind(LazyScript *lazy)
415 {
416 return JSTRACE_LAZY_SCRIPT;
417 }
418
419 } /* namespace gc */
420
421 void
422 TraceChildren(JSTracer *trc, void *thing, JSGCTraceKind kind);
423
424 } /* namespace js */
425
426 #endif /* gc_Marking_h */

mercurial