[test] Move cctest/test-concurrent-transition-array to
... unittests/objects/concurrent-transition-array-unittest. Bug: v8:12781 Change-Id: Ic6fbef71e1439c0a0056b122a4b42dcad674ca3b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3604961 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Commit-Queue: 王澳 <wangao.james@bytedance.com> Cr-Commit-Position: refs/heads/main@{#80174}
This commit is contained in:
parent
95dab01426
commit
237116d99d
@ -195,7 +195,6 @@ v8_source_set("cctest_sources") {
|
||||
"test-atomicops.cc",
|
||||
"test-bignum-dtoa.cc",
|
||||
"test-code-stub-assembler.cc",
|
||||
"test-concurrent-transition-array.cc",
|
||||
"test-constantpool.cc",
|
||||
"test-cpu-profiler.cc",
|
||||
"test-debug-helper.cc",
|
||||
|
@ -379,6 +379,7 @@ v8_source_set("unittests_sources") {
|
||||
"objects/concurrent-prototype-unittest.cc",
|
||||
"objects/concurrent-script-context-table-unittest.cc",
|
||||
"objects/concurrent-string-unittest.cc",
|
||||
"objects/concurrent-transition-array-unittest.cc",
|
||||
"objects/object-unittest.cc",
|
||||
"objects/swiss-hash-table-helpers-unittest.cc",
|
||||
"objects/value-serializer-unittest.cc",
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright 2020 the V8 project authors. All rights reserved.
|
||||
// Copyright 2022 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.
|
||||
|
||||
@ -10,11 +10,13 @@
|
||||
#include "src/heap/local-heap.h"
|
||||
#include "src/heap/parked-scope.h"
|
||||
#include "src/objects/transitions-inl.h"
|
||||
#include "test/cctest/cctest.h"
|
||||
#include "test/cctest/heap/heap-utils.h"
|
||||
#include "test/cctest/test-transitions.h"
|
||||
#include "test/unittests/test-utils.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace v8 {
|
||||
|
||||
using ConcurrentTransitionArrayTest = TestWithContext;
|
||||
|
||||
namespace internal {
|
||||
|
||||
namespace {
|
||||
@ -40,11 +42,13 @@ class ConcurrentSearchThread : public v8::base::Thread {
|
||||
|
||||
background_thread_started_->Signal();
|
||||
|
||||
CHECK_EQ(TransitionsAccessor(CcTest::i_isolate(), *map_, true)
|
||||
CHECK_EQ(TransitionsAccessor(heap_->isolate(), *map_, true)
|
||||
.SearchTransition(*name_, PropertyKind::kData, NONE),
|
||||
result_map_ ? **result_map_ : Map());
|
||||
}
|
||||
|
||||
Heap* heap() { return heap_; }
|
||||
|
||||
// protected instead of private due to having a subclass.
|
||||
protected:
|
||||
Heap* heap_;
|
||||
@ -77,7 +81,7 @@ class ConcurrentSearchOnOutdatedAccessorThread final
|
||||
background_thread_started_->Signal();
|
||||
main_thread_finished_->Wait();
|
||||
|
||||
CHECK_EQ(TransitionsAccessor(CcTest::i_isolate(), *map_, true)
|
||||
CHECK_EQ(TransitionsAccessor(heap()->isolate(), *map_, true)
|
||||
.SearchTransition(*name_, PropertyKind::kData, NONE),
|
||||
result_map_ ? **result_map_ : Map());
|
||||
}
|
||||
@ -86,29 +90,28 @@ class ConcurrentSearchOnOutdatedAccessorThread final
|
||||
};
|
||||
|
||||
// Search on the main thread and in the background thread at the same time.
|
||||
TEST(FullFieldTransitions_OnlySearch) {
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
TEST_F(ConcurrentTransitionArrayTest, FullFieldTransitions_OnlySearch) {
|
||||
v8::HandleScope scope(isolate());
|
||||
|
||||
Handle<String> name = CcTest::MakeString("name");
|
||||
Handle<String> name = MakeString("name");
|
||||
const PropertyAttributes attributes = NONE;
|
||||
const PropertyKind kind = PropertyKind::kData;
|
||||
|
||||
// Set map0 to be a full transition array with transition 'name' to map1.
|
||||
Handle<Map> map0 = Map::Create(isolate, 0);
|
||||
Handle<Map> map0 = Map::Create(i_isolate(), 0);
|
||||
Handle<Map> map1 =
|
||||
Map::CopyWithField(isolate, map0, name, FieldType::Any(isolate),
|
||||
Map::CopyWithField(i_isolate(), map0, name, FieldType::Any(i_isolate()),
|
||||
attributes, PropertyConstness::kMutable,
|
||||
Representation::Tagged(), OMIT_TRANSITION)
|
||||
.ToHandleChecked();
|
||||
TransitionsAccessor::Insert(isolate, map0, name, map1, PROPERTY_TRANSITION);
|
||||
TransitionsAccessor::Insert(i_isolate(), map0, name, map1,
|
||||
PROPERTY_TRANSITION);
|
||||
{
|
||||
TestTransitionsAccessor transitions(isolate, map0);
|
||||
TestTransitionsAccessor transitions(i_isolate(), map0);
|
||||
CHECK(transitions.IsFullTransitionArrayEncoding());
|
||||
}
|
||||
|
||||
std::unique_ptr<PersistentHandles> ph = isolate->NewPersistentHandles();
|
||||
std::unique_ptr<PersistentHandles> ph = i_isolate()->NewPersistentHandles();
|
||||
|
||||
Handle<Name> persistent_name = ph->NewHandle(name);
|
||||
Handle<Map> persistent_map0 = ph->NewHandle(map0);
|
||||
@ -118,14 +121,14 @@ TEST(FullFieldTransitions_OnlySearch) {
|
||||
|
||||
// Pass persistent handles to background thread.
|
||||
std::unique_ptr<ConcurrentSearchThread> thread(new ConcurrentSearchThread(
|
||||
isolate->heap(), &background_thread_started, std::move(ph),
|
||||
i_isolate()->heap(), &background_thread_started, std::move(ph),
|
||||
persistent_name, persistent_map0, persistent_result_map1));
|
||||
CHECK(thread->Start());
|
||||
|
||||
background_thread_started.Wait();
|
||||
|
||||
CHECK_EQ(*map1, *TransitionsAccessor::SearchTransition(isolate, map0, *name,
|
||||
kind, attributes)
|
||||
CHECK_EQ(*map1, *TransitionsAccessor::SearchTransition(
|
||||
i_isolate(), map0, *name, kind, attributes)
|
||||
.ToHandleChecked());
|
||||
|
||||
thread->Join();
|
||||
@ -133,35 +136,34 @@ TEST(FullFieldTransitions_OnlySearch) {
|
||||
|
||||
// Search and insert on the main thread, while the background thread searches at
|
||||
// the same time.
|
||||
TEST(FullFieldTransitions) {
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
TEST_F(ConcurrentTransitionArrayTest, FullFieldTransitions) {
|
||||
v8::HandleScope scope(isolate());
|
||||
|
||||
Handle<String> name1 = CcTest::MakeString("name1");
|
||||
Handle<String> name2 = CcTest::MakeString("name2");
|
||||
Handle<String> name1 = MakeString("name1");
|
||||
Handle<String> name2 = MakeString("name2");
|
||||
const PropertyAttributes attributes = NONE;
|
||||
const PropertyKind kind = PropertyKind::kData;
|
||||
|
||||
// Set map0 to be a full transition array with transition 'name1' to map1.
|
||||
Handle<Map> map0 = Map::Create(isolate, 0);
|
||||
Handle<Map> map0 = Map::Create(i_isolate(), 0);
|
||||
Handle<Map> map1 =
|
||||
Map::CopyWithField(isolate, map0, name1, FieldType::Any(isolate),
|
||||
Map::CopyWithField(i_isolate(), map0, name1, FieldType::Any(i_isolate()),
|
||||
attributes, PropertyConstness::kMutable,
|
||||
Representation::Tagged(), OMIT_TRANSITION)
|
||||
.ToHandleChecked();
|
||||
Handle<Map> map2 =
|
||||
Map::CopyWithField(isolate, map0, name2, FieldType::Any(isolate),
|
||||
Map::CopyWithField(i_isolate(), map0, name2, FieldType::Any(i_isolate()),
|
||||
attributes, PropertyConstness::kMutable,
|
||||
Representation::Tagged(), OMIT_TRANSITION)
|
||||
.ToHandleChecked();
|
||||
TransitionsAccessor::Insert(isolate, map0, name1, map1, PROPERTY_TRANSITION);
|
||||
TransitionsAccessor::Insert(i_isolate(), map0, name1, map1,
|
||||
PROPERTY_TRANSITION);
|
||||
{
|
||||
TestTransitionsAccessor transitions(isolate, map0);
|
||||
TestTransitionsAccessor transitions(i_isolate(), map0);
|
||||
CHECK(transitions.IsFullTransitionArrayEncoding());
|
||||
}
|
||||
|
||||
std::unique_ptr<PersistentHandles> ph = isolate->NewPersistentHandles();
|
||||
std::unique_ptr<PersistentHandles> ph = i_isolate()->NewPersistentHandles();
|
||||
|
||||
Handle<Name> persistent_name1 = ph->NewHandle(name1);
|
||||
Handle<Map> persistent_map0 = ph->NewHandle(map0);
|
||||
@ -171,18 +173,19 @@ TEST(FullFieldTransitions) {
|
||||
|
||||
// Pass persistent handles to background thread.
|
||||
std::unique_ptr<ConcurrentSearchThread> thread(new ConcurrentSearchThread(
|
||||
isolate->heap(), &background_thread_started, std::move(ph),
|
||||
i_isolate()->heap(), &background_thread_started, std::move(ph),
|
||||
persistent_name1, persistent_map0, persistent_result_map1));
|
||||
CHECK(thread->Start());
|
||||
|
||||
background_thread_started.Wait();
|
||||
|
||||
CHECK_EQ(*map1, *TransitionsAccessor::SearchTransition(isolate, map0, *name1,
|
||||
kind, attributes)
|
||||
CHECK_EQ(*map1, *TransitionsAccessor::SearchTransition(
|
||||
i_isolate(), map0, *name1, kind, attributes)
|
||||
.ToHandleChecked());
|
||||
TransitionsAccessor::Insert(isolate, map0, name2, map2, PROPERTY_TRANSITION);
|
||||
CHECK_EQ(*map2, *TransitionsAccessor::SearchTransition(isolate, map0, *name2,
|
||||
kind, attributes)
|
||||
TransitionsAccessor::Insert(i_isolate(), map0, name2, map2,
|
||||
PROPERTY_TRANSITION);
|
||||
CHECK_EQ(*map2, *TransitionsAccessor::SearchTransition(
|
||||
i_isolate(), map0, *name2, kind, attributes)
|
||||
.ToHandleChecked());
|
||||
|
||||
thread->Join();
|
||||
@ -191,36 +194,34 @@ TEST(FullFieldTransitions) {
|
||||
// Search and insert on the main thread which changes the encoding from kWeakRef
|
||||
// to kFullTransitionArray, while the background thread searches at the same
|
||||
// time.
|
||||
TEST(WeakRefToFullFieldTransitions) {
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
TEST_F(ConcurrentTransitionArrayTest, WeakRefToFullFieldTransitions) {
|
||||
v8::HandleScope scope(isolate());
|
||||
|
||||
Handle<String> name1 = CcTest::MakeString("name1");
|
||||
Handle<String> name2 = CcTest::MakeString("name2");
|
||||
Handle<String> name1 = MakeString("name1");
|
||||
Handle<String> name2 = MakeString("name2");
|
||||
const PropertyAttributes attributes = NONE;
|
||||
const PropertyKind kind = PropertyKind::kData;
|
||||
|
||||
// Set map0 to be a simple transition array with transition 'name1' to map1.
|
||||
Handle<Map> map0 = Map::Create(isolate, 0);
|
||||
Handle<Map> map0 = Map::Create(i_isolate(), 0);
|
||||
Handle<Map> map1 =
|
||||
Map::CopyWithField(isolate, map0, name1, FieldType::Any(isolate),
|
||||
Map::CopyWithField(i_isolate(), map0, name1, FieldType::Any(i_isolate()),
|
||||
attributes, PropertyConstness::kMutable,
|
||||
Representation::Tagged(), OMIT_TRANSITION)
|
||||
.ToHandleChecked();
|
||||
Handle<Map> map2 =
|
||||
Map::CopyWithField(isolate, map0, name2, FieldType::Any(isolate),
|
||||
Map::CopyWithField(i_isolate(), map0, name2, FieldType::Any(i_isolate()),
|
||||
attributes, PropertyConstness::kMutable,
|
||||
Representation::Tagged(), OMIT_TRANSITION)
|
||||
.ToHandleChecked();
|
||||
TransitionsAccessor::Insert(isolate, map0, name1, map1,
|
||||
TransitionsAccessor::Insert(i_isolate(), map0, name1, map1,
|
||||
SIMPLE_PROPERTY_TRANSITION);
|
||||
{
|
||||
TestTransitionsAccessor transitions(isolate, map0);
|
||||
TestTransitionsAccessor transitions(i_isolate(), map0);
|
||||
CHECK(transitions.IsWeakRefEncoding());
|
||||
}
|
||||
|
||||
std::unique_ptr<PersistentHandles> ph = isolate->NewPersistentHandles();
|
||||
std::unique_ptr<PersistentHandles> ph = i_isolate()->NewPersistentHandles();
|
||||
|
||||
Handle<Name> persistent_name1 = ph->NewHandle(name1);
|
||||
Handle<Map> persistent_map0 = ph->NewHandle(map0);
|
||||
@ -230,23 +231,23 @@ TEST(WeakRefToFullFieldTransitions) {
|
||||
|
||||
// Pass persistent handles to background thread.
|
||||
std::unique_ptr<ConcurrentSearchThread> thread(new ConcurrentSearchThread(
|
||||
isolate->heap(), &background_thread_started, std::move(ph),
|
||||
i_isolate()->heap(), &background_thread_started, std::move(ph),
|
||||
persistent_name1, persistent_map0, persistent_result_map1));
|
||||
CHECK(thread->Start());
|
||||
|
||||
background_thread_started.Wait();
|
||||
|
||||
CHECK_EQ(*map1, *TransitionsAccessor::SearchTransition(isolate, map0, *name1,
|
||||
kind, attributes)
|
||||
CHECK_EQ(*map1, *TransitionsAccessor::SearchTransition(
|
||||
i_isolate(), map0, *name1, kind, attributes)
|
||||
.ToHandleChecked());
|
||||
TransitionsAccessor::Insert(isolate, map0, name2, map2,
|
||||
TransitionsAccessor::Insert(i_isolate(), map0, name2, map2,
|
||||
SIMPLE_PROPERTY_TRANSITION);
|
||||
{
|
||||
TestTransitionsAccessor transitions(isolate, map0);
|
||||
TestTransitionsAccessor transitions(i_isolate(), map0);
|
||||
CHECK(transitions.IsFullTransitionArrayEncoding());
|
||||
}
|
||||
CHECK_EQ(*map2, *TransitionsAccessor::SearchTransition(isolate, map0, *name2,
|
||||
kind, attributes)
|
||||
CHECK_EQ(*map2, *TransitionsAccessor::SearchTransition(
|
||||
i_isolate(), map0, *name2, kind, attributes)
|
||||
.ToHandleChecked());
|
||||
|
||||
thread->Join();
|
||||
@ -255,42 +256,42 @@ TEST(WeakRefToFullFieldTransitions) {
|
||||
// Search and insert on the main thread, while the background thread searches at
|
||||
// the same time. In this case, we have a kFullTransitionArray with enough slack
|
||||
// when we are concurrently writing.
|
||||
TEST(FullFieldTransitions_withSlack) {
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
TEST_F(ConcurrentTransitionArrayTest, FullFieldTransitions_withSlack) {
|
||||
v8::HandleScope scope(isolate());
|
||||
|
||||
Handle<String> name1 = CcTest::MakeString("name1");
|
||||
Handle<String> name2 = CcTest::MakeString("name2");
|
||||
Handle<String> name3 = CcTest::MakeString("name3");
|
||||
Handle<String> name1 = MakeString("name1");
|
||||
Handle<String> name2 = MakeString("name2");
|
||||
Handle<String> name3 = MakeString("name3");
|
||||
const PropertyAttributes attributes = NONE;
|
||||
const PropertyKind kind = PropertyKind::kData;
|
||||
|
||||
// Set map0 to be a full transition array with transition 'name1' to map1.
|
||||
Handle<Map> map0 = Map::Create(isolate, 0);
|
||||
Handle<Map> map0 = Map::Create(i_isolate(), 0);
|
||||
Handle<Map> map1 =
|
||||
Map::CopyWithField(isolate, map0, name1, FieldType::Any(isolate),
|
||||
Map::CopyWithField(i_isolate(), map0, name1, FieldType::Any(i_isolate()),
|
||||
attributes, PropertyConstness::kMutable,
|
||||
Representation::Tagged(), OMIT_TRANSITION)
|
||||
.ToHandleChecked();
|
||||
Handle<Map> map2 =
|
||||
Map::CopyWithField(isolate, map0, name2, FieldType::Any(isolate),
|
||||
Map::CopyWithField(i_isolate(), map0, name2, FieldType::Any(i_isolate()),
|
||||
attributes, PropertyConstness::kMutable,
|
||||
Representation::Tagged(), OMIT_TRANSITION)
|
||||
.ToHandleChecked();
|
||||
Handle<Map> map3 =
|
||||
Map::CopyWithField(isolate, map0, name3, FieldType::Any(isolate),
|
||||
Map::CopyWithField(i_isolate(), map0, name3, FieldType::Any(i_isolate()),
|
||||
attributes, PropertyConstness::kMutable,
|
||||
Representation::Tagged(), OMIT_TRANSITION)
|
||||
.ToHandleChecked();
|
||||
TransitionsAccessor::Insert(isolate, map0, name1, map1, PROPERTY_TRANSITION);
|
||||
TransitionsAccessor::Insert(isolate, map0, name2, map2, PROPERTY_TRANSITION);
|
||||
TransitionsAccessor::Insert(i_isolate(), map0, name1, map1,
|
||||
PROPERTY_TRANSITION);
|
||||
TransitionsAccessor::Insert(i_isolate(), map0, name2, map2,
|
||||
PROPERTY_TRANSITION);
|
||||
{
|
||||
TestTransitionsAccessor transitions(isolate, map0);
|
||||
TestTransitionsAccessor transitions(i_isolate(), map0);
|
||||
CHECK(transitions.IsFullTransitionArrayEncoding());
|
||||
}
|
||||
|
||||
std::unique_ptr<PersistentHandles> ph = isolate->NewPersistentHandles();
|
||||
std::unique_ptr<PersistentHandles> ph = i_isolate()->NewPersistentHandles();
|
||||
|
||||
Handle<Name> persistent_name1 = ph->NewHandle(name1);
|
||||
Handle<Map> persistent_map0 = ph->NewHandle(map0);
|
||||
@ -300,27 +301,28 @@ TEST(FullFieldTransitions_withSlack) {
|
||||
|
||||
// Pass persistent handles to background thread.
|
||||
std::unique_ptr<ConcurrentSearchThread> thread(new ConcurrentSearchThread(
|
||||
isolate->heap(), &background_thread_started, std::move(ph),
|
||||
i_isolate()->heap(), &background_thread_started, std::move(ph),
|
||||
persistent_name1, persistent_map0, persistent_result_map1));
|
||||
CHECK(thread->Start());
|
||||
|
||||
background_thread_started.Wait();
|
||||
|
||||
CHECK_EQ(*map1, *TransitionsAccessor::SearchTransition(isolate, map0, *name1,
|
||||
kind, attributes)
|
||||
CHECK_EQ(*map1, *TransitionsAccessor::SearchTransition(
|
||||
i_isolate(), map0, *name1, kind, attributes)
|
||||
.ToHandleChecked());
|
||||
CHECK_EQ(*map2, *TransitionsAccessor::SearchTransition(isolate, map0, *name2,
|
||||
kind, attributes)
|
||||
CHECK_EQ(*map2, *TransitionsAccessor::SearchTransition(
|
||||
i_isolate(), map0, *name2, kind, attributes)
|
||||
.ToHandleChecked());
|
||||
{
|
||||
// Check that we have enough slack for the 3rd insertion into the
|
||||
// TransitionArray.
|
||||
TestTransitionsAccessor transitions(isolate, map0);
|
||||
TestTransitionsAccessor transitions(i_isolate(), map0);
|
||||
CHECK_GE(transitions.Capacity(), 3);
|
||||
}
|
||||
TransitionsAccessor::Insert(isolate, map0, name3, map3, PROPERTY_TRANSITION);
|
||||
CHECK_EQ(*map3, *TransitionsAccessor::SearchTransition(isolate, map0, *name3,
|
||||
kind, attributes)
|
||||
TransitionsAccessor::Insert(i_isolate(), map0, name3, map3,
|
||||
PROPERTY_TRANSITION);
|
||||
CHECK_EQ(*map3, *TransitionsAccessor::SearchTransition(
|
||||
i_isolate(), map0, *name3, kind, attributes)
|
||||
.ToHandleChecked());
|
||||
|
||||
thread->Join();
|
||||
@ -329,29 +331,27 @@ TEST(FullFieldTransitions_withSlack) {
|
||||
// Search and insert on the main thread which changes the encoding from
|
||||
// kUninitialized to kFullTransitionArray, while the background thread searches
|
||||
// at the same time.
|
||||
TEST(UninitializedToFullFieldTransitions) {
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
TEST_F(ConcurrentTransitionArrayTest, UninitializedToFullFieldTransitions) {
|
||||
v8::HandleScope scope(isolate());
|
||||
|
||||
Handle<String> name1 = CcTest::MakeString("name1");
|
||||
Handle<String> name2 = CcTest::MakeString("name2");
|
||||
Handle<String> name1 = MakeString("name1");
|
||||
Handle<String> name2 = MakeString("name2");
|
||||
const PropertyAttributes attributes = NONE;
|
||||
const PropertyKind kind = PropertyKind::kData;
|
||||
|
||||
// Set map0 to be a full transition array with transition 'name1' to map1.
|
||||
Handle<Map> map0 = Map::Create(isolate, 0);
|
||||
Handle<Map> map0 = Map::Create(i_isolate(), 0);
|
||||
Handle<Map> map1 =
|
||||
Map::CopyWithField(isolate, map0, name1, FieldType::Any(isolate),
|
||||
Map::CopyWithField(i_isolate(), map0, name1, FieldType::Any(i_isolate()),
|
||||
attributes, PropertyConstness::kMutable,
|
||||
Representation::Tagged(), OMIT_TRANSITION)
|
||||
.ToHandleChecked();
|
||||
{
|
||||
TestTransitionsAccessor transitions(isolate, map0);
|
||||
TestTransitionsAccessor transitions(i_isolate(), map0);
|
||||
CHECK(transitions.IsUninitializedEncoding());
|
||||
}
|
||||
|
||||
std::unique_ptr<PersistentHandles> ph = isolate->NewPersistentHandles();
|
||||
std::unique_ptr<PersistentHandles> ph = i_isolate()->NewPersistentHandles();
|
||||
|
||||
Handle<Name> persistent_name2 = ph->NewHandle(name2);
|
||||
Handle<Map> persistent_map0 = ph->NewHandle(map0);
|
||||
@ -361,18 +361,19 @@ TEST(UninitializedToFullFieldTransitions) {
|
||||
// Pass persistent handles to background thread.
|
||||
// Background thread will search for name2, guaranteed to *not* be on the map.
|
||||
std::unique_ptr<ConcurrentSearchThread> thread(new ConcurrentSearchThread(
|
||||
isolate->heap(), &background_thread_started, std::move(ph),
|
||||
i_isolate()->heap(), &background_thread_started, std::move(ph),
|
||||
persistent_name2, persistent_map0, base::nullopt));
|
||||
CHECK(thread->Start());
|
||||
|
||||
background_thread_started.Wait();
|
||||
|
||||
TransitionsAccessor::Insert(isolate, map0, name1, map1, PROPERTY_TRANSITION);
|
||||
CHECK_EQ(*map1, *TransitionsAccessor::SearchTransition(isolate, map0, *name1,
|
||||
kind, attributes)
|
||||
TransitionsAccessor::Insert(i_isolate(), map0, name1, map1,
|
||||
PROPERTY_TRANSITION);
|
||||
CHECK_EQ(*map1, *TransitionsAccessor::SearchTransition(
|
||||
i_isolate(), map0, *name1, kind, attributes)
|
||||
.ToHandleChecked());
|
||||
{
|
||||
TestTransitionsAccessor transitions(isolate, map0);
|
||||
TestTransitionsAccessor transitions(i_isolate(), map0);
|
||||
CHECK(transitions.IsFullTransitionArrayEncoding());
|
||||
}
|
||||
thread->Join();
|
||||
@ -382,35 +383,35 @@ TEST(UninitializedToFullFieldTransitions) {
|
||||
// array with no slack, while the main thread will try to insert a value into
|
||||
// it. This makes it so that the main thread will create a new array, and the
|
||||
// background thread will have a pointer to the old one.
|
||||
TEST(FullFieldTransitions_BackgroundSearchOldPointer) {
|
||||
CcTest::InitializeVM();
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
Isolate* isolate = CcTest::i_isolate();
|
||||
TEST_F(ConcurrentTransitionArrayTest,
|
||||
FullFieldTransitions_BackgroundSearchOldPointer) {
|
||||
v8::HandleScope scope(isolate());
|
||||
|
||||
Handle<String> name1 = CcTest::MakeString("name1");
|
||||
Handle<String> name2 = CcTest::MakeString("name2");
|
||||
Handle<String> name1 = MakeString("name1");
|
||||
Handle<String> name2 = MakeString("name2");
|
||||
const PropertyAttributes attributes = NONE;
|
||||
const PropertyKind kind = PropertyKind::kData;
|
||||
|
||||
// Set map0 to be a full transition array with transition 'name1' to map1.
|
||||
Handle<Map> map0 = Map::Create(isolate, 0);
|
||||
Handle<Map> map0 = Map::Create(i_isolate(), 0);
|
||||
Handle<Map> map1 =
|
||||
Map::CopyWithField(isolate, map0, name1, FieldType::Any(isolate),
|
||||
Map::CopyWithField(i_isolate(), map0, name1, FieldType::Any(i_isolate()),
|
||||
attributes, PropertyConstness::kMutable,
|
||||
Representation::Tagged(), OMIT_TRANSITION)
|
||||
.ToHandleChecked();
|
||||
Handle<Map> map2 =
|
||||
Map::CopyWithField(isolate, map0, name2, FieldType::Any(isolate),
|
||||
Map::CopyWithField(i_isolate(), map0, name2, FieldType::Any(i_isolate()),
|
||||
attributes, PropertyConstness::kMutable,
|
||||
Representation::Tagged(), OMIT_TRANSITION)
|
||||
.ToHandleChecked();
|
||||
TransitionsAccessor::Insert(isolate, map0, name1, map1, PROPERTY_TRANSITION);
|
||||
TransitionsAccessor::Insert(i_isolate(), map0, name1, map1,
|
||||
PROPERTY_TRANSITION);
|
||||
{
|
||||
TestTransitionsAccessor transitions(isolate, map0);
|
||||
TestTransitionsAccessor transitions(i_isolate(), map0);
|
||||
CHECK(transitions.IsFullTransitionArrayEncoding());
|
||||
}
|
||||
|
||||
std::unique_ptr<PersistentHandles> ph = isolate->NewPersistentHandles();
|
||||
std::unique_ptr<PersistentHandles> ph = i_isolate()->NewPersistentHandles();
|
||||
|
||||
Handle<Name> persistent_name1 = ph->NewHandle(name1);
|
||||
Handle<Map> persistent_map0 = ph->NewHandle(map0);
|
||||
@ -422,25 +423,26 @@ TEST(FullFieldTransitions_BackgroundSearchOldPointer) {
|
||||
// Pass persistent handles to background thread.
|
||||
std::unique_ptr<ConcurrentSearchThread> thread(
|
||||
new ConcurrentSearchOnOutdatedAccessorThread(
|
||||
isolate->heap(), &background_thread_started, &main_thread_finished,
|
||||
std::move(ph), persistent_name1, persistent_map0,
|
||||
persistent_result_map1));
|
||||
i_isolate()->heap(), &background_thread_started,
|
||||
&main_thread_finished, std::move(ph), persistent_name1,
|
||||
persistent_map0, persistent_result_map1));
|
||||
CHECK(thread->Start());
|
||||
|
||||
background_thread_started.Wait();
|
||||
|
||||
CHECK_EQ(*map1, *TransitionsAccessor::SearchTransition(isolate, map0, *name1,
|
||||
kind, attributes)
|
||||
CHECK_EQ(*map1, *TransitionsAccessor::SearchTransition(
|
||||
i_isolate(), map0, *name1, kind, attributes)
|
||||
.ToHandleChecked());
|
||||
{
|
||||
// Check that we do not have enough slack for the 2nd insertion into the
|
||||
// TransitionArray.
|
||||
TestTransitionsAccessor transitions(isolate, map0);
|
||||
TestTransitionsAccessor transitions(i_isolate(), map0);
|
||||
CHECK_EQ(transitions.Capacity(), 1);
|
||||
}
|
||||
TransitionsAccessor::Insert(isolate, map0, name2, map2, PROPERTY_TRANSITION);
|
||||
CHECK_EQ(*map2, *TransitionsAccessor::SearchTransition(isolate, map0, *name2,
|
||||
kind, attributes)
|
||||
TransitionsAccessor::Insert(i_isolate(), map0, name2, map2,
|
||||
PROPERTY_TRANSITION);
|
||||
CHECK_EQ(*map2, *TransitionsAccessor::SearchTransition(
|
||||
i_isolate(), map0, *name2, kind, attributes)
|
||||
.ToHandleChecked());
|
||||
main_thread_finished.Signal();
|
||||
|
@ -414,6 +414,26 @@ static inline uint16_t* AsciiToTwoByteString(const char* source) {
|
||||
return converted;
|
||||
}
|
||||
|
||||
class TestTransitionsAccessor : public TransitionsAccessor {
|
||||
public:
|
||||
TestTransitionsAccessor(Isolate* isolate, Map map)
|
||||
: TransitionsAccessor(isolate, map) {}
|
||||
TestTransitionsAccessor(Isolate* isolate, Handle<Map> map)
|
||||
: TransitionsAccessor(isolate, *map) {}
|
||||
|
||||
// Expose internals for tests.
|
||||
bool IsUninitializedEncoding() { return encoding() == kUninitialized; }
|
||||
bool IsWeakRefEncoding() { return encoding() == kWeakRef; }
|
||||
|
||||
bool IsFullTransitionArrayEncoding() {
|
||||
return encoding() == kFullTransitionArray;
|
||||
}
|
||||
|
||||
int Capacity() { return TransitionsAccessor::Capacity(); }
|
||||
|
||||
TransitionArray transitions() { return TransitionsAccessor::transitions(); }
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user