Commit ffbac83a authored by Samuel Groß's avatar Samuel Groß Committed by V8 LUCI CQ

Check instance type before initializing embedder data slots

JSObject::InitializeBody now checks whether the instance type of the
object being initialized can have embedder data slots around the
initialization logic for these slots. This fixes a performance
regression on certain benchmarks.

To perform this check efficiently, a new instance type,
JSObjectWithEmbedderSlots, is introduced so that the check becomes a
simple range check.

Bug: chromium:1304139
Change-Id: I00c892bc2276e950b59602257ca1c2435c10e517
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3507712Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Samuel Groß <saelo@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79497}
parent d16de301
......@@ -5092,7 +5092,8 @@ bool v8::Object::IsConstructor() const {
bool v8::Object::IsApiWrapper() const {
auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
return self->IsApiWrapper();
// Objects with embedder fields can wrap API objects.
return self->MayHaveEmbedderFields();
}
bool v8::Object::IsUndetectable() const {
......
......@@ -575,7 +575,8 @@ extern class Filler extends HeapObject generates 'TNode<HeapObject>';
// Like JSObject, but created from API function.
@apiExposedInstanceTypeValue(0x422)
@doNotGenerateCast
extern class JSApiObject extends JSObject generates 'TNode<JSObject>';
extern class JSApiObject extends JSObjectWithEmbedderSlots
generates 'TNode<JSObject>';
// TODO(gsathya): This only exists to make JSApiObject instance type into a
// range.
......
......@@ -79,7 +79,7 @@ class V8ToCppGCReferencesVisitor final
const internal::JSObject js_object =
*reinterpret_cast<const internal::JSObject* const&>(value);
if (!js_object.ptr() || !js_object.IsApiWrapper()) return;
if (!js_object.ptr() || !js_object.MayHaveEmbedderFields()) return;
internal::LocalEmbedderHeapTracer::WrapperInfo info;
if (!internal::LocalEmbedderHeapTracer::ExtractWrappableInfo(
......
......@@ -358,7 +358,8 @@ void* ExtractEmbedderDataBackref(Isolate* isolate,
if (!v8_value->IsObject()) return nullptr;
Handle<Object> v8_object = Utils::OpenHandle(*v8_value);
if (!v8_object->IsJSObject() || !JSObject::cast(*v8_object).IsApiWrapper())
if (!v8_object->IsJSObject() ||
!JSObject::cast(*v8_object).MayHaveEmbedderFields())
return nullptr;
JSObject js_object = JSObject::cast(*v8_object);
......
......@@ -15,7 +15,7 @@ namespace internal {
bool LocalEmbedderHeapTracer::ExtractWrappableInfo(
Isolate* isolate, JSObject js_object,
const WrapperDescriptor& wrapper_descriptor, WrapperInfo* info) {
DCHECK(js_object.IsApiWrapper());
DCHECK(js_object.MayHaveEmbedderFields());
if (js_object.GetEmbedderFieldCount() < 2) return false;
return ExtractWrappableInfo(
......
......@@ -139,7 +139,7 @@ LocalEmbedderHeapTracer::ExtractWrapperInfo(Isolate* isolate,
void LocalEmbedderHeapTracer::ProcessingScope::TracePossibleWrapper(
JSObject js_object) {
DCHECK(js_object.IsApiWrapper());
DCHECK(js_object.MayHaveEmbedderFields());
WrapperInfo info;
if (ExtractWrappableInfo(tracer_->isolate_, js_object, wrapper_descriptor_,
&info)) {
......@@ -189,7 +189,7 @@ void LocalEmbedderHeapTracer::NotifyEmptyEmbedderStack() {
void LocalEmbedderHeapTracer::EmbedderWriteBarrier(Heap* heap,
JSObject js_object) {
DCHECK(InUse());
DCHECK(js_object.IsApiWrapper());
DCHECK(js_object.MayHaveEmbedderFields());
if (cpp_heap_) {
DCHECK_NOT_NULL(heap->mark_compact_collector());
const EmbedderDataSlot type_slot(js_object,
......
......@@ -2960,6 +2960,7 @@ Handle<JSArrayBufferView> Factory::NewJSArrayBufferView(
raw.set_byte_offset(byte_offset);
raw.set_byte_length(byte_length);
raw.set_bit_field(0);
// TODO(v8) remove once embedder data slots are always zero-initialized.
InitEmbedderFields(raw, Smi::zero());
DCHECK_EQ(raw.GetEmbedderFieldCount(),
v8::ArrayBufferView::kEmbedderFieldCount);
......@@ -3875,6 +3876,7 @@ Handle<JSPromise> Factory::NewJSPromiseWithoutHook() {
JSPromise raw = *promise;
raw.set_reactions_or_result(Smi::zero(), SKIP_WRITE_BARRIER);
raw.set_flags(0);
// TODO(v8) remove once embedder data slots are always zero-initialized.
InitEmbedderFields(*promise, Smi::zero());
DCHECK_EQ(raw.GetEmbedderFieldCount(), v8::Promise::kEmbedderFieldCount);
return promise;
......
......@@ -301,7 +301,7 @@ template <typename T>
int MarkingVisitorBase<ConcreteVisitor,
MarkingState>::VisitEmbedderTracingSubclass(Map map,
T object) {
DCHECK(object.IsApiWrapper());
DCHECK(object.MayHaveEmbedderFields());
if (V8_LIKELY(is_embedder_tracing_enabled_)) {
return VisitEmbedderTracingSubClassWithEmbedderTracing(map, object);
}
......
......@@ -21,7 +21,8 @@ class ArrayBufferExtension;
#include "torque-generated/src/objects/js-array-buffer-tq.inc"
class JSArrayBuffer
: public TorqueGeneratedJSArrayBuffer<JSArrayBuffer, JSObject> {
: public TorqueGeneratedJSArrayBuffer<JSArrayBuffer,
JSObjectWithEmbedderSlots> {
public:
// The maximum length for JSArrayBuffer's supported by V8.
// On 32-bit architectures we limit this to 2GiB, so that
......@@ -231,7 +232,8 @@ class ArrayBufferExtension final : public Malloced {
};
class JSArrayBufferView
: public TorqueGeneratedJSArrayBufferView<JSArrayBufferView, JSObject> {
: public TorqueGeneratedJSArrayBufferView<JSArrayBufferView,
JSObjectWithEmbedderSlots> {
public:
// [byte_offset]: offset of typed array in bytes.
DECL_PRIMITIVE_ACCESSORS(byte_offset, size_t)
......
......@@ -11,7 +11,7 @@ bitfield struct JSArrayBufferFlags extends uint32 {
is_resizable: bool: 1 bit;
}
extern class JSArrayBuffer extends JSObject {
extern class JSArrayBuffer extends JSObjectWithEmbedderSlots {
byte_length: uintptr;
max_byte_length: uintptr;
// A SandboxedPtr if the sandbox is enabled
......@@ -53,7 +53,7 @@ bitfield struct JSArrayBufferViewFlags extends uint32 {
}
@abstract
extern class JSArrayBufferView extends JSObject {
extern class JSArrayBufferView extends JSObjectWithEmbedderSlots {
buffer: JSArrayBuffer;
byte_offset: uintptr;
byte_length: uintptr;
......
......@@ -33,6 +33,7 @@ namespace internal {
TQ_OBJECT_CONSTRUCTORS_IMPL(JSReceiver)
TQ_OBJECT_CONSTRUCTORS_IMPL(JSObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(JSObjectWithEmbedderSlots)
TQ_OBJECT_CONSTRUCTORS_IMPL(JSCustomElementsObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(JSSpecialObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(JSAsyncFromSyncIterator)
......@@ -283,6 +284,20 @@ int JSObject::GetEmbedderFieldsStartOffset() {
return GetEmbedderFieldsStartOffset(map());
}
// static
bool JSObject::MayHaveEmbedderFields(Map map) {
InstanceType instance_type = map.instance_type();
// TODO(v8) It'd be nice if all objects with embedder data slots inherited
// from JSObjectWithEmbedderSlots, but this is currently not possible due to
// instance_type constraints.
return InstanceTypeChecker::IsJSObjectWithEmbedderSlots(instance_type) ||
InstanceTypeChecker::IsJSSpecialObject(instance_type);
}
bool JSObject::MayHaveEmbedderFields() const {
return MayHaveEmbedderFields(map());
}
// static
int JSObject::GetEmbedderFieldCount(Map map) {
int instance_size = map.instance_size();
......@@ -320,6 +335,12 @@ void JSObject::SetEmbedderField(int index, Smi value) {
EmbedderDataSlot(*this, index).store_smi(value);
}
bool JSObject::IsDroppableApiObject() const {
auto instance_type = map().instance_type();
return InstanceTypeChecker::IsJSApiObject(instance_type) ||
instance_type == JS_SPECIAL_API_OBJECT_TYPE;
}
// Access fast-case object properties at index. The use of these routines
// is needed to correctly distinguish between properties stored in-object and
// properties stored in the properties array.
......@@ -479,10 +500,12 @@ void JSObject::InitializeBody(Map map, int start_offset,
MapWord filler_map, Object undefined_filler) {
int size = map.instance_size();
int offset = start_offset;
int embedder_field_start = GetEmbedderFieldsStartOffset(map);
int embedder_field_count = GetEmbedderFieldCount(map);
if (embedder_field_count) {
// embedder data slots need to be initialized separately
if (MayHaveEmbedderFields(map)) {
int embedder_field_start = GetEmbedderFieldsStartOffset(map);
int embedder_field_count = GetEmbedderFieldCount(map);
// fill start with references to the undefined value object
DCHECK_LE(offset, embedder_field_start);
while (offset < embedder_field_start) {
......@@ -497,6 +520,8 @@ void JSObject::InitializeBody(Map map, int start_offset,
EmbedderDataSlot(*this, i).Initialize(undefined_filler);
offset += kEmbedderDataSlotSize;
}
} else {
DCHECK_EQ(0, GetEmbedderFieldCount(map));
}
DCHECK_LE(offset, size);
......
......@@ -2830,7 +2830,7 @@ bool JSObject::IsUnmodifiedApiObject(FullObjectSlot o) {
HeapObject heap_object = HeapObject::cast(object);
if (!object.IsJSObject()) return false;
JSObject js_object = JSObject::cast(object);
if (!js_object.IsDroppableApiWrapper()) return false;
if (!js_object.IsDroppableApiObject()) return false;
Object maybe_constructor = js_object.map().GetConstructor();
if (!maybe_constructor.IsJSFunction()) return false;
JSFunction constructor = JSFunction::cast(maybe_constructor);
......@@ -5269,26 +5269,6 @@ Maybe<bool> JSObject::HasRealNamedCallbackProperty(Isolate* isolate,
: Nothing<bool>();
}
bool JSObject::IsApiWrapper() const {
// 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_ARRAY_BUFFER_TYPE ||
instance_type == JS_DATA_VIEW_TYPE ||
instance_type == JS_GLOBAL_OBJECT_TYPE ||
instance_type == JS_GLOBAL_PROXY_TYPE ||
instance_type == JS_SPECIAL_API_OBJECT_TYPE ||
instance_type == JS_TYPED_ARRAY_TYPE ||
InstanceTypeChecker::IsJSApiObject(instance_type);
}
bool JSObject::IsDroppableApiWrapper() const {
auto instance_type = map().instance_type();
return InstanceTypeChecker::IsJSApiObject(instance_type) ||
instance_type == JS_SPECIAL_API_OBJECT_TYPE;
}
bool JSGlobalProxy::IsDetached() const {
return native_context().IsNull(GetIsolate());
}
......
......@@ -605,6 +605,9 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
InstanceType instance_type, bool function_has_prototype_slot = false);
static inline int GetHeaderSize(Map map);
static inline bool MayHaveEmbedderFields(Map map);
inline bool MayHaveEmbedderFields() const;
static inline int GetEmbedderFieldsStartOffset(Map map);
inline int GetEmbedderFieldsStartOffset();
......@@ -615,14 +618,9 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
inline void SetEmbedderField(int index, Object value);
inline void SetEmbedderField(int index, Smi value);
// Returns true when the object is potentially a wrapper that gets special
// garbage collection treatment.
// TODO(mlippautz): Make check exact and replace the pattern match in
// Heap::TracePossibleWrapper.
V8_EXPORT_PRIVATE bool IsApiWrapper() const;
// Same as IsApiWrapper() but also allow dropping the wrapper on minor GCs.
bool IsDroppableApiWrapper() const;
// Returns true if this object is an Api object which can, if unmodified, be
// dropped during minor GC because the embedder can recreate it again later.
inline bool IsDroppableApiObject() const;
// Returns a new map with all transitions dropped from the object's current
// map and the ElementsKind set.
......@@ -910,6 +908,15 @@ class JSExternalObject
TQ_OBJECT_CONSTRUCTORS(JSExternalObject)
};
// An abstract superclass for JSObjects that may contain EmbedderDataSlots.
class JSObjectWithEmbedderSlots
: public TorqueGeneratedJSObjectWithEmbedderSlots<JSObjectWithEmbedderSlots,
JSObject> {
public:
STATIC_ASSERT(kHeaderSize == JSObject::kHeaderSize);
TQ_OBJECT_CONSTRUCTORS(JSObjectWithEmbedderSlots)
};
// An abstract superclass for JSObjects that may have elements while having an
// empty fixed array as elements backing store. It doesn't carry any
// functionality but allows function classes to be identified in the type
......@@ -925,6 +932,8 @@ class JSCustomElementsObject
// An abstract superclass for JSObjects that require non-standard element
// access. It doesn't carry any functionality but allows function classes to be
// identified in the type system.
// These may also contain EmbedderDataSlots, but can't currently inherit from
// JSObjectWithEmbedderSlots due to instance_type constraints.
class JSSpecialObject
: public TorqueGeneratedJSSpecialObject<JSSpecialObject,
JSCustomElementsObject> {
......
......@@ -42,11 +42,18 @@ macro NewJSObject(implicit context: Context)(): JSObject {
extern class JSExternalObject extends JSObject { value: ExternalPointer; }
// A JSObject that may contain EmbedderDataSlots.
@abstract
extern class JSObjectWithEmbedderSlots extends JSObject {
}
@abstract
@lowestInstanceTypeWithinParentClassRange
extern class JSCustomElementsObject extends JSObject {
}
// These may also contain EmbedderDataSlots but can't be a child class of
// JSObjectWithEmbedderSlots due to type id constraints.
@abstract
@lowestInstanceTypeWithinParentClassRange
extern class JSSpecialObject extends JSCustomElementsObject {
......
......@@ -28,7 +28,8 @@ namespace internal {
// We also overlay the result and reactions fields on the JSPromise, since
// the reactions are only necessary for pending promises, whereas the result
// is only meaningful for settled promises.
class JSPromise : public TorqueGeneratedJSPromise<JSPromise, JSObject> {
class JSPromise
: public TorqueGeneratedJSPromise<JSPromise, JSObjectWithEmbedderSlots> {
public:
// [result]: Checks that the promise is settled and returns the result.
inline Object result() const;
......
......@@ -10,7 +10,7 @@ bitfield struct JSPromiseFlags extends uint31 {
async_task_id: int32: 22 bit;
}
extern class JSPromise extends JSObject {
extern class JSPromise extends JSObjectWithEmbedderSlots {
macro Status(): PromiseState {
return this.flags.status;
}
......
......@@ -151,6 +151,7 @@ class ZoneForwardList;
V(JSMessageObject) \
V(JSModuleNamespace) \
V(JSObject) \
V(JSObjectWithEmbedderSlots) \
V(JSPrimitiveWrapper) \
V(JSPromise) \
V(JSProxy) \
......
......@@ -682,7 +682,8 @@ Handle<HeapObject> Deserializer<IsolateT>::ReadObject(SnapshotSpace space) {
#ifdef DEBUG
PtrComprCageBase cage_base(isolate());
// We want to make sure that all embedder pointers are initialized to null.
if (raw_obj.IsJSObject(cage_base) && JSObject::cast(raw_obj).IsApiWrapper()) {
if (raw_obj.IsJSObject(cage_base) &&
JSObject::cast(raw_obj).MayHaveEmbedderFields()) {
JSObject js_obj = JSObject::cast(raw_obj);
for (int i = 0; i < js_obj.GetEmbedderFieldCount(); ++i) {
void* pointer;
......
......@@ -179,67 +179,67 @@ INSTANCE_TYPES = {
1041: "JS_PRIMITIVE_WRAPPER_TYPE",
1058: "JS_API_OBJECT_TYPE",
2058: "JS_LAST_DUMMY_API_OBJECT_TYPE",
2059: "JS_BOUND_FUNCTION_TYPE",
2060: "JS_WRAPPED_FUNCTION_TYPE",
2061: "JS_FUNCTION_TYPE",
2062: "BIGINT64_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2063: "BIGUINT64_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2064: "FLOAT32_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2065: "FLOAT64_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2066: "INT16_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2067: "INT32_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2068: "INT8_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2069: "UINT16_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2070: "UINT32_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2071: "UINT8_CLAMPED_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2072: "UINT8_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2073: "JS_ARRAY_CONSTRUCTOR_TYPE",
2074: "JS_PROMISE_CONSTRUCTOR_TYPE",
2075: "JS_REG_EXP_CONSTRUCTOR_TYPE",
2076: "JS_CLASS_CONSTRUCTOR_TYPE",
2077: "JS_ARRAY_ITERATOR_PROTOTYPE_TYPE",
2078: "JS_ITERATOR_PROTOTYPE_TYPE",
2079: "JS_MAP_ITERATOR_PROTOTYPE_TYPE",
2080: "JS_OBJECT_PROTOTYPE_TYPE",
2081: "JS_PROMISE_PROTOTYPE_TYPE",
2082: "JS_REG_EXP_PROTOTYPE_TYPE",
2083: "JS_SET_ITERATOR_PROTOTYPE_TYPE",
2084: "JS_SET_PROTOTYPE_TYPE",
2085: "JS_STRING_ITERATOR_PROTOTYPE_TYPE",
2086: "JS_TYPED_ARRAY_PROTOTYPE_TYPE",
2087: "JS_MAP_KEY_ITERATOR_TYPE",
2088: "JS_MAP_KEY_VALUE_ITERATOR_TYPE",
2089: "JS_MAP_VALUE_ITERATOR_TYPE",
2090: "JS_SET_KEY_VALUE_ITERATOR_TYPE",
2091: "JS_SET_VALUE_ITERATOR_TYPE",
2092: "JS_GENERATOR_OBJECT_TYPE",
2093: "JS_ASYNC_FUNCTION_OBJECT_TYPE",
2094: "JS_ASYNC_GENERATOR_OBJECT_TYPE",
2095: "JS_DATA_VIEW_TYPE",
2096: "JS_TYPED_ARRAY_TYPE",
2097: "JS_MAP_TYPE",
2098: "JS_SET_TYPE",
2099: "JS_WEAK_MAP_TYPE",
2100: "JS_WEAK_SET_TYPE",
2101: "JS_ARGUMENTS_OBJECT_TYPE",
2102: "JS_ARRAY_TYPE",
2103: "JS_ARRAY_BUFFER_TYPE",
2104: "JS_ARRAY_ITERATOR_TYPE",
2105: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE",
2106: "JS_COLLATOR_TYPE",
2107: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
2108: "JS_DATE_TYPE",
2109: "JS_DATE_TIME_FORMAT_TYPE",
2110: "JS_DISPLAY_NAMES_TYPE",
2111: "JS_ERROR_TYPE",
2112: "JS_EXTERNAL_OBJECT_TYPE",
2113: "JS_FINALIZATION_REGISTRY_TYPE",
2114: "JS_LIST_FORMAT_TYPE",
2115: "JS_LOCALE_TYPE",
2116: "JS_MESSAGE_OBJECT_TYPE",
2117: "JS_NUMBER_FORMAT_TYPE",
2118: "JS_PLURAL_RULES_TYPE",
2119: "JS_PROMISE_TYPE",
2059: "JS_DATA_VIEW_TYPE",
2060: "JS_TYPED_ARRAY_TYPE",
2061: "JS_ARRAY_BUFFER_TYPE",
2062: "JS_PROMISE_TYPE",
2063: "JS_BOUND_FUNCTION_TYPE",
2064: "JS_WRAPPED_FUNCTION_TYPE",
2065: "JS_FUNCTION_TYPE",
2066: "BIGINT64_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2067: "BIGUINT64_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2068: "FLOAT32_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2069: "FLOAT64_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2070: "INT16_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2071: "INT32_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2072: "INT8_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2073: "UINT16_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2074: "UINT32_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2075: "UINT8_CLAMPED_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2076: "UINT8_TYPED_ARRAY_CONSTRUCTOR_TYPE",
2077: "JS_ARRAY_CONSTRUCTOR_TYPE",
2078: "JS_PROMISE_CONSTRUCTOR_TYPE",
2079: "JS_REG_EXP_CONSTRUCTOR_TYPE",
2080: "JS_CLASS_CONSTRUCTOR_TYPE",
2081: "JS_ARRAY_ITERATOR_PROTOTYPE_TYPE",
2082: "JS_ITERATOR_PROTOTYPE_TYPE",
2083: "JS_MAP_ITERATOR_PROTOTYPE_TYPE",
2084: "JS_OBJECT_PROTOTYPE_TYPE",
2085: "JS_PROMISE_PROTOTYPE_TYPE",
2086: "JS_REG_EXP_PROTOTYPE_TYPE",
2087: "JS_SET_ITERATOR_PROTOTYPE_TYPE",
2088: "JS_SET_PROTOTYPE_TYPE",
2089: "JS_STRING_ITERATOR_PROTOTYPE_TYPE",
2090: "JS_TYPED_ARRAY_PROTOTYPE_TYPE",
2091: "JS_MAP_KEY_ITERATOR_TYPE",
2092: "JS_MAP_KEY_VALUE_ITERATOR_TYPE",
2093: "JS_MAP_VALUE_ITERATOR_TYPE",
2094: "JS_SET_KEY_VALUE_ITERATOR_TYPE",
2095: "JS_SET_VALUE_ITERATOR_TYPE",
2096: "JS_GENERATOR_OBJECT_TYPE",
2097: "JS_ASYNC_FUNCTION_OBJECT_TYPE",
2098: "JS_ASYNC_GENERATOR_OBJECT_TYPE",
2099: "JS_MAP_TYPE",
2100: "JS_SET_TYPE",
2101: "JS_WEAK_MAP_TYPE",
2102: "JS_WEAK_SET_TYPE",
2103: "JS_ARGUMENTS_OBJECT_TYPE",
2104: "JS_ARRAY_TYPE",
2105: "JS_ARRAY_ITERATOR_TYPE",
2106: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE",
2107: "JS_COLLATOR_TYPE",
2108: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
2109: "JS_DATE_TYPE",
2110: "JS_DATE_TIME_FORMAT_TYPE",
2111: "JS_DISPLAY_NAMES_TYPE",
2112: "JS_ERROR_TYPE",
2113: "JS_EXTERNAL_OBJECT_TYPE",
2114: "JS_FINALIZATION_REGISTRY_TYPE",
2115: "JS_LIST_FORMAT_TYPE",
2116: "JS_LOCALE_TYPE",
2117: "JS_MESSAGE_OBJECT_TYPE",
2118: "JS_NUMBER_FORMAT_TYPE",
2119: "JS_PLURAL_RULES_TYPE",
2120: "JS_REG_EXP_TYPE",
2121: "JS_REG_EXP_STRING_ITERATOR_TYPE",
2122: "JS_RELATIVE_TIME_FORMAT_TYPE",
......@@ -448,8 +448,8 @@ KNOWN_MAPS = {
("read_only_space", 0x06a95): (138, "StoreHandler1Map"),
("read_only_space", 0x06abd): (138, "StoreHandler2Map"),
("read_only_space", 0x06ae5): (138, "StoreHandler3Map"),
("map_space", 0x02151): (2112, "ExternalMap"),
("map_space", 0x02179): (2116, "JSMessageObjectMap"),
("map_space", 0x02151): (2113, "ExternalMap"),
("map_space", 0x02179): (2117, "JSMessageObjectMap"),
}
# List of known V8 objects.
......
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