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