Commit b0d990f9 authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

api,heap: Add public version of CppHeap

Allows embedders to allocate C++ objects on the internal managed C++
heap.

Bug: chromium:1056170
Change-Id: Ibd81d0fc915478a81f14e8ab12a631e442790f04
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2536642Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarOmer Katz <omerkatz@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#71225}
parent 3599cce1
......@@ -2,5 +2,7 @@ include_rules = [
# v8-inspector-protocol.h depends on generated files under include/inspector.
"+inspector",
"+cppgc/common.h",
# Used by v8-cppgc.h to bridge to cppgc.
"+cppgc/custom-space.h",
"+cppgc/visitor.h",
]
......@@ -5,12 +5,47 @@
#ifndef INCLUDE_V8_CPPGC_H_
#define INCLUDE_V8_CPPGC_H_
#include <memory>
#include <vector>
#include "cppgc/custom-space.h"
#include "cppgc/visitor.h"
#include "v8-internal.h" // NOLINT(build/include_directory)
#include "v8.h" // NOLINT(build/include_directory)
namespace cppgc {
class AllocationHandle;
} // namespace cppgc
namespace v8 {
namespace internal {
class CppHeap;
} // namespace internal
struct V8_EXPORT CppHeapCreateParams {
std::vector<std::unique_ptr<cppgc::CustomSpaceBase>> custom_spaces;
};
/**
* A heap for allocating managed C++ objects.
*/
class V8_EXPORT CppHeap {
public:
virtual ~CppHeap() = default;
/**
* \returns the opaque handle for allocating objects using
* `MakeGarbageCollected()`.
*/
cppgc::AllocationHandle& GetAllocationHandle();
private:
CppHeap() = default;
friend class internal::CppHeap;
};
class JSVisitor : public cppgc::Visitor {
public:
explicit JSVisitor(cppgc::Visitor::Key key) : cppgc::Visitor(key) {}
......
......@@ -48,6 +48,8 @@ class Boolean;
class BooleanObject;
class CFunction;
class Context;
class CppHeap;
struct CppHeapCreateParams;
class Data;
class Date;
class External;
......@@ -8251,26 +8253,15 @@ class V8_EXPORT Isolate {
/**
* Initial configuration parameters for a new Isolate.
*/
struct CreateParams {
CreateParams()
: code_event_handler(nullptr),
snapshot_blob(nullptr),
counter_lookup_callback(nullptr),
create_histogram_callback(nullptr),
add_histogram_sample_callback(nullptr),
array_buffer_allocator(nullptr),
array_buffer_allocator_shared(),
external_references(nullptr),
allow_atomics_wait(true),
only_terminate_in_safe_scope(false),
embedder_wrapper_type_index(-1),
embedder_wrapper_object_index(-1) {}
struct V8_EXPORT CreateParams {
CreateParams();
~CreateParams();
/**
* Allows the host application to provide the address of a function that is
* notified each time code is added, moved or removed.
*/
JitCodeEventHandler code_event_handler;
JitCodeEventHandler code_event_handler = nullptr;
/**
* ResourceConstraints to use for the new Isolate.
......@@ -8280,14 +8271,13 @@ class V8_EXPORT Isolate {
/**
* Explicitly specify a startup snapshot blob. The embedder owns the blob.
*/
StartupData* snapshot_blob;
StartupData* snapshot_blob = nullptr;
/**
* Enables the host application to provide a mechanism for recording
* statistics counters.
*/
CounterLookupCallback counter_lookup_callback;
CounterLookupCallback counter_lookup_callback = nullptr;
/**
* Enables the host application to provide a mechanism for recording
......@@ -8295,8 +8285,8 @@ class V8_EXPORT Isolate {
* histogram which will later be passed to the AddHistogramSample
* function.
*/
CreateHistogramCallback create_histogram_callback;
AddHistogramSampleCallback add_histogram_sample_callback;
CreateHistogramCallback create_histogram_callback = nullptr;
AddHistogramSampleCallback add_histogram_sample_callback = nullptr;
/**
* The ArrayBuffer::Allocator to use for allocating and freeing the backing
......@@ -8307,7 +8297,7 @@ class V8_EXPORT Isolate {
* to the allocator, in order to facilitate lifetime
* management for the allocator instance.
*/
ArrayBuffer::Allocator* array_buffer_allocator;
ArrayBuffer::Allocator* array_buffer_allocator = nullptr;
std::shared_ptr<ArrayBuffer::Allocator> array_buffer_allocator_shared;
/**
......@@ -8316,28 +8306,37 @@ class V8_EXPORT Isolate {
* deserialization. This array and its content must stay valid for the
* entire lifetime of the isolate.
*/
const intptr_t* external_references;
const intptr_t* external_references = nullptr;
/**
* Whether calling Atomics.wait (a function that may block) is allowed in
* this isolate. This can also be configured via SetAllowAtomicsWait.
*/
bool allow_atomics_wait;
bool allow_atomics_wait = true;
/**
* Termination is postponed when there is no active SafeForTerminationScope.
*/
bool only_terminate_in_safe_scope;
bool only_terminate_in_safe_scope = false;
/**
* The following parameters describe the offsets for addressing type info
* for wrapped API objects and are used by the fast C API
* (for details see v8-fast-api-calls.h).
*/
int embedder_wrapper_type_index;
int embedder_wrapper_object_index;
};
int embedder_wrapper_type_index = -1;
int embedder_wrapper_object_index = -1;
/**
* If parameters are set, V8 creates a managed C++ heap as extension to its
* JavaScript heap.
*
* See v8::Isolate::GetCppHeap() for working with the heap.
*
* This is an experimental feature and may still change significantly.
*/
std::shared_ptr<CppHeapCreateParams> cpp_heap_params;
};
/**
* Stack-allocated class which sets the isolate for all operations
......@@ -8939,6 +8938,12 @@ class V8_EXPORT Isolate {
*/
EmbedderHeapTracer* GetEmbedderHeapTracer();
/**
* \returns the C++ heap managed by V8. Only available if the Isolate was
* created with proper CreatePrams::cpp_heap_params option.
*/
CppHeap* GetCppHeap() const;
/**
* Use for |AtomicsWaitCallback| to indicate the type of event it receives.
*/
......
......@@ -11,6 +11,7 @@
#include <utility> // For move
#include <vector>
#include "include/cppgc/custom-space.h"
#include "include/v8-cppgc.h"
#include "include/v8-fast-api-calls.h"
#include "include/v8-profiler.h"
......@@ -8249,6 +8250,11 @@ EmbedderHeapTracer* Isolate::GetEmbedderHeapTracer() {
return isolate->heap()->GetEmbedderHeapTracer();
}
CppHeap* Isolate::GetCppHeap() const {
const i::Isolate* isolate = reinterpret_cast<const i::Isolate*>(this);
return isolate->heap()->cpp_heap();
}
void Isolate::SetGetExternallyAllocatedMemoryInBytesCallback(
GetExternallyAllocatedMemoryInBytesCallback callback) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
......@@ -8305,6 +8311,10 @@ Isolate* Isolate::Allocate() {
return reinterpret_cast<Isolate*>(i::Isolate::New());
}
Isolate::CreateParams::CreateParams() = default;
Isolate::CreateParams::~CreateParams() = default;
// static
// This is separate so that tests can provide a different |isolate|.
void Isolate::Initialize(Isolate* isolate,
......@@ -8352,6 +8362,9 @@ void Isolate::Initialize(Isolate* isolate,
i_isolate->set_allow_atomics_wait(params.allow_atomics_wait);
i_isolate->heap()->ConfigureHeap(params.constraints);
if (params.cpp_heap_params) {
i_isolate->heap()->ConfigureCppHeap(params.cpp_heap_params);
}
if (params.constraints.stack_limit() != nullptr) {
uintptr_t limit =
reinterpret_cast<uintptr_t>(params.constraints.stack_limit());
......
......@@ -992,6 +992,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
}
StackGuard* stack_guard() { return isolate_data()->stack_guard(); }
Heap* heap() { return &heap_; }
const Heap* heap() const { return &heap_; }
ReadOnlyHeap* read_only_heap() const { return read_only_heap_; }
static Isolate* FromHeap(Heap* heap) {
return reinterpret_cast<Isolate*>(reinterpret_cast<Address>(heap) -
......
......@@ -33,6 +33,11 @@
#include "src/profiler/heap-profiler.h"
namespace v8 {
cppgc::AllocationHandle& CppHeap::GetAllocationHandle() {
return internal::CppHeap::From(this)->object_allocator();
}
namespace internal {
namespace {
......@@ -149,13 +154,17 @@ CppHeap::CppHeap(
kSupportsConservativeStackScan),
isolate_(*reinterpret_cast<Isolate*>(isolate)) {
CHECK(!FLAG_incremental_marking_wrappers);
isolate_.heap_profiler()->AddBuildEmbedderGraphCallback(&CppGraphBuilder::Run,
this);
if (isolate_.heap_profiler()) {
isolate_.heap_profiler()->AddBuildEmbedderGraphCallback(
&CppGraphBuilder::Run, this);
}
}
CppHeap::~CppHeap() {
isolate_.heap_profiler()->RemoveBuildEmbedderGraphCallback(
&CppGraphBuilder::Run, this);
if (isolate_.heap_profiler()) {
isolate_.heap_profiler()->RemoveBuildEmbedderGraphCallback(
&CppGraphBuilder::Run, this);
}
}
void CppHeap::RegisterV8References(
......
......@@ -5,6 +5,7 @@
#ifndef V8_HEAP_CPPGC_JS_CPP_HEAP_H_
#define V8_HEAP_CPPGC_JS_CPP_HEAP_H_
#include "include/v8-cppgc.h"
#include "include/v8.h"
#include "src/base/macros.h"
#include "src/heap/cppgc/heap-base.h"
......@@ -17,8 +18,16 @@ namespace internal {
// A C++ heap implementation used with V8 to implement unified heap.
class V8_EXPORT_PRIVATE CppHeap final : public cppgc::internal::HeapBase,
public v8::CppHeap,
public v8::EmbedderHeapTracer {
public:
static CppHeap* From(v8::CppHeap* heap) {
return static_cast<CppHeap*>(heap);
}
static const CppHeap* From(const v8::CppHeap* heap) {
return static_cast<const CppHeap*>(heap);
}
CppHeap(v8::Isolate* isolate,
const std::vector<std::unique_ptr<cppgc::CustomSpaceBase>>&
custom_spaces);
......
......@@ -12,6 +12,7 @@
#include "include/cppgc/platform.h"
#include "src/base/bits.h"
#include "src/base/lazy-instance.h"
#include "src/base/page-allocator.h"
namespace cppgc {
namespace internal {
......@@ -36,6 +37,13 @@ constexpr GCInfoIndex GCInfoTable::kMinIndex;
constexpr GCInfoIndex GCInfoTable::kInitialWantedLimit;
void GlobalGCInfoTable::Create(PageAllocator* page_allocator) {
if (!page_allocator) {
static v8::base::LeakyObject<v8::base::PageAllocator>
default_page_allocator;
page_allocator = default_page_allocator.get();
}
// TODO(chromium:1056170): Wrap page_allocator into LsanPageAllocator when
// running with LEAK_SANITIZER.
static v8::base::LeakyObject<GCInfoTable> table(page_allocator);
if (!global_table_) {
global_table_ = table.get();
......
......@@ -5,7 +5,6 @@
#ifndef V8_HEAP_CPPGC_VISITOR_H_
#define V8_HEAP_CPPGC_VISITOR_H_
#include "include/cppgc/persistent.h"
#include "include/cppgc/visitor.h"
#include "src/heap/cppgc/heap-object-header.h"
......
......@@ -39,6 +39,7 @@
#include "src/heap/combined-heap.h"
#include "src/heap/concurrent-allocator.h"
#include "src/heap/concurrent-marking.h"
#include "src/heap/cppgc-js/cpp-heap.h"
#include "src/heap/embedder-tracing.h"
#include "src/heap/finalization-registry-cleanup-task.h"
#include "src/heap/gc-idle-time-handler.h"
......@@ -4665,6 +4666,12 @@ void Heap::ConfigureHeap(const v8::ResourceConstraints& constraints) {
configured_ = true;
}
void Heap::ConfigureCppHeap(std::shared_ptr<CppHeapCreateParams> params) {
cpp_heap_ = std::make_unique<CppHeap>(
reinterpret_cast<v8::Isolate*>(isolate()), params->custom_spaces);
SetEmbedderHeapTracer(CppHeap::From(cpp_heap_.get()));
}
void Heap::AddToRingBuffer(const char* string) {
size_t first_part =
Min(strlen(string), kTraceRingBufferSize - ring_buffer_end_);
......@@ -5441,6 +5448,7 @@ void Heap::TearDown() {
dead_object_stats_.reset();
local_embedder_heap_tracer_.reset();
cpp_heap_.reset();
external_string_table_.TearDown();
......
......@@ -68,6 +68,7 @@ class BasicMemoryChunk;
class CodeLargeObjectSpace;
class CollectionBarrier;
class ConcurrentMarking;
class CppHeap;
class GCIdleTimeHandler;
class GCIdleTimeHeapState;
class GCTracer;
......@@ -1133,6 +1134,15 @@ class Heap {
EmbedderHeapTracer::TraceFlags flags_for_embedder_tracer() const;
// ===========================================================================
// Unified heap (C++) support. ===============================================
// ===========================================================================
V8_EXPORT_PRIVATE void ConfigureCppHeap(
std::shared_ptr<CppHeapCreateParams> params);
v8::CppHeap* cpp_heap() const { return cpp_heap_.get(); }
// ===========================================================================
// External string table API. ================================================
// ===========================================================================
......@@ -2219,6 +2229,7 @@ class Heap {
std::unique_ptr<AllocationObserver> stress_concurrent_allocation_observer_;
std::unique_ptr<LocalEmbedderHeapTracer> local_embedder_heap_tracer_;
std::unique_ptr<MarkingBarrier> marking_barrier_;
std::unique_ptr<v8::CppHeap> cpp_heap_;
StrongRootsEntry* strong_roots_head_ = nullptr;
base::Mutex strong_roots_mutex_;
......
......@@ -6,6 +6,7 @@
#include <fstream>
#include "include/cppgc/platform.h"
#include "src/api/api.h"
#include "src/base/atomicops.h"
#include "src/base/once.h"
......@@ -129,6 +130,7 @@ void V8::InitializePlatform(v8::Platform* platform) {
platform_ = platform;
v8::base::SetPrintStackTrace(platform_->GetStackTracePrinter());
v8::tracing::TracingCategoryObserver::SetUp();
cppgc::InitializeProcess(platform->GetPageAllocator());
}
void V8::ShutdownPlatform() {
......@@ -136,6 +138,7 @@ void V8::ShutdownPlatform() {
v8::tracing::TracingCategoryObserver::TearDown();
v8::base::SetPrintStackTrace(nullptr);
platform_ = nullptr;
cppgc::ShutdownProcess();
}
v8::Platform* V8::GetCurrentPlatform() {
......
......@@ -5,8 +5,10 @@
#include "test/unittests/heap/unified-heap-utils.h"
#include "include/cppgc/platform.h"
#include "include/v8-cppgc.h"
#include "src/api/api-inl.h"
#include "src/heap/cppgc-js/cpp-heap.h"
#include "src/heap/heap.h"
#include "src/objects/objects-inl.h"
namespace v8 {
......@@ -15,16 +17,11 @@ namespace internal {
UnifiedHeapTest::UnifiedHeapTest()
: saved_incremental_marking_wrappers_(FLAG_incremental_marking_wrappers) {
FLAG_incremental_marking_wrappers = false;
cppgc::InitializeProcess(V8::GetCurrentPlatform()->GetPageAllocator());
cpp_heap_ = std::make_unique<CppHeap>(
v8_isolate(), std::vector<std::unique_ptr<cppgc::CustomSpaceBase>>());
heap()->SetEmbedderHeapTracer(&cpp_heap());
isolate()->heap()->ConfigureCppHeap(std::make_unique<CppHeapCreateParams>());
}
UnifiedHeapTest::~UnifiedHeapTest() {
heap()->SetEmbedderHeapTracer(nullptr);
FLAG_incremental_marking_wrappers = saved_incremental_marking_wrappers_;
cppgc::ShutdownProcess();
}
void UnifiedHeapTest::CollectGarbageWithEmbedderStack() {
......@@ -39,7 +36,9 @@ void UnifiedHeapTest::CollectGarbageWithoutEmbedderStack() {
CollectGarbage(OLD_SPACE);
}
CppHeap& UnifiedHeapTest::cpp_heap() const { return *cpp_heap_.get(); }
CppHeap& UnifiedHeapTest::cpp_heap() const {
return *CppHeap::From(isolate()->heap()->cpp_heap());
}
cppgc::AllocationHandle& UnifiedHeapTest::allocation_handle() {
return cpp_heap().object_allocator();
......
......@@ -26,7 +26,6 @@ class UnifiedHeapTest : public TestWithHeapInternals {
cppgc::AllocationHandle& allocation_handle();
private:
std::unique_ptr<CppHeap> cpp_heap_;
bool saved_incremental_marking_wrappers_;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment