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

[js weak refs] Add cctests

These test mainly the data structures of JSWeakFactory / JSWeakCell.

BUG=v8:8179

Change-Id: I20ffd07c18bbb2e21c69d11aa65d1e245203cc82
Reviewed-on: https://chromium-review.googlesource.com/c/1267939
Commit-Queue: Marja Hölttä <marja@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56569}
parent 87c48d31
...@@ -53,14 +53,8 @@ BUILTIN(WeakFactoryMakeCell) { ...@@ -53,14 +53,8 @@ BUILTIN(WeakFactoryMakeCell) {
Handle<JSWeakCell> weak_cell = Handle<JSWeakCell> weak_cell =
Handle<JSWeakCell>::cast(isolate->factory()->NewJSObjectFromMap( Handle<JSWeakCell>::cast(isolate->factory()->NewJSObjectFromMap(
weak_cell_map, TENURED, Handle<AllocationSite>::null())); weak_cell_map, TENURED, Handle<AllocationSite>::null()));
weak_cell->set_factory(*weak_factory);
weak_cell->set_target(*js_object); weak_cell->set_target(*js_object);
weak_cell->set_prev(ReadOnlyRoots(isolate).undefined_value()); weak_factory->AddWeakCell(*weak_cell);
weak_cell->set_next(weak_factory->active_cells());
if (weak_factory->active_cells()->IsJSWeakCell()) {
JSWeakCell::cast(weak_factory->active_cells())->set_prev(*weak_cell);
}
weak_factory->set_active_cells(*weak_cell);
return *weak_cell; return *weak_cell;
} }
......
...@@ -31,6 +31,15 @@ CAST_ACCESSOR(JSWeakCell) ...@@ -31,6 +31,15 @@ CAST_ACCESSOR(JSWeakCell)
ACCESSORS(JSWeakFactoryCleanupIterator, factory, JSWeakFactory, kFactoryOffset) ACCESSORS(JSWeakFactoryCleanupIterator, factory, JSWeakFactory, kFactoryOffset)
CAST_ACCESSOR(JSWeakFactoryCleanupIterator) CAST_ACCESSOR(JSWeakFactoryCleanupIterator)
void JSWeakFactory::AddWeakCell(JSWeakCell* weak_cell) {
weak_cell->set_factory(this);
weak_cell->set_next(active_cells());
if (active_cells()->IsJSWeakCell()) {
JSWeakCell::cast(active_cells())->set_prev(weak_cell);
}
set_active_cells(weak_cell);
}
bool JSWeakFactory::NeedsCleanup() const { bool JSWeakFactory::NeedsCleanup() const {
return cleared_cells()->IsJSWeakCell(); return cleared_cells()->IsJSWeakCell();
} }
......
...@@ -30,6 +30,9 @@ class JSWeakFactory : public JSObject { ...@@ -30,6 +30,9 @@ class JSWeakFactory : public JSObject {
// For storing a list of JSWeakFactory objects in NativeContext. // For storing a list of JSWeakFactory objects in NativeContext.
DECL_ACCESSORS(next, Object) DECL_ACCESSORS(next, Object)
// Adds a newly constructed JSWeakCell object into this JSWeakFactory.
inline void AddWeakCell(JSWeakCell* weak_cell);
// Returns true if the cleared_cells list is non-empty. // Returns true if the cleared_cells list is non-empty.
inline bool NeedsCleanup() const; inline bool NeedsCleanup() const;
......
...@@ -197,6 +197,7 @@ v8_source_set("cctest_sources") { ...@@ -197,6 +197,7 @@ v8_source_set("cctest_sources") {
"test-inspector.cc", "test-inspector.cc",
"test-intl.cc", "test-intl.cc",
"test-isolate-independent-builtins.cc", "test-isolate-independent-builtins.cc",
"test-js-weak-refs.cc",
"test-liveedit.cc", "test-liveedit.cc",
"test-lockers.cc", "test-lockers.cc",
"test-log.cc", "test-log.cc",
......
// 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.
#include "src/handles-inl.h"
#include "src/heap/factory-inl.h"
#include "src/isolate.h"
#include "test/cctest/cctest.h"
namespace v8 {
namespace internal {
Handle<JSWeakFactory> ConstructJSWeakFactory(Isolate* isolate) {
Factory* factory = isolate->factory();
Handle<String> weak_factory_name = factory->WeakFactory_string();
Handle<Object> global =
handle(isolate->native_context()->global_object(), isolate);
Handle<JSFunction> weak_factory_fun = Handle<JSFunction>::cast(
Object::GetProperty(isolate, global, weak_factory_name)
.ToHandleChecked());
auto weak_factory = Handle<JSWeakFactory>::cast(
JSObject::New(weak_factory_fun, weak_factory_fun,
Handle<AllocationSite>::null())
.ToHandleChecked());
#ifdef VERIFY_HEAP
weak_factory->JSWeakFactoryVerify(isolate);
#endif // VERIFY_HEAP
return weak_factory;
}
Handle<JSWeakCell> MakeCell(Isolate* isolate, Handle<JSObject> js_object,
Handle<JSWeakFactory> weak_factory) {
Handle<Map> weak_cell_map(isolate->native_context()->js_weak_cell_map(),
isolate);
Handle<JSWeakCell> weak_cell =
Handle<JSWeakCell>::cast(isolate->factory()->NewJSObjectFromMap(
weak_cell_map, TENURED, Handle<AllocationSite>::null()));
weak_cell->set_target(*js_object);
weak_factory->AddWeakCell(*weak_cell);
#ifdef VERIFY_HEAP
weak_cell->JSWeakCellVerify(isolate);
#endif // VERIFY_HEAP
return weak_cell;
}
void NullifyWeakCell(Handle<JSWeakCell> weak_cell, Isolate* isolate) {
auto empty_func = [](HeapObject* object, Object** slot, Object* target) {};
weak_cell->Nullify(isolate, empty_func);
#ifdef VERIFY_HEAP
weak_cell->JSWeakCellVerify(isolate);
#endif // VERIFY_HEAP
}
TEST(TestJSWeakCellCreation) {
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());
// Create JSWeakCell and verify internal data structures.
Handle<JSWeakCell> weak_cell1 = MakeCell(isolate, js_object, weak_factory);
CHECK(weak_cell1->prev()->IsUndefined(isolate));
CHECK(weak_cell1->next()->IsUndefined(isolate));
CHECK_EQ(weak_factory->active_cells(), *weak_cell1);
CHECK(weak_factory->cleared_cells()->IsUndefined(isolate));
// Create another JSWeakCell and verify internal data structures.
Handle<JSWeakCell> weak_cell2 = MakeCell(isolate, js_object, weak_factory);
CHECK(weak_cell2->prev()->IsUndefined(isolate));
CHECK_EQ(weak_cell2->next(), *weak_cell1);
CHECK_EQ(weak_cell1->prev(), *weak_cell2);
CHECK(weak_cell1->next()->IsUndefined(isolate));
CHECK_EQ(weak_factory->active_cells(), *weak_cell2);
CHECK(weak_factory->cleared_cells()->IsUndefined(isolate));
}
TEST(TestJSWeakCellNullify1) {
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);
// Nullify the first JSWeakCell and verify internal data structures.
NullifyWeakCell(weak_cell1, isolate);
CHECK_EQ(weak_factory->active_cells(), *weak_cell2);
CHECK(weak_cell2->prev()->IsUndefined(isolate));
CHECK(weak_cell2->next()->IsUndefined(isolate));
CHECK_EQ(weak_factory->cleared_cells(), *weak_cell1);
CHECK(weak_cell1->prev()->IsUndefined(isolate));
CHECK(weak_cell1->next()->IsUndefined(isolate));
// Nullify the second JSWeakCell and verify internal data structures.
NullifyWeakCell(weak_cell2, isolate);
CHECK(weak_factory->active_cells()->IsUndefined(isolate));
CHECK_EQ(weak_factory->cleared_cells(), *weak_cell2);
CHECK_EQ(weak_cell2->next(), *weak_cell1);
CHECK(weak_cell2->prev()->IsUndefined(isolate));
CHECK_EQ(weak_cell1->prev(), *weak_cell2);
CHECK(weak_cell1->next()->IsUndefined(isolate));
}
TEST(TestJSWeakCellNullify2) {
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);
// Like TestJSWeakCellNullify1 but clear the JSWeakCells in opposite order.
NullifyWeakCell(weak_cell2, isolate);
CHECK_EQ(weak_factory->active_cells(), *weak_cell1);
CHECK(weak_cell1->prev()->IsUndefined(isolate));
CHECK(weak_cell1->next()->IsUndefined(isolate));
CHECK_EQ(weak_factory->cleared_cells(), *weak_cell2);
CHECK(weak_cell2->prev()->IsUndefined(isolate));
CHECK(weak_cell2->next()->IsUndefined(isolate));
NullifyWeakCell(weak_cell1, isolate);
CHECK(weak_factory->active_cells()->IsUndefined(isolate));
CHECK_EQ(weak_factory->cleared_cells(), *weak_cell1);
CHECK_EQ(weak_cell1->next(), *weak_cell2);
CHECK(weak_cell1->prev()->IsUndefined(isolate));
CHECK_EQ(weak_cell2->prev(), *weak_cell1);
CHECK(weak_cell2->next()->IsUndefined(isolate));
}
TEST(TestJSWeakFactoryPopClearedCell) {
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_cell2, isolate);
NullifyWeakCell(weak_cell3, isolate);
CHECK(weak_factory->NeedsCleanup());
JSWeakCell* cleared1 = weak_factory->PopClearedCell(isolate);
CHECK_EQ(cleared1, *weak_cell3);
CHECK(weak_cell3->prev()->IsUndefined(isolate));
CHECK(weak_cell3->next()->IsUndefined(isolate));
CHECK(weak_factory->NeedsCleanup());
JSWeakCell* cleared2 = weak_factory->PopClearedCell(isolate);
CHECK_EQ(cleared2, *weak_cell2);
CHECK(weak_cell2->prev()->IsUndefined(isolate));
CHECK(weak_cell2->next()->IsUndefined(isolate));
CHECK(!weak_factory->NeedsCleanup());
NullifyWeakCell(weak_cell1, isolate);
CHECK(weak_factory->NeedsCleanup());
JSWeakCell* cleared3 = weak_factory->PopClearedCell(isolate);
CHECK_EQ(cleared3, *weak_cell1);
CHECK(weak_cell1->prev()->IsUndefined(isolate));
CHECK(weak_cell1->next()->IsUndefined(isolate));
CHECK(!weak_factory->NeedsCleanup());
CHECK(weak_factory->active_cells()->IsUndefined(isolate));
CHECK(weak_factory->cleared_cells()->IsUndefined(isolate));
}
} // namespace internal
} // namespace v8
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