[runtime] Don't set ConstructedNonConstructable as a construct_stub
Part of ongoing work to remove the construct_stub. For non-constructable functions, don't use the non-constructable stub, instead handle non-constructables explicitly in ConstructFunction. Bug: v8:7503 Change-Id: I24aa7c2d5e934d5e80cd96afaf005342773d57af Reviewed-on: https://chromium-review.googlesource.com/975961 Commit-Queue: Peter Marshall <petermarshall@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#52185}
This commit is contained in:
parent
ed3636e21b
commit
d663614591
@ -1885,6 +1885,20 @@ void MacroAssembler::AssertFixedArray(Register object) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::AssertConstructor(Register object) {
|
||||
if (emit_debug_code()) {
|
||||
STATIC_ASSERT(kSmiTag == 0);
|
||||
tst(object, Operand(kSmiTagMask));
|
||||
Check(ne, AbortReason::kOperandIsASmiAndNotAConstructor);
|
||||
push(object);
|
||||
ldr(object, FieldMemOperand(object, HeapObject::kMapOffset));
|
||||
ldrb(object, FieldMemOperand(object, Map::kBitFieldOffset));
|
||||
tst(object, Operand(Map::IsConstructorBit::kMask));
|
||||
pop(object);
|
||||
Check(ne, AbortReason::kOperandIsNotAConstructor);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::AssertFunction(Register object) {
|
||||
if (emit_debug_code()) {
|
||||
STATIC_ASSERT(kSmiTag == 0);
|
||||
|
@ -837,6 +837,9 @@ class MacroAssembler : public TurboAssembler {
|
||||
// Abort execution if argument is not a FixedArray, enabled via --debug-code.
|
||||
void AssertFixedArray(Register object);
|
||||
|
||||
// Abort execution if argument is not a Constructor, enabled via --debug-code.
|
||||
void AssertConstructor(Register object);
|
||||
|
||||
// Abort execution if argument is not a JSFunction, enabled via --debug-code.
|
||||
void AssertFunction(Register object);
|
||||
|
||||
|
@ -1625,6 +1625,21 @@ void MacroAssembler::AssertFixedArray(Register object) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::AssertConstructor(Register object) {
|
||||
if (emit_debug_code()) {
|
||||
AssertNotSmi(object, AbortReason::kOperandIsASmiAndNotAConstructor);
|
||||
|
||||
UseScratchRegisterScope temps(this);
|
||||
Register temp = temps.AcquireX();
|
||||
|
||||
Ldr(temp, FieldMemOperand(object, HeapObject::kMapOffset));
|
||||
Ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset));
|
||||
Tst(temp, Operand(Map::IsConstructorBit::kMask));
|
||||
|
||||
Check(ne, AbortReason::kOperandIsNotAConstructor);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::AssertFunction(Register object) {
|
||||
if (emit_debug_code()) {
|
||||
AssertNotSmi(object, AbortReason::kOperandIsASmiAndNotAFunction);
|
||||
|
@ -1713,6 +1713,9 @@ class MacroAssembler : public TurboAssembler {
|
||||
// Abort execution if argument is not a FixedArray, enabled via --debug-code.
|
||||
void AssertFixedArray(Register object);
|
||||
|
||||
// Abort execution if argument is not a Constructor, enabled via --debug-code.
|
||||
void AssertConstructor(Register object);
|
||||
|
||||
// Abort execution if argument is not a JSFunction, enabled via --debug-code.
|
||||
void AssertFunction(Register object);
|
||||
|
||||
|
@ -40,11 +40,14 @@ namespace internal {
|
||||
V(kOperandIsASmi, "Operand is a smi") \
|
||||
V(kOperandIsASmiAndNotABoundFunction, \
|
||||
"Operand is a smi and not a bound function") \
|
||||
V(kOperandIsASmiAndNotAConstructor, \
|
||||
"Operand is a smi and not a constructor") \
|
||||
V(kOperandIsASmiAndNotAFixedArray, "Operand is a smi and not a fixed array") \
|
||||
V(kOperandIsASmiAndNotAFunction, "Operand is a smi and not a function") \
|
||||
V(kOperandIsASmiAndNotAGeneratorObject, \
|
||||
"Operand is a smi and not a generator object") \
|
||||
V(kOperandIsNotABoundFunction, "Operand is not a bound function") \
|
||||
V(kOperandIsNotAConstructor, "Operand is not a constructor") \
|
||||
V(kOperandIsNotAFixedArray, "Operand is not a fixed array") \
|
||||
V(kOperandIsNotAFunction, "Operand is not a function") \
|
||||
V(kOperandIsNotAGeneratorObject, "Operand is not a generator object") \
|
||||
|
@ -2233,6 +2233,7 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
|
||||
// -- r1 : the constructor to call (checked to be a JSFunction)
|
||||
// -- r3 : the new target (checked to be a constructor)
|
||||
// -----------------------------------
|
||||
__ AssertConstructor(r1);
|
||||
__ AssertFunction(r1);
|
||||
|
||||
// Calling convention for function specific ConstructStubs require
|
||||
@ -2253,6 +2254,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
|
||||
// -- r1 : the function to call (checked to be a JSBoundFunction)
|
||||
// -- r3 : the new target (checked to be a constructor)
|
||||
// -----------------------------------
|
||||
__ AssertConstructor(r1);
|
||||
__ AssertBoundFunction(r1);
|
||||
|
||||
// Push the [[BoundArguments]] onto the stack.
|
||||
@ -2281,16 +2283,17 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
Label non_constructor, non_proxy;
|
||||
__ JumpIfSmi(r1, &non_constructor);
|
||||
|
||||
// Dispatch based on instance type.
|
||||
__ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructFunction),
|
||||
RelocInfo::CODE_TARGET, eq);
|
||||
|
||||
// Check if target has a [[Construct]] internal method.
|
||||
__ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset));
|
||||
__ ldrb(r2, FieldMemOperand(r4, Map::kBitFieldOffset));
|
||||
__ tst(r2, Operand(Map::IsConstructorBit::kMask));
|
||||
__ b(eq, &non_constructor);
|
||||
|
||||
// Dispatch based on instance type.
|
||||
__ CompareInstanceType(r4, r5, JS_FUNCTION_TYPE);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructFunction),
|
||||
RelocInfo::CODE_TARGET, eq);
|
||||
|
||||
// Only dispatch to bound functions after checking whether they are
|
||||
// constructors.
|
||||
__ cmp(r5, Operand(JS_BOUND_FUNCTION_TYPE));
|
||||
|
@ -2637,6 +2637,7 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
|
||||
// -- x1 : the constructor to call (checked to be a JSFunction)
|
||||
// -- x3 : the new target (checked to be a constructor)
|
||||
// -----------------------------------
|
||||
__ AssertConstructor(x1);
|
||||
__ AssertFunction(x1);
|
||||
|
||||
// Calling convention for function specific ConstructStubs require
|
||||
@ -2658,6 +2659,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
|
||||
// -- x1 : the function to call (checked to be a JSBoundFunction)
|
||||
// -- x3 : the new target (checked to be a constructor)
|
||||
// -----------------------------------
|
||||
__ AssertConstructor(x1);
|
||||
__ AssertBoundFunction(x1);
|
||||
|
||||
// Push the [[BoundArguments]] onto the stack.
|
||||
@ -2691,16 +2693,17 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
Label non_constructor, non_proxy;
|
||||
__ JumpIfSmi(x1, &non_constructor);
|
||||
|
||||
// Dispatch based on instance type.
|
||||
__ CompareObjectType(x1, x4, x5, JS_FUNCTION_TYPE);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructFunction),
|
||||
RelocInfo::CODE_TARGET, eq);
|
||||
|
||||
// Check if target has a [[Construct]] internal method.
|
||||
__ Ldr(x4, FieldMemOperand(x1, HeapObject::kMapOffset));
|
||||
__ Ldrb(x2, FieldMemOperand(x4, Map::kBitFieldOffset));
|
||||
__ TestAndBranchIfAllClear(x2, Map::IsConstructorBit::kMask,
|
||||
&non_constructor);
|
||||
|
||||
// Dispatch based on instance type.
|
||||
__ CompareInstanceType(x4, x5, JS_FUNCTION_TYPE);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructFunction),
|
||||
RelocInfo::CODE_TARGET, eq);
|
||||
|
||||
// Only dispatch to bound functions after checking whether they are
|
||||
// constructors.
|
||||
__ Cmp(x5, JS_BOUND_FUNCTION_TYPE);
|
||||
|
@ -2377,6 +2377,7 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
|
||||
// -- edx : the new target (checked to be a constructor)
|
||||
// -- edi : the constructor to call (checked to be a JSFunction)
|
||||
// -----------------------------------
|
||||
__ AssertConstructor(edi);
|
||||
__ AssertFunction(edi);
|
||||
|
||||
// Calling convention for function specific ConstructStubs require
|
||||
@ -2398,6 +2399,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
|
||||
// -- edx : the new target (checked to be a constructor)
|
||||
// -- edi : the constructor to call (checked to be a JSBoundFunction)
|
||||
// -----------------------------------
|
||||
__ AssertConstructor(edi);
|
||||
__ AssertBoundFunction(edi);
|
||||
|
||||
// Push the [[BoundArguments]] onto the stack.
|
||||
@ -2430,16 +2432,17 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
Label non_constructor, non_proxy;
|
||||
__ JumpIfSmi(edi, &non_constructor, Label::kNear);
|
||||
|
||||
// Dispatch based on instance type.
|
||||
__ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
|
||||
__ j(equal, BUILTIN_CODE(masm->isolate(), ConstructFunction),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
// Check if target has a [[Construct]] internal method.
|
||||
__ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
|
||||
__ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
|
||||
Immediate(Map::IsConstructorBit::kMask));
|
||||
__ j(zero, &non_constructor, Label::kNear);
|
||||
|
||||
// Dispatch based on instance type.
|
||||
__ CmpInstanceType(ecx, JS_FUNCTION_TYPE);
|
||||
__ j(equal, BUILTIN_CODE(masm->isolate(), ConstructFunction),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
// Only dispatch to bound functions after checking whether they are
|
||||
// constructors.
|
||||
__ CmpInstanceType(ecx, JS_BOUND_FUNCTION_TYPE);
|
||||
|
@ -2230,6 +2230,7 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
|
||||
// -- a1 : the constructor to call (checked to be a JSFunction)
|
||||
// -- a3 : the new target (checked to be a constructor)
|
||||
// -----------------------------------
|
||||
__ AssertConstructor(a1);
|
||||
__ AssertFunction(a1);
|
||||
|
||||
// Calling convention for function specific ConstructStubs require
|
||||
@ -2250,6 +2251,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
|
||||
// -- a1 : the function to call (checked to be a JSBoundFunction)
|
||||
// -- a3 : the new target (checked to be a constructor)
|
||||
// -----------------------------------
|
||||
__ AssertConstructor(a1);
|
||||
__ AssertBoundFunction(a1);
|
||||
|
||||
// Load [[BoundArguments]] into a2 and length of that into t0.
|
||||
@ -2344,16 +2346,17 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
Label non_constructor, non_proxy;
|
||||
__ JumpIfSmi(a1, &non_constructor);
|
||||
|
||||
// Dispatch based on instance type.
|
||||
__ GetObjectType(a1, t1, t2);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructFunction),
|
||||
RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE));
|
||||
|
||||
// Check if target has a [[Construct]] internal method.
|
||||
__ lw(t1, FieldMemOperand(a1, HeapObject::kMapOffset));
|
||||
__ lbu(t3, FieldMemOperand(t1, Map::kBitFieldOffset));
|
||||
__ And(t3, t3, Operand(Map::IsConstructorBit::kMask));
|
||||
__ Branch(&non_constructor, eq, t3, Operand(zero_reg));
|
||||
|
||||
// Dispatch based on instance type.
|
||||
__ lhu(t2, FieldMemOperand(t1, Map::kInstanceTypeOffset));
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructFunction),
|
||||
RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE));
|
||||
|
||||
// Only dispatch to bound functions after checking whether they are
|
||||
// constructors.
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructBoundFunction),
|
||||
|
@ -2249,6 +2249,7 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
|
||||
// -- a1 : the constructor to call (checked to be a JSFunction)
|
||||
// -- a3 : the new target (checked to be a constructor)
|
||||
// -----------------------------------
|
||||
__ AssertConstructor(a1);
|
||||
__ AssertFunction(a1);
|
||||
|
||||
// Calling convention for function specific ConstructStubs require
|
||||
@ -2270,6 +2271,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
|
||||
// -- a1 : the function to call (checked to be a JSBoundFunction)
|
||||
// -- a3 : the new target (checked to be a constructor)
|
||||
// -----------------------------------
|
||||
__ AssertConstructor(a1);
|
||||
__ AssertBoundFunction(a1);
|
||||
|
||||
// Load [[BoundArguments]] into a2 and length of that into a4.
|
||||
@ -2362,16 +2364,17 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
Label non_constructor, non_proxy;
|
||||
__ JumpIfSmi(a1, &non_constructor);
|
||||
|
||||
// Dispatch based on instance type.
|
||||
__ GetObjectType(a1, t1, t2);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructFunction),
|
||||
RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE));
|
||||
|
||||
// Check if target has a [[Construct]] internal method.
|
||||
__ ld(t1, FieldMemOperand(a1, HeapObject::kMapOffset));
|
||||
__ Lbu(t3, FieldMemOperand(t1, Map::kBitFieldOffset));
|
||||
__ And(t3, t3, Operand(Map::IsConstructorBit::kMask));
|
||||
__ Branch(&non_constructor, eq, t3, Operand(zero_reg));
|
||||
|
||||
// Dispatch based on instance type.
|
||||
__ Lhu(t2, FieldMemOperand(t1, Map::kInstanceTypeOffset));
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructFunction),
|
||||
RelocInfo::CODE_TARGET, eq, t2, Operand(JS_FUNCTION_TYPE));
|
||||
|
||||
// Only dispatch to bound functions after checking whether they are
|
||||
// constructors.
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructBoundFunction),
|
||||
|
@ -2484,6 +2484,7 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
|
||||
// -- rdx : the new target (checked to be a constructor)
|
||||
// -- rdi : the constructor to call (checked to be a JSFunction)
|
||||
// -----------------------------------
|
||||
__ AssertConstructor(rdi);
|
||||
__ AssertFunction(rdi);
|
||||
|
||||
// Calling convention for function specific ConstructStubs require
|
||||
@ -2505,6 +2506,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
|
||||
// -- rdx : the new target (checked to be a constructor)
|
||||
// -- rdi : the constructor to call (checked to be a JSBoundFunction)
|
||||
// -----------------------------------
|
||||
__ AssertConstructor(rdi);
|
||||
__ AssertBoundFunction(rdi);
|
||||
|
||||
// Push the [[BoundArguments]] onto the stack.
|
||||
@ -2539,16 +2541,17 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
Label non_constructor, non_proxy;
|
||||
__ JumpIfSmi(rdi, &non_constructor, Label::kNear);
|
||||
|
||||
// Dispatch based on instance type.
|
||||
__ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
|
||||
__ j(equal, BUILTIN_CODE(masm->isolate(), ConstructFunction),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
// Check if target has a [[Construct]] internal method.
|
||||
__ movq(rcx, FieldOperand(rdi, HeapObject::kMapOffset));
|
||||
__ testb(FieldOperand(rcx, Map::kBitFieldOffset),
|
||||
Immediate(Map::IsConstructorBit::kMask));
|
||||
__ j(zero, &non_constructor, Label::kNear);
|
||||
|
||||
// Dispatch based on instance type.
|
||||
__ CmpInstanceType(rcx, JS_FUNCTION_TYPE);
|
||||
__ j(equal, BUILTIN_CODE(masm->isolate(), ConstructFunction),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
// Only dispatch to bound functions after checking whether they are
|
||||
// constructors.
|
||||
__ CmpInstanceType(rcx, JS_BOUND_FUNCTION_TYPE);
|
||||
|
@ -270,13 +270,6 @@ bool NeedsImplicitReceiver(Handle<SharedFunctionInfo> shared_info) {
|
||||
}
|
||||
}
|
||||
|
||||
bool IsNonConstructible(Handle<SharedFunctionInfo> shared_info) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
Isolate* const isolate = shared_info->GetIsolate();
|
||||
Code* const construct_stub = shared_info->construct_stub();
|
||||
return construct_stub == *BUILTIN_CODE(isolate, ConstructedNonConstructable);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// Determines whether the call target of the given call {node} is statically
|
||||
@ -402,7 +395,7 @@ Reduction JSInliner::ReduceJSCall(Node* node) {
|
||||
|
||||
// Constructor must be constructable.
|
||||
if (node->opcode() == IrOpcode::kJSConstruct &&
|
||||
IsNonConstructible(shared_info)) {
|
||||
!IsConstructable(shared_info->kind())) {
|
||||
TRACE("Not inlining %s into %s because constructor is not constructable.\n",
|
||||
shared_info->DebugName()->ToCString().get(),
|
||||
info_->shared_info()->DebugName()->ToCString().get());
|
||||
|
@ -1528,7 +1528,12 @@ Reduction JSTypedLowering::ReduceJSConstructForwardVarargs(Node* node) {
|
||||
Node* new_target = NodeProperties::GetValueInput(node, arity + 1);
|
||||
|
||||
// Check if {target} is a JSFunction.
|
||||
if (target_type->Is(Type::Function())) {
|
||||
if (target_type->IsHeapConstant() &&
|
||||
target_type->AsHeapConstant()->Value()->IsJSFunction()) {
|
||||
// Only optimize [[Construct]] here if {function} is a Constructor.
|
||||
Handle<JSFunction> function =
|
||||
Handle<JSFunction>::cast(target_type->AsHeapConstant()->Value());
|
||||
if (!function->IsConstructor()) return NoChange();
|
||||
// Patch {node} to an indirect call via ConstructFunctionForwardVarargs.
|
||||
Callable callable = CodeFactory::ConstructFunctionForwardVarargs(isolate());
|
||||
node->RemoveInput(arity + 1);
|
||||
@ -1568,6 +1573,9 @@ Reduction JSTypedLowering::ReduceJSConstruct(Node* node) {
|
||||
const int builtin_index = shared->construct_stub()->builtin_index();
|
||||
const bool is_builtin = (builtin_index != -1);
|
||||
|
||||
// Only optimize [[Construct]] here if {function} is a Constructor.
|
||||
if (!function->IsConstructor()) return NoChange();
|
||||
|
||||
CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
|
||||
|
||||
if (is_builtin && Builtins::HasCppImplementation(builtin_index) &&
|
||||
@ -1603,23 +1611,6 @@ Reduction JSTypedLowering::ReduceJSConstruct(Node* node) {
|
||||
return Changed(node);
|
||||
}
|
||||
|
||||
// Check if {target} is a JSFunction.
|
||||
if (target_type->Is(Type::Function())) {
|
||||
// Patch {node} to an indirect call via the ConstructFunction builtin.
|
||||
Callable callable = CodeFactory::ConstructFunction(isolate());
|
||||
node->RemoveInput(arity + 1);
|
||||
node->InsertInput(graph()->zone(), 0,
|
||||
jsgraph()->HeapConstant(callable.code()));
|
||||
node->InsertInput(graph()->zone(), 2, new_target);
|
||||
node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(arity));
|
||||
node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
|
||||
NodeProperties::ChangeOp(
|
||||
node, common()->Call(Linkage::GetStubCallDescriptor(
|
||||
isolate(), graph()->zone(), callable.descriptor(), 1 + arity,
|
||||
CallDescriptor::kNeedsFrameState)));
|
||||
return Changed(node);
|
||||
}
|
||||
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
|
@ -2625,11 +2625,7 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
|
||||
share->set_builtin_id(Builtins::kIllegal);
|
||||
}
|
||||
share->set_outer_scope_info(*the_hole_value());
|
||||
DCHECK(!Builtins::IsLazy(Builtins::kConstructedNonConstructable));
|
||||
Handle<Code> construct_stub =
|
||||
is_constructor ? isolate()->builtins()->JSConstructStubGeneric()
|
||||
: BUILTIN_CODE(isolate(), ConstructedNonConstructable);
|
||||
share->SetConstructStub(*construct_stub);
|
||||
share->SetConstructStub(*isolate()->builtins()->JSConstructStubGeneric());
|
||||
share->set_script(*undefined_value(), SKIP_WRITE_BARRIER);
|
||||
share->set_debug_info(Smi::kZero, SKIP_WRITE_BARRIER);
|
||||
share->set_function_identifier(*undefined_value(), SKIP_WRITE_BARRIER);
|
||||
|
@ -488,6 +488,19 @@ void MacroAssembler::AssertFixedArray(Register object) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::AssertConstructor(Register object) {
|
||||
if (emit_debug_code()) {
|
||||
test(object, Immediate(kSmiTagMask));
|
||||
Check(not_equal, AbortReason::kOperandIsASmiAndNotAConstructor);
|
||||
Push(object);
|
||||
mov(object, FieldOperand(object, HeapObject::kMapOffset));
|
||||
test_b(FieldOperand(object, Map::kBitFieldOffset),
|
||||
Immediate(Map::IsConstructorBit::kMask));
|
||||
Pop(object);
|
||||
Check(not_zero, AbortReason::kOperandIsNotAConstructor);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::AssertFunction(Register object) {
|
||||
if (emit_debug_code()) {
|
||||
test(object, Immediate(kSmiTagMask));
|
||||
|
@ -536,6 +536,9 @@ class MacroAssembler : public TurboAssembler {
|
||||
// Abort execution if argument is not a JSFunction, enabled via --debug-code.
|
||||
void AssertFunction(Register object);
|
||||
|
||||
// Abort execution if argument is not a Constructor, enabled via --debug-code.
|
||||
void AssertConstructor(Register object);
|
||||
|
||||
// Abort execution if argument is not a JSBoundFunction,
|
||||
// enabled via --debug-code.
|
||||
void AssertBoundFunction(Register object);
|
||||
|
@ -4809,6 +4809,20 @@ void MacroAssembler::AssertFixedArray(Register object) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::AssertConstructor(Register object) {
|
||||
if (emit_debug_code()) {
|
||||
STATIC_ASSERT(kSmiTag == 0);
|
||||
SmiTst(object, t8);
|
||||
Check(ne, AbortReason::kOperandIsASmiAndNotAConstructor, t8,
|
||||
Operand(zero_reg));
|
||||
|
||||
lw(t8, FieldMemOperand(object, HeapObject::kMapOffset));
|
||||
lbu(t8, FieldMemOperand(t8, Map::kBitFieldOffset));
|
||||
And(t8, t8, Operand(Map::IsConstructorBit::kMask));
|
||||
Check(ne, AbortReason::kOperandIsNotAConstructor, t8, Operand(zero_reg));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::AssertFunction(Register object) {
|
||||
if (emit_debug_code()) {
|
||||
STATIC_ASSERT(kSmiTag == 0);
|
||||
|
@ -1105,6 +1105,9 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
|
||||
// Abort execution if argument is not a FixedArray, enabled via --debug-code.
|
||||
void AssertFixedArray(Register object);
|
||||
|
||||
// Abort execution if argument is not a Constructor, enabled via --debug-code.
|
||||
void AssertConstructor(Register object);
|
||||
|
||||
// Abort execution if argument is not a JSFunction, enabled via --debug-code.
|
||||
void AssertFunction(Register object);
|
||||
|
||||
|
@ -5147,6 +5147,20 @@ void MacroAssembler::AssertFixedArray(Register object) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::AssertConstructor(Register object) {
|
||||
if (emit_debug_code()) {
|
||||
STATIC_ASSERT(kSmiTag == 0);
|
||||
SmiTst(object, t8);
|
||||
Check(ne, AbortReason::kOperandIsASmiAndNotAConstructor, t8,
|
||||
Operand(zero_reg));
|
||||
|
||||
ld(t8, FieldMemOperand(object, HeapObject::kMapOffset));
|
||||
Lbu(t8, FieldMemOperand(t8, Map::kBitFieldOffset));
|
||||
And(t8, t8, Operand(Map::IsConstructorBit::kMask));
|
||||
Check(ne, AbortReason::kOperandIsNotAConstructor, t8, Operand(zero_reg));
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::AssertFunction(Register object) {
|
||||
if (emit_debug_code()) {
|
||||
STATIC_ASSERT(kSmiTag == 0);
|
||||
|
@ -1197,6 +1197,9 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
|
||||
// Abort execution if argument is not a FixedArray, enabled via --debug-code.
|
||||
void AssertFixedArray(Register object);
|
||||
|
||||
// Abort execution if argument is not a Constructor, enabled via --debug-code.
|
||||
void AssertConstructor(Register object);
|
||||
|
||||
// Abort execution if argument is not a JSFunction, enabled via --debug-code.
|
||||
void AssertFunction(Register object);
|
||||
|
||||
|
@ -13807,10 +13807,8 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
|
||||
// shared_info->set_kind(lit->kind());
|
||||
// FunctionKind must have already been set.
|
||||
DCHECK(lit->kind() == shared_info->kind());
|
||||
if (!IsConstructable(lit->kind())) {
|
||||
shared_info->SetConstructStub(
|
||||
*BUILTIN_CODE(shared_info->GetIsolate(), ConstructedNonConstructable));
|
||||
}
|
||||
DCHECK_EQ(*shared_info->GetIsolate()->builtins()->JSConstructStubGeneric(),
|
||||
shared_info->construct_stub());
|
||||
shared_info->set_needs_home_object(lit->scope()->NeedsHomeObject());
|
||||
shared_info->set_function_literal_id(lit->function_literal_id());
|
||||
DCHECK_IMPLIES(lit->requires_instance_fields_initializer(),
|
||||
|
@ -1835,6 +1835,18 @@ void TurboAssembler::AssertZeroExtended(Register int32_register) {
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::AssertConstructor(Register object) {
|
||||
if (emit_debug_code()) {
|
||||
testb(object, Immediate(kSmiTagMask));
|
||||
Check(not_equal, AbortReason::kOperandIsASmiAndNotAConstructor);
|
||||
Push(object);
|
||||
movq(object, FieldOperand(object, HeapObject::kMapOffset));
|
||||
testb(FieldOperand(object, Map::kBitFieldOffset),
|
||||
Immediate(Map::IsConstructorBit::kMask));
|
||||
Pop(object);
|
||||
Check(not_zero, AbortReason::kOperandIsNotAConstructor);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::AssertFunction(Register object) {
|
||||
if (emit_debug_code()) {
|
||||
|
@ -816,6 +816,9 @@ class MacroAssembler : public TurboAssembler {
|
||||
// Abort execution if argument is not a FixedArray, enabled via --debug-code.
|
||||
void AssertFixedArray(Register object);
|
||||
|
||||
// Abort execution if argument is not a Constructor, enabled via --debug-code.
|
||||
void AssertConstructor(Register object);
|
||||
|
||||
// Abort execution if argument is not a JSFunction, enabled via --debug-code.
|
||||
void AssertFunction(Register object);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user