Line data Source code
1 : // Copyright 2018 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_OBJECTS_JS_WEAK_REFS_H_
6 : #define V8_OBJECTS_JS_WEAK_REFS_H_
7 :
8 : #include "src/objects/js-objects.h"
9 : #include "src/objects/microtask.h"
10 :
11 : // Has to be the last include (doesn't have include guards):
12 : #include "src/objects/object-macros.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 : class JSWeakCell;
18 : class NativeContext;
19 :
20 : // WeakFactory object from the JS Weak Refs spec proposal:
21 : // https://github.com/tc39/proposal-weakrefs
22 : class JSWeakFactory : public JSObject {
23 : public:
24 : DECL_PRINTER(JSWeakFactory)
25 : DECL_VERIFIER(JSWeakFactory)
26 : DECL_CAST(JSWeakFactory)
27 :
28 : DECL_ACCESSORS(native_context, NativeContext)
29 : DECL_ACCESSORS(cleanup, Object)
30 : DECL_ACCESSORS(active_cells, Object)
31 : DECL_ACCESSORS(cleared_cells, Object)
32 :
33 : // For storing a list of JSWeakFactory objects in NativeContext.
34 : DECL_ACCESSORS(next, Object)
35 :
36 : DECL_INT_ACCESSORS(flags)
37 :
38 : // Adds a newly constructed JSWeakCell object into this JSWeakFactory.
39 : inline void AddWeakCell(JSWeakCell weak_cell);
40 :
41 : // Returns true if the cleared_cells list is non-empty.
42 : inline bool NeedsCleanup() const;
43 :
44 : inline bool scheduled_for_cleanup() const;
45 : inline void set_scheduled_for_cleanup(bool scheduled_for_cleanup);
46 :
47 : // Get and remove the first cleared JSWeakCell from the cleared_cells
48 : // list. (Assumes there is one.)
49 : inline JSWeakCell PopClearedCell(Isolate* isolate);
50 :
51 : // Constructs an iterator for the WeakCells in the cleared_cells list and
52 : // calls the user's cleanup function.
53 : static void Cleanup(Handle<JSWeakFactory> weak_factory, Isolate* isolate);
54 :
55 : // Layout description.
56 : #define JS_WEAK_FACTORY_FIELDS(V) \
57 : V(kNativeContextOffset, kTaggedSize) \
58 : V(kCleanupOffset, kTaggedSize) \
59 : V(kActiveCellsOffset, kTaggedSize) \
60 : V(kClearedCellsOffset, kTaggedSize) \
61 : V(kNextOffset, kTaggedSize) \
62 : V(kFlagsOffset, kTaggedSize) \
63 : /* Header size. */ \
64 : V(kSize, 0)
65 :
66 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_WEAK_FACTORY_FIELDS)
67 : #undef JS_WEAK_FACTORY_FIELDS
68 :
69 : // Bitfields in flags.
70 : class ScheduledForCleanupField : public BitField<bool, 0, 1> {};
71 :
72 198 : OBJECT_CONSTRUCTORS(JSWeakFactory, JSObject);
73 : };
74 :
75 : // WeakCell object from the JS Weak Refs spec proposal.
76 : class JSWeakCell : public JSObject {
77 : public:
78 : DECL_PRINTER(JSWeakCell)
79 : DECL_VERIFIER(JSWeakCell)
80 : DECL_CAST(JSWeakCell)
81 :
82 : DECL_ACCESSORS(factory, Object)
83 : DECL_ACCESSORS(target, Object)
84 : DECL_ACCESSORS(holdings, Object)
85 :
86 : // For storing doubly linked lists of JSWeakCells in JSWeakFactory.
87 : DECL_ACCESSORS(prev, Object)
88 : DECL_ACCESSORS(next, Object)
89 :
90 : // Layout description.
91 : #define JS_WEAK_CELL_FIELDS(V) \
92 : V(kFactoryOffset, kTaggedSize) \
93 : V(kTargetOffset, kTaggedSize) \
94 : V(kHoldingsOffset, kTaggedSize) \
95 : V(kPrevOffset, kTaggedSize) \
96 : V(kNextOffset, kTaggedSize) \
97 : /* Header size. */ \
98 : V(kSize, 0)
99 :
100 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize, JS_WEAK_CELL_FIELDS)
101 : #undef JS_WEAK_CELL_FIELDS
102 :
103 : class BodyDescriptor;
104 :
105 : // Nullify is called during GC and it modifies the pointers in JSWeakCell and
106 : // JSWeakFactory. Thus we need to tell the GC about the modified slots via the
107 : // gc_notify_updated_slot function. The normal write barrier is not enough,
108 : // since it's disabled before GC.
109 : inline void Nullify(
110 : Isolate* isolate,
111 : std::function<void(HeapObject object, ObjectSlot slot, Object target)>
112 : gc_notify_updated_slot);
113 :
114 : inline void Clear(Isolate* isolate);
115 :
116 168 : OBJECT_CONSTRUCTORS(JSWeakCell, JSObject);
117 : };
118 :
119 : class JSWeakRef : public JSObject {
120 : public:
121 : DECL_PRINTER(JSWeakRef)
122 : DECL_VERIFIER(JSWeakRef)
123 : DECL_CAST(JSWeakRef)
124 :
125 : DECL_ACCESSORS(target, Object)
126 :
127 : static const int kTargetOffset = JSObject::kHeaderSize;
128 : static const int kSize = kTargetOffset + kPointerSize;
129 :
130 : class BodyDescriptor;
131 :
132 157 : OBJECT_CONSTRUCTORS(JSWeakRef, JSObject);
133 : };
134 :
135 : class WeakFactoryCleanupJobTask : public Microtask {
136 : public:
137 : DECL_ACCESSORS(factory, JSWeakFactory)
138 :
139 : DECL_CAST(WeakFactoryCleanupJobTask)
140 : DECL_VERIFIER(WeakFactoryCleanupJobTask)
141 : DECL_PRINTER(WeakFactoryCleanupJobTask)
142 :
143 : // Layout description.
144 : #define WEAK_FACTORY_CLEANUP_JOB_TASK_FIELDS(V) \
145 : V(kFactoryOffset, kTaggedSize) \
146 : /* Total size. */ \
147 : V(kSize, 0)
148 :
149 : DEFINE_FIELD_OFFSET_CONSTANTS(Microtask::kHeaderSize,
150 : WEAK_FACTORY_CLEANUP_JOB_TASK_FIELDS)
151 : #undef WEAK_FACTORY_CLEANUP_JOB_TASK_FIELDS
152 :
153 : OBJECT_CONSTRUCTORS(WeakFactoryCleanupJobTask, Microtask)
154 : };
155 :
156 : class JSWeakFactoryCleanupIterator : public JSObject {
157 : public:
158 : DECL_PRINTER(JSWeakFactoryCleanupIterator)
159 : DECL_VERIFIER(JSWeakFactoryCleanupIterator)
160 : DECL_CAST(JSWeakFactoryCleanupIterator)
161 :
162 : DECL_ACCESSORS(factory, JSWeakFactory)
163 :
164 : // Layout description.
165 : #define JS_WEAK_FACTORY_CLEANUP_ITERATOR_FIELDS(V) \
166 : V(kFactoryOffset, kTaggedSize) \
167 : /* Header size. */ \
168 : V(kSize, 0)
169 :
170 : DEFINE_FIELD_OFFSET_CONSTANTS(JSObject::kHeaderSize,
171 : JS_WEAK_FACTORY_CLEANUP_ITERATOR_FIELDS)
172 : #undef JS_WEAK_FACTORY_CLEANUP_ITERATOR_FIELDS
173 :
174 : OBJECT_CONSTRUCTORS(JSWeakFactoryCleanupIterator, JSObject);
175 : };
176 :
177 : } // namespace internal
178 : } // namespace v8
179 :
180 : #include "src/objects/object-macros-undef.h"
181 :
182 : #endif // V8_OBJECTS_JS_WEAK_REFS_H_
|