b5bf34bce7
LocalHeap can be used on main thread, however allocation might cause a GC which works differently on the main thread than on a background thread. Support collection on main thread by directly performing the GC instead of requesting the GC as done on background threads. To allow for differentiation between main and background threads, LocalHeap/LocalIsolate now require an additional argument. Change-Id: I08094ea633e303e149913f21dff395da9e046534 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2463238 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Commit-Queue: Dominik Inführ <dinfuehr@chromium.org> Cr-Commit-Position: refs/heads/master@{#70590}
141 lines
3.9 KiB
C++
141 lines
3.9 KiB
C++
// Copyright 2020 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 <memory>
|
|
|
|
#include "src/api/api.h"
|
|
#include "src/base/platform/condition-variable.h"
|
|
#include "src/base/platform/mutex.h"
|
|
#include "src/base/platform/semaphore.h"
|
|
#include "src/common/globals.h"
|
|
#include "src/handles/handles-inl.h"
|
|
#include "src/handles/local-handles-inl.h"
|
|
#include "src/handles/local-handles.h"
|
|
#include "src/heap/heap.h"
|
|
#include "src/heap/local-heap.h"
|
|
#include "src/heap/safepoint.h"
|
|
#include "src/objects/heap-number.h"
|
|
#include "test/cctest/cctest.h"
|
|
#include "test/cctest/heap/heap-utils.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
|
|
namespace {
|
|
|
|
class LocalHandlesThread final : public v8::base::Thread {
|
|
public:
|
|
LocalHandlesThread(Heap* heap, Address object, base::Semaphore* sema_started,
|
|
base::Semaphore* sema_gc_finished)
|
|
: v8::base::Thread(base::Thread::Options("ThreadWithLocalHeap")),
|
|
heap_(heap),
|
|
object_(object),
|
|
sema_started_(sema_started),
|
|
sema_gc_finished_(sema_gc_finished) {}
|
|
|
|
void Run() override {
|
|
LocalHeap local_heap(heap_, ThreadKind::kBackground);
|
|
UnparkedScope unparked_scope(&local_heap);
|
|
LocalHandleScope scope(&local_heap);
|
|
|
|
static constexpr int kNumHandles =
|
|
kHandleBlockSize * 2 + kHandleBlockSize / 2;
|
|
|
|
std::vector<Handle<HeapNumber>> handles;
|
|
handles.reserve(kNumHandles);
|
|
|
|
for (int i = 0; i < kNumHandles; i++) {
|
|
Handle<HeapNumber> number = handle(
|
|
HeapNumber::cast(HeapObject::FromAddress(object_)), &local_heap);
|
|
handles.push_back(number);
|
|
}
|
|
|
|
sema_started_->Signal();
|
|
|
|
{
|
|
ParkedScope scope(&local_heap);
|
|
sema_gc_finished_->Wait();
|
|
}
|
|
|
|
for (Handle<HeapNumber> handle : handles) {
|
|
CHECK_EQ(42.0, handle->value());
|
|
}
|
|
}
|
|
|
|
Heap* heap_;
|
|
Address object_;
|
|
base::Semaphore* sema_started_;
|
|
base::Semaphore* sema_gc_finished_;
|
|
};
|
|
|
|
TEST(CreateLocalHandles) {
|
|
heap::EnsureFlagLocalHeapsEnabled();
|
|
CcTest::InitializeVM();
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
|
|
Address object = kNullAddress;
|
|
|
|
{
|
|
HandleScope handle_scope(isolate);
|
|
Handle<HeapNumber> number = isolate->factory()->NewHeapNumber(42.0);
|
|
object = (*number).address();
|
|
}
|
|
|
|
base::Semaphore sema_started(0);
|
|
base::Semaphore sema_gc_finished(0);
|
|
|
|
std::unique_ptr<LocalHandlesThread> thread(new LocalHandlesThread(
|
|
isolate->heap(), object, &sema_started, &sema_gc_finished));
|
|
CHECK(thread->Start());
|
|
|
|
sema_started.Wait();
|
|
|
|
CcTest::CollectAllGarbage();
|
|
sema_gc_finished.Signal();
|
|
|
|
thread->Join();
|
|
}
|
|
|
|
TEST(CreateLocalHandlesWithoutLocalHandleScope) {
|
|
heap::EnsureFlagLocalHeapsEnabled();
|
|
CcTest::InitializeVM();
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
|
|
{
|
|
LocalHeap local_heap(isolate->heap(), ThreadKind::kMain);
|
|
UnparkedScope scope(&local_heap);
|
|
handle(Smi::FromInt(17), &local_heap);
|
|
}
|
|
}
|
|
|
|
TEST(DereferenceLocalHandle) {
|
|
heap::EnsureFlagLocalHeapsEnabled();
|
|
CcTest::InitializeVM();
|
|
Isolate* isolate = CcTest::i_isolate();
|
|
|
|
// Create a PersistentHandle to create the LocalHandle, and thus not have a
|
|
// HandleScope present to override the LocalHandleScope.
|
|
std::unique_ptr<PersistentHandles> phs = isolate->NewPersistentHandles();
|
|
Handle<HeapNumber> ph;
|
|
{
|
|
HandleScope handle_scope(isolate);
|
|
Handle<HeapNumber> number = isolate->factory()->NewHeapNumber(42.0);
|
|
ph = phs->NewHandle(number);
|
|
}
|
|
{
|
|
LocalHeap local_heap(isolate->heap(), ThreadKind::kMain, std::move(phs));
|
|
UnparkedScope unparked_scope(&local_heap);
|
|
LocalHandleScope scope(&local_heap);
|
|
Handle<HeapNumber> local_number = handle(*ph, &local_heap);
|
|
CHECK_EQ(42, local_number->value());
|
|
DisallowHandleDereference disallow_scope;
|
|
CHECK_EQ(42, local_number->value());
|
|
}
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
} // namespace internal
|
|
} // namespace v8
|