1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
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 /*
8  * Marking and sweeping APIs for use by implementations of different GC cell
9  * kinds.
10  */
11 
12 #ifndef gc_Marking_h
13 #define gc_Marking_h
14 
15 #include "js/TypeDecls.h"
16 #include "vm/TaggedProto.h"
17 
18 class JSLinearString;
19 class JSRope;
20 class JSTracer;
21 struct JSClass;
22 
23 namespace js {
24 class BaseShape;
25 class GCMarker;
26 class NativeObject;
27 class Shape;
28 class WeakMapBase;
29 
30 namespace jit {
31 class JitCode;
32 }  // namespace jit
33 
34 namespace gc {
35 
36 struct Cell;
37 class TenuredCell;
38 
39 /*** Liveness ***/
40 
41 // The IsMarkedInternal and IsAboutToBeFinalizedInternal function templates are
42 // used to implement the IsMarked and IsAboutToBeFinalized set of functions.
43 // These internal functions are instantiated for the base GC types and should
44 // not be called directly.
45 //
46 // Note that there are two function templates declared for each, not one
47 // template and a specialization. This is necessary so that pointer arguments
48 // (e.g. JSObject**) and tagged value arguments (e.g. JS::Value*) are routed to
49 // separate implementations.
50 
51 template <typename T>
52 bool IsMarkedInternal(JSRuntime* rt, T** thing);
53 
54 template <typename T>
55 bool IsAboutToBeFinalizedInternal(T* thingp);
56 template <typename T>
57 bool IsAboutToBeFinalizedInternal(T** thingp);
58 
59 // Report whether a GC thing has been marked with any color. Things which are in
60 // zones that are not currently being collected or are owned by another runtime
61 // are always reported as being marked.
62 template <typename T>
IsMarkedUnbarriered(JSRuntime * rt,T * thingp)63 inline bool IsMarkedUnbarriered(JSRuntime* rt, T* thingp) {
64   return IsMarkedInternal(rt, ConvertToBase(thingp));
65 }
66 
67 // Report whether a GC thing has been marked with any color. Things which are in
68 // zones that are not currently being collected or are owned by another runtime
69 // are always reported as being marked.
70 template <typename T>
IsMarked(JSRuntime * rt,BarrieredBase<T> * thingp)71 inline bool IsMarked(JSRuntime* rt, BarrieredBase<T>* thingp) {
72   return IsMarkedInternal(rt, ConvertToBase(thingp->unbarrieredAddress()));
73 }
74 
75 template <typename T>
IsAboutToBeFinalizedUnbarriered(T * thingp)76 inline bool IsAboutToBeFinalizedUnbarriered(T* thingp) {
77   return IsAboutToBeFinalizedInternal(ConvertToBase(thingp));
78 }
79 
80 template <typename T>
IsAboutToBeFinalized(const BarrieredBase<T> * thingp)81 inline bool IsAboutToBeFinalized(const BarrieredBase<T>* thingp) {
82   return IsAboutToBeFinalizedInternal(
83       ConvertToBase(thingp->unbarrieredAddress()));
84 }
85 
86 inline bool IsAboutToBeFinalizedDuringMinorSweep(Cell* cell);
87 
ToMarkable(const Value & v)88 inline Cell* ToMarkable(const Value& v) {
89   if (v.isGCThing()) {
90     return (Cell*)v.toGCThing();
91   }
92   return nullptr;
93 }
94 
ToMarkable(Cell * cell)95 inline Cell* ToMarkable(Cell* cell) { return cell; }
96 
97 bool UnmarkGrayGCThingUnchecked(JSRuntime* rt, JS::GCCellPtr thing);
98 
99 } /* namespace gc */
100 
101 // The return value indicates if anything was unmarked.
102 bool UnmarkGrayShapeRecursively(Shape* shape);
103 
104 namespace gc {
105 
106 // Functions for checking and updating GC thing pointers that might have been
107 // moved by compacting GC. Overloads are also provided that work with Values.
108 //
109 // IsForwarded    - check whether a pointer refers to an GC thing that has been
110 //                  moved.
111 //
112 // Forwarded      - return a pointer to the new location of a GC thing given a
113 //                  pointer to old location.
114 //
115 // MaybeForwarded - used before dereferencing a pointer that may refer to a
116 //                  moved GC thing without updating it. For JSObjects this will
117 //                  also update the object's shape pointer if it has been moved
118 //                  to allow slots to be accessed.
119 
120 template <typename T>
121 inline bool IsForwarded(const T* t);
122 
123 template <typename T>
124 inline T* Forwarded(const T* t);
125 
126 inline Value Forwarded(const JS::Value& value);
127 
128 template <typename T>
129 inline T MaybeForwarded(T t);
130 
131 // Helper functions for use in situations where the object's group might be
132 // forwarded, for example while marking.
133 
134 inline const JSClass* MaybeForwardedObjectClass(const JSObject* obj);
135 
136 template <typename T>
137 inline bool MaybeForwardedObjectIs(JSObject* obj);
138 
139 template <typename T>
140 inline T& MaybeForwardedObjectAs(JSObject* obj);
141 
142 #ifdef JSGC_HASH_TABLE_CHECKS
143 
144 template <typename T>
145 inline bool IsGCThingValidAfterMovingGC(T* t);
146 
147 template <typename T>
148 inline void CheckGCThingAfterMovingGC(T* t);
149 
150 template <typename T>
151 inline void CheckGCThingAfterMovingGC(const WeakHeapPtr<T*>& t);
152 
153 #endif  // JSGC_HASH_TABLE_CHECKS
154 
155 } /* namespace gc */
156 
157 // Debugging functions to check tracing invariants.
158 #ifdef DEBUG
159 template <typename T>
160 void CheckTracedThing(JSTracer* trc, T* thing);
161 template <typename T>
162 void CheckTracedThing(JSTracer* trc, const T& thing);
163 #else
164 template <typename T>
CheckTracedThing(JSTracer * trc,T * thing)165 inline void CheckTracedThing(JSTracer* trc, T* thing) {}
166 template <typename T>
CheckTracedThing(JSTracer * trc,const T & thing)167 inline void CheckTracedThing(JSTracer* trc, const T& thing) {}
168 #endif
169 
170 } /* namespace js */
171 
172 #endif /* gc_Marking_h */
173