v8/test/cctest/test-ptr-compr-cage.cc
Igor Sheludko 00c7e383a8 [ptr-compr] Store cage bases in globals when cage sharing is enabled
... instead of computing them on the fly. This approach seems to
perform slightly better because it requires less code.

Bug: v8:7703, v8:11460
Change-Id: If31a06fbc748251c491c011e9e3f118665e20159
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4020456
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84413}
2022-11-22 08:00:16 +00:00

180 lines
5.9 KiB
C++

// Copyright 2021 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/common/globals.h"
#include "src/execution/isolate-inl.h"
#include "src/heap/heap-inl.h"
#include "test/cctest/cctest.h"
#ifdef V8_COMPRESS_POINTERS
namespace v8 {
namespace internal {
UNINITIALIZED_TEST(PtrComprCageAndIsolateRoot) {
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate1 = v8::Isolate::New(create_params);
Isolate* i_isolate1 = reinterpret_cast<Isolate*>(isolate1);
v8::Isolate* isolate2 = v8::Isolate::New(create_params);
Isolate* i_isolate2 = reinterpret_cast<Isolate*>(isolate2);
#ifdef V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
CHECK_EQ(i_isolate1->isolate_root(), i_isolate1->cage_base());
CHECK_EQ(i_isolate2->isolate_root(), i_isolate2->cage_base());
CHECK_NE(i_isolate1->cage_base(), i_isolate2->cage_base());
#endif
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
CHECK_NE(i_isolate1->isolate_root(), i_isolate1->cage_base());
CHECK_NE(i_isolate2->isolate_root(), i_isolate2->cage_base());
CHECK_NE(i_isolate1->isolate_root(), i_isolate2->isolate_root());
CHECK_EQ(i_isolate1->cage_base(), i_isolate2->cage_base());
#endif
isolate1->Dispose();
isolate2->Dispose();
}
UNINITIALIZED_TEST(PtrComprCageCodeRange) {
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate = v8::Isolate::New(create_params);
Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
VirtualMemoryCage* cage = i_isolate->GetPtrComprCodeCageForTesting();
if (i_isolate->RequiresCodeRange()) {
CHECK(!i_isolate->heap()->code_region().is_empty());
CHECK(cage->reservation()->InVM(i_isolate->heap()->code_region().begin(),
i_isolate->heap()->code_region().size()));
}
isolate->Dispose();
}
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
UNINITIALIZED_TEST(SharedPtrComprCage) {
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate1 = v8::Isolate::New(create_params);
Isolate* i_isolate1 = reinterpret_cast<Isolate*>(isolate1);
v8::Isolate* isolate2 = v8::Isolate::New(create_params);
Isolate* i_isolate2 = reinterpret_cast<Isolate*>(isolate2);
Factory* factory1 = i_isolate1->factory();
Factory* factory2 = i_isolate2->factory();
{
HandleScope scope1(i_isolate1);
HandleScope scope2(i_isolate2);
Handle<FixedArray> isolate1_object = factory1->NewFixedArray(100);
Handle<FixedArray> isolate2_object = factory2->NewFixedArray(100);
CHECK_EQ(GetPtrComprCageBase(*isolate1_object),
GetPtrComprCageBase(*isolate2_object));
}
isolate1->Dispose();
isolate2->Dispose();
}
UNINITIALIZED_TEST(SharedPtrComprCageCodeRange) {
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate1 = v8::Isolate::New(create_params);
Isolate* i_isolate1 = reinterpret_cast<Isolate*>(isolate1);
v8::Isolate* isolate2 = v8::Isolate::New(create_params);
Isolate* i_isolate2 = reinterpret_cast<Isolate*>(isolate2);
if (i_isolate1->RequiresCodeRange() || i_isolate2->RequiresCodeRange()) {
CHECK_EQ(i_isolate1->heap()->code_region(),
i_isolate2->heap()->code_region());
}
isolate1->Dispose();
isolate2->Dispose();
}
namespace {
constexpr int kIsolatesToAllocate = 25;
class IsolateAllocatingThread final : public v8::base::Thread {
public:
IsolateAllocatingThread()
: v8::base::Thread(base::Thread::Options("IsolateAllocatingThread")) {}
void Run() override {
std::vector<v8::Isolate*> isolates;
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
for (int i = 0; i < kIsolatesToAllocate; i++) {
isolates.push_back(v8::Isolate::New(create_params));
}
for (auto* isolate : isolates) {
isolate->Dispose();
}
}
};
} // namespace
UNINITIALIZED_TEST(SharedPtrComprCageRace) {
// Make a bunch of Isolates concurrently as a smoke test against races during
// initialization and de-initialization.
// Repeat twice to enforce multiple initializations of CodeRange instances.
constexpr int kRepeats = 2;
for (int repeat = 0; repeat < kRepeats; repeat++) {
std::vector<std::unique_ptr<IsolateAllocatingThread>> threads;
constexpr int kThreads = 10;
for (int i = 0; i < kThreads; i++) {
auto thread = std::make_unique<IsolateAllocatingThread>();
CHECK(thread->Start());
threads.push_back(std::move(thread));
}
for (auto& thread : threads) {
thread->Join();
}
}
}
#ifdef V8_SHARED_RO_HEAP
UNINITIALIZED_TEST(SharedPtrComprCageImpliesSharedReadOnlyHeap) {
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* isolate1 = v8::Isolate::New(create_params);
Isolate* i_isolate1 = reinterpret_cast<Isolate*>(isolate1);
v8::Isolate* isolate2 = v8::Isolate::New(create_params);
Isolate* i_isolate2 = reinterpret_cast<Isolate*>(isolate2);
CHECK_EQ(i_isolate1->read_only_heap(), i_isolate2->read_only_heap());
// Spot check that some read-only roots are the same.
CHECK_EQ(ReadOnlyRoots(i_isolate1).the_hole_value(),
ReadOnlyRoots(i_isolate2).the_hole_value());
CHECK_EQ(ReadOnlyRoots(i_isolate1).code_map(),
ReadOnlyRoots(i_isolate2).code_map());
CHECK_EQ(ReadOnlyRoots(i_isolate1).exception(),
ReadOnlyRoots(i_isolate2).exception());
isolate1->Dispose();
isolate2->Dispose();
}
#endif // V8_SHARED_RO_HEAP
#endif // V8_COMPRESS_POINTERS_IN_SHARED_CAGE
} // namespace internal
} // namespace v8
#endif // V8_COMPRESS_POINTERS