v8/test/unittests/test-utils.cc
Nikolaos Papaspyrou 9554743a0b [heap] Refactor the stack object
The stack object is primarily used for conservative stack scanning, both
by the V8 and C++ garbage collectors. This CL introduces the notion of a
"stack context", which comprises of the current stack marker (the lowest
address on the stack that may contain interesting pointers) and the
values of the saved registers. It simplifies the way in which iteration
through the stack is invoked: the context must have previously been
saved and iteration always uses the stack marker.

Bug: v8:13257
Bug: v8:13493
Change-Id: Ia99ef702eb6ac67a3bcd006f0edf5e57d9975ab2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4017512
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Omer Katz <omerkatz@chromium.org>
Commit-Queue: Nikolaos Papaspyrou <nikolaos@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84303}
2022-11-16 16:21:50 +00:00

114 lines
3.8 KiB
C++

// Copyright 2014 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/test-utils.h"
#include "include/libplatform/libplatform.h"
#include "include/v8-isolate.h"
#include "src/api/api-inl.h"
#include "src/base/platform/time.h"
#include "src/execution/isolate.h"
#include "src/flags/flags.h"
#include "src/init/v8.h"
#include "src/objects/objects-inl.h"
namespace v8 {
namespace {
// counter_lookup_callback doesn't pass through any state information about
// the current Isolate, so we have to store the current counter map somewhere.
// Fortunately tests run serially, so we can just store it in a static global.
CounterMap* kCurrentCounterMap = nullptr;
} // namespace
IsolateWrapper::IsolateWrapper(CountersMode counters_mode)
: array_buffer_allocator_(
v8::ArrayBuffer::Allocator::NewDefaultAllocator()) {
CHECK_NULL(kCurrentCounterMap);
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = array_buffer_allocator_.get();
if (counters_mode == kEnableCounters) {
counter_map_ = std::make_unique<CounterMap>();
kCurrentCounterMap = counter_map_.get();
create_params.counter_lookup_callback = [](const char* name) {
CHECK_NOT_NULL(kCurrentCounterMap);
// If the name doesn't exist in the counter map, operator[] will default
// initialize it to zero.
return &(*kCurrentCounterMap)[name];
};
} else {
create_params.counter_lookup_callback = [](const char* name) -> int* {
return nullptr;
};
}
isolate_ = v8::Isolate::New(create_params);
CHECK_NOT_NULL(isolate());
}
IsolateWrapper::~IsolateWrapper() {
v8::Platform* platform = internal::V8::GetCurrentPlatform();
CHECK_NOT_NULL(platform);
isolate_->Enter();
while (platform::PumpMessageLoop(platform, isolate())) continue;
isolate_->Exit();
isolate_->Dispose();
if (counter_map_) {
CHECK_EQ(kCurrentCounterMap, counter_map_.get());
kCurrentCounterMap = nullptr;
} else {
CHECK_NULL(kCurrentCounterMap);
}
}
namespace internal {
SaveFlags::SaveFlags() {
// For each flag, save the current flag value.
#define FLAG_MODE_APPLY(ftype, ctype, nam, def, cmt) \
SAVED_##nam = v8_flags.nam.value();
#include "src/flags/flag-definitions.h"
#undef FLAG_MODE_APPLY
}
SaveFlags::~SaveFlags() {
// For each flag, set back the old flag value if it changed (don't write the
// flag if it didn't change, to keep TSAN happy).
#define FLAG_MODE_APPLY(ftype, ctype, nam, def, cmt) \
if (SAVED_##nam != v8_flags.nam.value()) { \
v8_flags.nam = SAVED_##nam; \
}
#include "src/flags/flag-definitions.h" // NOLINT
#undef FLAG_MODE_APPLY
}
ManualGCScope::ManualGCScope(i::Isolate* isolate) {
// Some tests run threaded (back-to-back) and thus the GC may already be
// running by the time a ManualGCScope is created. Finalizing existing marking
// prevents any undefined/unexpected behavior.
if (isolate && isolate->heap()->incremental_marking()->IsMarking()) {
DisableConservativeStackScanningScopeForTesting no_stack_scanning(
isolate->heap());
isolate->heap()->CollectGarbage(OLD_SPACE,
GarbageCollectionReason::kTesting);
// Make sure there is no concurrent sweeping running in the background.
isolate->heap()->CompleteSweepingFull();
}
i::v8_flags.concurrent_marking = false;
i::v8_flags.concurrent_sweeping = false;
i::v8_flags.concurrent_minor_mc_marking = false;
i::v8_flags.stress_incremental_marking = false;
i::v8_flags.stress_concurrent_allocation = false;
// Parallel marking has a dependency on concurrent marking.
i::v8_flags.parallel_marking = false;
i::v8_flags.detect_ineffective_gcs_near_heap_limit = false;
}
} // namespace internal
} // namespace v8