Revert "[api] Introduce CppHeapExternal"

This reverts commit c6c2d15dd4.

Reason for revert: https://ci.chromium.org/ui/p/v8/builders/ci/V8%20Linux64%20css%20-%20debug/12334/overview

Original change's description:
> [api] Introduce CppHeapExternal
>
> CppHeapExternal is an on-heap version of External, allowing embedders to
> store GarbageCollected objects in JS values that aren't exposed to
> JavaScript, and therefore aren't associated with a particular Context.
>
> Unlike JS wrapper objects, this new type extends HeapObject rather than
> JSObject since it is not exposed to JavaScript. To support this, the
> existing Cpp heap pointer logic is being updated to support objects with
> different layouts. The Cpp object is otherwise handled in the same way
> as Object::Wrap and Object::Unwrap, including using CppHeapPointerTag
> (we'll use distinct tags in Blink to separate these objects from
> ScriptWrappable objects; see crrev.com/c/6350413).
>
> Bug: 380911428
> Change-Id: I8777f7ce5c5447437557111be064ea195eaba175
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6343961
> Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
> Reviewed-by: Igor Sheludko <ishell@chromium.org>
> Commit-Queue: Scott Haseley <shaseley@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#99676}

Bug: 380911428
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Change-Id: I1266071a8bad1bc54b7ca977aec440b8e7a89b6a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6433845
Auto-Submit: Ilya Rezvov <irezvov@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Owners-Override: Ilya Rezvov <irezvov@chromium.org>
Reviewed-by: Ilya Rezvov <irezvov@chromium.org>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/main@{#99678}
This commit is contained in:
Ilya Rezvov authored and V8 LUCI CQ committed 2025-04-04 09:53:10 -07:00
1 parent e62729ccd1
commit 2f2bcbae2e
50 files changed
+166 -576

No files matched your search

-6
View File
@@ -685,7 +685,6 @@ filegroup(
"include/v8-callbacks.h",
"include/v8-container.h",
"include/v8-context.h",
"include/v8-cpp-heap-external.h",
"include/v8-cppgc.h",
"include/v8-data.h",
"include/v8-date.h",
@@ -1146,7 +1145,6 @@ filegroup(
"src/objects/call-site-info.tq",
"src/objects/cell.tq",
"src/objects/contexts.tq",
"src/objects/cpp-heap-external-object.tq",
"src/objects/data-handler.tq",
"src/objects/debug-objects.tq",
"src/objects/descriptor-array.tq",
@@ -1999,10 +1997,6 @@ filegroup(
"src/objects/contexts.cc",
"src/objects/contexts.h",
"src/objects/contexts-inl.h",
"src/objects/cpp-heap-external-object.h",
"src/objects/cpp-heap-external-object-inl.h",
"src/objects/cpp-heap-object-wrapper.h",
"src/objects/cpp-heap-object-wrapper-inl.h",
"src/objects/data-handler.h",
"src/objects/data-handler-inl.h",
"src/objects/debug-objects.cc",
-10
View File
@@ -1823,10 +1823,6 @@ if (v8_postmortem_support) {
"src/objects/casting-inl.h",
"src/objects/code.h",
"src/objects/code-inl.h",
"src/objects/cpp-heap-external-object.h",
"src/objects/cpp-heap-external-object-inl.h",
"src/objects/cpp-heap-object-wrapper.h",
"src/objects/cpp-heap-object-wrapper-inl.h",
"src/objects/data-handler.h",
"src/objects/data-handler-inl.h",
"src/objects/deoptimization-data.h",
@@ -2065,7 +2061,6 @@ torque_files = [
"src/objects/cell.tq",
"src/objects/bytecode-array.tq",
"src/objects/contexts.tq",
"src/objects/cpp-heap-external-object.tq",
"src/objects/data-handler.tq",
"src/objects/debug-objects.tq",
"src/objects/descriptor-array.tq",
@@ -3181,7 +3176,6 @@ v8_header_set("v8_headers") {
"include/v8-callbacks.h",
"include/v8-container.h",
"include/v8-context.h",
"include/v8-cpp-heap-external.h",
"include/v8-cppgc.h",
"include/v8-data.h",
"include/v8-date.h",
@@ -3942,10 +3936,6 @@ v8_header_set("v8_internal_headers") {
"src/objects/compressed-slots.h",
"src/objects/contexts-inl.h",
"src/objects/contexts.h",
"src/objects/cpp-heap-external-object-inl.h",
"src/objects/cpp-heap-external-object.h",
"src/objects/cpp-heap-object-wrapper-inl.h",
"src/objects/cpp-heap-object-wrapper.h",
"src/objects/data-handler-inl.h",
"src/objects/data-handler.h",
"src/objects/debug-objects-inl.h",
-1
View File
@@ -7,7 +7,6 @@ include_rules = [
"+cppgc/heap-statistics.h",
"+cppgc/internal/conditional-stack-allocated.h",
"+cppgc/internal/write-barrier.h",
"+cppgc/type-traits.h",
"+cppgc/visitor.h",
"+perfetto",
]
-56
View File
@@ -1,56 +0,0 @@
// Copyright 2025 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.
#ifndef INCLUDE_V8_HEAP_EXTERNAL_H_
#define INCLUDE_V8_HEAP_EXTERNAL_H_
#include "cppgc/type-traits.h" // NOLINT(build/include_directory)
#include "v8-sandbox.h" // NOLINT(build/include_directory)
#include "v8-value.h" // NOLINT(build/include_directory)
#include "v8config.h" // NOLINT(build/include_directory)
namespace v8 {
class Isolate;
/**
* A JavaScript value that wraps a `cppgc::GarbageCollected<T>` object allocated
* on the managed C++ heap (CppHeap). This type of value is mainly used to
* associate C++ data structures which aren't exposed to JavaScript with
* JavaScript objects.
*/
class V8_EXPORT CppHeapExternal : public Data {
public:
template <typename T>
static Local<CppHeapExternal> New(Isolate* isolate, T* value,
CppHeapPointerTag tag) {
static_assert(cppgc::IsGarbageCollectedTypeV<T>,
"Object must be of type GarbageCollected.");
return NewImpl(isolate, value, tag);
}
V8_INLINE static CppHeapExternal* Cast(Data* data) {
#ifdef V8_ENABLE_CHECKS
CheckCast(data);
#endif
return static_cast<CppHeapExternal*>(data);
}
template <typename T>
T* Value(Isolate* isolate, CppHeapPointerTagRange tag_range) const {
static_assert(cppgc::IsGarbageCollectedTypeV<T>,
"Object must be of type GarbageCollected.");
return static_cast<T*>(ValueImpl(isolate, tag_range));
}
private:
static void CheckCast(v8::Data* obj);
static Local<CppHeapExternal> NewImpl(Isolate* isolate, void* value,
CppHeapPointerTag tag);
void* ValueImpl(Isolate*, CppHeapPointerTagRange tag_range) const;
};
} // namespace v8
#endif // INCLUDE_V8_HEAP_EXTERNAL_H_
-5
View File
@@ -57,11 +57,6 @@ class V8_EXPORT Data {
*/
bool IsContext() const;
/**
* Returns true if this value is a `CppHeapExternal` object.
*/
bool IsCppHeapExternal() const;
private:
Data() = delete;
};
+1 -1
View File
@@ -330,7 +330,7 @@ MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
const auto new_js_object_type =
constructor->has_initial_map() &&
IsJSApiWrapperObjectMap(constructor->initial_map())
IsJSApiWrapperObject(constructor->initial_map())
? NewJSObjectType::kAPIWrapper
: NewJSObjectType::kNoAPIWrapper;
Handle<JSObject> object;
+3 -34
View File
@@ -86,7 +86,6 @@
#include "src/objects/api-callbacks.h"
#include "src/objects/backing-store.h"
#include "src/objects/contexts.h"
#include "src/objects/cpp-heap-object-wrapper-inl.h"
#include "src/objects/embedder-data-array-inl.h"
#include "src/objects/embedder-data-slot-inl.h"
#include "src/objects/hash-table-inl.h"
@@ -816,10 +815,6 @@ bool Data::IsContext() const {
return i::IsContext(*Utils::OpenDirectHandle(this));
}
bool Data::IsCppHeapExternal() const {
return IsCppHeapExternalObject(*Utils::OpenDirectHandle(this));
}
void Context::Enter() {
i::DisallowGarbageCollection no_gc;
i::Tagged<i::NativeContext> env = *Utils::OpenDirectHandle(this);
@@ -3999,11 +3994,6 @@ void v8::WasmModuleObject::CheckCast(Value* that) {
"Value is not a WasmModuleObject");
}
void v8::CppHeapExternal::CheckCast(v8::Data* that) {
Utils::ApiCheck(that->IsCppHeapExternal(), "v8::CppHeapExternal::Cast",
"Value is not a CppHeapExternal");
}
v8::BackingStore::~BackingStore() {
auto i_this = reinterpret_cast<const i::BackingStore*>(this);
i_this->~BackingStore(); // manually call internal destructor
@@ -6376,7 +6366,7 @@ void v8::Object::SetAlignedPointerInInternalFields(int argc, int indices[],
void* v8::Object::Unwrap(v8::Isolate* isolate, i::Address wrapper_obj,
CppHeapPointerTagRange tag_range) {
DCHECK_LE(tag_range.lower_bound, tag_range.upper_bound);
return i::CppHeapObjectWrapper(
return i::JSApiWrapper(
i::Cast<i::JSObject>(i::Tagged<i::Object>(wrapper_obj)))
.GetCppHeapWrappable(reinterpret_cast<i::Isolate*>(isolate), tag_range);
}
@@ -6384,7 +6374,7 @@ void* v8::Object::Unwrap(v8::Isolate* isolate, i::Address wrapper_obj,
// static
void v8::Object::Wrap(v8::Isolate* isolate, i::Address wrapper_obj,
CppHeapPointerTag tag, void* wrappable) {
return i::CppHeapObjectWrapper(
return i::JSApiWrapper(
i::Cast<i::JSObject>(i::Tagged<i::Object>(wrapper_obj)))
.SetCppHeapWrappable(reinterpret_cast<i::Isolate*>(isolate), wrappable,
tag);
@@ -6886,8 +6876,7 @@ bool RequiresEmbedderSupportToFreeze(i::InstanceType obj_type) {
return (i::InstanceTypeChecker::IsJSApiObject(obj_type) ||
i::InstanceTypeChecker::IsJSExternalObject(obj_type) ||
i::InstanceTypeChecker::IsJSAPIObjectWithEmbedderSlots(obj_type) ||
i::InstanceTypeChecker::IsCppHeapExternalObject(obj_type));
i::InstanceTypeChecker::IsJSAPIObjectWithEmbedderSlots(obj_type));
}
bool IsJSReceiverSafeToFreeze(i::InstanceType obj_type) {
@@ -7512,26 +7501,6 @@ void* External::Value() const {
->value(isolate);
}
Local<CppHeapExternal> v8::CppHeapExternal::NewImpl(Isolate* v8_isolate,
void* value,
CppHeapPointerTag tag) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
API_RCS_SCOPE(i_isolate, CppHeapExternal, New);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
i::DirectHandle<i::CppHeapExternalObject> external =
i_isolate->factory()->NewCppHeapExternal();
i::CppHeapObjectWrapper(*external).SetCppHeapWrappable(i_isolate, value, tag);
return Utils::CppHeapExternalToLocal(external);
}
void* CppHeapExternal::ValueImpl(v8::Isolate* isolate,
CppHeapPointerTagRange tag_range) const {
DCHECK_LE(tag_range.lower_bound, tag_range.upper_bound);
auto self = Utils::OpenDirectHandle(this);
return i::CppHeapObjectWrapper(*self).GetCppHeapWrappable(
reinterpret_cast<i::Isolate*>(isolate), tag_range);
}
// anonymous namespace for string creation helper functions
namespace {
+1 -5
View File
@@ -8,7 +8,6 @@
#include <memory>
#include "include/v8-container.h"
#include "include/v8-cpp-heap-external.h"
#include "include/v8-external.h"
#include "include/v8-function-callback.h"
#include "include/v8-proxy.h"
@@ -132,7 +131,6 @@ class RegisteredExtension {
V(FixedArrayToLocal, FixedArray, FixedArray) \
V(PrimitiveArrayToLocal, FixedArray, PrimitiveArray) \
V(ToLocal, ScriptOrModule, ScriptOrModule) \
V(CppHeapExternalToLocal, CppHeapExternalObject, CppHeapExternal) \
IF_WASM(V, ToLocal, WasmMemoryMapDescriptor, WasmMemoryMapDescriptor) \
IF_WASM(V, ToLocal, WasmModuleObject, WasmModuleObject)
@@ -151,8 +149,7 @@ class RegisteredExtension {
V(CallableToLocal) \
V(ToLocalPrimitive) \
V(FixedArrayToLocal) \
V(PrimitiveArrayToLocal) \
V(CppHeapExternalToLocal)
V(PrimitiveArrayToLocal)
#define OPEN_HANDLE_LIST(V) \
V(Template, TemplateInfoWithProperties) \
@@ -209,7 +206,6 @@ class RegisteredExtension {
V(ScriptOrModule, ScriptOrModule) \
V(FixedArray, FixedArray) \
V(ModuleRequest, ModuleRequest) \
V(CppHeapExternal, CppHeapExternalObject) \
IF_WASM(V, WasmMemoryMapDescriptor, WasmMemoryMapDescriptor) \
IF_WASM(V, WasmMemoryObject, WasmMemoryObject)
+2 -2
View File
@@ -69,8 +69,8 @@ BUILTIN(ErrorIsError) {
// DOMExceptions should return true. See
// https://github.com/whatwg/webidl/pull/1421
return *isolate->factory()->ToBoolean(
IsJSErrorMap(obj_map) ||
(IsJSApiWrapperObjectMap(obj_map) &&
InstanceTypeChecker::IsJSError(obj_map) ||
(IsJSApiWrapperObject(obj_map) &&
isolate->IsJSApiWrapperNativeError(Cast<JSReceiver>(obj))));
} else {
return ReadOnlyRoots(isolate).false_value();
-1
View File
@@ -195,7 +195,6 @@ Type::bitset BitsetType::Lub(MapRefLike map, JSHeapBroker* broker) {
UNREACHABLE();
case HEAP_NUMBER_TYPE:
return kNumber;
case CPP_HEAP_EXTERNAL_OBJECT_TYPE:
case JS_ARRAY_ITERATOR_PROTOTYPE_TYPE:
case JS_ITERATOR_PROTOTYPE_TYPE:
case JS_MAP_ITERATOR_PROTOTYPE_TYPE:
-11
View File
@@ -24,7 +24,6 @@
#include "src/objects/all-objects-inl.h"
#include "src/objects/allocation-site.h"
#include "src/objects/code-kind.h"
#include "src/objects/cpp-heap-object-wrapper-inl.h"
#include "src/objects/instance-type.h"
#include "src/objects/js-function-inl.h"
#include "src/objects/js-objects.h"
@@ -826,16 +825,6 @@ void JSExternalObject::JSExternalObjectPrint(std::ostream& os) {
JSObjectPrintBody(os, *this);
}
void CppHeapExternalObject::CppHeapExternalObjectPrint(std::ostream& os) {
if (i::Isolate* isolate = i::Isolate::TryGetCurrent()) {
os << "\n - cpp_heap_wrappable: "
<< CppHeapObjectWrapper(*this).GetCppHeapWrappable(isolate,
kAnyCppHeapPointer);
} else {
os << "\n - cpp_heap_wrappable: <object>";
}
}
void JSGeneratorObject::JSGeneratorObjectPrint(std::ostream& os) {
JSObjectPrintHeader(os, *this, "JSGeneratorObject");
os << "\n - function: " << Brief(function());
+2 -5
View File
@@ -23,7 +23,6 @@ static_assert(
#include "src/heap/cppgc/marker.h"
#include "src/heap/cppgc/stats-collector.h"
#include "src/logging/metrics.h"
#include "src/objects/cpp-heap-object-wrapper.h"
#include "src/objects/js-objects.h"
namespace v8 {
@@ -192,8 +191,7 @@ class V8_EXPORT_PRIVATE CppHeap final
#endif // V8_ENABLE_ALLOCATION_TIMEOUT
V8_INLINE void RememberCrossHeapReferenceIfNeeded(
v8::internal::Tagged<v8::internal::CppHeapPointerWrapperObjectT> host_obj,
void* value);
v8::internal::Tagged<v8::internal::JSObject> host_obj, void* value);
template <typename F>
inline void VisitCrossHeapRememberedSetIfNeeded(F f);
void ResetCrossHeapRememberedSet();
@@ -279,8 +277,7 @@ class V8_EXPORT_PRIVATE CppHeap final
};
void CppHeap::RememberCrossHeapReferenceIfNeeded(
v8::internal::Tagged<v8::internal::CppHeapPointerWrapperObjectT> host_obj,
void* value) {
v8::internal::Tagged<v8::internal::JSObject> host_obj, void* value) {
if (!generational_gc_supported()) return;
DCHECK(isolate_);
cross_heap_remembered_set_.RememberReferenceIfNeeded(*isolate_, host_obj,
+1 -2
View File
@@ -21,7 +21,6 @@
#include "src/heap/cppgc/heap-visitor.h"
#include "src/heap/cppgc/visitor.h"
#include "src/heap/mark-compact.h"
#include "src/objects/cpp-heap-object-wrapper-inl.h"
#include "src/objects/js-objects.h"
#include "src/objects/objects-inl.h"
#include "src/profiler/heap-profiler.h"
@@ -395,7 +394,7 @@ void* ExtractEmbedderDataBackref(Isolate* isolate, CppHeap& cpp_heap,
return nullptr;
}
// Wrapper using cpp_heap_wrappable field.
return CppHeapObjectWrapper(*js_object)
return JSApiWrapper(*js_object)
.GetCppHeapWrappable(isolate, kAnyCppHeapPointer);
}
@@ -11,8 +11,7 @@
namespace v8::internal {
void CrossHeapRememberedSet::RememberReferenceIfNeeded(
Isolate& isolate, Tagged<CppHeapPointerWrapperObjectT> host_obj,
void* cppgc_object) {
Isolate& isolate, Tagged<JSObject> host_obj, void* cppgc_object) {
DCHECK_NOT_NULL(cppgc_object);
// Any in-cage pointer must point to a vaild, not freed cppgc object.
auto* page =
@@ -9,7 +9,6 @@
#include "src/base/macros.h"
#include "src/handles/handles.h"
#include "src/objects/cpp-heap-object-wrapper.h"
#include "src/objects/tagged.h"
namespace cppgc::internal {
@@ -18,6 +17,8 @@ class HeapBase;
namespace v8::internal {
class JSObject;
// The class is used to remember V8 to Oilpan references.
class V8_EXPORT_PRIVATE CrossHeapRememberedSet final {
public:
@@ -27,8 +28,7 @@ class V8_EXPORT_PRIVATE CrossHeapRememberedSet final {
CrossHeapRememberedSet(const CrossHeapRememberedSet&) = delete;
CrossHeapRememberedSet(CrossHeapRememberedSet&&) = delete;
void RememberReferenceIfNeeded(Isolate& isolate,
Tagged<CppHeapPointerWrapperObjectT> host_obj,
void RememberReferenceIfNeeded(Isolate& isolate, Tagged<JSObject> host_obj,
void* cppgc_object);
void Reset(Isolate& isolate);
@@ -41,8 +41,7 @@ class V8_EXPORT_PRIVATE CrossHeapRememberedSet final {
cppgc::internal::HeapBase& heap_base_;
// The vector keeps handles to remembered V8 objects that have outgoing
// references to the cppgc heap. Please note that the handles are global.
std::vector<IndirectHandle<CppHeapPointerWrapperObjectT>>
remembered_v8_to_cppgc_references_;
std::vector<IndirectHandle<JSObject>> remembered_v8_to_cppgc_references_;
};
template <typename F>
+11 -12
View File
@@ -45,7 +45,6 @@
#include "src/objects/bigint.h"
#include "src/objects/call-site-info-inl.h"
#include "src/objects/cell-inl.h"
#include "src/objects/cpp-heap-object-wrapper-inl.h"
#include "src/objects/debug-objects-inl.h"
#include "src/objects/embedder-data-array-inl.h"
#include "src/objects/feedback-cell-inl.h"
@@ -2908,15 +2907,6 @@ Handle<JSObject> Factory::NewExternal(void* value,
return external;
}
Handle<CppHeapExternalObject> Factory::NewCppHeapExternal(
AllocationType allocation_type) {
Tagged<CppHeapExternalObject> external = Cast<CppHeapExternalObject>(
AllocateRawWithAllocationSite(cpp_heap_external_map(), allocation_type,
DirectHandle<AllocationSite>::null()));
CppHeapObjectWrapper(external).InitializeCppHeapWrapper();
return handle(external, isolate());
}
DirectHandle<Code> Factory::NewCodeObjectForEmbeddedBuiltin(
DirectHandle<Code> code, Address off_heap_entry) {
CHECK_NOT_NULL(isolate()->embedded_blob_code());
@@ -3084,6 +3074,15 @@ Handle<JSGlobalObject> Factory::NewJSGlobalObject(
return global;
}
void Factory::InitializeCppHeapWrapper(Tagged<JSObject> obj) {
DCHECK(IsJSApiWrapperObject(obj));
DCHECK(IsJSAPIObjectWithEmbedderSlots(obj) || IsJSSpecialObject(obj));
static_assert(JSSpecialObject::kCppHeapWrappableOffset ==
JSAPIObjectWithEmbedderSlots::kCppHeapWrappableOffset);
obj->SetupLazilyInitializedCppHeapPointerField(
JSAPIObjectWithEmbedderSlots::kCppHeapWrappableOffset);
}
void Factory::InitializeJSObjectFromMap(Tagged<JSObject> obj,
Tagged<Object> properties,
Tagged<Map> map,
@@ -3098,14 +3097,14 @@ void Factory::InitializeJSObjectFromMap(Tagged<JSObject> obj,
// fixed array (e.g. Heap::empty_fixed_array()). Currently, the object
// verification code has to cope with (temporarily) invalid objects. See
// for example, JSArray::JSArrayVerify).
DCHECK_EQ(IsJSApiWrapperObjectMap(map),
DCHECK_EQ(IsJSApiWrapperObject(map),
new_js_object_type == NewJSObjectType::kAPIWrapper);
InitializeJSObjectBody(obj, map,
new_js_object_type == NewJSObjectType::kNoAPIWrapper
? JSObject::kHeaderSize
: JSAPIObjectWithEmbedderSlots::kHeaderSize);
if (new_js_object_type == NewJSObjectType::kAPIWrapper) {
CppHeapObjectWrapper(obj).InitializeCppHeapWrapper();
InitializeCppHeapWrapper(obj);
}
}
+1 -4
View File
@@ -889,10 +889,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
Handle<JSObject> NewExternal(
void* value, AllocationType allocation = AllocationType::kYoung);
// Create a CppHeapExternal object for V8's external API.
Handle<CppHeapExternalObject> NewCppHeapExternal(
AllocationType allocation = AllocationType::kYoung);
// Allocates a new code object and initializes it to point to the given
// off-heap entry point.
//
@@ -1389,6 +1385,7 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
// Initializes JSObject body starting at given offset.
void InitializeJSObjectBody(Tagged<JSObject> obj, Tagged<Map> map,
int start_offset);
void InitializeCppHeapWrapper(Tagged<JSObject> obj);
Handle<WeakArrayList> NewUninitializedWeakArrayList(
int capacity, AllocationType allocation = AllocationType::kYoung);
-21
View File
@@ -176,11 +176,6 @@ size_t HeapVisitor<ConcreteVisitor>::Visit(Tagged<Map> map,
return visitor->VisitJSApiObject(
map, ConcreteVisitor::template Cast<JSObject>(object, heap_),
maybe_object_size);
case kVisitCppHeapExternalObject:
return visitor->VisitCppHeapExternalObject(
map,
ConcreteVisitor::template Cast<CppHeapExternalObject>(object, heap_),
maybe_object_size);
case kVisitStruct:
return visitor->VisitStruct(map, object, maybe_object_size);
case kVisitFiller:
@@ -304,22 +299,6 @@ size_t HeapVisitor<ConcreteVisitor>::VisitJSApiObject(
map, object, maybe_object_size);
}
template <typename ConcreteVisitor>
size_t HeapVisitor<ConcreteVisitor>::VisitCppHeapExternalObject(
Tagged<Map> map, Tagged<CppHeapExternalObject> object,
MaybeObjectSize maybe_object_size) {
ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
const size_t size =
ConcreteVisitor::UsePrecomputedObjectSize()
? maybe_object_size.AssumeSize()
: CppHeapExternalObject::BodyDescriptor::SizeOf(map, object);
visitor->template VisitMapPointerIfNeeded<
VisitorId::kVisitCppHeapExternalObject>(object);
CppHeapExternalObject::BodyDescriptor::IterateBody(
map, object, static_cast<int>(size), visitor);
return size;
}
template <typename ConcreteVisitor>
size_t HeapVisitor<ConcreteVisitor>::VisitStruct(
Tagged<Map> map, Tagged<HeapObject> object,
-3
View File
@@ -266,9 +266,6 @@ class HeapVisitor : public ObjectVisitorWithCageBases {
MaybeObjectSize maybe_object_size);
V8_INLINE size_t VisitJSApiObject(Tagged<Map> map, Tagged<JSObject> object,
MaybeObjectSize maybe_object_size);
V8_INLINE size_t VisitCppHeapExternalObject(
Tagged<Map> map, Tagged<CppHeapExternalObject> object,
MaybeObjectSize maybe_object_size);
V8_INLINE size_t VisitStruct(Tagged<Map> map, Tagged<HeapObject> object,
MaybeObjectSize maybe_object_size);
V8_INLINE size_t VisitFiller(Tagged<Map> map, Tagged<HeapObject> object,
+3 -4
View File
@@ -15,7 +15,6 @@
#include "src/heap/marking-barrier.h"
#include "src/heap/memory-chunk.h"
#include "src/objects/compressed-slots-inl.h"
#include "src/objects/cpp-heap-object-wrapper.h"
#include "src/objects/descriptor-array.h"
#include "src/objects/maybe-object-inl.h"
@@ -349,7 +348,7 @@ void WriteBarrier::MarkingFromTracedHandle(Tagged<Object> value) {
}
// static
void WriteBarrier::ForCppHeapPointer(Tagged<CppHeapPointerWrapperObjectT> host,
void WriteBarrier::ForCppHeapPointer(Tagged<JSObject> host,
CppHeapPointerSlot slot, void* value) {
// Note: this is currently a combined barrier for marking both the
// CppHeapPointerTable entry and the referenced object.
@@ -376,8 +375,8 @@ void WriteBarrier::ForCppHeapPointer(Tagged<CppHeapPointerWrapperObjectT> host,
}
// static
void WriteBarrier::GenerationalBarrierForCppHeapPointer(
Tagged<CppHeapPointerWrapperObjectT> host, void* value) {
void WriteBarrier::GenerationalBarrierForCppHeapPointer(Tagged<JSObject> host,
void* value) {
if (!value) {
return;
}
+4 -3
View File
@@ -62,9 +62,10 @@ void WriteBarrier::MarkingSlowFromTracedHandle(Tagged<HeapObject> value) {
}
// static
void WriteBarrier::MarkingSlowFromCppHeapWrappable(
Heap* heap, Tagged<CppHeapPointerWrapperObjectT> host,
CppHeapPointerSlot slot, void* object) {
void WriteBarrier::MarkingSlowFromCppHeapWrappable(Heap* heap,
Tagged<JSObject> host,
CppHeapPointerSlot slot,
void* object) {
// Note: this is currently a combined barrier for marking both the
// CppHeapPointerTable entry and the referenced object (if any).
+7 -9
View File
@@ -10,7 +10,6 @@
#include "include/v8-internal.h"
#include "src/common/globals.h"
#include "src/objects/cpp-heap-object-wrapper.h"
#include "src/objects/heap-object.h"
namespace v8::internal {
@@ -75,9 +74,8 @@ class V8_EXPORT_PRIVATE WriteBarrier final {
Tagged<TrustedObject> host, ProtectedPointerSlot slot,
Tagged<TrustedObject> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
static inline void ForCppHeapPointer(
Tagged<CppHeapPointerWrapperObjectT> host, CppHeapPointerSlot slot,
void* value);
static inline void ForCppHeapPointer(Tagged<JSObject> host,
CppHeapPointerSlot slot, void* value);
static inline void ForJSDispatchHandle(
Tagged<HeapObject> host, JSDispatchHandle handle,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
@@ -154,14 +152,14 @@ class V8_EXPORT_PRIVATE WriteBarrier final {
Tagged<TrustedObject> value);
static void MarkingSlow(Tagged<HeapObject> host, JSDispatchHandle handle);
static void MarkingSlowFromTracedHandle(Tagged<HeapObject> value);
static void MarkingSlowFromCppHeapWrappable(
Heap* heap, Tagged<CppHeapPointerWrapperObjectT> host,
CppHeapPointerSlot slot, void* object);
static void MarkingSlowFromCppHeapWrappable(Heap* heap, Tagged<JSObject> host,
CppHeapPointerSlot slot,
void* object);
static void GenerationalBarrierSlow(Tagged<HeapObject> object, Address slot,
Tagged<HeapObject> value);
static inline void GenerationalBarrierForCppHeapPointer(
Tagged<CppHeapPointerWrapperObjectT> host, void* value);
static inline void GenerationalBarrierForCppHeapPointer(Tagged<JSObject> host,
void* value);
static void SharedSlow(Tagged<TrustedObject> host, ProtectedPointerSlot slot,
Tagged<TrustedObject> value);
+14 -13
View File
@@ -48,7 +48,6 @@
#include "src/heap/traced-handles-marking-visitor.h"
#include "src/heap/weak-object-worklists.h"
#include "src/init/v8.h"
#include "src/objects/cpp-heap-object-wrapper-inl.h"
#include "src/objects/js-collection-inl.h"
#include "src/objects/objects.h"
#include "src/objects/string-forwarding-table-inl.h"
@@ -604,15 +603,18 @@ void MinorMarkSweepCollector::ClearNonLiveReferences() {
}
namespace {
void VisitObjectWithCppHeapPointerField(
Isolate* isolate, Tagged<CppHeapPointerWrapperObjectT> object,
MarkingWorklists::Local& worklist) {
DCHECK(IsCppHeapPointerWrapperObject(object));
DCHECK(!HeapLayout::InYoungGeneration(object));
void VisitObjectWithEmbedderFields(Isolate* isolate, Tagged<JSObject> js_object,
MarkingWorklists::Local& worklist) {
DCHECK(js_object->MayHaveEmbedderFields());
DCHECK(!HeapLayout::InYoungGeneration(js_object));
// Not every object that can have embedder fields is actually a JSApiWrapper.
if (!IsJSApiWrapperObject(js_object)) {
return;
}
// Wrapper using cpp_heap_wrappable field.
void* wrappable = CppHeapObjectWrapper::From(object).GetCppHeapWrappable(
isolate, kAnyCppHeapPointer);
void* wrappable =
JSApiWrapper(js_object).GetCppHeapWrappable(isolate, kAnyCppHeapPointer);
if (wrappable) {
worklist.cpp_marking_state()->MarkAndPush(wrappable);
}
@@ -628,11 +630,10 @@ void MinorMarkSweepCollector::MarkRootsFromTracedHandles(
heap_->isolate()->traced_handles()->IterateAndMarkYoungRootsWithOldHosts(
&root_visitor);
// Visit the V8-to-Oilpan remembered set.
cpp_heap->VisitCrossHeapRememberedSetIfNeeded(
[this](Tagged<CppHeapPointerWrapperObjectT> obj) {
VisitObjectWithCppHeapPointerField(heap_->isolate(), obj,
*local_marking_worklists());
});
cpp_heap->VisitCrossHeapRememberedSetIfNeeded([this](Tagged<JSObject> obj) {
VisitObjectWithEmbedderFields(heap_->isolate(), obj,
*local_marking_worklists());
});
} else {
// Otherwise, visit all young roots.
heap_->isolate()->traced_handles()->IterateYoungRoots(&root_visitor);
-9
View File
@@ -450,8 +450,6 @@ class ScavengeVisitor final : public NewSpaceVisitor<ScavengeVisitor> {
MaybeObjectSize);
V8_INLINE size_t VisitJSApiObject(Tagged<Map> map, Tagged<JSObject> object,
MaybeObjectSize);
V8_INLINE size_t VisitCppHeapExternalObject(
Tagged<Map> map, Tagged<CppHeapExternalObject> object, MaybeObjectSize);
V8_INLINE void VisitExternalPointer(Tagged<HeapObject> host,
ExternalPointerSlot slot);
@@ -532,13 +530,6 @@ size_t ScavengeVisitor::VisitJSApiObject(Tagged<Map> map,
return size;
}
size_t ScavengeVisitor::VisitCppHeapExternalObject(
Tagged<Map> map, Tagged<CppHeapExternalObject> object, MaybeObjectSize) {
int size = CppHeapExternalObject::BodyDescriptor::SizeOf(map, object);
CppHeapExternalObject::BodyDescriptor::IterateBody(map, object, size, this);
return size;
}
void ScavengeVisitor::VisitExternalPointer(Tagged<HeapObject> host,
ExternalPointerSlot slot) {
#ifdef V8_COMPRESS_POINTERS
-3
View File
@@ -835,9 +835,6 @@ bool Heap::CreateLateReadOnlyJSReceiverMaps() {
external)
roots.external_map()->SetEnumLength(0);
roots.external_map()->set_is_extensible(false);
ALLOCATE_MAP(CPP_HEAP_EXTERNAL_OBJECT_TYPE,
CppHeapExternalObject::kHeaderSize, cpp_heap_external)
}
// Shared space object maps are immutable and can be in RO space.
-1
View File
@@ -173,7 +173,6 @@ class RuntimeCallTimer final {
V(FunctionTemplate_NewRemoteInstance) \
V(FunctionTemplate_NewWithCache) \
V(FunctionTemplate_NewWithFastHandler) \
V(CppHeapExternal_New) \
V(Int16Array_New) \
V(Int32Array_New) \
V(Int8Array_New) \
-2
View File
@@ -19,8 +19,6 @@
#include "src/objects/compilation-cache-table-inl.h"
#include "src/objects/compressed-slots-inl.h"
#include "src/objects/contexts-inl.h"
#include "src/objects/cpp-heap-external-object-inl.h"
#include "src/objects/cpp-heap-object-wrapper-inl.h"
#include "src/objects/data-handler-inl.h"
#include "src/objects/debug-objects-inl.h"
#include "src/objects/descriptor-array-inl.h"
@@ -1,23 +0,0 @@
// Copyright 2025 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.
#ifndef V8_OBJECTS_CPP_HEAP_EXTERNAL_OBJECT_INL_H_
#define V8_OBJECTS_CPP_HEAP_EXTERNAL_OBJECT_INL_H_
#include "src/objects/cpp-heap-external-object.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8::internal {
#include "torque-generated/src/objects/cpp-heap-external-object-tq-inl.inc"
TQ_OBJECT_CONSTRUCTORS_IMPL(CppHeapExternalObject)
} // namespace v8::internal
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_CPP_HEAP_EXTERNAL_OBJECT_INL_H_
-32
View File
@@ -1,32 +0,0 @@
// Copyright 2025 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.
#ifndef V8_OBJECTS_CPP_HEAP_EXTERNAL_OBJECT_H_
#define V8_OBJECTS_CPP_HEAP_EXTERNAL_OBJECT_H_
#include "src/objects/heap-object.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8::internal {
#include "torque-generated/src/objects/cpp-heap-external-object-tq.inc"
class CppHeapExternalObject
: public TorqueGeneratedCppHeapExternalObject<CppHeapExternalObject,
HeapObject> {
public:
DECL_PRINTER(CppHeapExternalObject)
class BodyDescriptor;
TQ_OBJECT_CONSTRUCTORS(CppHeapExternalObject)
};
} // namespace v8::internal
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_CPP_HEAP_EXTERNAL_OBJECT_H_
-7
View File
@@ -1,7 +0,0 @@
// Copyright 2025 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.
extern class CppHeapExternalObject extends HeapObject {
cpp_heap_wrappable: CppHeapPointer;
}
-79
View File
@@ -1,79 +0,0 @@
// Copyright 2025 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.
#ifndef V8_OBJECTS_CPP_HEAP_OBJECT_WRAPPER_INL_H_
#define V8_OBJECTS_CPP_HEAP_OBJECT_WRAPPER_INL_H_
#include "src/objects/cpp-heap-object-wrapper.h"
// Include the non-inl header before the rest of the headers.
#include "src/heap/heap-write-barrier-inl.h"
#include "src/objects/heap-object-inl.h"
namespace v8::internal {
// static
CppHeapObjectWrapper CppHeapObjectWrapper::From(
Tagged<CppHeapPointerWrapperObjectT> object) {
DCHECK(IsCppHeapPointerWrapperObject(object));
if (IsCppHeapExternalObject(object)) {
return CppHeapObjectWrapper(Cast<CppHeapExternalObject>(object));
}
DCHECK(IsJSObject(object));
return CppHeapObjectWrapper(Cast<JSObject>(object));
}
CppHeapObjectWrapper::CppHeapObjectWrapper(Tagged<CppHeapExternalObject> object)
: object_(object), offset_(CppHeapExternalObject::kCppHeapWrappableOffset) {
DCHECK(IsCppHeapPointerWrapperObject(object));
}
CppHeapObjectWrapper::CppHeapObjectWrapper(Tagged<JSObject> object)
: object_(object),
offset_(JSAPIObjectWithEmbedderSlots::kCppHeapWrappableOffset) {
DCHECK(IsCppHeapPointerWrapperObject(object));
DCHECK(IsJSApiWrapperObject(object));
DCHECK(IsJSAPIObjectWithEmbedderSlots(object_) || IsJSSpecialObject(object_));
}
void CppHeapObjectWrapper::InitializeCppHeapWrapper() {
object_->SetupLazilyInitializedCppHeapPointerField(offset_);
}
template <CppHeapPointerTag lower_bound, CppHeapPointerTag upper_bound>
void* CppHeapObjectWrapper::GetCppHeapWrappable(
IsolateForPointerCompression isolate) const {
return reinterpret_cast<void*>(
object_->ReadCppHeapPointerField<lower_bound, upper_bound>(offset_,
isolate));
}
void* CppHeapObjectWrapper::GetCppHeapWrappable(
IsolateForPointerCompression isolate,
CppHeapPointerTagRange tag_range) const {
return reinterpret_cast<void*>(
object_->ReadCppHeapPointerField(offset_, isolate, tag_range));
}
template <CppHeapPointerTag tag>
void CppHeapObjectWrapper::SetCppHeapWrappable(
IsolateForPointerCompression isolate, void* instance) {
object_->WriteLazilyInitializedCppHeapPointerField<tag>(
offset_, isolate, reinterpret_cast<Address>(instance));
WriteBarrier::ForCppHeapPointer(
object_, object_->RawCppHeapPointerField(offset_), instance);
}
void CppHeapObjectWrapper::SetCppHeapWrappable(
IsolateForPointerCompression isolate, void* instance,
CppHeapPointerTag tag) {
object_->WriteLazilyInitializedCppHeapPointerField(
offset_, isolate, reinterpret_cast<Address>(instance), tag);
WriteBarrier::ForCppHeapPointer(
object_, object_->RawCppHeapPointerField(offset_), instance);
}
} // namespace v8::internal
#endif // V8_OBJECTS_CPP_HEAP_OBJECT_WRAPPER_INL_H_
-51
View File
@@ -1,51 +0,0 @@
// Copyright 2025 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.
#ifndef V8_OBJECTS_CPP_HEAP_OBJECT_WRAPPER_H_
#define V8_OBJECTS_CPP_HEAP_OBJECT_WRAPPER_H_
#include "src/objects/cpp-heap-external-object.h"
#include "src/objects/js-objects.h"
#include "src/objects/union.h"
#include "src/sandbox/isolate.h"
namespace v8::internal {
// Object types that can have a cpp heap object pointer field.
using CppHeapPointerWrapperObjectT = UnionOf<JSObject, CppHeapExternalObject>;
// Helper union that doesn't actually exist as type. Used to get and set the cpp
// heap pointer for objects that are associated with one. Use by value.
class CppHeapObjectWrapper {
public:
V8_INLINE static CppHeapObjectWrapper From(
Tagged<CppHeapPointerWrapperObjectT> object);
V8_INLINE explicit CppHeapObjectWrapper(Tagged<JSObject> object);
V8_INLINE explicit CppHeapObjectWrapper(Tagged<CppHeapExternalObject> object);
V8_INLINE void InitializeCppHeapWrapper();
template <CppHeapPointerTag tag>
V8_INLINE void SetCppHeapWrappable(IsolateForPointerCompression isolate,
void*);
V8_INLINE void SetCppHeapWrappable(IsolateForPointerCompression isolate,
void*, CppHeapPointerTag tag);
template <CppHeapPointerTag lower_bound, CppHeapPointerTag upper_bound>
V8_INLINE void* GetCppHeapWrappable(
IsolateForPointerCompression isolate) const;
V8_INLINE void* GetCppHeapWrappable(IsolateForPointerCompression isolate,
CppHeapPointerTagRange tag_range) const;
private:
static_assert(JSAPIObjectWithEmbedderSlots::kCppHeapWrappableOffset ==
JSSpecialObject::kCppHeapWrappableOffset);
Tagged<CppHeapPointerWrapperObjectT> object_;
int offset_;
};
} // namespace v8::internal
#endif // V8_OBJECTS_CPP_HEAP_OBJECT_WRAPPER_H_
-2
View File
@@ -32,12 +32,10 @@ class Map;
#define INSTANCE_TYPE_CHECKERS_CUSTOM(V) \
V(AbstractCode) \
V(CppHeapPointerWrapperObject) \
V(ExternalString) \
V(FreeSpaceOrFiller) \
V(GcSafeCode) \
V(InternalizedString) \
V(JSApiWrapperObject) \
V(MaybeReadOnlyJSObject) \
V(PropertyDictionary)
+2 -20
View File
@@ -487,7 +487,8 @@ V8_INLINE constexpr bool IsNativeContextSpecific(InstanceType instance_type) {
// Most of the JSReceivers are tied to some native context modulo the
// following exceptions.
if (IsMaybeReadOnlyJSObject(instance_type)) {
if (instance_type == JS_MESSAGE_OBJECT_TYPE ||
instance_type == JS_EXTERNAL_OBJECT_TYPE) {
// These JSObject types are wrappers around a set of primitive values
// and exist only for the purpose of passing the data across V8 Api.
// Thus they are not tied to any native context.
@@ -510,25 +511,6 @@ V8_INLINE bool IsNativeContextSpecificMap(Tagged<Map> map_object) {
return IsNativeContextSpecific(map_object->instance_type());
}
V8_INLINE constexpr bool IsJSApiWrapperObject(InstanceType instance_type) {
return IsJSAPIObjectWithEmbedderSlots(instance_type) ||
IsJSSpecialObject(instance_type);
}
V8_INLINE bool IsJSApiWrapperObject(Tagged<Map> map_object) {
return IsJSApiWrapperObject(map_object->instance_type());
}
V8_INLINE constexpr bool IsCppHeapPointerWrapperObject(
InstanceType instance_type) {
return IsJSApiWrapperObject(instance_type) ||
IsCppHeapExternalObject(instance_type);
}
V8_INLINE bool IsCppHeapPointerWrapperObject(Tagged<Map> map_object) {
return IsCppHeapPointerWrapperObject(map_object->instance_type());
}
} // namespace InstanceTypeChecker
#define TYPE_CHECKER(type, ...) \
+44 -2
View File
@@ -13,8 +13,6 @@
#include "src/common/globals.h"
#include "src/heap/heap-layout-inl.h"
#include "src/heap/heap-write-barrier.h"
#include "src/objects/cpp-heap-external-object.h"
#include "src/objects/cpp-heap-object-wrapper.h"
#include "src/objects/dictionary.h"
#include "src/objects/elements.h"
#include "src/objects/embedder-data-slot-inl.h"
@@ -646,6 +644,50 @@ TQ_OBJECT_CONSTRUCTORS_IMPL(JSExternalObject)
EXTERNAL_POINTER_ACCESSORS(JSExternalObject, value, void*, kValueOffset,
kExternalObjectValueTag)
JSApiWrapper::JSApiWrapper(Tagged<JSObject> object) : object_(object) {
DCHECK(IsJSApiWrapperObject(object));
}
template <CppHeapPointerTag lower_bound, CppHeapPointerTag upper_bound>
void* JSApiWrapper::GetCppHeapWrappable(
IsolateForPointerCompression isolate) const {
return reinterpret_cast<void*>(
object_->ReadCppHeapPointerField<lower_bound, upper_bound>(
kCppHeapWrappableOffset, isolate));
}
void* JSApiWrapper::GetCppHeapWrappable(
IsolateForPointerCompression isolate,
CppHeapPointerTagRange tag_range) const {
return reinterpret_cast<void*>(object_->ReadCppHeapPointerField(
kCppHeapWrappableOffset, isolate, tag_range));
}
template <CppHeapPointerTag tag>
void JSApiWrapper::SetCppHeapWrappable(IsolateForPointerCompression isolate,
void* instance) {
object_->WriteLazilyInitializedCppHeapPointerField<tag>(
JSAPIObjectWithEmbedderSlots::kCppHeapWrappableOffset, isolate,
reinterpret_cast<Address>(instance));
WriteBarrier::ForCppHeapPointer(
object_,
object_->RawCppHeapPointerField(
JSAPIObjectWithEmbedderSlots::kCppHeapWrappableOffset),
instance);
}
void JSApiWrapper::SetCppHeapWrappable(IsolateForPointerCompression isolate,
void* instance, CppHeapPointerTag tag) {
object_->WriteLazilyInitializedCppHeapPointerField(
JSAPIObjectWithEmbedderSlots::kCppHeapWrappableOffset, isolate,
reinterpret_cast<Address>(instance), tag);
WriteBarrier::ForCppHeapPointer(
object_,
object_->RawCppHeapPointerField(
JSAPIObjectWithEmbedderSlots::kCppHeapWrappableOffset),
instance);
}
bool JSMessageObject::DidEnsureSourcePositionsAvailable() const {
return shared_info() == Smi::zero();
}
-3
View File
@@ -2927,9 +2927,6 @@ void JSObject::JSObjectShortPrint(StringStream* accumulator) {
case JS_EXTERNAL_OBJECT_TYPE:
accumulator->Add("<JSExternalObject>");
break;
case CPP_HEAP_EXTERNAL_OBJECT_TYPE:
accumulator->Add("<CppHeapExternalObject>");
break;
default: {
Tagged<Map> map_of_this = map();
+25
View File
@@ -1082,6 +1082,31 @@ class JSSpecialObject
TQ_OBJECT_CONSTRUCTORS(JSSpecialObject)
};
// Helper union that doesn't actually exist as type. Use by value.
class JSApiWrapper {
public:
V8_INLINE explicit JSApiWrapper(Tagged<JSObject> object);
template <CppHeapPointerTag tag>
V8_INLINE void SetCppHeapWrappable(IsolateForPointerCompression isolate,
void*);
V8_INLINE void SetCppHeapWrappable(IsolateForPointerCompression isolate,
void*, CppHeapPointerTag tag);
template <CppHeapPointerTag lower_bound, CppHeapPointerTag upper_bound>
V8_INLINE void* GetCppHeapWrappable(
IsolateForPointerCompression isolate) const;
V8_INLINE void* GetCppHeapWrappable(IsolateForPointerCompression isolate,
CppHeapPointerTagRange tag_range) const;
private:
static_assert(JSAPIObjectWithEmbedderSlots::kCppHeapWrappableOffset ==
JSSpecialObject::kCppHeapWrappableOffset);
static constexpr int kCppHeapWrappableOffset =
JSAPIObjectWithEmbedderSlots::kCppHeapWrappableOffset;
Tagged<JSObject> object_;
};
// JSAccessorPropertyDescriptor is just a JSObject with a specific initial
// map. This initial map adds in-object properties for "get", "set",
// "enumerable" and "configurable" properties, as assigned by the
-3
View File
@@ -339,9 +339,6 @@ VisitorId Map::GetVisitorId(Tagged<Map> map) {
case JS_SPECIAL_API_OBJECT_TYPE:
return kVisitJSApiObject;
case CPP_HEAP_EXTERNAL_OBJECT_TYPE:
return kVisitCppHeapExternalObject;
case JS_DATE_TYPE:
return kVisitJSDate;
-1
View File
@@ -50,7 +50,6 @@ enum InstanceType : uint16_t;
V(CodeWrapper) \
V(ConsString) \
V(ContextSidePropertyCell) \
V(CppHeapExternalObject) \
V(DataHandler) \
V(DebugInfo) \
V(EmbedderDataArray) \
-3
View File
@@ -111,7 +111,6 @@ namespace internal {
V(ContextSidePropertyCell) \
V(Context) \
V(CoverageInfo) \
V(CppHeapExternalObject) \
V(DataHandler) \
V(DeoptimizationData) \
V(DependentCode) \
@@ -411,13 +410,11 @@ namespace internal {
V(CallableJSFunction) \
V(CallableJSProxy) \
V(CatchContext) \
V(CppHeapPointerWrapperObject) \
V(DebugEvaluateContext) \
V(EvalContext) \
V(FreeSpaceOrFiller) \
V(FunctionContext) \
V(JSApiObject) \
V(JSApiWrapperObject) \
V(JSClassConstructor) \
V(JSLastDummyApiObject) \
V(JSPromiseConstructor) \
@@ -186,25 +186,6 @@ class JSAPIObjectWithEmbedderSlots::BodyDescriptor
}
};
class CppHeapExternalObject::BodyDescriptor final : public BodyDescriptorBase {
public:
template <typename ObjectVisitor>
static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
int object_size, ObjectVisitor* v) {
static_assert(CppHeapExternalObject::kCppHeapWrappableOffsetEnd + 1 ==
CppHeapExternalObject::kHeaderSize);
v->VisitCppHeapPointer(obj,
obj->RawCppHeapPointerField(
CppHeapExternalObject::kCppHeapWrappableOffset));
DCHECK_EQ(object_size, kHeaderSize);
}
static inline int SizeOf(Tagged<Map> map, Tagged<HeapObject> object) {
DCHECK_EQ(map->instance_size(), kHeaderSize);
return kHeaderSize;
}
};
template <typename ObjectVisitor>
DISABLE_CFI_PERF void BodyDescriptorBase::IteratePointers(
Tagged<HeapObject> obj, int start_offset, int end_offset,
+10
View File
@@ -411,6 +411,16 @@ bool IsJSObjectThatCanBeTrackedAsPrototype(Tagged<HeapObject> obj) {
return IsJSObject(obj) && !HeapLayout::InWritableSharedSpace(*obj);
}
bool IsJSApiWrapperObject(Tagged<Map> map) {
const InstanceType instance_type = map->instance_type();
return InstanceTypeChecker::IsJSAPIObjectWithEmbedderSlots(instance_type) ||
InstanceTypeChecker::IsJSSpecialObject(instance_type);
}
bool IsJSApiWrapperObject(Tagged<HeapObject> js_obj) {
return IsJSApiWrapperObject(js_obj->map());
}
DEF_HEAP_OBJECT_PREDICATE(HeapObject, IsUniqueName) {
return IsInternalizedString(obj, cage_base) || IsSymbol(obj, cage_base);
}
+3
View File
@@ -730,6 +730,9 @@ V8_INLINE bool IsWasmObject(T obj, Isolate* = nullptr) {
V8_INLINE bool IsJSObjectThatCanBeTrackedAsPrototype(Tagged<Object> obj);
V8_INLINE bool IsJSObjectThatCanBeTrackedAsPrototype(Tagged<HeapObject> obj);
V8_INLINE bool IsJSApiWrapperObject(Tagged<HeapObject> obj);
V8_INLINE bool IsJSApiWrapperObject(Tagged<Map> map);
#define DECL_STRUCT_PREDICATE(NAME, Name, name) \
V8_INLINE bool Is##Name(Tagged<Object> obj); \
V8_INLINE bool Is##Name(Tagged<Object> obj, PtrComprCageBase cage_base);
+1 -2
View File
@@ -14,7 +14,6 @@
#include "src/heap/heap-inl.h"
#include "src/heap/heap-layout-inl.h"
#include "src/heap/heap.h"
#include "src/objects/cpp-heap-object-wrapper-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/profiler/allocation-tracker.h"
#include "src/profiler/heap-snapshot-generator-inl.h"
@@ -60,7 +59,7 @@ std::vector<v8::Local<v8::Value>> HeapProfiler::GetDetachedJSWrapperObjects() {
if (HeapLayout::InCodeSpace(obj)) continue;
if (!IsJSApiWrapperObject(obj)) continue;
// Ensure object is wrappable, otherwise GetDetachedness() can crash
CppHeapObjectWrapper wrapper = CppHeapObjectWrapper(Cast<JSObject>(obj));
JSApiWrapper wrapper = JSApiWrapper(Cast<JSObject>(obj));
if (!wrapper.GetCppHeapWrappable(isolate(), kAnyCppHeapPointer)) continue;
v8::Local<v8::Value> data(
+14 -15
View File
@@ -465,21 +465,20 @@ class RootVisitor;
#define ACCESSOR_INFO_ROOT_LIST(V) \
ACCESSOR_INFO_LIST_GENERATOR(ACCESSOR_INFO_ROOT_LIST_ADAPTER, V)
#define READ_ONLY_ROOT_LIST(V) \
STRONG_READ_ONLY_ROOT_LIST(V) \
INTERNALIZED_STRING_ROOT_LIST(V) \
PRIVATE_SYMBOL_ROOT_LIST(V) \
PUBLIC_SYMBOL_ROOT_LIST(V) \
WELL_KNOWN_SYMBOL_ROOT_LIST(V) \
STRUCT_MAPS_LIST(V) \
TORQUE_DEFINED_MAP_ROOT_LIST(V) \
ALLOCATION_SITE_MAPS_LIST(V) \
NAME_FOR_PROTECTOR_ROOT_LIST(V) \
DATA_HANDLER_MAPS_LIST(V) \
/* Maps */ \
V(Map, external_map, ExternalMap) \
V(Map, message_object_map, JSMessageObjectMap) \
V(Map, cpp_heap_external_map, CppHeapExternalMap)
#define READ_ONLY_ROOT_LIST(V) \
STRONG_READ_ONLY_ROOT_LIST(V) \
INTERNALIZED_STRING_ROOT_LIST(V) \
PRIVATE_SYMBOL_ROOT_LIST(V) \
PUBLIC_SYMBOL_ROOT_LIST(V) \
WELL_KNOWN_SYMBOL_ROOT_LIST(V) \
STRUCT_MAPS_LIST(V) \
TORQUE_DEFINED_MAP_ROOT_LIST(V) \
ALLOCATION_SITE_MAPS_LIST(V) \
NAME_FOR_PROTECTOR_ROOT_LIST(V) \
DATA_HANDLER_MAPS_LIST(V) \
/* Maps */ \
V(Map, external_map, ExternalMap) \
V(Map, message_object_map, JSMessageObjectMap)
#define MUTABLE_ROOT_LIST(V) \
STRONG_MUTABLE_IMMOVABLE_ROOT_LIST(V) \
+6 -8
View File
@@ -1052,17 +1052,16 @@ struct StaticReadOnlyRoot {
static constexpr Tagged_t kWasmNull = 0xfffd;
static constexpr Tagged_t kJSMessageObjectMap = 0x20001;
static constexpr Tagged_t kExternalMap = 0x20029;
static constexpr Tagged_t kCppHeapExternalMap = 0x20051;
static constexpr Tagged_t kJSSharedArrayMap = 0x20079;
static constexpr Tagged_t kJSAtomicsMutexMap = 0x200bd;
static constexpr Tagged_t kJSAtomicsConditionMap = 0x200e5;
static constexpr Tagged_t kNoOpInterceptorInfo = 0x2010d;
static constexpr Tagged_t kJSSharedArrayMap = 0x20051;
static constexpr Tagged_t kJSAtomicsMutexMap = 0x20095;
static constexpr Tagged_t kJSAtomicsConditionMap = 0x200bd;
static constexpr Tagged_t kNoOpInterceptorInfo = 0x200e5;
static constexpr Tagged_t kFirstAllocatedRoot = 0x11;
static constexpr Tagged_t kLastAllocatedRoot = 0x2010d;
static constexpr Tagged_t kLastAllocatedRoot = 0x200e5;
};
static constexpr std::array<Tagged_t, 1028> StaticReadOnlyRootsPointerTable = {
static constexpr std::array<Tagged_t, 1027> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kFreeSpaceMap,
StaticReadOnlyRoot::kOnePointerFillerMap,
StaticReadOnlyRoot::kTwoPointerFillerMap,
@@ -2090,7 +2089,6 @@ static constexpr std::array<Tagged_t, 1028> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kStoreHandler3Map,
StaticReadOnlyRoot::kExternalMap,
StaticReadOnlyRoot::kJSMessageObjectMap,
StaticReadOnlyRoot::kCppHeapExternalMap,
};
} // namespace internal
+2 -3
View File
@@ -8,7 +8,6 @@
#include "src/execution/microtask-queue.h"
#include "src/heap/combined-heap.h"
#include "src/numbers/math-random.h"
#include "src/objects/cpp-heap-object-wrapper-inl.h"
#include "src/objects/embedder-data-array-inl.h"
#include "src/objects/js-objects.h"
#include "src/objects/objects-inl.h"
@@ -259,7 +258,7 @@ void ContextSerializer::SerializeObjectImpl(Handle<HeapObject> obj,
// Object has not yet been serialized. Serialize it here.
ObjectSerializer serializer(this, obj, &sink_);
serializer.Serialize(slot_type);
if (InstanceTypeChecker::IsJSApiWrapperObject(instance_type)) {
if (IsJSApiWrapperObject(obj->map())) {
SerializeApiWrapperFields(Cast<JSObject>(obj));
}
}
@@ -289,7 +288,7 @@ void ContextSerializer::SerializeApiWrapperFields(
DirectHandle<JSObject> js_object) {
DCHECK(IsJSApiWrapperObject(*js_object));
auto* cpp_heap_pointer =
CppHeapObjectWrapper(*js_object)
JSApiWrapper(*js_object)
.GetCppHeapWrappable(isolate(), kAnyCppHeapPointer);
const auto& callback_data = serialize_embedder_fields_.api_wrapper_callback;
if (callback_data.callback == nullptr && cpp_heap_pointer == nullptr) {
+1 -1
View File
@@ -1136,7 +1136,7 @@ void Serializer::ObjectSerializer::VisitCppHeapPointer(
// We serialize the slot as initialized-but-unused slot. The actual API
// wrapper serialization is implemented in
// `ContextSerializer::SerializeApiWrapperFields()`.
DCHECK(IsJSApiWrapperObjectMap(object_->map(cage_base)));
DCHECK(IsJSApiWrapperObject(object_->map(cage_base)));
static_assert(kCppHeapPointerSlotSize % kTaggedSize == 0);
sink_->Put(
FixedRawDataWithSize::Encode(kCppHeapPointerSlotSize >> kTaggedSizeLog2),
-68
View File
@@ -41,9 +41,6 @@
#include <unistd.h>
#endif
#include "include/cppgc/allocation.h"
#include "include/cppgc/persistent.h"
#include "include/v8-cpp-heap-external.h"
#include "include/v8-date.h"
#include "include/v8-extension.h"
#include "include/v8-fast-api-calls.h"
@@ -67,9 +64,7 @@
#include "src/execution/protectors-inl.h"
#include "src/handles/global-handles.h"
#include "src/heap/heap-inl.h"
#include "src/heap/heap.h"
#include "src/heap/incremental-marking.h"
#include "src/init/v8.h"
#include "src/logging/metrics.h"
#include "src/objects/feedback-vector-inl.h"
#include "src/objects/feedback-vector.h"
@@ -101,7 +96,6 @@ using ::v8::Array;
using ::v8::Boolean;
using ::v8::BooleanObject;
using ::v8::Context;
using ::v8::CppHeapExternal;
using ::v8::Extension;
using ::v8::External;
using ::v8::FixedArray;
@@ -31321,65 +31315,3 @@ TEST(LocalCasts) {
v8::MaybeLocal<v8::String>::Cast(no_data);
}
}
class TestGarbagedCollectedData
: public cppgc::GarbageCollected<TestGarbagedCollectedData> {
public:
void Trace(cppgc::Visitor*) const {}
};
TEST(CppHeapExternal) {
v8::Isolate::CreateParams create_params = CreateTestParams();
create_params.cpp_heap =
v8::CppHeap::Create(::v8::internal::V8::GetCurrentPlatform(),
v8::CppHeapCreateParams({}))
.release();
v8::Isolate* isolate = v8::Isolate::New(create_params);
isolate->Enter();
v8::CppHeap* cpp_heap = isolate->GetCppHeap();
i::Heap* heap = reinterpret_cast<i::Isolate*>(isolate)->heap();
cppgc::WeakPersistent<TestGarbagedCollectedData> cpp_object(
cppgc::MakeGarbageCollected<TestGarbagedCollectedData>(
cpp_heap->GetAllocationHandle()));
{
v8::HandleScope scope(isolate);
v8::Local<v8::CppHeapExternal> external =
v8::CppHeapExternal::New<TestGarbagedCollectedData>(
isolate, cpp_object, v8::CppHeapPointerTag::kDefaultTag);
CHECK_EQ(cpp_object.Get(),
external->Value<TestGarbagedCollectedData>(
isolate, v8::CppHeapPointerTagRange(
v8::CppHeapPointerTag::kDefaultTag,
v8::CppHeapPointerTag::kDefaultTag)));
// Check casting.
{
v8::Local<v8::Data> as_data = external;
CHECK(as_data->IsCppHeapExternal());
v8::Local<v8::CppHeapExternal>::Cast(as_data);
}
// The `cpp_object` should still exist and match the `external` after GC.
i::EmbedderStackStateScope stack_scope(
heap, i::EmbedderStackStateOrigin::kExplicitInvocation,
v8::StackState::kNoHeapPointers);
i::heap::InvokeMajorGC(heap);
CHECK(cpp_object.Get());
CHECK_EQ(cpp_object.Get(),
external->Value<TestGarbagedCollectedData>(
isolate, v8::CppHeapPointerTagRange(
v8::CppHeapPointerTag::kDefaultTag,
v8::CppHeapPointerTag::kDefaultTag)));
}
{
i::EmbedderStackStateScope stack_scope(
heap, i::EmbedderStackStateOrigin::kExplicitInvocation,
v8::StackState::kNoHeapPointers);
i::heap::InvokeMajorGC(heap);
CHECK(!cpp_object.Get());
}
isolate->Exit();
isolate->Dispose();
}
@@ -10,7 +10,6 @@
#include "src/api/api-inl.h"
#include "src/heap/cppgc-js/cpp-heap.h"
#include "src/heap/heap.h"
#include "src/objects/cpp-heap-object-wrapper-inl.h"
#include "src/objects/js-objects.h"
#include "src/objects/objects-inl.h"
#include "test/unittests/heap/heap-utils.h"
@@ -49,7 +48,7 @@ void WrapperHelper::ResetWrappableConnection(v8::Isolate* isolate,
v8::Local<v8::Object> api_object) {
i::DirectHandle<i::JSReceiver> js_obj =
v8::Utils::OpenDirectHandle(*api_object);
CppHeapObjectWrapper(Cast<JSObject>(*js_obj))
JSApiWrapper(Cast<JSObject>(*js_obj))
.SetCppHeapWrappable<CppHeapPointerTag::kDefaultTag>(
reinterpret_cast<i::Isolate*>(isolate), nullptr);
}
@@ -60,7 +59,7 @@ void WrapperHelper::SetWrappableConnection(v8::Isolate* isolate,
void* instance) {
i::DirectHandle<i::JSReceiver> js_obj =
v8::Utils::OpenDirectHandle(*api_object);
CppHeapObjectWrapper(Cast<JSObject>(*js_obj))
JSApiWrapper(Cast<JSObject>(*js_obj))
.SetCppHeapWrappable<CppHeapPointerTag::kDefaultTag>(
reinterpret_cast<i::Isolate*>(isolate), instance);
}
@@ -70,7 +69,7 @@ void* WrapperHelper::ReadWrappablePointer(v8::Isolate* isolate,
v8::Local<v8::Object> api_object) {
i::DirectHandle<i::JSReceiver> js_obj =
v8::Utils::OpenDirectHandle(*api_object);
return CppHeapObjectWrapper(Cast<JSObject>(*js_obj))
return JSApiWrapper(Cast<JSObject>(*js_obj))
.GetCppHeapWrappable(reinterpret_cast<i::Isolate*>(isolate),
kAnyCppHeapPointer);
}