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 : #include "src/handles-inl.h"
6 : #include "src/heap/factory-inl.h"
7 : #include "src/isolate.h"
8 : #include "src/microtask-queue.h"
9 : #include "src/objects/js-objects.h"
10 : #include "src/objects/js-weak-refs-inl.h"
11 : #include "test/cctest/cctest.h"
12 : #include "test/cctest/heap/heap-utils.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 40 : Handle<JSWeakFactory> ConstructJSWeakFactory(Isolate* isolate) {
18 : Factory* factory = isolate->factory();
19 : Handle<String> weak_factory_name = factory->WeakFactory_string();
20 : Handle<Object> global =
21 120 : handle(isolate->native_context()->global_object(), isolate);
22 : Handle<JSFunction> weak_factory_fun = Handle<JSFunction>::cast(
23 40 : Object::GetProperty(isolate, global, weak_factory_name)
24 80 : .ToHandleChecked());
25 : auto weak_factory = Handle<JSWeakFactory>::cast(
26 : JSObject::New(weak_factory_fun, weak_factory_fun,
27 40 : Handle<AllocationSite>::null())
28 80 : .ToHandleChecked());
29 : #ifdef VERIFY_HEAP
30 : weak_factory->JSWeakFactoryVerify(isolate);
31 : #endif // VERIFY_HEAP
32 40 : return weak_factory;
33 : }
34 :
35 20 : Handle<JSWeakRef> ConstructJSWeakRef(Isolate* isolate,
36 : Handle<JSReceiver> target) {
37 : Factory* factory = isolate->factory();
38 : Handle<String> weak_ref_name = factory->WeakRef_string();
39 : Handle<Object> global =
40 60 : handle(isolate->native_context()->global_object(), isolate);
41 : Handle<JSFunction> weak_ref_fun = Handle<JSFunction>::cast(
42 40 : Object::GetProperty(isolate, global, weak_ref_name).ToHandleChecked());
43 : auto weak_ref = Handle<JSWeakRef>::cast(
44 20 : JSObject::New(weak_ref_fun, weak_ref_fun, Handle<AllocationSite>::null())
45 40 : .ToHandleChecked());
46 40 : weak_ref->set_target(*target);
47 : #ifdef VERIFY_HEAP
48 : weak_ref->JSWeakRefVerify(isolate);
49 : #endif // VERIFY_HEAP
50 20 : return weak_ref;
51 : }
52 :
53 85 : Handle<JSWeakCell> MakeCell(Isolate* isolate, Handle<JSObject> js_object,
54 : Handle<JSWeakFactory> weak_factory) {
55 255 : Handle<Map> weak_cell_map(isolate->native_context()->js_weak_cell_map(),
56 85 : isolate);
57 : Handle<JSWeakCell> weak_cell =
58 : Handle<JSWeakCell>::cast(isolate->factory()->NewJSObjectFromMap(
59 85 : weak_cell_map, TENURED, Handle<AllocationSite>::null()));
60 170 : weak_cell->set_target(*js_object);
61 85 : weak_factory->AddWeakCell(*weak_cell);
62 : #ifdef VERIFY_HEAP
63 : weak_cell->JSWeakCellVerify(isolate);
64 : #endif // VERIFY_HEAP
65 85 : return weak_cell;
66 : }
67 :
68 55 : void NullifyWeakCell(Handle<JSWeakCell> weak_cell, Isolate* isolate) {
69 : auto empty_func = [](HeapObject object, ObjectSlot slot, Object target) {};
70 110 : weak_cell->Nullify(isolate, empty_func);
71 : #ifdef VERIFY_HEAP
72 : weak_cell->JSWeakCellVerify(isolate);
73 : #endif // VERIFY_HEAP
74 55 : }
75 :
76 45 : void ClearWeakCell(Handle<JSWeakCell> weak_cell, Isolate* isolate) {
77 45 : weak_cell->Clear(isolate);
78 90 : CHECK(weak_cell->next()->IsUndefined(isolate));
79 90 : CHECK(weak_cell->prev()->IsUndefined(isolate));
80 : #ifdef VERIFY_HEAP
81 : weak_cell->JSWeakCellVerify(isolate);
82 : #endif // VERIFY_HEAP
83 45 : }
84 :
85 28342 : TEST(TestJSWeakCellCreation) {
86 5 : FLAG_harmony_weak_refs = true;
87 5 : CcTest::InitializeVM();
88 5 : LocalContext context;
89 : Isolate* isolate = CcTest::i_isolate();
90 : HandleScope outer_scope(isolate);
91 5 : Handle<JSWeakFactory> weak_factory = ConstructJSWeakFactory(isolate);
92 : Handle<JSObject> js_object =
93 5 : isolate->factory()->NewJSObject(isolate->object_function());
94 :
95 : // Create JSWeakCell and verify internal data structures.
96 5 : Handle<JSWeakCell> weak_cell1 = MakeCell(isolate, js_object, weak_factory);
97 10 : CHECK(weak_cell1->prev()->IsUndefined(isolate));
98 10 : CHECK(weak_cell1->next()->IsUndefined(isolate));
99 :
100 15 : CHECK_EQ(weak_factory->active_cells(), *weak_cell1);
101 10 : CHECK(weak_factory->cleared_cells()->IsUndefined(isolate));
102 :
103 : // Create another JSWeakCell and verify internal data structures.
104 5 : Handle<JSWeakCell> weak_cell2 = MakeCell(isolate, js_object, weak_factory);
105 10 : CHECK(weak_cell2->prev()->IsUndefined(isolate));
106 15 : CHECK_EQ(weak_cell2->next(), *weak_cell1);
107 15 : CHECK_EQ(weak_cell1->prev(), *weak_cell2);
108 10 : CHECK(weak_cell1->next()->IsUndefined(isolate));
109 :
110 15 : CHECK_EQ(weak_factory->active_cells(), *weak_cell2);
111 15 : CHECK(weak_factory->cleared_cells()->IsUndefined(isolate));
112 5 : }
113 :
114 28342 : TEST(TestJSWeakCellNullify1) {
115 5 : FLAG_harmony_weak_refs = true;
116 5 : CcTest::InitializeVM();
117 5 : LocalContext context;
118 : Isolate* isolate = CcTest::i_isolate();
119 : HandleScope outer_scope(isolate);
120 5 : Handle<JSWeakFactory> weak_factory = ConstructJSWeakFactory(isolate);
121 : Handle<JSObject> js_object =
122 5 : isolate->factory()->NewJSObject(isolate->object_function());
123 :
124 5 : Handle<JSWeakCell> weak_cell1 = MakeCell(isolate, js_object, weak_factory);
125 5 : Handle<JSWeakCell> weak_cell2 = MakeCell(isolate, js_object, weak_factory);
126 :
127 : // Nullify the first JSWeakCell and verify internal data structures.
128 5 : NullifyWeakCell(weak_cell1, isolate);
129 15 : CHECK_EQ(weak_factory->active_cells(), *weak_cell2);
130 10 : CHECK(weak_cell2->prev()->IsUndefined(isolate));
131 10 : CHECK(weak_cell2->next()->IsUndefined(isolate));
132 15 : CHECK_EQ(weak_factory->cleared_cells(), *weak_cell1);
133 10 : CHECK(weak_cell1->prev()->IsUndefined(isolate));
134 10 : CHECK(weak_cell1->next()->IsUndefined(isolate));
135 :
136 : // Nullify the second JSWeakCell and verify internal data structures.
137 5 : NullifyWeakCell(weak_cell2, isolate);
138 10 : CHECK(weak_factory->active_cells()->IsUndefined(isolate));
139 15 : CHECK_EQ(weak_factory->cleared_cells(), *weak_cell2);
140 15 : CHECK_EQ(weak_cell2->next(), *weak_cell1);
141 10 : CHECK(weak_cell2->prev()->IsUndefined(isolate));
142 15 : CHECK_EQ(weak_cell1->prev(), *weak_cell2);
143 15 : CHECK(weak_cell1->next()->IsUndefined(isolate));
144 5 : }
145 :
146 28342 : TEST(TestJSWeakCellNullify2) {
147 5 : FLAG_harmony_weak_refs = true;
148 5 : CcTest::InitializeVM();
149 5 : LocalContext context;
150 : Isolate* isolate = CcTest::i_isolate();
151 : HandleScope outer_scope(isolate);
152 5 : Handle<JSWeakFactory> weak_factory = ConstructJSWeakFactory(isolate);
153 : Handle<JSObject> js_object =
154 5 : isolate->factory()->NewJSObject(isolate->object_function());
155 :
156 5 : Handle<JSWeakCell> weak_cell1 = MakeCell(isolate, js_object, weak_factory);
157 5 : Handle<JSWeakCell> weak_cell2 = MakeCell(isolate, js_object, weak_factory);
158 :
159 : // Like TestJSWeakCellNullify1 but clear the JSWeakCells in opposite order.
160 5 : NullifyWeakCell(weak_cell2, isolate);
161 15 : CHECK_EQ(weak_factory->active_cells(), *weak_cell1);
162 10 : CHECK(weak_cell1->prev()->IsUndefined(isolate));
163 10 : CHECK(weak_cell1->next()->IsUndefined(isolate));
164 15 : CHECK_EQ(weak_factory->cleared_cells(), *weak_cell2);
165 10 : CHECK(weak_cell2->prev()->IsUndefined(isolate));
166 10 : CHECK(weak_cell2->next()->IsUndefined(isolate));
167 :
168 5 : NullifyWeakCell(weak_cell1, isolate);
169 10 : CHECK(weak_factory->active_cells()->IsUndefined(isolate));
170 15 : CHECK_EQ(weak_factory->cleared_cells(), *weak_cell1);
171 15 : CHECK_EQ(weak_cell1->next(), *weak_cell2);
172 10 : CHECK(weak_cell1->prev()->IsUndefined(isolate));
173 15 : CHECK_EQ(weak_cell2->prev(), *weak_cell1);
174 15 : CHECK(weak_cell2->next()->IsUndefined(isolate));
175 5 : }
176 :
177 28342 : TEST(TestJSWeakFactoryPopClearedCell) {
178 5 : FLAG_harmony_weak_refs = true;
179 5 : CcTest::InitializeVM();
180 : LocalContext context;
181 : Isolate* isolate = CcTest::i_isolate();
182 : HandleScope outer_scope(isolate);
183 5 : Handle<JSWeakFactory> weak_factory = ConstructJSWeakFactory(isolate);
184 : Handle<JSObject> js_object =
185 5 : isolate->factory()->NewJSObject(isolate->object_function());
186 :
187 5 : Handle<JSWeakCell> weak_cell1 = MakeCell(isolate, js_object, weak_factory);
188 5 : Handle<JSWeakCell> weak_cell2 = MakeCell(isolate, js_object, weak_factory);
189 5 : Handle<JSWeakCell> weak_cell3 = MakeCell(isolate, js_object, weak_factory);
190 :
191 5 : NullifyWeakCell(weak_cell2, isolate);
192 5 : NullifyWeakCell(weak_cell3, isolate);
193 :
194 5 : CHECK(weak_factory->NeedsCleanup());
195 5 : JSWeakCell cleared1 = weak_factory->PopClearedCell(isolate);
196 10 : CHECK_EQ(cleared1, *weak_cell3);
197 10 : CHECK(weak_cell3->prev()->IsUndefined(isolate));
198 10 : CHECK(weak_cell3->next()->IsUndefined(isolate));
199 :
200 5 : CHECK(weak_factory->NeedsCleanup());
201 5 : JSWeakCell cleared2 = weak_factory->PopClearedCell(isolate);
202 10 : CHECK_EQ(cleared2, *weak_cell2);
203 10 : CHECK(weak_cell2->prev()->IsUndefined(isolate));
204 10 : CHECK(weak_cell2->next()->IsUndefined(isolate));
205 :
206 5 : CHECK(!weak_factory->NeedsCleanup());
207 :
208 5 : NullifyWeakCell(weak_cell1, isolate);
209 :
210 5 : CHECK(weak_factory->NeedsCleanup());
211 5 : JSWeakCell cleared3 = weak_factory->PopClearedCell(isolate);
212 10 : CHECK_EQ(cleared3, *weak_cell1);
213 10 : CHECK(weak_cell1->prev()->IsUndefined(isolate));
214 10 : CHECK(weak_cell1->next()->IsUndefined(isolate));
215 :
216 5 : CHECK(!weak_factory->NeedsCleanup());
217 10 : CHECK(weak_factory->active_cells()->IsUndefined(isolate));
218 15 : CHECK(weak_factory->cleared_cells()->IsUndefined(isolate));
219 5 : }
220 :
221 28342 : TEST(TestJSWeakCellClearActiveCells) {
222 5 : FLAG_harmony_weak_refs = true;
223 5 : CcTest::InitializeVM();
224 5 : LocalContext context;
225 : Isolate* isolate = CcTest::i_isolate();
226 : HandleScope outer_scope(isolate);
227 5 : Handle<JSWeakFactory> weak_factory = ConstructJSWeakFactory(isolate);
228 : Handle<JSObject> js_object =
229 5 : isolate->factory()->NewJSObject(isolate->object_function());
230 :
231 5 : Handle<JSWeakCell> weak_cell1 = MakeCell(isolate, js_object, weak_factory);
232 5 : Handle<JSWeakCell> weak_cell2 = MakeCell(isolate, js_object, weak_factory);
233 5 : Handle<JSWeakCell> weak_cell3 = MakeCell(isolate, js_object, weak_factory);
234 :
235 15 : CHECK_EQ(weak_factory->active_cells(), *weak_cell3);
236 10 : CHECK(weak_cell3->prev()->IsUndefined(isolate));
237 15 : CHECK_EQ(weak_cell3->next(), *weak_cell2);
238 15 : CHECK_EQ(weak_cell2->prev(), *weak_cell3);
239 15 : CHECK_EQ(weak_cell2->next(), *weak_cell1);
240 15 : CHECK_EQ(weak_cell1->prev(), *weak_cell2);
241 10 : CHECK(weak_cell1->next()->IsUndefined(isolate));
242 :
243 : // Clear all JSWeakCells in active_cells and verify the consistency of the
244 : // active_cells list in all stages.
245 5 : ClearWeakCell(weak_cell2, isolate);
246 15 : CHECK_EQ(weak_factory->active_cells(), *weak_cell3);
247 10 : CHECK(weak_cell3->prev()->IsUndefined(isolate));
248 15 : CHECK_EQ(weak_cell3->next(), *weak_cell1);
249 15 : CHECK_EQ(weak_cell1->prev(), *weak_cell3);
250 10 : CHECK(weak_cell1->next()->IsUndefined(isolate));
251 :
252 5 : ClearWeakCell(weak_cell3, isolate);
253 15 : CHECK_EQ(weak_factory->active_cells(), *weak_cell1);
254 10 : CHECK(weak_cell1->prev()->IsUndefined(isolate));
255 10 : CHECK(weak_cell1->next()->IsUndefined(isolate));
256 :
257 5 : ClearWeakCell(weak_cell1, isolate);
258 15 : CHECK(weak_factory->active_cells()->IsUndefined(isolate));
259 5 : }
260 :
261 28342 : TEST(TestJSWeakCellClearClearedCells) {
262 5 : FLAG_harmony_weak_refs = true;
263 5 : CcTest::InitializeVM();
264 5 : LocalContext context;
265 : Isolate* isolate = CcTest::i_isolate();
266 : HandleScope outer_scope(isolate);
267 5 : Handle<JSWeakFactory> weak_factory = ConstructJSWeakFactory(isolate);
268 : Handle<JSObject> js_object =
269 5 : isolate->factory()->NewJSObject(isolate->object_function());
270 :
271 5 : Handle<JSWeakCell> weak_cell1 = MakeCell(isolate, js_object, weak_factory);
272 5 : Handle<JSWeakCell> weak_cell2 = MakeCell(isolate, js_object, weak_factory);
273 5 : Handle<JSWeakCell> weak_cell3 = MakeCell(isolate, js_object, weak_factory);
274 :
275 5 : NullifyWeakCell(weak_cell1, isolate);
276 5 : NullifyWeakCell(weak_cell2, isolate);
277 5 : NullifyWeakCell(weak_cell3, isolate);
278 :
279 15 : CHECK_EQ(weak_factory->cleared_cells(), *weak_cell3);
280 10 : CHECK(weak_cell3->prev()->IsUndefined(isolate));
281 15 : CHECK_EQ(weak_cell3->next(), *weak_cell2);
282 15 : CHECK_EQ(weak_cell2->prev(), *weak_cell3);
283 15 : CHECK_EQ(weak_cell2->next(), *weak_cell1);
284 15 : CHECK_EQ(weak_cell1->prev(), *weak_cell2);
285 10 : CHECK(weak_cell1->next()->IsUndefined(isolate));
286 :
287 : // Clear all JSWeakCells in cleared_cells and verify the consistency of the
288 : // cleared_cells list in all stages.
289 5 : ClearWeakCell(weak_cell2, isolate);
290 15 : CHECK_EQ(weak_factory->cleared_cells(), *weak_cell3);
291 10 : CHECK(weak_cell3->prev()->IsUndefined(isolate));
292 15 : CHECK_EQ(weak_cell3->next(), *weak_cell1);
293 15 : CHECK_EQ(weak_cell1->prev(), *weak_cell3);
294 10 : CHECK(weak_cell1->next()->IsUndefined(isolate));
295 :
296 5 : ClearWeakCell(weak_cell3, isolate);
297 15 : CHECK_EQ(weak_factory->cleared_cells(), *weak_cell1);
298 10 : CHECK(weak_cell1->prev()->IsUndefined(isolate));
299 10 : CHECK(weak_cell1->next()->IsUndefined(isolate));
300 :
301 5 : ClearWeakCell(weak_cell1, isolate);
302 15 : CHECK(weak_factory->cleared_cells()->IsUndefined(isolate));
303 5 : }
304 :
305 28342 : TEST(TestJSWeakCellClearTwice) {
306 5 : FLAG_harmony_weak_refs = true;
307 5 : CcTest::InitializeVM();
308 5 : LocalContext context;
309 : Isolate* isolate = CcTest::i_isolate();
310 : HandleScope outer_scope(isolate);
311 5 : Handle<JSWeakFactory> weak_factory = ConstructJSWeakFactory(isolate);
312 : Handle<JSObject> js_object =
313 5 : isolate->factory()->NewJSObject(isolate->object_function());
314 :
315 5 : Handle<JSWeakCell> weak_cell1 = MakeCell(isolate, js_object, weak_factory);
316 :
317 5 : ClearWeakCell(weak_cell1, isolate);
318 10 : ClearWeakCell(weak_cell1, isolate);
319 5 : }
320 :
321 28342 : TEST(TestJSWeakCellClearPopped) {
322 5 : FLAG_harmony_weak_refs = true;
323 5 : CcTest::InitializeVM();
324 5 : LocalContext context;
325 : Isolate* isolate = CcTest::i_isolate();
326 : HandleScope outer_scope(isolate);
327 5 : Handle<JSWeakFactory> weak_factory = ConstructJSWeakFactory(isolate);
328 : Handle<JSObject> js_object =
329 5 : isolate->factory()->NewJSObject(isolate->object_function());
330 :
331 5 : Handle<JSWeakCell> weak_cell1 = MakeCell(isolate, js_object, weak_factory);
332 5 : NullifyWeakCell(weak_cell1, isolate);
333 5 : JSWeakCell cleared1 = weak_factory->PopClearedCell(isolate);
334 10 : CHECK_EQ(cleared1, *weak_cell1);
335 :
336 10 : ClearWeakCell(weak_cell1, isolate);
337 5 : }
338 :
339 28342 : TEST(TestJSWeakRef) {
340 5 : FLAG_harmony_weak_refs = true;
341 5 : CcTest::InitializeVM();
342 5 : LocalContext context;
343 :
344 : Isolate* isolate = CcTest::i_isolate();
345 : HandleScope outer_scope(isolate);
346 : Handle<JSWeakRef> weak_ref;
347 : {
348 : HandleScope inner_scope(isolate);
349 :
350 : Handle<JSObject> js_object =
351 5 : isolate->factory()->NewJSObject(isolate->object_function());
352 : // This doesn't add the target into the KeepDuringJob set.
353 5 : Handle<JSWeakRef> inner_weak_ref = ConstructJSWeakRef(isolate, js_object);
354 :
355 5 : CcTest::CollectAllGarbage();
356 10 : CHECK(!inner_weak_ref->target()->IsUndefined(isolate));
357 :
358 5 : weak_ref = inner_scope.CloseAndEscape(inner_weak_ref);
359 : }
360 :
361 10 : CHECK(!weak_ref->target()->IsUndefined(isolate));
362 :
363 5 : CcTest::CollectAllGarbage();
364 :
365 15 : CHECK(weak_ref->target()->IsUndefined(isolate));
366 5 : }
367 :
368 28342 : TEST(TestJSWeakRefIncrementalMarking) {
369 5 : FLAG_harmony_weak_refs = true;
370 5 : if (!FLAG_incremental_marking) {
371 0 : return;
372 : }
373 : ManualGCScope manual_gc_scope;
374 5 : CcTest::InitializeVM();
375 10 : LocalContext context;
376 :
377 : Isolate* isolate = CcTest::i_isolate();
378 5 : Heap* heap = isolate->heap();
379 : HandleScope outer_scope(isolate);
380 : Handle<JSWeakRef> weak_ref;
381 : {
382 : HandleScope inner_scope(isolate);
383 :
384 : Handle<JSObject> js_object =
385 5 : isolate->factory()->NewJSObject(isolate->object_function());
386 : // This doesn't add the target into the KeepDuringJob set.
387 5 : Handle<JSWeakRef> inner_weak_ref = ConstructJSWeakRef(isolate, js_object);
388 :
389 5 : heap::SimulateIncrementalMarking(heap, true);
390 5 : CcTest::CollectAllGarbage();
391 10 : CHECK(!inner_weak_ref->target()->IsUndefined(isolate));
392 :
393 5 : weak_ref = inner_scope.CloseAndEscape(inner_weak_ref);
394 : }
395 :
396 10 : CHECK(!weak_ref->target()->IsUndefined(isolate));
397 :
398 5 : heap::SimulateIncrementalMarking(heap, true);
399 5 : CcTest::CollectAllGarbage();
400 :
401 10 : CHECK(weak_ref->target()->IsUndefined(isolate));
402 : }
403 :
404 28342 : TEST(TestJSWeakRefKeepDuringJob) {
405 5 : FLAG_harmony_weak_refs = true;
406 5 : CcTest::InitializeVM();
407 5 : LocalContext context;
408 :
409 5 : Isolate* isolate = CcTest::i_isolate();
410 5 : Heap* heap = isolate->heap();
411 : HandleScope outer_scope(isolate);
412 : Handle<JSWeakRef> weak_ref;
413 : {
414 : HandleScope inner_scope(isolate);
415 :
416 : Handle<JSObject> js_object =
417 5 : isolate->factory()->NewJSObject(isolate->object_function());
418 5 : Handle<JSWeakRef> inner_weak_ref = ConstructJSWeakRef(isolate, js_object);
419 5 : heap->AddKeepDuringJobTarget(js_object);
420 :
421 5 : weak_ref = inner_scope.CloseAndEscape(inner_weak_ref);
422 : }
423 :
424 10 : CHECK(!weak_ref->target()->IsUndefined(isolate));
425 :
426 5 : CcTest::CollectAllGarbage();
427 :
428 10 : CHECK(!weak_ref->target()->IsUndefined(isolate));
429 :
430 : // Clears the KeepDuringJob set.
431 5 : isolate->default_microtask_queue()->RunMicrotasks(isolate);
432 5 : CcTest::CollectAllGarbage();
433 :
434 15 : CHECK(weak_ref->target()->IsUndefined(isolate));
435 5 : }
436 :
437 28342 : TEST(TestJSWeakRefKeepDuringJobIncrementalMarking) {
438 5 : FLAG_harmony_weak_refs = true;
439 5 : if (!FLAG_incremental_marking) {
440 0 : return;
441 : }
442 : ManualGCScope manual_gc_scope;
443 5 : CcTest::InitializeVM();
444 10 : LocalContext context;
445 :
446 5 : Isolate* isolate = CcTest::i_isolate();
447 5 : Heap* heap = isolate->heap();
448 : HandleScope outer_scope(isolate);
449 : Handle<JSWeakRef> weak_ref;
450 : {
451 : HandleScope inner_scope(isolate);
452 :
453 : Handle<JSObject> js_object =
454 5 : isolate->factory()->NewJSObject(isolate->object_function());
455 5 : Handle<JSWeakRef> inner_weak_ref = ConstructJSWeakRef(isolate, js_object);
456 5 : heap->AddKeepDuringJobTarget(js_object);
457 :
458 5 : weak_ref = inner_scope.CloseAndEscape(inner_weak_ref);
459 : }
460 :
461 10 : CHECK(!weak_ref->target()->IsUndefined(isolate));
462 :
463 5 : heap::SimulateIncrementalMarking(heap, true);
464 5 : CcTest::CollectAllGarbage();
465 :
466 10 : CHECK(!weak_ref->target()->IsUndefined(isolate));
467 :
468 : // Clears the KeepDuringJob set.
469 5 : isolate->default_microtask_queue()->RunMicrotasks(isolate);
470 5 : heap::SimulateIncrementalMarking(heap, true);
471 5 : CcTest::CollectAllGarbage();
472 :
473 10 : CHECK(weak_ref->target()->IsUndefined(isolate));
474 : }
475 :
476 : } // namespace internal
477 85011 : } // namespace v8
|