v8/test/unittests/api/gc-callbacks-unittest.cc
Clemens Backes f9bb65eb9f [unittests] Use v8_flags for accessing flag values
Avoid the deprecated FLAG_* syntax, access flag values via the
{v8_flags} struct instead.

R=mliedtke@chromium.org

Bug: v8:12887
Change-Id: I06e12314495c2d89135e58e5d3a01310f108e865
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3899303
Reviewed-by: Matthias Liedtke <mliedtke@chromium.org>
Commit-Queue: Matthias Liedtke <mliedtke@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83233}
2022-09-15 17:51:59 +00:00

168 lines
5.9 KiB
C++

// Copyright 2017 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 "test/unittests/heap/heap-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace v8 {
namespace {
namespace {
class GCCallbacksTest : public internal::TestWithHeapInternalsAndContext {
public:
static void PrologueCallbackAlloc(v8::Isolate* isolate, v8::GCType,
v8::GCCallbackFlags flags) {
v8::HandleScope scope(isolate);
CHECK_EQ(flags, v8::kNoGCCallbackFlags);
CHECK_EQ(current_test_->gc_callbacks_isolate_, isolate);
++current_test_->prologue_call_count_alloc_;
if (!i::v8_flags.single_generation) {
// Simulate full heap to see if we will reenter this callback
current_test_->SimulateFullSpace(current_test_->heap()->new_space());
}
Local<Object> obj = Object::New(isolate);
CHECK(!obj.IsEmpty());
current_test_->PreciseCollectAllGarbage();
}
static void EpilogueCallbackAlloc(v8::Isolate* isolate, v8::GCType,
v8::GCCallbackFlags flags) {
v8::HandleScope scope(isolate);
CHECK_EQ(flags, v8::kNoGCCallbackFlags);
CHECK_EQ(current_test_->gc_callbacks_isolate_, isolate);
++current_test_->epilogue_call_count_alloc_;
if (!i::v8_flags.single_generation) {
// Simulate full heap to see if we will reenter this callback
current_test_->SimulateFullSpace(current_test_->heap()->new_space());
}
Local<Object> obj = Object::New(isolate);
CHECK(!obj.IsEmpty());
current_test_->PreciseCollectAllGarbage();
}
static void PrologueCallback(v8::Isolate* isolate, v8::GCType,
v8::GCCallbackFlags flags) {
CHECK_EQ(flags, v8::kNoGCCallbackFlags);
CHECK_EQ(current_test_->gc_callbacks_isolate_, isolate);
++current_test_->prologue_call_count_;
}
static void EpilogueCallback(v8::Isolate* isolate, v8::GCType,
v8::GCCallbackFlags flags) {
CHECK_EQ(flags, v8::kNoGCCallbackFlags);
CHECK_EQ(current_test_->gc_callbacks_isolate_, isolate);
++current_test_->epilogue_call_count_;
}
static void PrologueCallbackSecond(v8::Isolate* isolate, v8::GCType,
v8::GCCallbackFlags flags) {
CHECK_EQ(flags, v8::kNoGCCallbackFlags);
CHECK_EQ(current_test_->gc_callbacks_isolate_, isolate);
++current_test_->prologue_call_count_second_;
}
static void EpilogueCallbackSecond(v8::Isolate* isolate, v8::GCType,
v8::GCCallbackFlags flags) {
CHECK_EQ(flags, v8::kNoGCCallbackFlags);
CHECK_EQ(current_test_->gc_callbacks_isolate_, isolate);
++current_test_->epilogue_call_count_second_;
}
static void PrologueCallbackNew(v8::Isolate* isolate, v8::GCType,
v8::GCCallbackFlags flags, void* data) {
CHECK_EQ(flags, v8::kNoGCCallbackFlags);
CHECK_EQ(current_test_->gc_callbacks_isolate_, isolate);
++*static_cast<int*>(data);
}
static void EpilogueCallbackNew(v8::Isolate* isolate, v8::GCType,
v8::GCCallbackFlags flags, void* data) {
CHECK_EQ(flags, v8::kNoGCCallbackFlags);
CHECK_EQ(current_test_->gc_callbacks_isolate_, isolate);
++*static_cast<int*>(data);
}
protected:
void SetUp() override {
internal::TestWithHeapInternalsAndContext::SetUp();
DCHECK_NULL(current_test_);
current_test_ = this;
}
void TearDown() override {
DCHECK_NOT_NULL(current_test_);
current_test_ = nullptr;
internal::TestWithHeapInternalsAndContext::TearDown();
}
static GCCallbacksTest* current_test_;
v8::Isolate* gc_callbacks_isolate_ = nullptr;
int prologue_call_count_ = 0;
int epilogue_call_count_ = 0;
int prologue_call_count_second_ = 0;
int epilogue_call_count_second_ = 0;
int prologue_call_count_alloc_ = 0;
int epilogue_call_count_alloc_ = 0;
};
GCCallbacksTest* GCCallbacksTest::current_test_ = nullptr;
} // namespace
TEST_F(GCCallbacksTest, GCCallbacks) {
// For SimulateFullSpace in PrologueCallbackAlloc and EpilogueCallbackAlloc.
i::v8_flags.stress_concurrent_allocation = false;
v8::Isolate* isolate = context()->GetIsolate();
gc_callbacks_isolate_ = isolate;
isolate->AddGCPrologueCallback(PrologueCallback);
isolate->AddGCEpilogueCallback(EpilogueCallback);
CHECK_EQ(0, prologue_call_count_);
CHECK_EQ(0, epilogue_call_count_);
CollectAllGarbage();
CHECK_EQ(1, prologue_call_count_);
CHECK_EQ(1, epilogue_call_count_);
isolate->AddGCPrologueCallback(PrologueCallbackSecond);
isolate->AddGCEpilogueCallback(EpilogueCallbackSecond);
CollectAllGarbage();
CHECK_EQ(2, prologue_call_count_);
CHECK_EQ(2, epilogue_call_count_);
CHECK_EQ(1, prologue_call_count_second_);
CHECK_EQ(1, epilogue_call_count_second_);
isolate->RemoveGCPrologueCallback(PrologueCallback);
isolate->RemoveGCEpilogueCallback(EpilogueCallback);
CollectAllGarbage();
CHECK_EQ(2, prologue_call_count_);
CHECK_EQ(2, epilogue_call_count_);
CHECK_EQ(2, prologue_call_count_second_);
CHECK_EQ(2, epilogue_call_count_second_);
isolate->RemoveGCPrologueCallback(PrologueCallbackSecond);
isolate->RemoveGCEpilogueCallback(EpilogueCallbackSecond);
CollectAllGarbage();
CHECK_EQ(2, prologue_call_count_);
CHECK_EQ(2, epilogue_call_count_);
CHECK_EQ(2, prologue_call_count_second_);
CHECK_EQ(2, epilogue_call_count_second_);
CHECK_EQ(0, prologue_call_count_alloc_);
CHECK_EQ(0, epilogue_call_count_alloc_);
isolate->AddGCPrologueCallback(PrologueCallbackAlloc);
isolate->AddGCEpilogueCallback(EpilogueCallbackAlloc);
PreciseCollectAllGarbage();
CHECK_EQ(1, prologue_call_count_alloc_);
CHECK_EQ(1, epilogue_call_count_alloc_);
isolate->RemoveGCPrologueCallback(PrologueCallbackAlloc);
isolate->RemoveGCEpilogueCallback(EpilogueCallbackAlloc);
}
} // namespace
} // namespace v8