[runtime] Add new instance types for constructor functions

This will allow us optimize the protector cell checks in the fast path
from checking against the function object in every context to just
doing a range check against the instance type.

This patch adds new instance types for constructor functions that
require such protector cell checks.

Bug: v8:11256
Change-Id: Iea722f9c6326dfa470149dd02e689a23942097f4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2595442
Reviewed-by: Mythri Alle <mythria@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Commit-Queue: Sathya Gunasekaran  <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72146}
This commit is contained in:
Sathya Gunasekaran 2021-01-18 17:01:02 +00:00 committed by Commit Bot
parent 47135e0368
commit 624030e975
36 changed files with 375 additions and 142 deletions

View File

@ -694,8 +694,8 @@ Handle<JSFunction> ApiNatives::CreateApiFunction(
immutable_proto = GetInstanceTemplate->immutable_proto();
}
// JS_FUNCTION_TYPE requires information about the prototype slot.
DCHECK_NE(JS_FUNCTION_TYPE, type);
// JSFunction requires information about the prototype slot.
DCHECK(!InstanceTypeChecker::IsJSFunction(type));
int instance_size = JSObject::GetHeaderSize(type) +
kEmbedderDataSlotSize * embedder_field_count;

View File

@ -2160,9 +2160,11 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
Label non_callable, non_smi;
__ JumpIfSmi(r1, &non_callable);
__ bind(&non_smi);
__ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE);
__ LoadMap(r4, r1);
__ CompareInstanceTypeRange(r4, r5, FIRST_JS_FUNCTION_TYPE,
LAST_JS_FUNCTION_TYPE);
__ Jump(masm->isolate()->builtins()->CallFunction(mode),
RelocInfo::CODE_TARGET, eq);
RelocInfo::CODE_TARGET, ls);
__ cmp(r5, Operand(JS_BOUND_FUNCTION_TYPE));
__ Jump(BUILTIN_CODE(masm->isolate(), CallBoundFunction),
RelocInfo::CODE_TARGET, eq);
@ -2268,9 +2270,10 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
__ b(eq, &non_constructor);
// Dispatch based on instance type.
__ CompareInstanceType(r4, r5, JS_FUNCTION_TYPE);
__ CompareInstanceTypeRange(r4, r5, FIRST_JS_FUNCTION_TYPE,
LAST_JS_FUNCTION_TYPE);
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructFunction),
RelocInfo::CODE_TARGET, eq);
RelocInfo::CODE_TARGET, ls);
// Only dispatch to bound functions after checking whether they are
// constructors.

View File

@ -2523,9 +2523,11 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
Label non_callable, non_smi;
__ JumpIfSmi(x1, &non_callable);
__ Bind(&non_smi);
__ CompareObjectType(x1, x4, x5, JS_FUNCTION_TYPE);
__ LoadMap(x4, x1);
__ CompareInstanceTypeRange(x4, x5, FIRST_JS_FUNCTION_TYPE,
LAST_JS_FUNCTION_TYPE);
__ Jump(masm->isolate()->builtins()->CallFunction(mode),
RelocInfo::CODE_TARGET, eq);
RelocInfo::CODE_TARGET, ls);
__ Cmp(x5, JS_BOUND_FUNCTION_TYPE);
__ Jump(BUILTIN_CODE(masm->isolate(), CallBoundFunction),
RelocInfo::CODE_TARGET, eq);
@ -2639,9 +2641,10 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
&non_constructor);
// Dispatch based on instance type.
__ CompareInstanceType(x4, x5, JS_FUNCTION_TYPE);
__ CompareInstanceTypeRange(x4, x5, FIRST_JS_FUNCTION_TYPE,
LAST_JS_FUNCTION_TYPE);
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructFunction),
RelocInfo::CODE_TARGET, eq);
RelocInfo::CODE_TARGET, ls);
// Only dispatch to bound functions after checking whether they are
// constructors.

View File

@ -517,8 +517,7 @@ TNode<JSReceiver> CallOrConstructBuiltinsAssembler::GetCompatibleReceiver(
//
var_template = CAST(constructor);
TNode<Uint16T> template_type = LoadInstanceType(var_template.value());
GotoIf(InstanceTypeEqual(template_type, JS_FUNCTION_TYPE),
&template_from_closure);
GotoIf(IsJSFunctionInstanceType(template_type), &template_from_closure);
Branch(InstanceTypeEqual(template_type, MAP_TYPE), &template_map_loop,
&template_loop);
}

View File

@ -737,16 +737,15 @@ TF_BUILTIN(ObjectToString, ObjectBuiltinsAssembler) {
var_holder = receiver_heap_object;
TNode<Uint16T> receiver_instance_type = LoadMapInstanceType(receiver_map);
GotoIf(IsPrimitiveInstanceType(receiver_instance_type), &if_primitive);
GotoIf(IsFunctionInstanceType(receiver_instance_type), &if_function);
const struct {
InstanceType value;
Label* label;
} kJumpTable[] = {{JS_OBJECT_TYPE, &if_object},
{JS_ARRAY_TYPE, &if_array},
{JS_FUNCTION_TYPE, &if_function},
{JS_REG_EXP_TYPE, &if_regexp},
{JS_ARGUMENTS_OBJECT_TYPE, &if_arguments},
{JS_DATE_TYPE, &if_date},
{JS_BOUND_FUNCTION_TYPE, &if_function},
{JS_API_OBJECT_TYPE, &if_object},
{JS_SPECIAL_API_OBJECT_TYPE, &if_object},
{JS_PROXY_TYPE, &if_proxy},

View File

@ -1377,7 +1377,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
__ Pop(kJavaScriptCallTargetRegister);
__ PushReturnAddressFrom(eax);
__ AssertFunction(kJavaScriptCallTargetRegister);
__ AssertFunction(kJavaScriptCallTargetRegister, eax);
__ AssertUndefinedOrAllocationSite(kJavaScriptCallExtraArg1Register, eax);
__ movd(eax, xmm0); // Reload number of arguments.
@ -2113,7 +2113,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
// -- edi : the function to call (checked to be a JSFunction)
// -----------------------------------
StackArgumentsAccessor args(eax);
__ AssertFunction(edi);
__ AssertFunction(edi, edx);
// See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
// Check that the function is not a "classConstructor".
@ -2328,12 +2328,15 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
non_jsboundfunction;
__ JumpIfSmi(edi, &non_callable);
__ bind(&non_smi);
__ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
__ j(not_equal, &non_jsfunction);
__ LoadMap(ecx, edi);
__ CmpInstanceTypeRange(ecx, ecx, FIRST_JS_FUNCTION_TYPE,
LAST_JS_FUNCTION_TYPE);
__ j(above, &non_jsfunction);
__ Jump(masm->isolate()->builtins()->CallFunction(mode),
RelocInfo::CODE_TARGET);
__ bind(&non_jsfunction);
__ LoadMap(ecx, edi);
__ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE);
__ j(not_equal, &non_jsboundfunction);
__ Jump(BUILTIN_CODE(masm->isolate(), CallBoundFunction),
@ -2378,7 +2381,7 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
// -- edi : the constructor to call (checked to be a JSFunction)
// -----------------------------------
__ AssertConstructor(edi);
__ AssertFunction(edi);
__ AssertFunction(edi, ecx);
Label call_generic_stub;
@ -2450,14 +2453,16 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
__ j(zero, &non_constructor);
// Dispatch based on instance type.
__ CmpInstanceType(ecx, JS_FUNCTION_TYPE);
__ j(not_equal, &non_jsfunction);
__ CmpInstanceTypeRange(ecx, ecx, FIRST_JS_FUNCTION_TYPE,
LAST_JS_FUNCTION_TYPE);
__ j(above, &non_jsfunction);
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructFunction),
RelocInfo::CODE_TARGET);
// Only dispatch to bound functions after checking whether they are
// constructors.
__ bind(&non_jsfunction);
__ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
__ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE);
__ j(not_equal, &non_jsboundfunction);
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructBoundFunction),

View File

@ -2259,9 +2259,10 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
Label non_callable;
__ JumpIfSmi(rdi, &non_callable);
__ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
__ LoadMap(rcx, rdi);
__ CmpInstanceTypeRange(rcx, FIRST_JS_FUNCTION_TYPE, LAST_JS_FUNCTION_TYPE);
__ Jump(masm->isolate()->builtins()->CallFunction(mode),
RelocInfo::CODE_TARGET, equal);
RelocInfo::CODE_TARGET, below_equal);
__ CmpInstanceType(rcx, JS_BOUND_FUNCTION_TYPE);
__ Jump(BUILTIN_CODE(masm->isolate(), CallBoundFunction),
@ -2373,9 +2374,9 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
__ j(zero, &non_constructor);
// Dispatch based on instance type.
__ CmpInstanceType(rcx, JS_FUNCTION_TYPE);
__ CmpInstanceTypeRange(rcx, FIRST_JS_FUNCTION_TYPE, LAST_JS_FUNCTION_TYPE);
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructFunction),
RelocInfo::CODE_TARGET, equal);
RelocInfo::CODE_TARGET, below_equal);
// Only dispatch to bound functions after checking whether they are
// constructors.

View File

@ -1841,6 +1841,17 @@ void MacroAssembler::CompareInstanceType(Register map, Register type_reg,
cmp(type_reg, Operand(type));
}
void MacroAssembler::CompareInstanceTypeRange(Register map, Register type_reg,
InstanceType lower_limit,
InstanceType higher_limit) {
DCHECK_LT(lower_limit, higher_limit);
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
ldrh(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset));
sub(scratch, type_reg, Operand(lower_limit));
cmp(scratch, Operand(higher_limit - lower_limit));
}
void MacroAssembler::CompareRoot(Register obj, RootIndex index) {
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
@ -2141,9 +2152,11 @@ void MacroAssembler::AssertFunction(Register object) {
tst(object, Operand(kSmiTagMask));
Check(ne, AbortReason::kOperandIsASmiAndNotAFunction);
push(object);
CompareObjectType(object, object, object, JS_FUNCTION_TYPE);
LoadMap(object, object);
CompareInstanceTypeRange(object, object, FIRST_JS_FUNCTION_TYPE,
LAST_JS_FUNCTION_TYPE);
pop(object);
Check(eq, AbortReason::kOperandIsNotAFunction);
Check(ls, AbortReason::kOperandIsNotAFunction);
}
}

View File

@ -718,6 +718,14 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// sets the flags and leaves the object type in the type_reg register.
void CompareInstanceType(Register map, Register type_reg, InstanceType type);
// Compare instance type ranges for a map (lower_limit and higher_limit
// inclusive).
//
// Always use unsigned comparisons: ls for a positive result.
void CompareInstanceTypeRange(Register map, Register type_reg,
InstanceType lower_limit,
InstanceType higher_limit);
// Compare the object in a register to a value from the root list.
// Acquires a scratch register.
void CompareRoot(Register obj, RootIndex index);

View File

@ -1488,9 +1488,10 @@ void MacroAssembler::AssertFunction(Register object) {
UseScratchRegisterScope temps(this);
Register temp = temps.AcquireX();
CompareObjectType(object, temp, temp, JS_FUNCTION_TYPE);
Check(eq, AbortReason::kOperandIsNotAFunction);
LoadMap(temp, object);
CompareInstanceTypeRange(temp, temp, FIRST_JS_FUNCTION_TYPE,
LAST_JS_FUNCTION_TYPE);
Check(ls, AbortReason::kOperandIsNotAFunction);
}
}
@ -2661,6 +2662,18 @@ void MacroAssembler::CompareInstanceType(Register map, Register type_reg,
Cmp(type_reg, type);
}
// Sets condition flags based on comparison, and returns type in type_reg.
void MacroAssembler::CompareInstanceTypeRange(Register map, Register type_reg,
InstanceType lower_limit,
InstanceType higher_limit) {
DCHECK_LT(lower_limit, higher_limit);
UseScratchRegisterScope temps(this);
Register scratch = temps.AcquireX();
Ldrh(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset));
Sub(scratch, type_reg, Operand(lower_limit));
Cmp(scratch, Operand(higher_limit - lower_limit));
}
void MacroAssembler::LoadElementsKindFromMap(Register result, Register map) {
// Load the map's "bit field 2".
Ldrb(result, FieldMemOperand(map, Map::kBitField2Offset));

View File

@ -1913,6 +1913,14 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// sets the flags and leaves the object type in the type_reg register.
void CompareInstanceType(Register map, Register type_reg, InstanceType type);
// Compare instance type ranges for a map (lower_limit and higher_limit
// inclusive).
//
// Always use unsigned comparisons: ls for a positive result.
void CompareInstanceTypeRange(Register map, Register type_reg,
InstanceType lower_limit,
InstanceType higher_limit);
// Load the elements kind field from a map, and return it in the result
// register.
void LoadElementsKindFromMap(Register result, Register map);

View File

@ -6369,9 +6369,15 @@ TNode<BoolT> CodeStubAssembler::IsJSGeneratorObject(TNode<HeapObject> object) {
return HasInstanceType(object, JS_GENERATOR_OBJECT_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsFunctionInstanceType(
TNode<Int32T> instance_type) {
return IsInRange(instance_type, FIRST_JS_FUNCTION_OR_BOUND_FUNCTION_TYPE,
LAST_JS_FUNCTION_OR_BOUND_FUNCTION_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsJSFunctionInstanceType(
SloppyTNode<Int32T> instance_type) {
return InstanceTypeEqual(instance_type, JS_FUNCTION_TYPE);
return IsInRange(instance_type, FIRST_JS_FUNCTION_TYPE,
LAST_JS_FUNCTION_TYPE);
}
TNode<BoolT> CodeStubAssembler::IsJSFunction(TNode<HeapObject> object) {
@ -9429,7 +9435,7 @@ TNode<Oddball> CodeStubAssembler::OrdinaryHasInstance(
// Goto runtime if {callable} is not a JSFunction.
TNode<Uint16T> callable_instance_type = LoadMapInstanceType(callable_map);
GotoIfNot(InstanceTypeEqual(callable_instance_type, JS_FUNCTION_TYPE),
GotoIfNot(IsJSFunctionInstanceType(callable_instance_type),
&return_runtime);
GotoIfPrototypeRequiresRuntimeLookup(CAST(callable), callable_map,

View File

@ -2365,6 +2365,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> IsJSArray(TNode<HeapObject> object);
TNode<BoolT> IsJSArrayIterator(TNode<HeapObject> object);
TNode<BoolT> IsJSAsyncGeneratorObject(TNode<HeapObject> object);
TNode<BoolT> IsFunctionInstanceType(TNode<Int32T> instance_type);
TNode<BoolT> IsJSFunctionInstanceType(SloppyTNode<Int32T> instance_type);
TNode<BoolT> IsJSFunctionMap(TNode<Map> map);
TNode<BoolT> IsJSFunction(TNode<HeapObject> object);

View File

@ -871,6 +871,15 @@ void MacroAssembler::CmpInstanceType(Register map, InstanceType type) {
cmpw(FieldOperand(map, Map::kInstanceTypeOffset), Immediate(type));
}
void MacroAssembler::CmpInstanceTypeRange(Register map, Register scratch,
InstanceType lower_limit,
InstanceType higher_limit) {
DCHECK_LT(lower_limit, higher_limit);
movzx_w(scratch, FieldOperand(map, Map::kInstanceTypeOffset));
lea(scratch, Operand(scratch, 0u - lower_limit));
cmp(scratch, Immediate(higher_limit - lower_limit));
}
void MacroAssembler::AssertSmi(Register object) {
if (emit_debug_code()) {
test(object, Immediate(kSmiTagMask));
@ -891,14 +900,16 @@ void MacroAssembler::AssertConstructor(Register object) {
}
}
void MacroAssembler::AssertFunction(Register object) {
void MacroAssembler::AssertFunction(Register object, Register scratch) {
if (emit_debug_code()) {
test(object, Immediate(kSmiTagMask));
Check(not_equal, AbortReason::kOperandIsASmiAndNotAFunction);
Push(object);
CmpObjectType(object, JS_FUNCTION_TYPE, object);
LoadMap(object, object);
CmpInstanceTypeRange(object, scratch, FIRST_JS_FUNCTION_TYPE,
LAST_JS_FUNCTION_TYPE);
Pop(object);
Check(equal, AbortReason::kOperandIsNotAFunction);
Check(below_equal, AbortReason::kOperandIsNotAFunction);
}
}

View File

@ -810,6 +810,15 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// Compare instance type for map.
void CmpInstanceType(Register map, InstanceType type);
// Compare instance type ranges for a map (lower_limit and higher_limit
// inclusive).
//
// Always use unsigned comparisons: below_equal for a positive
// result.
void CmpInstanceTypeRange(Register map, Register scratch,
InstanceType lower_limit,
InstanceType higher_limit);
// Smi tagging support.
void SmiTag(Register reg) {
STATIC_ASSERT(kSmiTag == 0);
@ -847,7 +856,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
void AssertNotSmi(Register object);
// Abort execution if argument is not a JSFunction, enabled via --debug-code.
void AssertFunction(Register object);
void AssertFunction(Register object, Register scratch);
// Abort execution if argument is not a Constructor, enabled via --debug-code.
void AssertConstructor(Register object);

View File

@ -2465,6 +2465,15 @@ void MacroAssembler::CmpInstanceType(Register map, InstanceType type) {
cmpw(FieldOperand(map, Map::kInstanceTypeOffset), Immediate(type));
}
void MacroAssembler::CmpInstanceTypeRange(Register map,
InstanceType lower_limit,
InstanceType higher_limit) {
DCHECK_LT(lower_limit, higher_limit);
movzxwl(kScratchRegister, FieldOperand(map, Map::kInstanceTypeOffset));
leal(kScratchRegister, Operand(kScratchRegister, 0u - lower_limit));
cmpl(kScratchRegister, Immediate(higher_limit - lower_limit));
}
void MacroAssembler::AssertNotSmi(Register object) {
if (emit_debug_code()) {
Condition is_smi = CheckSmi(object);
@ -2513,9 +2522,10 @@ void MacroAssembler::AssertFunction(Register object) {
testb(object, Immediate(kSmiTagMask));
Check(not_equal, AbortReason::kOperandIsASmiAndNotAFunction);
Push(object);
CmpObjectType(object, JS_FUNCTION_TYPE, object);
LoadMap(object, object);
CmpInstanceTypeRange(object, FIRST_JS_FUNCTION_TYPE, LAST_JS_FUNCTION_TYPE);
Pop(object);
Check(equal, AbortReason::kOperandIsNotAFunction);
Check(below_equal, AbortReason::kOperandIsNotAFunction);
}
}

View File

@ -986,6 +986,10 @@ class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {
// Always use unsigned comparisons: above and below, not less and greater.
void CmpInstanceType(Register map, InstanceType type);
// Compare instance type ranges for a map (low and high inclusive)
// Always use unsigned comparisons: below_equal for a positive result.
void CmpInstanceTypeRange(Register map, InstanceType low, InstanceType high);
template <typename Field>
void DecodeField(Register reg) {
static const int shift = Field::kShift;

View File

@ -1773,8 +1773,10 @@ Node* EffectControlLinearizer::LowerCheckClosure(Node* node,
Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
Node* value_instance_type =
__ LoadField(AccessBuilder::ForMapInstanceType(), value_map);
Node* check_instance_type =
__ Word32Equal(value_instance_type, __ Int32Constant(JS_FUNCTION_TYPE));
Node* check_instance_type = __ Uint32LessThanOrEqual(
__ Int32Sub(value_instance_type,
__ Int32Constant(FIRST_JS_FUNCTION_TYPE)),
__ Int32Constant(LAST_JS_FUNCTION_TYPE - FIRST_JS_FUNCTION_TYPE));
__ DeoptimizeIfNot(DeoptimizeReason::kWrongCallTarget, FeedbackSource(),
check_instance_type, frame_state);

View File

@ -271,6 +271,13 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) {
DCHECK(!map.is_undetectable());
return kBoundFunction;
case JS_FUNCTION_TYPE:
case JS_PROMISE_CONSTRUCTOR_TYPE:
case JS_REG_EXP_CONSTRUCTOR_TYPE:
case JS_ARRAY_CONSTRUCTOR_TYPE:
#define TYPED_ARRAY_CONSTRUCTORS_SWITCH(Type, type, TYPE, Ctype) \
case TYPE##_TYPED_ARRAY_CONSTRUCTOR_TYPE:
TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTORS_SWITCH)
#undef TYPED_ARRAY_CONSTRUCTORS_SWITCH
DCHECK(!map.is_undetectable());
return kFunction;
case JS_PROXY_TYPE:

View File

@ -265,6 +265,16 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
case STORE_HANDLER_TYPE:
StoreHandler::cast(*this).StoreHandlerVerify(isolate);
break;
case JS_PROMISE_CONSTRUCTOR_TYPE:
case JS_REG_EXP_CONSTRUCTOR_TYPE:
case JS_ARRAY_CONSTRUCTOR_TYPE:
#define TYPED_ARRAY_CONSTRUCTORS_SWITCH(Type, type, TYPE, Ctype) \
case TYPE##_TYPED_ARRAY_CONSTRUCTOR_TYPE:
TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTORS_SWITCH)
#undef TYPED_ARRAY_CONSTRUCTORS_SWITCH
JSFunction::cast(*this).JSFunctionVerify(isolate);
break;
}
}
@ -482,7 +492,8 @@ void Map::MapVerify(Isolate* isolate) {
layout_descriptor(kAcquireLoad).IsConsistentWithMap(*this));
// Only JSFunction maps have has_prototype_slot() bit set and constructible
// JSFunction objects must have prototype slot.
CHECK_IMPLIES(has_prototype_slot(), instance_type() == JS_FUNCTION_TYPE);
CHECK_IMPLIES(has_prototype_slot(),
InstanceTypeChecker::IsJSFunction(instance_type()));
if (!may_have_interesting_symbols()) {
CHECK(!has_named_interceptor());
CHECK(!is_dictionary_map());

View File

@ -215,6 +215,15 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
case FEEDBACK_METADATA_TYPE:
FeedbackMetadata::cast(*this).FeedbackMetadataPrint(os);
break;
case JS_PROMISE_CONSTRUCTOR_TYPE:
case JS_REG_EXP_CONSTRUCTOR_TYPE:
case JS_ARRAY_CONSTRUCTOR_TYPE:
#define TYPED_ARRAY_CONSTRUCTORS_SWITCH(Type, type, TYPE, Ctype) \
case TYPE##_TYPED_ARRAY_CONSTRUCTOR_TYPE:
TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTORS_SWITCH)
#undef TYPED_ARRAY_CONSTRUCTORS_SWITCH
JSFunction::cast(*this).JSFunctionPrint(os);
break;
case INTERNALIZED_STRING_TYPE:
case EXTERNAL_INTERNALIZED_STRING_TYPE:
case ONE_BYTE_INTERNALIZED_STRING_TYPE:

View File

@ -2125,7 +2125,7 @@ Handle<JSObject> Factory::NewJSObjectFromMap(
Handle<AllocationSite> allocation_site) {
// JSFunctions should be allocated using AllocateFunction to be
// properly initialized.
DCHECK(map->instance_type() != JS_FUNCTION_TYPE);
DCHECK(!InstanceTypeChecker::IsJSFunction((map->instance_type())));
// Both types of global objects should be allocated using
// AllocateGlobalObject to be properly initialized.
@ -3510,7 +3510,7 @@ Handle<JSFunction> Factory::JSFunctionBuilder::BuildRaw(Handle<Code> code) {
Handle<Map> map = maybe_map_.ToHandleChecked();
Handle<FeedbackCell> feedback_cell = maybe_feedback_cell_.ToHandleChecked();
DCHECK_EQ(JS_FUNCTION_TYPE, map->instance_type());
DCHECK(InstanceTypeChecker::IsJSFunction(map->instance_type()));
// Allocation.
Handle<JSFunction> function(

View File

@ -2890,8 +2890,7 @@ void AccessorAssembler::LoadIC_NoFeedback(const LoadICParameters* p,
// Special case for Function.prototype load, because it's very common
// for ICs that are only executed once (MyFunc.prototype.foo = ...).
Label not_function_prototype(this, Label::kDeferred);
GotoIfNot(InstanceTypeEqual(instance_type, JS_FUNCTION_TYPE),
&not_function_prototype);
GotoIfNot(IsJSFunctionInstanceType(instance_type), &not_function_prototype);
GotoIfNot(IsPrototypeString(p->name()), &not_function_prototype);
GotoIfPrototypeRequiresRuntimeLookup(CAST(lookup_start_object),

View File

@ -239,7 +239,8 @@ class Genesis {
bool InstallExtrasBindings();
Handle<JSFunction> InstallTypedArray(const char* name,
ElementsKind elements_kind);
ElementsKind elements_kind,
InstanceType type);
void InitializeNormalizedMapCaches();
enum ExtensionTraversalState { UNVISITED, VISITED, INSTALLED };
@ -518,6 +519,24 @@ V8_NOINLINE Handle<JSFunction> InstallFunction(
instance_size, inobject_properties, prototype, call);
}
// This installs an instance type (|constructor_type|) on the constructor map
// which will be used for protector cell checks -- this is separate from |type|
// which is used to set the instance type of the object created by this
// constructor. If protector cell checks are not required, continue to use the
// default JS_FUNCTION_TYPE by directly calling InstallFunction.
V8_NOINLINE Handle<JSFunction> InstallConstructor(
Isolate* isolate, Handle<JSObject> target, const char* name,
InstanceType type, int instance_size, int inobject_properties,
Handle<HeapObject> prototype, Builtins::Name call,
InstanceType constructor_type) {
Handle<JSFunction> function = InstallFunction(
isolate, target, isolate->factory()->InternalizeUtf8String(name), type,
instance_size, inobject_properties, prototype, call);
DCHECK(InstanceTypeChecker::IsJSFunction(constructor_type));
function->map().set_instance_type(constructor_type);
return function;
}
V8_NOINLINE Handle<JSFunction> SimpleCreateFunction(Isolate* isolate,
Handle<String> name,
Builtins::Name call,
@ -1702,9 +1721,10 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
Handle<JSFunction> array_prototype_to_string_fun;
{ // --- A r r a y ---
Handle<JSFunction> array_function = InstallFunction(
Handle<JSFunction> array_function = InstallConstructor(
isolate_, global, "Array", JS_ARRAY_TYPE, JSArray::kHeaderSize, 0,
isolate_->initial_object_prototype(), Builtins::kArrayConstructor);
isolate_->initial_object_prototype(), Builtins::kArrayConstructor,
JS_ARRAY_CONSTRUCTOR_TYPE);
array_function->shared().DontAdaptArguments();
// This seems a bit hackish, but we need to make sure Array.length
@ -2390,10 +2410,10 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
}
{ // -- P r o m i s e
Handle<JSFunction> promise_fun = InstallFunction(
Handle<JSFunction> promise_fun = InstallConstructor(
isolate_, global, "Promise", JS_PROMISE_TYPE,
JSPromise::kSizeWithEmbedderFields, 0, factory->the_hole_value(),
Builtins::kPromiseConstructor);
Builtins::kPromiseConstructor, JS_PROMISE_CONSTRUCTOR_TYPE);
InstallWithIntrinsicDefaultProto(isolate_, promise_fun,
Context::PROMISE_FUNCTION_INDEX);
@ -2453,14 +2473,13 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
{ // -- R e g E x p
// Builtin functions for RegExp.prototype.
Handle<JSFunction> regexp_fun = InstallFunction(
Handle<JSFunction> regexp_fun = InstallConstructor(
isolate_, global, "RegExp", JS_REG_EXP_TYPE,
JSRegExp::kHeaderSize + JSRegExp::kInObjectFieldCount * kTaggedSize,
JSRegExp::kInObjectFieldCount, factory->the_hole_value(),
Builtins::kRegExpConstructor);
Builtins::kRegExpConstructor, JS_REG_EXP_CONSTRUCTOR_TYPE);
InstallWithIntrinsicDefaultProto(isolate_, regexp_fun,
Context::REGEXP_FUNCTION_INDEX);
Handle<SharedFunctionInfo> shared(regexp_fun->shared(), isolate_);
shared->set_internal_formal_parameter_count(2);
shared->set_length(2);
@ -3432,12 +3451,12 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
}
{// -- T y p e d A r r a y s
#define INSTALL_TYPED_ARRAY(Type, type, TYPE, ctype) \
{ \
Handle<JSFunction> fun = \
InstallTypedArray(#Type "Array", TYPE##_ELEMENTS); \
InstallWithIntrinsicDefaultProto(isolate_, fun, \
Context::TYPE##_ARRAY_FUN_INDEX); \
#define INSTALL_TYPED_ARRAY(Type, type, TYPE, ctype) \
{ \
Handle<JSFunction> fun = InstallTypedArray( \
#Type "Array", TYPE##_ELEMENTS, TYPE##_TYPED_ARRAY_CONSTRUCTOR_TYPE); \
InstallWithIntrinsicDefaultProto(isolate_, fun, \
Context::TYPE##_ARRAY_FUN_INDEX); \
}
TYPED_ARRAYS(INSTALL_TYPED_ARRAY)
#undef INSTALL_TYPED_ARRAY
@ -4012,17 +4031,18 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
} // NOLINT(readability/fn_size)
Handle<JSFunction> Genesis::InstallTypedArray(const char* name,
ElementsKind elements_kind) {
ElementsKind elements_kind,
InstanceType type) {
Handle<JSObject> global =
Handle<JSObject>(native_context()->global_object(), isolate());
Handle<JSObject> typed_array_prototype = isolate()->typed_array_prototype();
Handle<JSFunction> typed_array_function = isolate()->typed_array_function();
Handle<JSFunction> result = InstallFunction(
Handle<JSFunction> result = InstallConstructor(
isolate(), global, name, JS_TYPED_ARRAY_TYPE,
JSTypedArray::kSizeWithEmbedderFields, 0, factory()->the_hole_value(),
Builtins::kTypedArrayConstructor);
Builtins::kTypedArrayConstructor, type);
result->initial_map().set_elements_kind(elements_kind);
result->shared().DontAdaptArguments();

View File

@ -929,8 +929,8 @@ TNode<Object> InterpreterAssembler::ConstructWithSpread(
TNode<Uint16T> current_instance_type = LoadInstanceType(current);
GotoIf(InstanceTypeEqual(current_instance_type, JS_BOUND_FUNCTION_TYPE),
&if_boundfunction);
Branch(InstanceTypeEqual(current_instance_type, JS_FUNCTION_TYPE),
&if_function, &mark_megamorphic);
Branch(IsJSFunctionInstanceType(current_instance_type), &if_function,
&mark_megamorphic);
BIND(&if_function);
{

View File

@ -58,3 +58,40 @@ StoreJSTypedArrayExternalPointerPtr(JSTypedArray, RawPtr);
extern class JSDataView extends JSArrayBufferView {
data_pointer: ExternalPointer;
}
@abstract
@doNotGenerateCast extern class TypedArrayConstructor extends JSFunction
generates 'TNode<JSFunction>';
@doNotGenerateCast
extern class Uint8TypedArrayConstructor extends TypedArrayConstructor
generates 'TNode<JSFunction>';
@doNotGenerateCast
extern class Int8TypedArrayConstructor extends TypedArrayConstructor
generates 'TNode<JSFunction>';
@doNotGenerateCast
extern class Uint16TypedArrayConstructor extends TypedArrayConstructor
generates 'TNode<JSFunction>';
@doNotGenerateCast
extern class Int16TypedArrayConstructor extends TypedArrayConstructor
generates 'TNode<JSFunction>';
@doNotGenerateCast
extern class Uint32TypedArrayConstructor extends TypedArrayConstructor
generates 'TNode<JSFunction>';
@doNotGenerateCast
extern class Int32TypedArrayConstructor extends TypedArrayConstructor
generates 'TNode<JSFunction>';
@doNotGenerateCast
extern class Float32TypedArrayConstructor extends TypedArrayConstructor
generates 'TNode<JSFunction>';
@doNotGenerateCast
extern class Float64TypedArrayConstructor extends TypedArrayConstructor
generates 'TNode<JSFunction>';
@doNotGenerateCast
extern class Uint8ClampedTypedArrayConstructor extends TypedArrayConstructor
generates 'TNode<JSFunction>';
@doNotGenerateCast
extern class Biguint64TypedArrayConstructor extends TypedArrayConstructor
generates 'TNode<JSFunction>';
@doNotGenerateCast
extern class Bigint64TypedArrayConstructor extends TypedArrayConstructor
generates 'TNode<JSFunction>';

View File

@ -31,6 +31,10 @@ extern class JSArray extends JSObject {
length: Number;
}
@doNotGenerateCast
extern class JSArrayConstructor extends JSFunction
generates 'TNode<JSFunction>';
macro NewJSArray(implicit context: Context)(
map: Map, elements: FixedArrayBase): JSArray {
return new JSArray{

View File

@ -520,8 +520,15 @@ bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
case JS_DATA_VIEW_TYPE:
case JS_DATE_TYPE:
case JS_FUNCTION_TYPE:
case JS_GENERATOR_OBJECT_TYPE:
case JS_FUNCTION_TYPE:
case JS_PROMISE_CONSTRUCTOR_TYPE:
case JS_REG_EXP_CONSTRUCTOR_TYPE:
case JS_ARRAY_CONSTRUCTOR_TYPE:
#define TYPED_ARRAY_CONSTRUCTORS_SWITCH(Type, type, TYPE, Ctype) \
case TYPE##_TYPED_ARRAY_CONSTRUCTOR_TYPE:
TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTORS_SWITCH)
#undef TYPED_ARRAY_CONSTRUCTORS_SWITCH
case JS_ITERATOR_PROTOTYPE_TYPE:
case JS_MAP_ITERATOR_PROTOTYPE_TYPE:
case JS_OBJECT_PROTOTYPE_TYPE:

View File

@ -2128,7 +2128,8 @@ MaybeHandle<JSObject> JSObject::New(Handle<JSFunction> constructor,
DCHECK(constructor->IsConstructor());
DCHECK(new_target->IsConstructor());
DCHECK(!constructor->has_initial_map() ||
constructor->initial_map().instance_type() != JS_FUNCTION_TYPE);
!InstanceTypeChecker::IsJSFunction(
constructor->initial_map().instance_type()));
Handle<Map> initial_map;
ASSIGN_RETURN_ON_EXCEPTION(
@ -2205,6 +2206,13 @@ int JSObject::GetHeaderSize(InstanceType type,
case JS_BOUND_FUNCTION_TYPE:
return JSBoundFunction::kHeaderSize;
case JS_FUNCTION_TYPE:
case JS_PROMISE_CONSTRUCTOR_TYPE:
case JS_REG_EXP_CONSTRUCTOR_TYPE:
case JS_ARRAY_CONSTRUCTOR_TYPE:
#define TYPED_ARRAY_CONSTRUCTORS_SWITCH(Type, type, TYPE, Ctype) \
case TYPE##_TYPED_ARRAY_CONSTRUCTOR_TYPE:
TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTORS_SWITCH)
#undef TYPED_ARRAY_CONSTRUCTORS_SWITCH
return JSFunction::GetHeaderSize(function_has_prototype_slot);
case JS_PRIMITIVE_WRAPPER_TYPE:
return JSPrimitiveWrapper::kHeaderSize;
@ -2527,6 +2535,13 @@ void JSObject::JSObjectShortPrint(StringStream* accumulator) {
break;
}
case JS_PROMISE_CONSTRUCTOR_TYPE:
case JS_REG_EXP_CONSTRUCTOR_TYPE:
case JS_ARRAY_CONSTRUCTOR_TYPE:
#define TYPED_ARRAY_CONSTRUCTORS_SWITCH(Type, type, TYPE, Ctype) \
case TYPE##_TYPED_ARRAY_CONSTRUCTOR_TYPE:
TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTORS_SWITCH)
#undef TYPED_ARRAY_CONSTRUCTORS_SWITCH
case JS_FUNCTION_TYPE: {
JSFunction function = JSFunction::cast(*this);
std::unique_ptr<char[]> fun_name = function.shared().DebugNameCStr();

View File

@ -35,3 +35,7 @@ extern class JSPromise extends JSObject {
reactions_or_result: Zero|PromiseReaction|JSAny;
flags: SmiTagged<JSPromiseFlags>;
}
@doNotGenerateCast
extern class JSPromiseConstructor extends JSFunction
generates 'TNode<JSFunction>';

View File

@ -48,6 +48,10 @@ extern shape JSRegExpResult extends JSArray {
regexp_last_index: Smi;
}
@doNotGenerateCast
extern class JSRegExpConstructor extends JSFunction
generates 'TNode<JSFunction>';
extern shape JSRegExpResultIndices extends JSArray {
// In-object properties:
// The groups field is externally exposed.

View File

@ -174,26 +174,6 @@ void LookupIterator::ReloadPropertyInformation() {
DCHECK(IsFound() || !holder_->HasFastProperties(isolate_));
}
namespace {
bool IsTypedArrayFunctionInAnyContext(Isolate* isolate, HeapObject object) {
static uint32_t context_slots[] = {
#define TYPED_ARRAY_CONTEXT_SLOTS(Type, type, TYPE, ctype) \
Context::TYPE##_ARRAY_FUN_INDEX,
TYPED_ARRAYS(TYPED_ARRAY_CONTEXT_SLOTS)
#undef TYPED_ARRAY_CONTEXT_SLOTS
};
if (!object.IsJSFunction(isolate)) return false;
return std::any_of(
std::begin(context_slots), std::end(context_slots),
[=](uint32_t slot) { return isolate->IsInAnyContext(object, slot); });
}
} // namespace
// static
void LookupIterator::InternalUpdateProtector(Isolate* isolate,
Handle<Object> receiver_generic,
@ -282,20 +262,18 @@ void LookupIterator::InternalUpdateProtector(Isolate* isolate,
}
// Setting the Symbol.species property of any Array, Promise or TypedArray
// constructor invalidates the @@species protector
if (isolate->IsInAnyContext(*receiver, Context::ARRAY_FUNCTION_INDEX)) {
if (receiver->IsJSArrayConstructor()) {
if (!Protectors::IsArraySpeciesLookupChainIntact(isolate)) return;
isolate->CountUsage(
v8::Isolate::UseCounterFeature::kArraySpeciesModified);
Protectors::InvalidateArraySpeciesLookupChain(isolate);
} else if (isolate->IsInAnyContext(*receiver,
Context::PROMISE_FUNCTION_INDEX)) {
} else if (receiver->IsJSPromiseConstructor()) {
if (!Protectors::IsPromiseSpeciesLookupChainIntact(isolate)) return;
Protectors::InvalidatePromiseSpeciesLookupChain(isolate);
} else if (isolate->IsInAnyContext(*receiver,
Context::REGEXP_FUNCTION_INDEX)) {
} else if (receiver->IsJSRegExpConstructor()) {
if (!Protectors::IsRegExpSpeciesLookupChainIntact(isolate)) return;
Protectors::InvalidateRegExpSpeciesLookupChain(isolate);
} else if (IsTypedArrayFunctionInAnyContext(isolate, *receiver)) {
} else if (receiver->IsTypedArrayConstructor()) {
if (!Protectors::IsTypedArraySpeciesLookupChainIntact(isolate)) return;
Protectors::InvalidateTypedArraySpeciesLookupChain(isolate);
}
@ -337,7 +315,7 @@ void LookupIterator::InternalUpdateProtector(Isolate* isolate,
if (!Protectors::IsPromiseResolveLookupChainIntact(isolate)) return;
// Setting the "resolve" property on any %Promise% intrinsic object
// invalidates the Promise.resolve protector.
if (isolate->IsInAnyContext(*receiver, Context::PROMISE_FUNCTION_INDEX)) {
if (receiver->IsJSPromiseConstructor()) {
Protectors::InvalidatePromiseResolveLookupChain(isolate);
}
} else if (*name == roots.then_string()) {

View File

@ -222,6 +222,13 @@ VisitorId Map::GetVisitorId(Map map) {
return kVisitJSDataView;
case JS_FUNCTION_TYPE:
case JS_PROMISE_CONSTRUCTOR_TYPE:
case JS_REG_EXP_CONSTRUCTOR_TYPE:
case JS_ARRAY_CONSTRUCTOR_TYPE:
#define TYPED_ARRAY_CONSTRUCTORS_SWITCH(Type, type, TYPE, Ctype) \
case TYPE##_TYPED_ARRAY_CONSTRUCTOR_TYPE:
TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTORS_SWITCH)
#undef TYPED_ARRAY_CONSTRUCTORS_SWITCH
return kVisitJSFunction;
case JS_TYPED_ARRAY_TYPE:
@ -1911,7 +1918,7 @@ Handle<Map> Map::CopyAsElementsKind(Isolate* isolate, Handle<Map> map,
Handle<Map> Map::AsLanguageMode(Isolate* isolate, Handle<Map> initial_map,
Handle<SharedFunctionInfo> shared_info) {
DCHECK_EQ(JS_FUNCTION_TYPE, initial_map->instance_type());
DCHECK(InstanceTypeChecker::IsJSFunction(initial_map->instance_type()));
// Initial map for sloppy mode function is stored in the function
// constructor. Initial maps for strict mode are cached as special transitions
// using |strict_function_transition_symbol| as a key.
@ -2482,7 +2489,7 @@ bool Map::EquivalentToForTransition(const Map other) const {
if (bit_field() != other.bit_field()) return false;
if (new_target_is_base() != other.new_target_is_base()) return false;
if (prototype() != other.prototype()) return false;
if (instance_type() == JS_FUNCTION_TYPE) {
if (InstanceTypeChecker::IsJSFunction(instance_type())) {
// JSFunctions require more checks to ensure that sloppy function is
// not equivalent to strict function.
int nof =

View File

@ -265,6 +265,9 @@ class ZoneForwardList;
V(FreeSpaceOrFiller) \
V(FunctionContext) \
V(JSApiObject) \
V(JSPromiseConstructor) \
V(JSArrayConstructor) \
V(JSRegExpConstructor) \
V(JSMapKeyIterator) \
V(JSMapKeyValueIterator) \
V(JSMapValueIterator) \
@ -285,7 +288,19 @@ class ZoneForwardList;
V(JSMapIteratorPrototype) \
V(JSTypedArrayPrototype) \
V(JSSetIteratorPrototype) \
V(JSStringIteratorPrototype)
V(JSStringIteratorPrototype) \
V(TypedArrayConstructor) \
V(Uint8TypedArrayConstructor) \
V(Int8TypedArrayConstructor) \
V(Uint16TypedArrayConstructor) \
V(Int16TypedArrayConstructor) \
V(Uint32TypedArrayConstructor) \
V(Int32TypedArrayConstructor) \
V(Float32TypedArrayConstructor) \
V(Float64TypedArrayConstructor) \
V(Uint8ClampedTypedArrayConstructor) \
V(Biguint64TypedArrayConstructor) \
V(Bigint64TypedArrayConstructor)
#define HEAP_OBJECT_TYPE_LIST(V) \
HEAP_OBJECT_ORDINARY_TYPE_LIST(V) \

View File

@ -1011,6 +1011,13 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
case JS_TYPED_ARRAY_TYPE:
return Op::template apply<JSTypedArray::BodyDescriptor>(p1, p2, p3, p4);
case JS_FUNCTION_TYPE:
case JS_PROMISE_CONSTRUCTOR_TYPE:
case JS_REG_EXP_CONSTRUCTOR_TYPE:
case JS_ARRAY_CONSTRUCTOR_TYPE:
#define TYPED_ARRAY_CONSTRUCTORS_SWITCH(Type, type, TYPE, Ctype) \
case TYPE##_TYPED_ARRAY_CONSTRUCTOR_TYPE:
TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTORS_SWITCH)
#undef TYPED_ARRAY_CONSTRUCTORS_SWITCH
return Op::template apply<JSFunction::BodyDescriptor>(p1, p2, p3, p4);
case WEAK_CELL_TYPE:
return Op::template apply<WeakCell::BodyDescriptor>(p1, p2, p3, p4);

View File

@ -167,51 +167,65 @@ INSTANCE_TYPES = {
1054: "JS_ASYNC_GENERATOR_OBJECT_TYPE",
1055: "JS_ARGUMENTS_OBJECT_TYPE",
1056: "JS_API_OBJECT_TYPE",
1058: "JS_MAP_KEY_ITERATOR_TYPE",
1059: "JS_MAP_KEY_VALUE_ITERATOR_TYPE",
1060: "JS_MAP_VALUE_ITERATOR_TYPE",
1061: "JS_SET_KEY_VALUE_ITERATOR_TYPE",
1062: "JS_SET_VALUE_ITERATOR_TYPE",
1063: "JS_DATA_VIEW_TYPE",
1064: "JS_TYPED_ARRAY_TYPE",
1065: "JS_MAP_TYPE",
1066: "JS_SET_TYPE",
1067: "JS_BOUND_FUNCTION_TYPE",
1068: "JS_FUNCTION_TYPE",
1069: "JS_WEAK_MAP_TYPE",
1070: "JS_WEAK_SET_TYPE",
1071: "JS_ARRAY_TYPE",
1072: "JS_ARRAY_BUFFER_TYPE",
1073: "JS_ARRAY_ITERATOR_TYPE",
1074: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE",
1075: "JS_COLLATOR_TYPE",
1076: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
1077: "JS_DATE_TYPE",
1078: "JS_DATE_TIME_FORMAT_TYPE",
1079: "JS_DISPLAY_NAMES_TYPE",
1080: "JS_ERROR_TYPE",
1081: "JS_FINALIZATION_REGISTRY_TYPE",
1082: "JS_LIST_FORMAT_TYPE",
1083: "JS_LOCALE_TYPE",
1084: "JS_MESSAGE_OBJECT_TYPE",
1085: "JS_NUMBER_FORMAT_TYPE",
1086: "JS_PLURAL_RULES_TYPE",
1087: "JS_PROMISE_TYPE",
1088: "JS_REG_EXP_TYPE",
1089: "JS_REG_EXP_STRING_ITERATOR_TYPE",
1090: "JS_RELATIVE_TIME_FORMAT_TYPE",
1091: "JS_SEGMENT_ITERATOR_TYPE",
1092: "JS_SEGMENTER_TYPE",
1093: "JS_SEGMENTS_TYPE",
1094: "JS_STRING_ITERATOR_TYPE",
1095: "JS_V8_BREAK_ITERATOR_TYPE",
1096: "JS_WEAK_REF_TYPE",
1097: "WASM_EXCEPTION_OBJECT_TYPE",
1098: "WASM_GLOBAL_OBJECT_TYPE",
1099: "WASM_INSTANCE_OBJECT_TYPE",
1100: "WASM_MEMORY_OBJECT_TYPE",
1101: "WASM_MODULE_OBJECT_TYPE",
1102: "WASM_TABLE_OBJECT_TYPE",
1058: "JS_BOUND_FUNCTION_TYPE",
1059: "JS_FUNCTION_TYPE",
1060: "BIGINT64_TYPED_ARRAY_CONSTRUCTOR_TYPE",
1061: "BIGUINT64_TYPED_ARRAY_CONSTRUCTOR_TYPE",
1062: "FLOAT32_TYPED_ARRAY_CONSTRUCTOR_TYPE",
1063: "FLOAT64_TYPED_ARRAY_CONSTRUCTOR_TYPE",
1064: "INT16_TYPED_ARRAY_CONSTRUCTOR_TYPE",
1065: "INT32_TYPED_ARRAY_CONSTRUCTOR_TYPE",
1066: "INT8_TYPED_ARRAY_CONSTRUCTOR_TYPE",
1067: "UINT16_TYPED_ARRAY_CONSTRUCTOR_TYPE",
1068: "UINT32_TYPED_ARRAY_CONSTRUCTOR_TYPE",
1069: "UINT8_CLAMPED_TYPED_ARRAY_CONSTRUCTOR_TYPE",
1070: "UINT8_TYPED_ARRAY_CONSTRUCTOR_TYPE",
1071: "JS_ARRAY_CONSTRUCTOR_TYPE",
1072: "JS_PROMISE_CONSTRUCTOR_TYPE",
1073: "JS_REG_EXP_CONSTRUCTOR_TYPE",
1074: "JS_MAP_KEY_ITERATOR_TYPE",
1075: "JS_MAP_KEY_VALUE_ITERATOR_TYPE",
1076: "JS_MAP_VALUE_ITERATOR_TYPE",
1077: "JS_SET_KEY_VALUE_ITERATOR_TYPE",
1078: "JS_SET_VALUE_ITERATOR_TYPE",
1079: "JS_DATA_VIEW_TYPE",
1080: "JS_TYPED_ARRAY_TYPE",
1081: "JS_MAP_TYPE",
1082: "JS_SET_TYPE",
1083: "JS_WEAK_MAP_TYPE",
1084: "JS_WEAK_SET_TYPE",
1085: "JS_ARRAY_TYPE",
1086: "JS_ARRAY_BUFFER_TYPE",
1087: "JS_ARRAY_ITERATOR_TYPE",
1088: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE",
1089: "JS_COLLATOR_TYPE",
1090: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
1091: "JS_DATE_TYPE",
1092: "JS_DATE_TIME_FORMAT_TYPE",
1093: "JS_DISPLAY_NAMES_TYPE",
1094: "JS_ERROR_TYPE",
1095: "JS_FINALIZATION_REGISTRY_TYPE",
1096: "JS_LIST_FORMAT_TYPE",
1097: "JS_LOCALE_TYPE",
1098: "JS_MESSAGE_OBJECT_TYPE",
1099: "JS_NUMBER_FORMAT_TYPE",
1100: "JS_PLURAL_RULES_TYPE",
1101: "JS_PROMISE_TYPE",
1102: "JS_REG_EXP_TYPE",
1103: "JS_REG_EXP_STRING_ITERATOR_TYPE",
1104: "JS_RELATIVE_TIME_FORMAT_TYPE",
1105: "JS_SEGMENT_ITERATOR_TYPE",
1106: "JS_SEGMENTER_TYPE",
1107: "JS_SEGMENTS_TYPE",
1108: "JS_STRING_ITERATOR_TYPE",
1109: "JS_V8_BREAK_ITERATOR_TYPE",
1110: "JS_WEAK_REF_TYPE",
1111: "WASM_EXCEPTION_OBJECT_TYPE",
1112: "WASM_GLOBAL_OBJECT_TYPE",
1113: "WASM_INSTANCE_OBJECT_TYPE",
1114: "WASM_MEMORY_OBJECT_TYPE",
1115: "WASM_MODULE_OBJECT_TYPE",
1116: "WASM_TABLE_OBJECT_TYPE",
}
# List of known V8 maps.
@ -368,7 +382,7 @@ KNOWN_MAPS = {
("read_only_space", 0x05d05): (78, "StoreHandler2Map"),
("read_only_space", 0x05d2d): (78, "StoreHandler3Map"),
("map_space", 0x02115): (1057, "ExternalMap"),
("map_space", 0x0213d): (1084, "JSMessageObjectMap"),
("map_space", 0x0213d): (1098, "JSMessageObjectMap"),
("map_space", 0x02165): (181, "WasmRttEqrefMap"),
("map_space", 0x0218d): (181, "WasmRttAnyrefMap"),
("map_space", 0x021b5): (181, "WasmRttExternrefMap"),