Skip to content

Commit 16a005c

Browse files
committed
deps: V8: cherry-pick 4e24c353d812
Original commit message: [compiler] Test linear searches in a DescriptorArray in the background This CL adds a linear search test in a DescriptorArray in a known flat object in the background thread, while the main thread exercises the same DescriptorArray. Also sets the foundation for the follow-ups tests in background threads. Bug: v8:7790 Change-Id: I0e99508204808baaf605161d2eeb717eabe712fb Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2207147 Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Dominik Inführ <dinfuehr@chromium.org> Reviewed-by: Michael Stanton <mvstanton@chromium.org> Cr-Commit-Position: refs/heads/master@{#68299} Refs: v8/v8@4e24c35 PR-URL: #38275 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Shelley Vohr <codebytere@gmail.com>
1 parent 42140a1 commit 16a005c

File tree

11 files changed

+165
-16
lines changed

11 files changed

+165
-16
lines changed

common.gypi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
# Reset this number to 0 on major V8 upgrades.
3838
# Increment by one for each non-official patch applied to deps/v8.
39-
'v8_embedder_string': '-node.57',
39+
'v8_embedder_string': '-node.58',
4040

4141
##### V8 defaults for Node.js #####
4242

deps/v8/src/common/checks.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ namespace internal {
1818
#ifdef ENABLE_SLOW_DCHECKS
1919
#define SLOW_DCHECK(condition) \
2020
CHECK(!v8::internal::FLAG_enable_slow_asserts || (condition))
21+
#define SLOW_DCHECK_IMPLIES(lhs, rhs) SLOW_DCHECK(!(lhs) || (rhs))
2122
V8_EXPORT_PRIVATE extern bool FLAG_enable_slow_asserts;
2223
#else
2324
#define SLOW_DCHECK(condition) ((void)0)
25+
#define SLOW_DCHECK_IMPLIES(v1, v2) ((void)0)
2426
static const bool FLAG_enable_slow_asserts = false;
2527
#endif
2628

deps/v8/src/objects/descriptor-array-inl.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,19 @@ void DescriptorArray::CopyEnumCacheFrom(DescriptorArray array) {
5555
set_enum_cache(array.enum_cache());
5656
}
5757

58-
InternalIndex DescriptorArray::Search(Name name, int valid_descriptors) {
58+
InternalIndex DescriptorArray::Search(Name name, int valid_descriptors,
59+
bool concurrent_search) {
5960
DCHECK(name.IsUniqueName());
60-
return InternalIndex(
61-
internal::Search<VALID_ENTRIES>(this, name, valid_descriptors, nullptr));
61+
return InternalIndex(internal::Search<VALID_ENTRIES>(
62+
this, name, valid_descriptors, nullptr, concurrent_search));
6263
}
6364

64-
InternalIndex DescriptorArray::Search(Name name, Map map) {
65+
InternalIndex DescriptorArray::Search(Name name, Map map,
66+
bool concurrent_search) {
6567
DCHECK(name.IsUniqueName());
6668
int number_of_own_descriptors = map.NumberOfOwnDescriptors();
6769
if (number_of_own_descriptors == 0) return InternalIndex::NotFound();
68-
return Search(name, number_of_own_descriptors);
70+
return Search(name, number_of_own_descriptors, concurrent_search);
6971
}
7072

7173
InternalIndex DescriptorArray::SearchWithCache(Isolate* isolate, Name name,

deps/v8/src/objects/descriptor-array.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,13 @@ class DescriptorArray
115115
// Sort the instance descriptors by the hash codes of their keys.
116116
V8_EXPORT_PRIVATE void Sort();
117117

118-
// Search the instance descriptors for given name.
119-
V8_INLINE InternalIndex Search(Name name, int number_of_own_descriptors);
120-
V8_INLINE InternalIndex Search(Name name, Map map);
118+
// Search the instance descriptors for given name. {concurrent_search} signals
119+
// if we are doing the search on a background thread. If so, we will sacrifice
120+
// speed for thread-safety.
121+
V8_INLINE InternalIndex Search(Name name, int number_of_own_descriptors,
122+
bool concurrent_search = false);
123+
V8_INLINE InternalIndex Search(Name name, Map map,
124+
bool concurrent_search = false);
121125

122126
// As the above, but uses DescriptorLookupCache and updates it when
123127
// necessary.

deps/v8/src/objects/fixed-array-inl.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,9 @@ int LinearSearch(T* array, Name name, int valid_entries,
284284
}
285285

286286
template <SearchMode search_mode, typename T>
287-
int Search(T* array, Name name, int valid_entries, int* out_insertion_index) {
288-
SLOW_DCHECK(array->IsSortedNoDuplicates());
287+
int Search(T* array, Name name, int valid_entries, int* out_insertion_index,
288+
bool concurrent_search) {
289+
SLOW_DCHECK_IMPLIES(!concurrent_search, array->IsSortedNoDuplicates());
289290

290291
if (valid_entries == 0) {
291292
if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
@@ -294,14 +295,14 @@ int Search(T* array, Name name, int valid_entries, int* out_insertion_index) {
294295
return T::kNotFound;
295296
}
296297

297-
// Fast case: do linear search for small arrays.
298+
// Do linear search for small arrays, and for searches in the background
299+
// thread.
298300
const int kMaxElementsForLinearSearch = 8;
299-
if (valid_entries <= kMaxElementsForLinearSearch) {
301+
if (valid_entries <= kMaxElementsForLinearSearch || concurrent_search) {
300302
return LinearSearch<search_mode>(array, name, valid_entries,
301303
out_insertion_index);
302304
}
303305

304-
// Slow case: perform binary search.
305306
return BinarySearch<search_mode>(array, name, valid_entries,
306307
out_insertion_index);
307308
}

deps/v8/src/objects/fixed-array.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,8 @@ enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
465465

466466
template <SearchMode search_mode, typename T>
467467
inline int Search(T* array, Name name, int valid_entries = 0,
468-
int* out_insertion_index = nullptr);
468+
int* out_insertion_index = nullptr,
469+
bool concurrent_search = false);
469470

470471
// ByteArray represents fixed sized byte arrays. Used for the relocation info
471472
// that is attached to code objects.

deps/v8/src/objects/map.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,7 @@ class Map : public HeapObject {
594594
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
595595

596596
// [instance descriptors]: describes the object.
597+
DECL_GETTER(synchronized_instance_descriptors, DescriptorArray)
597598
DECL_GETTER(instance_descriptors, DescriptorArray)
598599
V8_EXPORT_PRIVATE void SetInstanceDescriptors(Isolate* isolate,
599600
DescriptorArray descriptors,
@@ -976,7 +977,8 @@ class Map : public HeapObject {
976977
MaybeHandle<Object> new_value);
977978

978979
// Use the high-level instance_descriptors/SetInstanceDescriptors instead.
979-
DECL_ACCESSORS(synchronized_instance_descriptors, DescriptorArray)
980+
inline void set_synchronized_instance_descriptors(
981+
DescriptorArray value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
980982

981983
static const int kFastPropertiesSoftLimit = 12;
982984
static const int kMaxFastProperties = 128;

deps/v8/test/cctest/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ v8_source_set("cctest_sources") {
196196
"test-code-pages.cc",
197197
"test-code-stub-assembler.cc",
198198
"test-compiler.cc",
199+
"test-concurrent-descriptor-array.cc",
199200
"test-constantpool.cc",
200201
"test-conversions.cc",
201202
"test-cpu-profiler.cc",
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// Copyright 2020 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/api/api.h"
6+
#include "src/base/platform/semaphore.h"
7+
#include "src/handles/handles-inl.h"
8+
#include "src/handles/local-handles-inl.h"
9+
#include "src/handles/persistent-handles.h"
10+
#include "src/heap/heap.h"
11+
#include "src/heap/local-heap.h"
12+
#include "test/cctest/cctest.h"
13+
#include "test/cctest/heap/heap-utils.h"
14+
15+
namespace v8 {
16+
namespace internal {
17+
18+
static constexpr int kNumHandles = kHandleBlockSize * 2 + kHandleBlockSize / 2;
19+
20+
namespace {
21+
22+
class PersistentHandlesThread final : public v8::base::Thread {
23+
public:
24+
PersistentHandlesThread(Heap* heap, std::vector<Handle<JSObject>> handles,
25+
std::unique_ptr<PersistentHandles> ph,
26+
Handle<Name> name, base::Semaphore* sema_started)
27+
: v8::base::Thread(base::Thread::Options("ThreadWithLocalHeap")),
28+
heap_(heap),
29+
handles_(std::move(handles)),
30+
ph_(std::move(ph)),
31+
name_(name),
32+
sema_started_(sema_started) {}
33+
34+
void Run() override {
35+
LocalHeap local_heap(heap_, std::move(ph_));
36+
LocalHandleScope scope(&local_heap);
37+
Address object = handles_[0]->ptr();
38+
39+
for (int i = 0; i < kNumHandles; i++) {
40+
handles_.push_back(
41+
Handle<JSObject>::cast(local_heap.NewPersistentHandle(object)));
42+
}
43+
44+
sema_started_->Signal();
45+
46+
for (Handle<JSObject> handle : handles_) {
47+
// Lookup the named property on the {map}.
48+
CHECK(name_->IsUniqueName());
49+
Handle<Map> map(handle->map(), &local_heap);
50+
51+
Handle<DescriptorArray> descriptors(
52+
map->synchronized_instance_descriptors(), &local_heap);
53+
bool is_background_thread = true;
54+
InternalIndex const number =
55+
descriptors->Search(*name_, *map, is_background_thread);
56+
CHECK(number.is_found());
57+
}
58+
59+
CHECK_EQ(handles_.size(), kNumHandles * 2);
60+
61+
CHECK(!ph_);
62+
ph_ = local_heap.DetachPersistentHandles();
63+
}
64+
65+
Heap* heap_;
66+
std::vector<Handle<JSObject>> handles_;
67+
std::unique_ptr<PersistentHandles> ph_;
68+
Handle<Name> name_;
69+
base::Semaphore* sema_started_;
70+
};
71+
72+
// Uses linear search on a flat object, with up to 8 elements.
73+
TEST(LinearSearchFlatObject) {
74+
CcTest::InitializeVM();
75+
FLAG_local_heaps = true;
76+
Isolate* isolate = CcTest::i_isolate();
77+
78+
std::unique_ptr<PersistentHandles> ph = isolate->NewPersistentHandles();
79+
std::vector<Handle<JSObject>> handles;
80+
81+
auto factory = isolate->factory();
82+
HandleScope handle_scope(isolate);
83+
84+
Handle<JSFunction> function =
85+
factory->NewFunctionForTest(factory->empty_string());
86+
Handle<JSObject> js_object = factory->NewJSObject(function);
87+
Handle<String> name = CcTest::MakeString("property");
88+
Handle<Object> value = CcTest::MakeString("dummy_value");
89+
// For the default constructor function no in-object properties are reserved
90+
// hence adding a single property will initialize the property-array.
91+
JSObject::DefinePropertyOrElementIgnoreAttributes(js_object, name, value,
92+
NONE)
93+
.Check();
94+
95+
Address object = js_object->ptr();
96+
for (int i = 0; i < kNumHandles; i++) {
97+
handles.push_back(Handle<JSObject>::cast(ph->NewHandle(object)));
98+
}
99+
100+
Handle<Name> persistent_name = Handle<Name>::cast(ph->NewHandle(name->ptr()));
101+
102+
base::Semaphore sema_started(0);
103+
104+
// Pass persistent handles to background thread.
105+
std::unique_ptr<PersistentHandlesThread> thread(new PersistentHandlesThread(
106+
isolate->heap(), std::move(handles), std::move(ph), persistent_name,
107+
&sema_started));
108+
CHECK(thread->Start());
109+
110+
sema_started.Wait();
111+
112+
// Exercise descriptor in main thread too.
113+
for (int i = 0; i < 7; ++i) {
114+
Handle<String> filler_name = CcTest::MakeName("filler_property_", i);
115+
Handle<Object> filler_value = CcTest::MakeString("dummy_value");
116+
JSObject::DefinePropertyOrElementIgnoreAttributes(js_object, filler_name,
117+
filler_value, NONE)
118+
.Check();
119+
}
120+
CHECK_EQ(js_object->map().NumberOfOwnDescriptors(), 8);
121+
122+
thread->Join();
123+
}
124+
125+
} // anonymous namespace
126+
127+
} // namespace internal
128+
} // namespace v8

deps/v8/test/cctest/test-local-handles.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
namespace v8 {
2121
namespace internal {
2222

23+
namespace {
24+
2325
class LocalHandlesThread final : public v8::base::Thread {
2426
public:
2527
LocalHandlesThread(Heap* heap, Address object, base::Semaphore* sema_started,
@@ -92,5 +94,7 @@ TEST(CreateLocalHandles) {
9294
thread->Join();
9395
}
9496

97+
} // anonymous namespace
98+
9599
} // namespace internal
96100
} // namespace v8

deps/v8/test/cctest/test-persistent-handles.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ namespace internal {
2323

2424
static constexpr int kNumHandles = kHandleBlockSize * 2 + kHandleBlockSize / 2;
2525

26+
namespace {
27+
2628
class PersistentHandlesThread final : public v8::base::Thread {
2729
public:
2830
PersistentHandlesThread(Heap* heap, std::vector<Handle<HeapNumber>> handles,
@@ -110,5 +112,7 @@ TEST(CreatePersistentHandles) {
110112
ph->NewHandle(number->ptr());
111113
}
112114

115+
} // anonymous namespace
116+
113117
} // namespace internal
114118
} // namespace v8

0 commit comments

Comments
 (0)