Refactor ExternalObjects

Instead of implementing ExternalObjects as plain JSObjects with a single
EmbedderDataSlot pointing to a Foreign containing the actual raw
pointer, this CL now creates a new JSExternalObject type that directly
contains the external pointer.

As a side-effect of this refactoring, nullptr values are now no longer
valid for ExternalObjects.

Change-Id: Ic8ff334681c966e823ca70f34dd1efaaa21a0789
Cq-Include-Trybots: luci.v8.try:v8_linux64_heap_sandbox_dbg_ng,v8_linux_arm64_sim_heap_sandbox_dbg_ng
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3513234
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Commit-Queue: Samuel Groß <saelo@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79459}
This commit is contained in:
Samuel Groß 2022-03-10 19:44:52 +01:00 committed by V8 LUCI CQ
parent bed5bc495f
commit 5a968b08b3
24 changed files with 203 additions and 81 deletions

View File

@ -303,6 +303,7 @@ enum ExternalPointerTag : uint64_t {
kNativeContextMicrotaskQueueTag = 0b1000000111011111ULL << 48,
kEmbedderDataSlotPayloadTag = 0b1000000111101111ULL << 48,
kCodeEntryPointTag = 0b1000000111110111ULL << 48,
kExternalObjectValueTag = 0b1000000111111011ULL << 48,
};
// clang-format on

View File

@ -3633,15 +3633,7 @@ bool Value::IsBoolean() const { return Utils::OpenHandle(this)->IsBoolean(); }
bool Value::IsExternal() const {
i::Object obj = *Utils::OpenHandle(this);
if (!obj.IsHeapObject()) return false;
i::HeapObject heap_obj = i::HeapObject::cast(obj);
// Check the instance type is JS_OBJECT (instance type of Externals) before
// attempting to get the Isolate since that guarantees the object is writable
// and GetIsolate will work.
if (heap_obj.map().instance_type() != i::JS_OBJECT_TYPE) return false;
i::Isolate* isolate = i::JSObject::cast(heap_obj).GetIsolate();
ASSERT_NO_SCRIPT_NO_EXCEPTION(isolate);
return heap_obj.IsExternal(isolate);
return obj.IsJSExternalObject();
}
bool Value::IsInt32() const {
@ -5996,15 +5988,6 @@ void v8::Object::SetAlignedPointerInInternalFields(int argc, int indices[],
#endif // VERIFY_HEAP
}
static void* ExternalValue(i::Object obj) {
// Obscure semantics for undefined, but somehow checked in our unit tests...
if (obj.IsUndefined()) {
return nullptr;
}
i::Object foreign = i::JSObject::cast(obj).GetEmbedderField(0);
return reinterpret_cast<void*>(i::Foreign::cast(foreign).foreign_address());
}
// --- E n v i r o n m e n t ---
void v8::V8::InitializePlatform(Platform* platform) {
@ -6732,6 +6715,11 @@ bool FunctionTemplate::IsLeafTemplateForApiObject(
Local<External> v8::External::New(Isolate* isolate, void* value) {
STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
// Nullptr is not allowed here because serialization/deserialization of
// nullptr external api references is not possible as nullptr is used as an
// external_references table terminator, see v8::SnapshotCreator()
// constructors.
DCHECK_NOT_NULL(value);
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
LOG_API(i_isolate, External, New);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(i_isolate);
@ -6740,7 +6728,8 @@ Local<External> v8::External::New(Isolate* isolate, void* value) {
}
void* External::Value() const {
return ExternalValue(*Utils::OpenHandle(this));
auto self = Utils::OpenHandle(this);
return i::JSExternalObject::cast(*self).value();
}
// anonymous namespace for string creation helper functions

View File

@ -196,6 +196,7 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) {
case JS_STRING_ITERATOR_PROTOTYPE_TYPE:
case JS_ARGUMENTS_OBJECT_TYPE:
case JS_ERROR_TYPE:
case JS_EXTERNAL_OBJECT_TYPE:
case JS_GLOBAL_OBJECT_TYPE:
case JS_GLOBAL_PROXY_TYPE:
case JS_API_OBJECT_TYPE:

View File

@ -116,6 +116,10 @@ class ConcurrentMarkingVisitor final
return VisitJSObjectSubclassFast(map, object);
}
int VisitJSExternalObject(Map map, JSExternalObject object) {
return VisitJSObjectSubclass(map, object);
}
#if V8_ENABLE_WEBASSEMBLY
int VisitWasmInstanceObject(Map map, WasmInstanceObject object) {
return VisitJSObjectSubclass(map, object);

View File

@ -2272,9 +2272,10 @@ Handle<JSObject> Factory::NewFunctionPrototype(Handle<JSFunction> function) {
}
Handle<JSObject> Factory::NewExternal(void* value) {
Handle<Foreign> foreign = NewForeign(reinterpret_cast<Address>(value));
Handle<JSObject> external = NewJSObjectFromMap(external_map());
external->SetEmbedderField(0, *foreign);
auto external =
Handle<JSExternalObject>::cast(NewJSObjectFromMap(external_map()));
external->AllocateExternalPointerEntries(isolate());
external->set_value(isolate(), value);
return external;
}

View File

@ -30,6 +30,7 @@ namespace internal {
V(FixedDoubleArray) \
V(JSArrayBuffer) \
V(JSDataView) \
V(JSExternalObject) \
V(JSFinalizationRegistry) \
V(JSFunction) \
V(JSObject) \

View File

@ -527,7 +527,7 @@ bool Heap::CreateInitialMaps() {
ALLOCATE_MAP(JS_MESSAGE_OBJECT_TYPE, JSMessageObject::kHeaderSize,
message_object)
ALLOCATE_MAP(JS_OBJECT_TYPE, JSObject::kHeaderSize + kEmbedderDataSlotSize,
ALLOCATE_MAP(JS_EXTERNAL_OBJECT_TYPE, JSExternalObject::kHeaderSize,
external)
external_map().set_is_extensible(false);
#undef ALLOCATE_PRIMITIVE_MAP

View File

@ -96,8 +96,6 @@ class HeapObject : public Object {
IS_TYPE_FUNCTION_DECL(CodeT)
#undef IS_TYPE_FUNCTION_DECL
bool IsExternal(Isolate* isolate) const;
// Oddball checks are faster when they are raw pointer comparisons, so the
// isolate/read-only roots overloads should be preferred where possible.
#define IS_TYPE_FUNCTION_DECL(Type, Value) \

View File

@ -525,6 +525,35 @@ void JSObject::InitializeBody(Map map, int start_offset,
}
}
TQ_OBJECT_CONSTRUCTORS_IMPL(JSExternalObject)
DEF_GETTER(JSExternalObject, value, void*) {
Isolate* isolate = GetIsolateForSandbox(*this);
return reinterpret_cast<void*>(
ReadExternalPointerField(kValueOffset, isolate, kExternalObjectValueTag));
}
void JSExternalObject::AllocateExternalPointerEntries(Isolate* isolate) {
InitExternalPointerField(kValueOffset, isolate, kExternalObjectValueTag);
}
void JSExternalObject::set_value(Isolate* isolate, void* value) {
WriteExternalPointerField(kValueOffset, isolate,
reinterpret_cast<Address>(value),
kExternalObjectValueTag);
}
uint32_t JSExternalObject::GetValueRefForDeserialization() {
ExternalPointer_t encoded_address =
ReadField<ExternalPointer_t>(kValueOffset);
return static_cast<uint32_t>(encoded_address);
}
void JSExternalObject::SetValueRefForSerialization(uint32_t ref) {
WriteField<ExternalPointer_t>(kValueOffset,
static_cast<ExternalPointer_t>(ref));
}
DEF_GETTER(JSGlobalObject, native_context_unchecked, Object) {
return TaggedField<Object, kNativeContextOffset>::Relaxed_Load(cage_base,
*this);

View File

@ -584,7 +584,7 @@ Handle<String> JSReceiver::GetConstructorName(Isolate* isolate,
MaybeHandle<NativeContext> JSReceiver::GetCreationContext() {
JSReceiver receiver = *this;
// Externals are JSObjects with null as a constructor.
DCHECK(!receiver.IsExternal(GetIsolate()));
DCHECK(!receiver.IsJSExternalObject());
Object constructor = receiver.map().GetConstructor();
JSFunction function;
if (constructor.IsJSFunction()) {
@ -2344,6 +2344,8 @@ int JSObject::GetHeaderSize(InstanceType type,
return JSObject::kHeaderSize;
case JS_ERROR_TYPE:
return JSObject::kHeaderSize;
case JS_EXTERNAL_OBJECT_TYPE:
return JSExternalObject::kHeaderSize;
case JS_SHADOW_REALM_TYPE:
return JSShadowRealm::kHeaderSize;
case JS_STRING_ITERATOR_TYPE:

View File

@ -890,6 +890,30 @@ class JSObject : public TorqueGeneratedJSObject<JSObject, JSReceiver> {
TQ_OBJECT_CONSTRUCTORS(JSObject)
};
// A JSObject created through the public api which wraps an external pointer.
// See v8::External.
class JSExternalObject
: public TorqueGeneratedJSExternalObject<JSExternalObject, JSObject> {
public:
inline void AllocateExternalPointerEntries(Isolate* isolate);
// [value]: field containing the pointer value.
DECL_GETTER(value, void*)
inline void set_value(Isolate* isolate, void* value);
// Used in the serializer/deserializer.
inline uint32_t GetValueRefForDeserialization();
inline void SetValueRefForSerialization(uint32_t ref);
static constexpr int kEndOfTaggedFieldsOffset = JSObject::kHeaderSize;
class BodyDescriptor;
private:
TQ_OBJECT_CONSTRUCTORS(JSExternalObject)
};
// 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

View File

@ -40,6 +40,8 @@ macro NewJSObject(implicit context: Context)(): JSObject {
return AllocateJSObjectFromMap(map);
}
extern class JSExternalObject extends JSObject { value: ExternalPointer; }
@abstract
@lowestInstanceTypeWithinParentClassRange
extern class JSCustomElementsObject extends JSObject {

View File

@ -206,6 +206,9 @@ VisitorId Map::GetVisitorId(Map map) {
case JS_DATA_VIEW_TYPE:
return kVisitJSDataView;
case JS_EXTERNAL_OBJECT_TYPE:
return kVisitJSExternalObject;
case JS_FUNCTION_TYPE:
case JS_CLASS_CONSTRUCTOR_TYPE:
case JS_PROMISE_CONSTRUCTOR_TYPE:

View File

@ -46,6 +46,7 @@ enum InstanceType : uint16_t;
V(JSApiObject) \
V(JSArrayBuffer) \
V(JSDataView) \
V(JSExternalObject) \
V(JSFinalizationRegistry) \
V(JSFunction) \
V(JSObject) \

View File

@ -139,6 +139,7 @@ class ZoneForwardList;
V(JSDataView) \
V(JSDate) \
V(JSError) \
V(JSExternalObject) \
V(JSFinalizationRegistry) \
V(JSFunction) \
V(JSFunctionOrBoundFunctionOrWrappedFunction) \

View File

@ -436,6 +436,22 @@ class JSDataView::BodyDescriptor final : public BodyDescriptorBase {
}
};
class JSExternalObject::BodyDescriptor final : public BodyDescriptorBase {
public:
static bool IsValidSlot(Map map, HeapObject obj, int offset) { return false; }
template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject obj, int object_size,
ObjectVisitor* v) {
IteratePointers(obj, kPropertiesOrHashOffset, kEndOfTaggedFieldsOffset, v);
v->VisitExternalPointer(obj, obj.RawExternalPointerField(kValueOffset));
}
static inline int SizeOf(Map map, HeapObject object) {
return map.instance_size();
}
};
template <typename Derived>
class V8_EXPORT_PRIVATE SmallOrderedHashTable<Derived>::BodyDescriptor final
: public BodyDescriptorBase {
@ -1211,6 +1227,8 @@ auto BodyDescriptorApply(InstanceType type, Args&&... args) {
return CALL_APPLY(JSDataView);
case JS_TYPED_ARRAY_TYPE:
return CALL_APPLY(JSTypedArray);
case JS_EXTERNAL_OBJECT_TYPE:
return CALL_APPLY(JSExternalObject);
case WEAK_CELL_TYPE:
return CALL_APPLY(WeakCell);
case JS_WEAK_REF_TYPE:

View File

@ -2448,10 +2448,6 @@ void HeapObject::RehashBasedOnMap(IsolateT* isolate) {
template void HeapObject::RehashBasedOnMap(Isolate* isolate);
template void HeapObject::RehashBasedOnMap(LocalIsolate* isolate);
bool HeapObject::IsExternal(Isolate* isolate) const {
return map(isolate).FindRootMap(isolate) == isolate->heap()->external_map();
}
void DescriptorArray::GeneralizeAllFields() {
int length = number_of_descriptors();
for (InternalIndex i : InternalIndex::Range(length)) {

View File

@ -264,9 +264,12 @@ void HeapProfiler::QueryObjects(Handle<Context> context,
heap()->CollectAllAvailableGarbage(GarbageCollectionReason::kHeapProfiler);
CombinedHeapObjectIterator heap_iterator(
heap(), HeapObjectIterator::kFilterUnreachable);
PtrComprCageBase cage_base(isolate());
for (HeapObject heap_obj = heap_iterator.Next(); !heap_obj.is_null();
heap_obj = heap_iterator.Next()) {
if (!heap_obj.IsJSObject() || heap_obj.IsExternal(isolate())) continue;
if (!heap_obj.IsJSObject(cage_base) ||
heap_obj.IsJSExternalObject(cage_base))
continue;
v8::Local<v8::Object> v8_obj(
Utils::ToLocal(handle(JSObject::cast(heap_obj), isolate())));
if (!predicate->Filter(v8_obj)) continue;

View File

@ -380,6 +380,14 @@ template bool StringTableInsertionKey::IsMatch(LocalIsolate* isolate,
namespace {
void NoExternalReferencesCallback() {
// The following check will trigger if a function or object template
// with references to native functions have been deserialized from
// snapshot, but no actual external references were provided when the
// isolate was created.
FATAL("No external references provided via API");
}
void PostProcessExternalString(ExternalString string, Isolate* isolate) {
DisallowGarbageCollection no_gc;
uint32_t index = string.GetResourceRefForDeserialization();
@ -450,6 +458,24 @@ void Deserializer<IsolateT>::PostProcessNewJSReceiver(
HeapObject::RequiredAlignment(map)));
}
template <typename IsolateT>
void Deserializer<IsolateT>::PostProcessJSExternalObject(
JSExternalObject object, Isolate* isolate) {
DisallowGarbageCollection no_gc;
uint32_t index = object.GetValueRefForDeserialization();
Address address;
if (main_thread_isolate()->api_external_references()) {
DCHECK_WITH_MSG(index < num_api_references_,
"too few external references provided through the API");
address = static_cast<Address>(
main_thread_isolate()->api_external_references()[index]);
} else {
address = reinterpret_cast<Address>(NoExternalReferencesCallback);
}
object.AllocateExternalPointerEntries(isolate);
object.set_value(isolate, reinterpret_cast<void*>(address));
}
template <typename IsolateT>
void Deserializer<IsolateT>::PostProcessNewObject(Handle<Map> map,
Handle<HeapObject> obj,
@ -545,6 +571,9 @@ void Deserializer<IsolateT>::PostProcessNewObject(Handle<Map> map,
} else if (InstanceTypeChecker::IsExternalString(instance_type)) {
PostProcessExternalString(ExternalString::cast(raw_obj),
main_thread_isolate());
} else if (InstanceTypeChecker::IsJSExternalObject(instance_type)) {
PostProcessJSExternalObject(JSExternalObject::cast(raw_obj),
main_thread_isolate());
} else if (InstanceTypeChecker::IsJSReceiver(instance_type)) {
return PostProcessNewJSReceiver(raw_map, Handle<JSReceiver>::cast(obj),
JSReceiver::cast(raw_obj), instance_type,
@ -859,14 +888,6 @@ int Deserializer<IsolateT>::ReadRepeatedObject(SlotAccessor slot_accessor,
namespace {
void NoExternalReferencesCallback() {
// The following check will trigger if a function or object template
// with references to native functions have been deserialized from
// snapshot, but no actual external references were provided when the
// isolate was created.
FATAL("No external references provided via API");
}
// Template used by the below CASE_RANGE macro to statically verify that the
// given number of cases matches the number of expected cases for that bytecode.
template <int byte_code_count, int expected>

View File

@ -198,6 +198,7 @@ class Deserializer : public SerializerDeserializer {
void PostProcessNewJSReceiver(Map map, Handle<JSReceiver> obj,
JSReceiver raw_obj, InstanceType instance_type,
SnapshotSpace space);
void PostProcessJSExternalObject(JSExternalObject object, Isolate* isolate);
HeapObject Allocate(AllocationType allocation, int size,
AllocationAlignment alignment);

View File

@ -549,6 +549,26 @@ void Serializer::ObjectSerializer::SerializeJSArrayBuffer() {
buffer->set_extension(extension);
}
void Serializer::ObjectSerializer::SerializeJSExternalObject() {
Handle<JSExternalObject> obj = Handle<JSExternalObject>::cast(object_);
Address value = reinterpret_cast<Address>(obj->value());
ExternalReferenceEncoder::Value reference =
serializer_->EncodeExternalReference(value);
DCHECK(reference.is_from_api());
#ifdef V8_SANDBOXED_EXTERNAL_POINTERS
// TODO(saelo) unify this code with the non-sandbox version maybe?
STATIC_ASSERT(sizeof(ExternalPointer_t) == sizeof(uint32_t));
uint32_t external_pointer_entry = obj->GetValueRefForDeserialization();
#endif
obj->SetValueRefForSerialization(reference.index());
SerializeObject();
#ifdef V8_SANDBOXED_EXTERNAL_POINTERS
obj->SetValueRefForSerialization(external_pointer_entry);
#else
obj->set_value(isolate(), reinterpret_cast<void*>(value));
#endif
}
void Serializer::ObjectSerializer::SerializeExternalString() {
// For external strings with known resources, we replace the resource field
// with the encoded external reference, which we restore upon deserialize.
@ -692,6 +712,9 @@ void Serializer::ObjectSerializer::Serialize() {
if (object_->IsExternalString(cage_base)) {
SerializeExternalString();
return;
} else if (object_->IsJSExternalObject(cage_base)) {
SerializeJSExternalObject();
return;
} else if (!ReadOnlyHeap::Contains(*object_)) {
// Only clear padding for strings outside the read-only heap. Read-only heap
// should have been cleared elsewhere.

View File

@ -472,6 +472,7 @@ class Serializer::ObjectSerializer : public ObjectVisitor {
uint32_t SerializeBackingStore(void* backing_store, int32_t byte_length);
void SerializeJSTypedArray();
void SerializeJSArrayBuffer();
void SerializeJSExternalObject();
void SerializeExternalString();
void SerializeExternalStringAsSequentialString();

View File

@ -3415,8 +3415,8 @@ UNINITIALIZED_TEST(SnapshotCreatorTemplates) {
object_template->NewInstance(context).ToLocalChecked();
v8::Local<v8::Object> c =
object_template->NewInstance(context).ToLocalChecked();
v8::Local<v8::External> null_external =
v8::External::New(isolate, nullptr);
v8::Local<v8::External> resource_external =
v8::External::New(isolate, &serializable_one_byte_resource);
v8::Local<v8::External> field_external =
v8::External::New(isolate, &serialized_static_field);
@ -3427,7 +3427,7 @@ UNINITIALIZED_TEST(SnapshotCreatorTemplates) {
b->SetAlignedPointerInInternalField(1, b1);
c->SetAlignedPointerInInternalField(1, c1);
a->SetInternalField(2, null_external);
a->SetInternalField(2, resource_external);
b->SetInternalField(2, field_external);
c->SetInternalField(2, v8_num(35));
CHECK(context->Global()->Set(context, v8_str("a"), a).FromJust());
@ -3525,7 +3525,8 @@ UNINITIALIZED_TEST(SnapshotCreatorTemplates) {
CHECK_EQ(30u, c1->data);
CHECK(a2->IsExternal());
CHECK_NULL(v8::Local<v8::External>::Cast(a2)->Value());
CHECK_EQ(static_cast<void*>(&serializable_one_byte_resource),
v8::Local<v8::External>::Cast(a2)->Value());
CHECK(b2->IsExternal());
CHECK_EQ(static_cast<void*>(&serialized_static_field),
v8::Local<v8::External>::Cast(b2)->Value());

View File

@ -232,42 +232,43 @@ INSTANCE_TYPES = {
2109: "JS_DATE_TIME_FORMAT_TYPE",
2110: "JS_DISPLAY_NAMES_TYPE",
2111: "JS_ERROR_TYPE",
2112: "JS_FINALIZATION_REGISTRY_TYPE",
2113: "JS_LIST_FORMAT_TYPE",
2114: "JS_LOCALE_TYPE",
2115: "JS_MESSAGE_OBJECT_TYPE",
2116: "JS_NUMBER_FORMAT_TYPE",
2117: "JS_PLURAL_RULES_TYPE",
2118: "JS_PROMISE_TYPE",
2119: "JS_REG_EXP_TYPE",
2120: "JS_REG_EXP_STRING_ITERATOR_TYPE",
2121: "JS_RELATIVE_TIME_FORMAT_TYPE",
2122: "JS_SEGMENT_ITERATOR_TYPE",
2123: "JS_SEGMENTER_TYPE",
2124: "JS_SEGMENTS_TYPE",
2125: "JS_SHADOW_REALM_TYPE",
2126: "JS_SHARED_STRUCT_TYPE",
2127: "JS_STRING_ITERATOR_TYPE",
2128: "JS_TEMPORAL_CALENDAR_TYPE",
2129: "JS_TEMPORAL_DURATION_TYPE",
2130: "JS_TEMPORAL_INSTANT_TYPE",
2131: "JS_TEMPORAL_PLAIN_DATE_TYPE",
2132: "JS_TEMPORAL_PLAIN_DATE_TIME_TYPE",
2133: "JS_TEMPORAL_PLAIN_MONTH_DAY_TYPE",
2134: "JS_TEMPORAL_PLAIN_TIME_TYPE",
2135: "JS_TEMPORAL_PLAIN_YEAR_MONTH_TYPE",
2136: "JS_TEMPORAL_TIME_ZONE_TYPE",
2137: "JS_TEMPORAL_ZONED_DATE_TIME_TYPE",
2138: "JS_V8_BREAK_ITERATOR_TYPE",
2139: "JS_WEAK_REF_TYPE",
2140: "WASM_GLOBAL_OBJECT_TYPE",
2141: "WASM_INSTANCE_OBJECT_TYPE",
2142: "WASM_MEMORY_OBJECT_TYPE",
2143: "WASM_MODULE_OBJECT_TYPE",
2144: "WASM_SUSPENDER_OBJECT_TYPE",
2145: "WASM_TABLE_OBJECT_TYPE",
2146: "WASM_TAG_OBJECT_TYPE",
2147: "WASM_VALUE_OBJECT_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",
2120: "JS_REG_EXP_TYPE",
2121: "JS_REG_EXP_STRING_ITERATOR_TYPE",
2122: "JS_RELATIVE_TIME_FORMAT_TYPE",
2123: "JS_SEGMENT_ITERATOR_TYPE",
2124: "JS_SEGMENTER_TYPE",
2125: "JS_SEGMENTS_TYPE",
2126: "JS_SHADOW_REALM_TYPE",
2127: "JS_SHARED_STRUCT_TYPE",
2128: "JS_STRING_ITERATOR_TYPE",
2129: "JS_TEMPORAL_CALENDAR_TYPE",
2130: "JS_TEMPORAL_DURATION_TYPE",
2131: "JS_TEMPORAL_INSTANT_TYPE",
2132: "JS_TEMPORAL_PLAIN_DATE_TYPE",
2133: "JS_TEMPORAL_PLAIN_DATE_TIME_TYPE",
2134: "JS_TEMPORAL_PLAIN_MONTH_DAY_TYPE",
2135: "JS_TEMPORAL_PLAIN_TIME_TYPE",
2136: "JS_TEMPORAL_PLAIN_YEAR_MONTH_TYPE",
2137: "JS_TEMPORAL_TIME_ZONE_TYPE",
2138: "JS_TEMPORAL_ZONED_DATE_TIME_TYPE",
2139: "JS_V8_BREAK_ITERATOR_TYPE",
2140: "JS_WEAK_REF_TYPE",
2141: "WASM_GLOBAL_OBJECT_TYPE",
2142: "WASM_INSTANCE_OBJECT_TYPE",
2143: "WASM_MEMORY_OBJECT_TYPE",
2144: "WASM_MODULE_OBJECT_TYPE",
2145: "WASM_SUSPENDER_OBJECT_TYPE",
2146: "WASM_TABLE_OBJECT_TYPE",
2147: "WASM_TAG_OBJECT_TYPE",
2148: "WASM_VALUE_OBJECT_TYPE",
}
# List of known V8 maps.
@ -447,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): (1057, "ExternalMap"),
("map_space", 0x02179): (2115, "JSMessageObjectMap"),
("map_space", 0x02151): (2112, "ExternalMap"),
("map_space", 0x02179): (2116, "JSMessageObjectMap"),
}
# List of known V8 objects.