Commit 4d9f09b5 authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

[heap] Add support for non-API wrapper types

Adds support for tracing wrappers of the following types:
- JSArrayBuffer
- JSDataView
- JSTypedArray

Unlike API objects, these objects are equipped with embedder fields at compile
time and can thus be attached to Blink objects at any time.

Bug: chromium:885125, chromium:843903
Change-Id: If2dab4831f42a4edc0748b7071d451fe1953f076
Reviewed-on: https://chromium-review.googlesource.com/1234418Reviewed-by: 's avatarHannes Payer <hpayer@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56092}
parent 95a979e0
......@@ -184,23 +184,26 @@ class ConcurrentMarkingVisitor final
return VisitJSObjectSubclass(map, object);
}
int VisitJSArrayBuffer(Map* map, JSArrayBuffer* object) {
int VisitWasmInstanceObject(Map* map, WasmInstanceObject* object) {
return VisitJSObjectSubclass(map, object);
}
int VisitJSDataView(Map* map, JSDataView* object) {
return VisitJSObjectSubclass(map, object);
// Some JS objects can carry back links to embedders that contain information
// relevant to the garbage collectors.
int VisitJSApiObject(Map* map, JSObject* object) {
return VisitEmbedderTracingSubclass(map, object);
}
int VisitJSTypedArray(Map* map, JSTypedArray* object) {
return VisitJSObjectSubclass(map, object);
int VisitJSArrayBuffer(Map* map, JSArrayBuffer* object) {
return VisitEmbedderTracingSubclass(map, object);
}
int VisitWasmInstanceObject(Map* map, WasmInstanceObject* object) {
return VisitJSObjectSubclass(map, object);
int VisitJSDataView(Map* map, JSDataView* object) {
return VisitEmbedderTracingSubclass(map, object);
}
int VisitJSApiObject(Map* map, JSObject* object) {
int VisitJSTypedArray(Map* map, JSTypedArray* object) {
return VisitEmbedderTracingSubclass(map, object);
}
......
......@@ -46,16 +46,50 @@ int MarkingVisitor<fixed_array_mode, retaining_path_mode,
template <FixedArrayVisitationMode fixed_array_mode,
TraceRetainingPathMode retaining_path_mode, typename MarkingState>
int MarkingVisitor<fixed_array_mode, retaining_path_mode,
MarkingState>::VisitJSApiObject(Map* map, JSObject* object) {
template <typename T>
V8_INLINE int
MarkingVisitor<fixed_array_mode, retaining_path_mode,
MarkingState>::VisitEmbedderTracingSubclass(Map* map,
T* object) {
if (heap_->local_embedder_heap_tracer()->InUse()) {
heap_->TracePossibleWrapper(object);
}
int size = JSObject::BodyDescriptor::SizeOf(map, object);
JSObject::BodyDescriptor::IterateBody(map, object, size, this);
int size = T::BodyDescriptor::SizeOf(map, object);
T::BodyDescriptor::IterateBody(map, object, size, this);
return size;
}
template <FixedArrayVisitationMode fixed_array_mode,
TraceRetainingPathMode retaining_path_mode, typename MarkingState>
int MarkingVisitor<fixed_array_mode, retaining_path_mode,
MarkingState>::VisitJSApiObject(Map* map, JSObject* object) {
return VisitEmbedderTracingSubclass(map, object);
}
template <FixedArrayVisitationMode fixed_array_mode,
TraceRetainingPathMode retaining_path_mode, typename MarkingState>
int MarkingVisitor<fixed_array_mode, retaining_path_mode,
MarkingState>::VisitJSArrayBuffer(Map* map,
JSArrayBuffer* object) {
return VisitEmbedderTracingSubclass(map, object);
}
template <FixedArrayVisitationMode fixed_array_mode,
TraceRetainingPathMode retaining_path_mode, typename MarkingState>
int MarkingVisitor<fixed_array_mode, retaining_path_mode,
MarkingState>::VisitJSDataView(Map* map,
JSDataView* object) {
return VisitEmbedderTracingSubclass(map, object);
}
template <FixedArrayVisitationMode fixed_array_mode,
TraceRetainingPathMode retaining_path_mode, typename MarkingState>
int MarkingVisitor<fixed_array_mode, retaining_path_mode,
MarkingState>::VisitJSTypedArray(Map* map,
JSTypedArray* object) {
return VisitEmbedderTracingSubclass(map, object);
}
template <FixedArrayVisitationMode fixed_array_mode,
TraceRetainingPathMode retaining_path_mode, typename MarkingState>
int MarkingVisitor<fixed_array_mode, retaining_path_mode, MarkingState>::
......
......@@ -925,6 +925,9 @@ class MarkingVisitor final
V8_INLINE int VisitEphemeronHashTable(Map* map, EphemeronHashTable* object);
V8_INLINE int VisitFixedArray(Map* map, FixedArray* object);
V8_INLINE int VisitJSApiObject(Map* map, JSObject* object);
V8_INLINE int VisitJSArrayBuffer(Map* map, JSArrayBuffer* object);
V8_INLINE int VisitJSDataView(Map* map, JSDataView* object);
V8_INLINE int VisitJSTypedArray(Map* map, JSTypedArray* object);
V8_INLINE int VisitMap(Map* map, Map* object);
V8_INLINE int VisitTransitionArray(Map* map, TransitionArray* object);
......@@ -950,6 +953,9 @@ class MarkingVisitor final
V8_INLINE int VisitFixedArrayIncremental(Map* map, FixedArray* object);
template <typename T>
V8_INLINE int VisitEmbedderTracingSubclass(Map* map, T* object);
V8_INLINE void MarkMapContents(Map* map);
// Marks the object black without pushing it on the marking work list. Returns
......
......@@ -3364,7 +3364,7 @@ bool JSObject::IsUnmodifiedApiObject(Object** o) {
HeapObject* heap_object = HeapObject::cast(object);
if (!object->IsJSObject()) return false;
JSObject* js_object = JSObject::cast(object);
if (!js_object->IsApiWrapper()) return false;
if (!js_object->IsDroppableApiWrapper()) return false;
Object* maybe_constructor = js_object->map()->GetConstructor();
if (!maybe_constructor->IsJSFunction()) return false;
JSFunction* constructor = JSFunction::cast(maybe_constructor);
......@@ -16008,6 +16008,18 @@ bool FixedArrayBase::IsCowArray() const {
}
bool JSObject::IsApiWrapper() {
// These object types can carry information relevant for embedders. The
// *_API_* types are generated through templates which can have embedder
// fields. The other types have their embedder fields added at compile time.
auto instance_type = map()->instance_type();
return instance_type == JS_API_OBJECT_TYPE ||
instance_type == JS_ARRAY_BUFFER_TYPE ||
instance_type == JS_DATA_VIEW_TYPE ||
instance_type == JS_SPECIAL_API_OBJECT_TYPE ||
instance_type == JS_TYPED_ARRAY_TYPE;
}
bool JSObject::IsDroppableApiWrapper() {
auto instance_type = map()->instance_type();
return instance_type == JS_API_OBJECT_TYPE ||
instance_type == JS_SPECIAL_API_OBJECT_TYPE;
......
......@@ -2543,6 +2543,9 @@ class JSObject: public JSReceiver {
// Heap::TracePossibleWrapper.
bool IsApiWrapper();
// Same as IsApiWrapper() but also allow dropping the wrapper on minor GCs.
bool IsDroppableApiWrapper();
// Returns a new map with all transitions dropped from the object's current
// map and the ElementsKind set.
static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
......
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