Commit 33439472 authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

Reland [js weak refs] Add WeakCell.clear()

Previous version:
https://chromium-review.googlesource.com/c/v8/v8/+/1292058

BUG=v8:8179
TBR=hpayer@chromium.org, gsathya@chromium.org

Change-Id: Ia79b75a0630c5926e59206c29053addc88bfb6fe
Reviewed-on: https://chromium-review.googlesource.com/c/1296210Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarHannes Payer <hpayer@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56886}
parent 0c76110d
......@@ -4565,7 +4565,6 @@ void Genesis::InitializeGlobal_harmony_weak_refs() {
factory->NewJSObject(isolate()->object_function(), TENURED);
Map::SetPrototype(isolate(), weak_cell_map, weak_cell_prototype);
// TODO(marja): install functions here.
JSObject::AddProperty(
isolate(), weak_cell_prototype, factory->to_string_tag_symbol(),
factory->WeakCell_string(),
......@@ -4574,6 +4573,9 @@ void Genesis::InitializeGlobal_harmony_weak_refs() {
SimpleInstallGetter(isolate(), weak_cell_prototype,
factory->holdings_string(),
Builtins::kWeakCellHoldingsGetter, false);
Handle<String> clear_name = factory->clear_string();
SimpleInstallFunction(isolate(), weak_cell_prototype, clear_name,
Builtins::kWeakCellClear, 0, false);
}
{
......
......@@ -1336,6 +1336,7 @@ namespace internal {
CPP(Trace) \
\
/* Weak refs */ \
CPP(WeakCellClear) \
CPP(WeakCellHoldingsGetter) \
CPP(WeakFactoryCleanupIteratorNext) \
CPP(WeakFactoryConstructor) \
......
......@@ -94,5 +94,12 @@ BUILTIN(WeakCellHoldingsGetter) {
return weak_cell->holdings();
}
BUILTIN(WeakCellClear) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSWeakCell, weak_cell, "WeakCell.clear");
weak_cell->Clear(isolate);
return ReadOnlyRoots(isolate).undefined_value();
}
} // namespace internal
} // namespace v8
......@@ -117,6 +117,7 @@
V(_, cell_value_string, "%cell_value") \
V(_, char_at_string, "CharAt") \
V(_, character_string, "character") \
V(_, clear_string, "clear") \
V(_, closure_string, "(closure)") \
V(_, code_string, "code") \
V(_, column_string, "column") \
......
......@@ -2098,8 +2098,8 @@ void MarkCompactCollector::ClearJSWeakCells() {
// We do not insert cleared weak cells into the list, so the value
// cannot be a Smi here.
HeapObject* target = HeapObject::cast(weak_cell->target());
JSWeakFactory* weak_factory = weak_cell->factory();
if (!non_atomic_marking_state()->IsBlackOrGrey(target)) {
JSWeakFactory* weak_factory = JSWeakFactory::cast(weak_cell->factory());
if (!weak_factory->scheduled_for_cleanup()) {
isolate()->native_context()->AddDirtyJSWeakFactory(
weak_factory, isolate(),
......
......@@ -1251,7 +1251,7 @@ void JSWeakCell::JSWeakCellVerify(Isolate* isolate) {
CHECK_EQ(JSWeakCell::cast(prev())->next(), this);
}
CHECK(factory()->IsJSWeakFactory());
CHECK(factory()->IsUndefined(isolate) || factory()->IsJSWeakFactory());
}
void JSWeakFactory::JSWeakFactoryVerify(Isolate* isolate) {
......
......@@ -18972,9 +18972,12 @@ void JSWeakFactory::CleanupJSWeakFactoriesCallback(void* data) {
weak_factory->set_next(ReadOnlyRoots(isolate).undefined_value());
weak_factory->set_scheduled_for_cleanup(false);
// TODO(marja): After WeakCell.clear() is added, it's possible that it's
// called for something already in cleared_cells list. In that case, we
// shouldn't call the user's cleanup function.
// It's possible that the cleared_cells list is empty, since
// WeakCell.clear() was called on all its elements before this task ran. In
// that case, don't call the cleanup function.
if (weak_factory->cleared_cells()->IsUndefined(isolate)) {
continue;
}
// Construct the iterator.
Handle<JSWeakFactoryCleanupIterator> iterator;
......
......@@ -23,7 +23,7 @@ SMI_ACCESSORS(JSWeakFactory, flags, kFlagsOffset)
ACCESSORS(JSWeakFactory, next, Object, kNextOffset)
CAST_ACCESSOR(JSWeakFactory)
ACCESSORS(JSWeakCell, factory, JSWeakFactory, kFactoryOffset)
ACCESSORS(JSWeakCell, factory, Object, kFactoryOffset)
ACCESSORS(JSWeakCell, target, Object, kTargetOffset)
ACCESSORS(JSWeakCell, holdings, Object, kHoldingsOffset)
ACCESSORS(JSWeakCell, next, Object, kNextOffset)
......@@ -75,9 +75,9 @@ void JSWeakCell::Nullify(
std::function<void(HeapObject* object, Object** slot, Object* target)>
gc_notify_updated_slot) {
DCHECK(target()->IsJSReceiver());
set_target(Smi::kZero);
set_target(ReadOnlyRoots(isolate).undefined_value());
JSWeakFactory* weak_factory = factory();
JSWeakFactory* weak_factory = JSWeakFactory::cast(factory());
// Remove from the JSWeakCell from the "active_cells" list of its
// JSWeakFactory and insert it into the "cleared" list.
if (prev()->IsJSWeakCell()) {
......@@ -122,6 +122,44 @@ void JSWeakCell::Nullify(
this);
}
void JSWeakCell::Clear(Isolate* isolate) {
// Unlink the JSWeakCell from the list it's in (if any). The JSWeakCell can be
// in its JSWeakFactory's active_cells list, cleared_cells list or neither (if
// it has been already taken out).
DCHECK(target()->IsUndefined() || target()->IsJSReceiver());
set_target(ReadOnlyRoots(isolate).undefined_value());
if (factory()->IsJSWeakFactory()) {
JSWeakFactory* weak_factory = JSWeakFactory::cast(factory());
if (weak_factory->active_cells() == this) {
DCHECK(!prev()->IsJSWeakCell());
weak_factory->set_active_cells(next());
} else if (weak_factory->cleared_cells() == this) {
DCHECK(!prev()->IsJSWeakCell());
weak_factory->set_cleared_cells(next());
} else if (prev()->IsJSWeakCell()) {
JSWeakCell* prev_cell = JSWeakCell::cast(prev());
prev_cell->set_next(next());
}
if (next()->IsJSWeakCell()) {
JSWeakCell* next_cell = JSWeakCell::cast(next());
next_cell->set_prev(prev());
}
set_prev(ReadOnlyRoots(isolate).undefined_value());
set_next(ReadOnlyRoots(isolate).undefined_value());
set_holdings(ReadOnlyRoots(isolate).undefined_value());
set_factory(ReadOnlyRoots(isolate).undefined_value());
} else {
// Already cleared.
DCHECK(next()->IsUndefined(isolate));
DCHECK(prev()->IsUndefined(isolate));
DCHECK(holdings()->IsUndefined(isolate));
DCHECK(factory()->IsUndefined(isolate));
}
}
} // namespace internal
} // namespace v8
......
......@@ -68,7 +68,7 @@ class JSWeakCell : public JSObject {
DECL_VERIFIER(JSWeakCell)
DECL_CAST(JSWeakCell)
DECL_ACCESSORS(factory, JSWeakFactory)
DECL_ACCESSORS(factory, Object)
DECL_ACCESSORS(target, Object)
DECL_ACCESSORS(holdings, Object)
......@@ -94,6 +94,8 @@ class JSWeakCell : public JSObject {
std::function<void(HeapObject* object, Object** slot, Object* target)>
gc_notify_updated_slot);
inline void Clear(Isolate* isolate);
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSWeakCell);
};
......
......@@ -51,6 +51,15 @@ void NullifyWeakCell(Handle<JSWeakCell> weak_cell, Isolate* isolate) {
#endif // VERIFY_HEAP
}
void ClearWeakCell(Handle<JSWeakCell> weak_cell, Isolate* isolate) {
weak_cell->Clear(isolate);
CHECK(weak_cell->next()->IsUndefined(isolate));
CHECK(weak_cell->prev()->IsUndefined(isolate));
#ifdef VERIFY_HEAP
weak_cell->JSWeakCellVerify(isolate);
#endif // VERIFY_HEAP
}
TEST(TestJSWeakCellCreation) {
FLAG_harmony_weak_refs = true;
CcTest::InitializeVM();
......@@ -187,5 +196,123 @@ TEST(TestJSWeakFactoryPopClearedCell) {
CHECK(weak_factory->cleared_cells()->IsUndefined(isolate));
}
TEST(TestJSWeakCellClearActiveCells) {
FLAG_harmony_weak_refs = true;
CcTest::InitializeVM();
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
HandleScope outer_scope(isolate);
Handle<JSWeakFactory> weak_factory = ConstructJSWeakFactory(isolate);
Handle<JSObject> js_object =
isolate->factory()->NewJSObject(isolate->object_function());
Handle<JSWeakCell> weak_cell1 = MakeCell(isolate, js_object, weak_factory);
Handle<JSWeakCell> weak_cell2 = MakeCell(isolate, js_object, weak_factory);
Handle<JSWeakCell> weak_cell3 = MakeCell(isolate, js_object, weak_factory);
CHECK_EQ(weak_factory->active_cells(), *weak_cell3);
CHECK(weak_cell3->prev()->IsUndefined(isolate));
CHECK_EQ(weak_cell3->next(), *weak_cell2);
CHECK_EQ(weak_cell2->prev(), *weak_cell3);
CHECK_EQ(weak_cell2->next(), *weak_cell1);
CHECK_EQ(weak_cell1->prev(), *weak_cell2);
CHECK(weak_cell1->next()->IsUndefined(isolate));
// Clear all JSWeakCells in active_cells and verify the consistency of the
// active_cells list in all stages.
ClearWeakCell(weak_cell2, isolate);
CHECK_EQ(weak_factory->active_cells(), *weak_cell3);
CHECK(weak_cell3->prev()->IsUndefined(isolate));
CHECK_EQ(weak_cell3->next(), *weak_cell1);
CHECK_EQ(weak_cell1->prev(), *weak_cell3);
CHECK(weak_cell1->next()->IsUndefined(isolate));
ClearWeakCell(weak_cell3, isolate);
CHECK_EQ(weak_factory->active_cells(), *weak_cell1);
CHECK(weak_cell1->prev()->IsUndefined(isolate));
CHECK(weak_cell1->next()->IsUndefined(isolate));
ClearWeakCell(weak_cell1, isolate);
CHECK(weak_factory->active_cells()->IsUndefined(isolate));
}
TEST(TestJSWeakCellClearClearedCells) {
FLAG_harmony_weak_refs = true;
CcTest::InitializeVM();
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
HandleScope outer_scope(isolate);
Handle<JSWeakFactory> weak_factory = ConstructJSWeakFactory(isolate);
Handle<JSObject> js_object =
isolate->factory()->NewJSObject(isolate->object_function());
Handle<JSWeakCell> weak_cell1 = MakeCell(isolate, js_object, weak_factory);
Handle<JSWeakCell> weak_cell2 = MakeCell(isolate, js_object, weak_factory);
Handle<JSWeakCell> weak_cell3 = MakeCell(isolate, js_object, weak_factory);
NullifyWeakCell(weak_cell1, isolate);
NullifyWeakCell(weak_cell2, isolate);
NullifyWeakCell(weak_cell3, isolate);
CHECK_EQ(weak_factory->cleared_cells(), *weak_cell3);
CHECK(weak_cell3->prev()->IsUndefined(isolate));
CHECK_EQ(weak_cell3->next(), *weak_cell2);
CHECK_EQ(weak_cell2->prev(), *weak_cell3);
CHECK_EQ(weak_cell2->next(), *weak_cell1);
CHECK_EQ(weak_cell1->prev(), *weak_cell2);
CHECK(weak_cell1->next()->IsUndefined(isolate));
// Clear all JSWeakCells in cleared_cells and verify the consistency of the
// cleared_cells list in all stages.
ClearWeakCell(weak_cell2, isolate);
CHECK_EQ(weak_factory->cleared_cells(), *weak_cell3);
CHECK(weak_cell3->prev()->IsUndefined(isolate));
CHECK_EQ(weak_cell3->next(), *weak_cell1);
CHECK_EQ(weak_cell1->prev(), *weak_cell3);
CHECK(weak_cell1->next()->IsUndefined(isolate));
ClearWeakCell(weak_cell3, isolate);
CHECK_EQ(weak_factory->cleared_cells(), *weak_cell1);
CHECK(weak_cell1->prev()->IsUndefined(isolate));
CHECK(weak_cell1->next()->IsUndefined(isolate));
ClearWeakCell(weak_cell1, isolate);
CHECK(weak_factory->cleared_cells()->IsUndefined(isolate));
}
TEST(TestJSWeakCellClearTwice) {
FLAG_harmony_weak_refs = true;
CcTest::InitializeVM();
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
HandleScope outer_scope(isolate);
Handle<JSWeakFactory> weak_factory = ConstructJSWeakFactory(isolate);
Handle<JSObject> js_object =
isolate->factory()->NewJSObject(isolate->object_function());
Handle<JSWeakCell> weak_cell1 = MakeCell(isolate, js_object, weak_factory);
ClearWeakCell(weak_cell1, isolate);
ClearWeakCell(weak_cell1, isolate);
}
TEST(TestJSWeakCellClearPopped) {
FLAG_harmony_weak_refs = true;
CcTest::InitializeVM();
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
HandleScope outer_scope(isolate);
Handle<JSWeakFactory> weak_factory = ConstructJSWeakFactory(isolate);
Handle<JSObject> js_object =
isolate->factory()->NewJSObject(isolate->object_function());
Handle<JSWeakCell> weak_cell1 = MakeCell(isolate, js_object, weak_factory);
NullifyWeakCell(weak_cell1, isolate);
JSWeakCell* cleared1 = weak_factory->PopClearedCell(isolate);
CHECK_EQ(cleared1, *weak_cell1);
ClearWeakCell(weak_cell1, isolate);
}
} // namespace internal
} // namespace v8
......@@ -32,11 +32,17 @@
assertNotSame(wc.__proto__, Object.prototype);
assertSame(wc.__proto__.__proto__, Object.prototype);
assertEquals(wc.holdings, undefined);
let desc = Object.getOwnPropertyDescriptor(wc.__proto__, "holdings");
assertEquals(true, desc.configurable);
assertEquals(false, desc.enumerable);
assertEquals("function", typeof desc.get);
assertEquals(undefined, desc.set);
let holdings_desc = Object.getOwnPropertyDescriptor(wc.__proto__, "holdings");
assertEquals(true, holdings_desc.configurable);
assertEquals(false, holdings_desc.enumerable);
assertEquals("function", typeof holdings_desc.get);
assertEquals(undefined, holdings_desc.set);
let clear_desc = Object.getOwnPropertyDescriptor(wc.__proto__, "clear");
assertEquals(true, clear_desc.configurable);
assertEquals(false, clear_desc.enumerable);
assertEquals("function", typeof clear_desc.value);
})();
(function TestMakeCellWithHoldings() {
......@@ -112,3 +118,12 @@
// Does not throw:
holdings_getter.call(wc);
})();
(function TestClearWithoutWeakCell() {
let wf = new WeakFactory();
let wc = wf.makeCell({});
let clear = Object.getOwnPropertyDescriptor(wc.__proto__, "clear").value;
assertThrows(() => clear.call({}), TypeError);
// Does not throw:
clear.call(wc);
})();
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-weak-refs --expose-gc
let cleanup_call_count = 0;
let cleanup_weak_cell_count = 0;
let cleanup = function(iter) {
for (wc of iter) {
assertSame(wc, weak_cell);
++cleanup_weak_cell_count;
}
++cleanup_call_count;
}
let wf = new WeakFactory(cleanup);
// Create an object and a WeakCell pointing to it. The object needs to be inside
// a closure so that we can reliably kill them!
let weak_cell;
(function() {
let object = {};
weak_cell = wf.makeCell(object);
// object goes out of scope.
})();
// This GC will discover dirty WeakCells and schedule cleanup.
gc();
assertEquals(0, cleanup_call_count);
// Assert that the cleanup function was called and iterated the WeakCell.
let timeout_func = function() {
assertEquals(1, cleanup_call_count);
assertEquals(1, cleanup_weak_cell_count);
// Clear an already iterated over WeakCell.
weak_cell.clear();
// Assert that it didn't do anything.
setTimeout(() => { assertEquals(1, cleanup_call_count); }, 0);
setTimeout(() => { assertEquals(1, cleanup_weak_cell_count); }, 0);
}
setTimeout(timeout_func, 0);
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-weak-refs --expose-gc
let cleanup_call_count = 0;
let cleanup = function(iter) {
++cleanup_call_count;
}
let wf = new WeakFactory(cleanup);
// Create an object and a WeakCell pointing to it. The object needs to be inside
// a closure so that we can reliably kill them!
let weak_cell;
(function() {
let object = {};
weak_cell = wf.makeCell(object, "my holdings");
// Clear the WeakCell before the GC has a chance to discover it.
let return_value = weak_cell.clear();
assertEquals(undefined, return_value);
// Assert holdings got cleared too.
assertEquals(undefined, weak_cell.holdings);
// object goes out of scope.
})();
// This GC will discover dirty WeakCells.
gc();
assertEquals(0, cleanup_call_count);
// Assert that the cleanup function won't be called, since the WeakCell was cleared.
let timeout_func = function() {
assertEquals(0, cleanup_call_count);
}
setTimeout(timeout_func, 0);
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-weak-refs --expose-gc
let cleanup_call_count = 0;
let cleanup = function(iter) {
++cleanup_call_count;
}
let wf = new WeakFactory(cleanup);
// Create an object and a WeakCell pointing to it. The object needs to be inside
// a closure so that we can reliably kill them!
let weak_cell;
(function() {
let object = {};
weak_cell = wf.makeCell(object);
// Clear the WeakCell before the GC has a chance to discover it.
weak_cell.clear();
// Call clear again (just to assert we handle this gracefully).
weak_cell.clear();
// object goes out of scope.
})();
// This GC will discover dirty WeakCells.
gc();
assertEquals(0, cleanup_call_count);
// Assert that the cleanup function won't be called, since the WeakCell was cleared.
let timeout_func = function() {
assertEquals(0, cleanup_call_count);
}
setTimeout(timeout_func, 0);
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-weak-refs --expose-gc
// Test that WeakCell.prototype.clear() also clears the WeakFactory pointer of
// WeakCell. The only way to observe this is to assert that the WeakCell no
// longer keeps its WeakFactory alive after clear() has been called.
let weak_cell;
let weak_cell_pointing_to_factory;
let cleanup1_call_count = 0;
let cleanup2_call_count = 0;
let cleanup1 = function() {
++cleanup1_call_count;
}
let cleanup2 = function() {
++cleanup2_call_count;
}
let wf1 = new WeakFactory(cleanup1);
(function(){
let wf2 = new WeakFactory(cleanup2);
(function() {
let object = {};
weak_cell = wf2.makeCell(object);
// object goes out of scope.
})();
weak_cell_pointing_to_factory = wf1.makeCell(wf2);
// wf goes out of scope
})();
weak_cell.clear();
gc();
// Assert that weak_cell_pointing_to_factory now got cleared.
let timeout_func = function() {
assertEquals(1, cleanup1_call_count);
assertEquals(0, cleanup2_call_count);
}
setTimeout(timeout_func, 0);
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-weak-refs --expose-gc
let cleanup_call_count = 0;
let cleanup_weak_cell_count = 0;
let cleanup = function(iter) {
// Clear the WeakCell before we've iterated through it.
weak_cell.clear();
for (wc of iter) {
++cleanup_weak_cell_count;
}
++cleanup_call_count;
}
let wf = new WeakFactory(cleanup);
// Create an object and a WeakCell pointing to it. The object needs to be inside
// a closure so that we can reliably kill them!
let weak_cell;
(function() {
let object = {};
weak_cell = wf.makeCell(object);
// object goes out of scope.
})();
// This GC will discover dirty WeakCells and schedule cleanup.
gc();
assertEquals(0, cleanup_call_count);
// Assert that the cleanup function was called, but didn't iterate any weak cells.
let timeout_func = function() {
assertEquals(1, cleanup_call_count);
assertEquals(0, cleanup_weak_cell_count);
}
setTimeout(timeout_func, 0);
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-weak-refs --expose-gc
let cleanup_call_count = 0;
let cleanup_weak_cell_count = 0;
let cleanup = function(iter) {
for (wc of iter) {
assertSame(wc, weak_cell);
wc.clear();
++cleanup_weak_cell_count;
}
++cleanup_call_count;
}
let wf = new WeakFactory(cleanup);
// Create an object and a WeakCell pointing to it. The object needs to be inside
// a closure so that we can reliably kill them!
let weak_cell;
(function() {
let object = {};
weak_cell = wf.makeCell(object);
// object goes out of scope.
})();
// This GC will discover dirty WeakCells and schedule cleanup.
gc();
assertEquals(0, cleanup_call_count);
// Assert that the cleanup function was called and iterated the WeakCell.
let timeout_func = function() {
assertEquals(1, cleanup_call_count);
assertEquals(1, cleanup_weak_cell_count);
}
setTimeout(timeout_func, 0);
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-weak-refs --expose-gc
let cleanup_call_count = 0;
let cleanup_weak_cell_count = 0;
let cleanup = function(iter) {
for (wc of iter) {
assertSame(wc, weak_cell);
++cleanup_weak_cell_count;
}
// Clear an already iterated over WeakCell.
weak_cell.clear();
++cleanup_call_count;
}
let wf = new WeakFactory(cleanup);
// Create an object and a WeakCell pointing to it. The object needs to be inside
// a closure so that we can reliably kill them!
let weak_cell;
(function() {
let object = {};
weak_cell = wf.makeCell(object);
// object goes out of scope.
})();
// This GC will discover dirty WeakCells and schedule cleanup.
gc();
assertEquals(0, cleanup_call_count);
// Assert that the cleanup function was called and iterated the WeakCell.
let timeout_func = function() {
assertEquals(1, cleanup_call_count);
assertEquals(1, cleanup_weak_cell_count);
}
setTimeout(timeout_func, 0);
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-weak-refs --expose-gc
let cleanup_call_count = 0;
let cleanup_weak_cell_count = 0;
let cleanup = function(iter) {
for (wc of iter) {
// See which WeakCell we're iterating over and clear the other one.
if (wc == weak_cell1) {
weak_cell2.clear();
} else {
assertSame(wc, weak_cell2);
weak_cell1.clear();
}
++cleanup_weak_cell_count;
}
++cleanup_call_count;
}
let wf = new WeakFactory(cleanup);
// Create an object and a WeakCell pointing to it. The object needs to be inside
// a closure so that we can reliably kill them!
let weak_cell1;
let weak_cell2;
(function() {
let object1 = {};
weak_cell1 = wf.makeCell(object1);
let object2 = {};
weak_cell2 = wf.makeCell(object2);
// object1 and object2 go out of scope.
})();
// This GC will discover dirty WeakCells and schedule cleanup.
gc();
assertEquals(0, cleanup_call_count);
// Assert that the cleanup function was called and iterated one WeakCell (but not the other one).
let timeout_func = function() {
assertEquals(1, cleanup_call_count);
assertEquals(1, cleanup_weak_cell_count);
}
setTimeout(timeout_func, 0);
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-weak-refs --expose-gc
let cleanup_call_count = 0;
let cleanup = function(iter) {
++cleanup_call_count;
}
let wf = new WeakFactory(cleanup);
// Create an object and a WeakCell pointing to it. The object needs to be inside
// a closure so that we can reliably kill them!
let weak_cell;
(function() {
let object = {};
weak_cell = wf.makeCell(object);
// object goes out of scope.
})();
// This GC will discover dirty WeakCells and schedule cleanup.
gc();
assertEquals(0, cleanup_call_count);
// Clear the WeakCell before cleanup has ran.
weak_cell.clear();
// Assert that the cleanup function won't be called, since the WeakCell was cleared.
let timeout_func = function() {
assertEquals(0, cleanup_call_count);
}
setTimeout(timeout_func, 0);
......@@ -296,41 +296,41 @@ KNOWN_MAPS = {
("RO_SPACE", 0x02699): (171, "Tuple2Map"),
("RO_SPACE", 0x02739): (173, "ArrayBoilerplateDescriptionMap"),
("RO_SPACE", 0x02a79): (161, "InterceptorInfoMap"),
("RO_SPACE", 0x05061): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x050b1): (154, "AccessorInfoMap"),
("RO_SPACE", 0x05101): (155, "AccessorPairMap"),
("RO_SPACE", 0x05151): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x051a1): (157, "AllocationMementoMap"),
("RO_SPACE", 0x051f1): (158, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x05241): (159, "DebugInfoMap"),
("RO_SPACE", 0x05291): (160, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x052e1): (162, "InterpreterDataMap"),
("RO_SPACE", 0x05331): (163, "ModuleInfoEntryMap"),
("RO_SPACE", 0x05381): (164, "ModuleMap"),
("RO_SPACE", 0x053d1): (165, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x05421): (166, "PromiseCapabilityMap"),
("RO_SPACE", 0x05471): (167, "PromiseReactionMap"),
("RO_SPACE", 0x054c1): (168, "PrototypeInfoMap"),
("RO_SPACE", 0x05511): (169, "ScriptMap"),
("RO_SPACE", 0x05561): (170, "StackFrameInfoMap"),
("RO_SPACE", 0x055b1): (172, "Tuple3Map"),
("RO_SPACE", 0x05601): (174, "WasmDebugInfoMap"),
("RO_SPACE", 0x05651): (175, "WasmExportedFunctionDataMap"),
("RO_SPACE", 0x056a1): (176, "CallableTaskMap"),
("RO_SPACE", 0x056f1): (177, "CallbackTaskMap"),
("RO_SPACE", 0x05741): (178, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x05791): (179, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x057e1): (180, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x05831): (181, "MicrotaskQueueMap"),
("RO_SPACE", 0x05881): (182, "AllocationSiteWithWeakNextMap"),
("RO_SPACE", 0x058d1): (182, "AllocationSiteWithoutWeakNextMap"),
("RO_SPACE", 0x05921): (214, "LoadHandler1Map"),
("RO_SPACE", 0x05971): (214, "LoadHandler2Map"),
("RO_SPACE", 0x059c1): (214, "LoadHandler3Map"),
("RO_SPACE", 0x05a11): (221, "StoreHandler0Map"),
("RO_SPACE", 0x05a61): (221, "StoreHandler1Map"),
("RO_SPACE", 0x05ab1): (221, "StoreHandler2Map"),
("RO_SPACE", 0x05b01): (221, "StoreHandler3Map"),
("RO_SPACE", 0x05079): (153, "AccessCheckInfoMap"),
("RO_SPACE", 0x050c9): (154, "AccessorInfoMap"),
("RO_SPACE", 0x05119): (155, "AccessorPairMap"),
("RO_SPACE", 0x05169): (156, "AliasedArgumentsEntryMap"),
("RO_SPACE", 0x051b9): (157, "AllocationMementoMap"),
("RO_SPACE", 0x05209): (158, "AsyncGeneratorRequestMap"),
("RO_SPACE", 0x05259): (159, "DebugInfoMap"),
("RO_SPACE", 0x052a9): (160, "FunctionTemplateInfoMap"),
("RO_SPACE", 0x052f9): (162, "InterpreterDataMap"),
("RO_SPACE", 0x05349): (163, "ModuleInfoEntryMap"),
("RO_SPACE", 0x05399): (164, "ModuleMap"),
("RO_SPACE", 0x053e9): (165, "ObjectTemplateInfoMap"),
("RO_SPACE", 0x05439): (166, "PromiseCapabilityMap"),
("RO_SPACE", 0x05489): (167, "PromiseReactionMap"),
("RO_SPACE", 0x054d9): (168, "PrototypeInfoMap"),
("RO_SPACE", 0x05529): (169, "ScriptMap"),
("RO_SPACE", 0x05579): (170, "StackFrameInfoMap"),
("RO_SPACE", 0x055c9): (172, "Tuple3Map"),
("RO_SPACE", 0x05619): (174, "WasmDebugInfoMap"),
("RO_SPACE", 0x05669): (175, "WasmExportedFunctionDataMap"),
("RO_SPACE", 0x056b9): (176, "CallableTaskMap"),
("RO_SPACE", 0x05709): (177, "CallbackTaskMap"),
("RO_SPACE", 0x05759): (178, "PromiseFulfillReactionJobTaskMap"),
("RO_SPACE", 0x057a9): (179, "PromiseRejectReactionJobTaskMap"),
("RO_SPACE", 0x057f9): (180, "PromiseResolveThenableJobTaskMap"),
("RO_SPACE", 0x05849): (181, "MicrotaskQueueMap"),
("RO_SPACE", 0x05899): (182, "AllocationSiteWithWeakNextMap"),
("RO_SPACE", 0x058e9): (182, "AllocationSiteWithoutWeakNextMap"),
("RO_SPACE", 0x05939): (214, "LoadHandler1Map"),
("RO_SPACE", 0x05989): (214, "LoadHandler2Map"),
("RO_SPACE", 0x059d9): (214, "LoadHandler3Map"),
("RO_SPACE", 0x05a29): (221, "StoreHandler0Map"),
("RO_SPACE", 0x05a79): (221, "StoreHandler1Map"),
("RO_SPACE", 0x05ac9): (221, "StoreHandler2Map"),
("RO_SPACE", 0x05b19): (221, "StoreHandler3Map"),
("MAP_SPACE", 0x00139): (1057, "ExternalMap"),
("MAP_SPACE", 0x00189): (1073, "JSMessageObjectMap"),
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment