v8/test/unittests/heap/persistent-handles-unittest.cc
Dominik Inführ 3c6d9aac45 [handles] Add PersistentHandlesScope
PersistentHandlesScope works similar to the DeferredHandleScope, but
returns PersistentHandles instead of DeferredHandles on Detach().

Since PersistentHandlesScope takes over filled blocks from the
main thread local handle, remove the block_size_ field and use
kHandleBlockSize instead. This way all blocks have exactly the same size.

Bug: v8:10315
Change-Id: I295cad6f84852f87c55d95572905069443f5698c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2324254
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69138}
2020-07-30 10:30:26 +00:00

108 lines
3.0 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 "src/handles/persistent-handles.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace v8 {
namespace internal {
using PersistentHandlesTest = TestWithIsolate;
TEST_F(PersistentHandlesTest, OrderOfBlocks) {
Isolate* isolate = i_isolate();
Heap* heap = isolate->heap();
HandleScope scope(isolate);
handle(ReadOnlyRoots(heap).empty_string(), isolate);
HandleScopeData* data = isolate->handle_scope_data();
Address* next;
Address* limit;
Handle<String> first_empty, last_empty;
std::unique_ptr<PersistentHandles> ph;
{
PersistentHandlesScope persistent_scope(isolate);
// fill block
first_empty = handle(ReadOnlyRoots(heap).empty_string(), isolate);
while (data->next < data->limit) {
handle(ReadOnlyRoots(heap).empty_string(), isolate);
}
// add second block and two more handles on it
handle(ReadOnlyRoots(heap).empty_string(), isolate);
last_empty = handle(ReadOnlyRoots(heap).empty_string(), isolate);
// remember next and limit in second block
next = data->next;
limit = data->limit;
ph = persistent_scope.Detach();
}
CHECK_EQ(ph->block_next_, next);
CHECK_EQ(ph->block_limit_, limit);
CHECK_EQ(first_empty->length(), 0);
CHECK_EQ(last_empty->length(), 0);
CHECK_EQ(*first_empty, *last_empty);
}
namespace {
class CounterDummyVisitor : public RootVisitor {
public:
void VisitRootPointers(Root root, const char* description,
FullObjectSlot start, FullObjectSlot end) override {
counter += end - start;
}
size_t counter = 0;
};
size_t count_handles(Isolate* isolate) {
CounterDummyVisitor visitor;
isolate->handle_scope_implementer()->Iterate(&visitor);
return visitor.counter;
}
size_t count_handles(PersistentHandles* ph) {
CounterDummyVisitor visitor;
ph->Iterate(&visitor);
return visitor.counter;
}
} // namespace
TEST_F(PersistentHandlesTest, Iterate) {
Isolate* isolate = i_isolate();
Heap* heap = isolate->heap();
v8::HandleScope scope(reinterpret_cast<v8::Isolate*>(isolate));
HandleScopeData* data = isolate->handle_scope_data();
size_t handles_in_empty_scope = count_handles(isolate);
Handle<Object> init(ReadOnlyRoots(heap).empty_string(), isolate);
Address* old_limit = data->limit;
CHECK_EQ(count_handles(isolate), handles_in_empty_scope + 1);
std::unique_ptr<PersistentHandles> ph;
{
PersistentHandlesScope persistent_scope(isolate);
handle(ReadOnlyRoots(heap).empty_string(), isolate);
CHECK_NE(old_limit, data->limit);
CHECK_EQ(count_handles(isolate), handles_in_empty_scope + 2);
ph = persistent_scope.Detach();
}
ph->NewHandle(ReadOnlyRoots(heap).empty_string());
CHECK_EQ(count_handles(ph.get()), 2);
CHECK_EQ(count_handles(isolate), handles_in_empty_scope + 1);
}
} // namespace internal
} // namespace v8