V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
js-weak-refs-inl.h
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_INL_H_
6 #define V8_OBJECTS_JS_WEAK_REFS_INL_H_
7 
8 #include "src/objects/js-weak-refs.h"
9 
10 #include "src/api-inl.h"
11 #include "src/heap/heap-write-barrier-inl.h"
12 #include "src/objects/smi-inl.h"
13 
14 // Has to be the last include (doesn't have include guards):
15 #include "src/objects/object-macros.h"
16 
17 namespace v8 {
18 namespace internal {
19 
20 ACCESSORS2(JSWeakFactory, native_context, Context, kNativeContextOffset)
21 ACCESSORS(JSWeakFactory, cleanup, Object, kCleanupOffset)
22 ACCESSORS(JSWeakFactory, active_cells, Object, kActiveCellsOffset)
23 ACCESSORS(JSWeakFactory, cleared_cells, Object, kClearedCellsOffset)
24 SMI_ACCESSORS(JSWeakFactory, flags, kFlagsOffset)
25 ACCESSORS(JSWeakFactory, next, Object, kNextOffset)
26 CAST_ACCESSOR(JSWeakFactory)
27 
28 ACCESSORS(JSWeakCell, factory, Object, kFactoryOffset)
29 ACCESSORS(JSWeakCell, target, Object, kTargetOffset)
30 ACCESSORS(JSWeakCell, holdings, Object, kHoldingsOffset)
31 ACCESSORS(JSWeakCell, next, Object, kNextOffset)
32 ACCESSORS(JSWeakCell, prev, Object, kPrevOffset)
33 CAST_ACCESSOR(JSWeakCell)
34 
35 CAST_ACCESSOR(JSWeakRef)
36 
37 ACCESSORS(JSWeakFactoryCleanupIterator, factory, JSWeakFactory, kFactoryOffset)
38 CAST_ACCESSOR(JSWeakFactoryCleanupIterator)
39 
40 ACCESSORS(WeakFactoryCleanupJobTask, factory, JSWeakFactory, kFactoryOffset)
41 CAST_ACCESSOR(WeakFactoryCleanupJobTask)
42 
43 void JSWeakFactory::AddWeakCell(JSWeakCell* weak_cell) {
44  weak_cell->set_factory(this);
45  weak_cell->set_next(active_cells());
46  if (active_cells()->IsJSWeakCell()) {
47  JSWeakCell::cast(active_cells())->set_prev(weak_cell);
48  }
49  set_active_cells(weak_cell);
50 }
51 
52 bool JSWeakFactory::NeedsCleanup() const {
53  return cleared_cells()->IsJSWeakCell();
54 }
55 
56 bool JSWeakFactory::scheduled_for_cleanup() const {
57  return ScheduledForCleanupField::decode(flags());
58 }
59 
60 void JSWeakFactory::set_scheduled_for_cleanup(bool scheduled_for_cleanup) {
61  set_flags(ScheduledForCleanupField::update(flags(), scheduled_for_cleanup));
62 }
63 
64 JSWeakCell* JSWeakFactory::PopClearedCell(Isolate* isolate) {
65  JSWeakCell* weak_cell = JSWeakCell::cast(cleared_cells());
66  DCHECK(weak_cell->prev()->IsUndefined(isolate));
67  set_cleared_cells(weak_cell->next());
68  weak_cell->set_next(ReadOnlyRoots(isolate).undefined_value());
69 
70  if (cleared_cells()->IsJSWeakCell()) {
71  JSWeakCell* cleared_cells_head = JSWeakCell::cast(cleared_cells());
72  DCHECK_EQ(cleared_cells_head->prev(), weak_cell);
73  cleared_cells_head->set_prev(ReadOnlyRoots(isolate).undefined_value());
74  } else {
75  DCHECK(cleared_cells()->IsUndefined(isolate));
76  }
77  return weak_cell;
78 }
79 
80 void JSWeakCell::Nullify(
81  Isolate* isolate,
82  std::function<void(HeapObject* object, ObjectSlot slot, Object* target)>
83  gc_notify_updated_slot) {
84  DCHECK(target()->IsJSReceiver());
85  set_target(ReadOnlyRoots(isolate).undefined_value());
86 
87  JSWeakFactory* weak_factory = JSWeakFactory::cast(factory());
88  // Remove from the JSWeakCell from the "active_cells" list of its
89  // JSWeakFactory and insert it into the "cleared" list.
90  if (prev()->IsJSWeakCell()) {
91  DCHECK_NE(weak_factory->active_cells(), this);
92  JSWeakCell* prev_cell = JSWeakCell::cast(prev());
93  prev_cell->set_next(next());
94  gc_notify_updated_slot(
95  prev_cell, HeapObject::RawField(prev_cell, JSWeakCell::kNextOffset),
96  next());
97  } else {
98  DCHECK_EQ(weak_factory->active_cells(), this);
99  weak_factory->set_active_cells(next());
100  gc_notify_updated_slot(
101  weak_factory,
102  HeapObject::RawField(weak_factory, JSWeakFactory::kActiveCellsOffset),
103  next());
104  }
105  if (next()->IsJSWeakCell()) {
106  JSWeakCell* next_cell = JSWeakCell::cast(next());
107  next_cell->set_prev(prev());
108  gc_notify_updated_slot(
109  next_cell, HeapObject::RawField(next_cell, JSWeakCell::kPrevOffset),
110  prev());
111  }
112 
113  set_prev(ReadOnlyRoots(isolate).undefined_value());
114  Object* cleared_head = weak_factory->cleared_cells();
115  if (cleared_head->IsJSWeakCell()) {
116  JSWeakCell* cleared_head_cell = JSWeakCell::cast(cleared_head);
117  cleared_head_cell->set_prev(this);
118  gc_notify_updated_slot(
119  cleared_head_cell,
120  HeapObject::RawField(cleared_head_cell, JSWeakCell::kPrevOffset), this);
121  }
122  set_next(weak_factory->cleared_cells());
123  gc_notify_updated_slot(
124  this, HeapObject::RawField(this, JSWeakCell::kNextOffset), next());
125  weak_factory->set_cleared_cells(this);
126  gc_notify_updated_slot(
127  weak_factory,
128  HeapObject::RawField(weak_factory, JSWeakFactory::kClearedCellsOffset),
129  this);
130 }
131 
132 void JSWeakCell::Clear(Isolate* isolate) {
133  // Unlink the JSWeakCell from the list it's in (if any). The JSWeakCell can be
134  // in its JSWeakFactory's active_cells list, cleared_cells list or neither (if
135  // it has been already taken out).
136 
137  DCHECK(target()->IsUndefined() || target()->IsJSReceiver());
138  set_target(ReadOnlyRoots(isolate).undefined_value());
139 
140  if (factory()->IsJSWeakFactory()) {
141  JSWeakFactory* weak_factory = JSWeakFactory::cast(factory());
142  if (weak_factory->active_cells() == this) {
143  DCHECK(!prev()->IsJSWeakCell());
144  weak_factory->set_active_cells(next());
145  } else if (weak_factory->cleared_cells() == this) {
146  DCHECK(!prev()->IsJSWeakCell());
147  weak_factory->set_cleared_cells(next());
148  } else if (prev()->IsJSWeakCell()) {
149  JSWeakCell* prev_cell = JSWeakCell::cast(prev());
150  prev_cell->set_next(next());
151  }
152  if (next()->IsJSWeakCell()) {
153  JSWeakCell* next_cell = JSWeakCell::cast(next());
154  next_cell->set_prev(prev());
155  }
156  set_prev(ReadOnlyRoots(isolate).undefined_value());
157  set_next(ReadOnlyRoots(isolate).undefined_value());
158 
159  set_holdings(ReadOnlyRoots(isolate).undefined_value());
160  set_factory(ReadOnlyRoots(isolate).undefined_value());
161  } else {
162  // Already cleared.
163  DCHECK(next()->IsUndefined(isolate));
164  DCHECK(prev()->IsUndefined(isolate));
165  DCHECK(holdings()->IsUndefined(isolate));
166  DCHECK(factory()->IsUndefined(isolate));
167  }
168 }
169 
170 } // namespace internal
171 } // namespace v8
172 
173 #include "src/objects/object-macros-undef.h"
174 
175 #endif // V8_OBJECTS_JS_WEAK_REFS_INL_H_
Definition: libplatform.h:13