Deprecate the %IsConstructCall intrinsic completely.
R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/1479233002 Cr-Commit-Position: refs/heads/master@{#32470}
This commit is contained in:
parent
3a4846d2bd
commit
82e6bed4db
@ -178,7 +178,6 @@ int Linkage::FrameStateInputCount(Runtime::FunctionId function) {
|
||||
case Runtime::kInlineDefaultConstructorCallSuper:
|
||||
case Runtime::kInlineGetCallerJSFunction:
|
||||
case Runtime::kInlineGetPrototype:
|
||||
case Runtime::kInlineIsConstructCall:
|
||||
case Runtime::kInlineRegExpExec:
|
||||
case Runtime::kInlineSubString:
|
||||
case Runtime::kInlineToInteger:
|
||||
|
@ -2531,12 +2531,6 @@ LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
|
||||
HIsConstructCallAndBranch* instr) {
|
||||
return new(zone()) LIsConstructCallAndBranch(TempRegister());
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
|
||||
instr->ReplayEnvironment(current_block_->last_environment());
|
||||
return NULL;
|
||||
|
@ -88,7 +88,6 @@ class LCodeGen;
|
||||
V(InstructionGap) \
|
||||
V(Integer32ToDouble) \
|
||||
V(InvokeFunction) \
|
||||
V(IsConstructCallAndBranch) \
|
||||
V(IsStringAndBranch) \
|
||||
V(IsSmiAndBranch) \
|
||||
V(IsUndetectableAndBranch) \
|
||||
@ -2535,19 +2534,6 @@ class LTypeofIsAndBranch final : public LControlInstruction<1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LIsConstructCallAndBranch final : public LControlInstruction<0, 1> {
|
||||
public:
|
||||
explicit LIsConstructCallAndBranch(LOperand* temp) {
|
||||
temps_[0] = temp;
|
||||
}
|
||||
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
|
||||
"is-construct-call-and-branch")
|
||||
};
|
||||
|
||||
|
||||
class LOsrEntry final : public LTemplateInstruction<0, 0, 0> {
|
||||
public:
|
||||
LOsrEntry() {}
|
||||
|
@ -5417,30 +5417,6 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
|
||||
Register temp1 = ToRegister(instr->temp());
|
||||
|
||||
EmitIsConstructCall(temp1, scratch0());
|
||||
EmitBranch(instr, eq);
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) {
|
||||
DCHECK(!temp1.is(temp2));
|
||||
// Get the frame pointer for the calling frame.
|
||||
__ ldr(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Skip the arguments adaptor frame if it exists.
|
||||
__ ldr(temp2, MemOperand(temp1, StandardFrameConstants::kContextOffset));
|
||||
__ cmp(temp2, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset), eq);
|
||||
|
||||
// Check the marker in the calling frame.
|
||||
__ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset));
|
||||
__ cmp(temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
|
||||
if (info()->ShouldEnsureSpaceForLazyDeopt()) {
|
||||
// Ensure that we have enough space after the previous lazy-bailout
|
||||
|
@ -292,10 +292,6 @@ class LCodeGen: public LCodeGenBase {
|
||||
Label* is_not_string,
|
||||
SmiCheck check_needed);
|
||||
|
||||
// Emits optimized code for %_IsConstructCall().
|
||||
// Caller should branch on equal condition.
|
||||
void EmitIsConstructCall(Register temp1, Register temp2);
|
||||
|
||||
// Emits optimized code to deep-copy the contents of statically known
|
||||
// object graphs (e.g. object literal boilerplate).
|
||||
void EmitDeepCopy(Handle<JSObject> object,
|
||||
|
@ -1571,12 +1571,6 @@ LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
|
||||
HIsConstructCallAndBranch* instr) {
|
||||
return new(zone()) LIsConstructCallAndBranch(TempRegister(), TempRegister());
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch(
|
||||
HCompareMinusZeroAndBranch* instr) {
|
||||
LOperand* value = UseRegister(instr->value());
|
||||
|
@ -91,7 +91,6 @@ class LCodeGen;
|
||||
V(InstructionGap) \
|
||||
V(Integer32ToDouble) \
|
||||
V(InvokeFunction) \
|
||||
V(IsConstructCallAndBranch) \
|
||||
V(IsSmiAndBranch) \
|
||||
V(IsStringAndBranch) \
|
||||
V(IsUndetectableAndBranch) \
|
||||
@ -1562,21 +1561,6 @@ class LInvokeFunction final : public LTemplateInstruction<1, 2, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LIsConstructCallAndBranch final : public LControlInstruction<0, 2> {
|
||||
public:
|
||||
LIsConstructCallAndBranch(LOperand* temp1, LOperand* temp2) {
|
||||
temps_[0] = temp1;
|
||||
temps_[1] = temp2;
|
||||
}
|
||||
|
||||
LOperand* temp1() { return temps_[0]; }
|
||||
LOperand* temp2() { return temps_[1]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
|
||||
"is-construct-call-and-branch")
|
||||
};
|
||||
|
||||
|
||||
class LIsStringAndBranch final : public LControlInstruction<1, 1> {
|
||||
public:
|
||||
LIsStringAndBranch(LOperand* value, LOperand* temp) {
|
||||
|
@ -3017,29 +3017,6 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
|
||||
Register temp1 = ToRegister(instr->temp1());
|
||||
Register temp2 = ToRegister(instr->temp2());
|
||||
|
||||
// Get the frame pointer for the calling frame.
|
||||
__ Ldr(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Skip the arguments adaptor frame if it exists.
|
||||
Label check_frame_marker;
|
||||
__ Ldr(temp2, MemOperand(temp1, StandardFrameConstants::kContextOffset));
|
||||
__ Cmp(temp2, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
||||
__ B(ne, &check_frame_marker);
|
||||
__ Ldr(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Check the marker in the calling frame.
|
||||
__ Bind(&check_frame_marker);
|
||||
__ Ldr(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset));
|
||||
|
||||
EmitCompareAndBranch(
|
||||
instr, eq, temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
|
||||
}
|
||||
|
||||
|
||||
Condition LCodeGen::EmitIsString(Register input,
|
||||
Register temp1,
|
||||
Label* is_not_string,
|
||||
|
@ -802,7 +802,6 @@ bool HInstruction::CanDeoptimize() {
|
||||
case HValue::kHasInstanceTypeAndBranch:
|
||||
case HValue::kInnerAllocatedObject:
|
||||
case HValue::kInstanceOf:
|
||||
case HValue::kIsConstructCallAndBranch:
|
||||
case HValue::kHasInPrototypeChainAndBranch:
|
||||
case HValue::kIsSmiAndBranch:
|
||||
case HValue::kIsStringAndBranch:
|
||||
|
@ -104,7 +104,6 @@ class LChunkBuilder;
|
||||
V(InnerAllocatedObject) \
|
||||
V(InstanceOf) \
|
||||
V(InvokeFunction) \
|
||||
V(IsConstructCallAndBranch) \
|
||||
V(HasInPrototypeChainAndBranch) \
|
||||
V(IsStringAndBranch) \
|
||||
V(IsSmiAndBranch) \
|
||||
@ -4541,20 +4540,6 @@ class HStringCompareAndBranch final : public HTemplateControlInstruction<2, 3> {
|
||||
};
|
||||
|
||||
|
||||
class HIsConstructCallAndBranch : public HTemplateControlInstruction<2, 0> {
|
||||
public:
|
||||
DECLARE_INSTRUCTION_FACTORY_P0(HIsConstructCallAndBranch);
|
||||
|
||||
Representation RequiredInputRepresentation(int index) override {
|
||||
return Representation::None();
|
||||
}
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch)
|
||||
private:
|
||||
HIsConstructCallAndBranch() {}
|
||||
};
|
||||
|
||||
|
||||
class HHasInstanceTypeAndBranch final : public HUnaryControlInstruction {
|
||||
public:
|
||||
DECLARE_INSTRUCTION_FACTORY_P2(
|
||||
|
@ -12354,22 +12354,6 @@ void HOptimizedGraphBuilder::GenerateHasFastPackedElements(CallRuntime* call) {
|
||||
}
|
||||
|
||||
|
||||
// Support for construct call checks.
|
||||
void HOptimizedGraphBuilder::GenerateIsConstructCall(CallRuntime* call) {
|
||||
DCHECK(call->arguments()->length() == 0);
|
||||
if (function_state()->outer() != NULL) {
|
||||
// We are generating graph for inlined function.
|
||||
HValue* value = function_state()->inlining_kind() == CONSTRUCT_CALL_RETURN
|
||||
? graph()->GetConstantTrue()
|
||||
: graph()->GetConstantFalse();
|
||||
return ast_context()->ReturnValue(value);
|
||||
} else {
|
||||
return ast_context()->ReturnControl(New<HIsConstructCallAndBranch>(),
|
||||
call->id());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Support for arguments.length and arguments[?].
|
||||
void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) {
|
||||
DCHECK(call->arguments()->length() == 0);
|
||||
|
@ -2202,7 +2202,6 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
||||
F(IsTypedArray) \
|
||||
F(IsRegExp) \
|
||||
F(IsJSProxy) \
|
||||
F(IsConstructCall) \
|
||||
F(Call) \
|
||||
F(ArgumentsLength) \
|
||||
F(Arguments) \
|
||||
|
@ -5297,32 +5297,6 @@ Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
|
||||
Register temp = ToRegister(instr->temp());
|
||||
|
||||
EmitIsConstructCall(temp);
|
||||
EmitBranch(instr, equal);
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::EmitIsConstructCall(Register temp) {
|
||||
// Get the frame pointer for the calling frame.
|
||||
__ mov(temp, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Skip the arguments adaptor frame if it exists.
|
||||
Label check_frame_marker;
|
||||
__ cmp(Operand(temp, StandardFrameConstants::kContextOffset),
|
||||
Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ j(not_equal, &check_frame_marker, Label::kNear);
|
||||
__ mov(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Check the marker in the calling frame.
|
||||
__ bind(&check_frame_marker);
|
||||
__ cmp(Operand(temp, StandardFrameConstants::kMarkerOffset),
|
||||
Immediate(Smi::FromInt(StackFrame::CONSTRUCT)));
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
|
||||
if (info()->ShouldEnsureSpaceForLazyDeopt()) {
|
||||
// Ensure that we have enough space after the previous lazy-bailout
|
||||
|
@ -277,10 +277,6 @@ class LCodeGen: public LCodeGenBase {
|
||||
Label* is_not_string,
|
||||
SmiCheck check_needed);
|
||||
|
||||
// Emits optimized code for %_IsConstructCall().
|
||||
// Caller should branch on equal condition.
|
||||
void EmitIsConstructCall(Register temp);
|
||||
|
||||
// Emits optimized code to deep-copy the contents of statically known
|
||||
// object graphs (e.g. object literal boilerplate).
|
||||
void EmitDeepCopy(Handle<JSObject> object,
|
||||
|
@ -2587,12 +2587,6 @@ LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
|
||||
HIsConstructCallAndBranch* instr) {
|
||||
return new(zone()) LIsConstructCallAndBranch(TempRegister());
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
|
||||
instr->ReplayEnvironment(current_block_->last_environment());
|
||||
return NULL;
|
||||
|
@ -92,7 +92,6 @@ class LCodeGen;
|
||||
V(InstructionGap) \
|
||||
V(Integer32ToDouble) \
|
||||
V(InvokeFunction) \
|
||||
V(IsConstructCallAndBranch) \
|
||||
V(IsStringAndBranch) \
|
||||
V(IsSmiAndBranch) \
|
||||
V(IsUndetectableAndBranch) \
|
||||
@ -1111,19 +1110,6 @@ class LHasCachedArrayIndexAndBranch final : public LControlInstruction<1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LIsConstructCallAndBranch final : public LControlInstruction<0, 1> {
|
||||
public:
|
||||
explicit LIsConstructCallAndBranch(LOperand* temp) {
|
||||
temps_[0] = temp;
|
||||
}
|
||||
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
|
||||
"is-construct-call-and-branch")
|
||||
};
|
||||
|
||||
|
||||
class LClassOfTestAndBranch final : public LControlInstruction<1, 2> {
|
||||
public:
|
||||
LClassOfTestAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) {
|
||||
|
@ -5461,34 +5461,6 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
|
||||
Register temp1 = ToRegister(instr->temp());
|
||||
|
||||
EmitIsConstructCall(temp1, scratch0());
|
||||
|
||||
EmitBranch(instr, eq, temp1,
|
||||
Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) {
|
||||
DCHECK(!temp1.is(temp2));
|
||||
// Get the frame pointer for the calling frame.
|
||||
__ lw(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Skip the arguments adaptor frame if it exists.
|
||||
Label check_frame_marker;
|
||||
__ lw(temp2, MemOperand(temp1, StandardFrameConstants::kContextOffset));
|
||||
__ Branch(&check_frame_marker, ne, temp2,
|
||||
Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ lw(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Check the marker in the calling frame.
|
||||
__ bind(&check_frame_marker);
|
||||
__ lw(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset));
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
|
||||
if (info()->ShouldEnsureSpaceForLazyDeopt()) {
|
||||
// Ensure that we have enough space after the previous lazy-bailout
|
||||
|
@ -310,10 +310,6 @@ class LCodeGen: public LCodeGenBase {
|
||||
Label* is_not_string,
|
||||
SmiCheck check_needed);
|
||||
|
||||
// Emits optimized code for %_IsConstructCall().
|
||||
// Caller should branch on equal condition.
|
||||
void EmitIsConstructCall(Register temp1, Register temp2);
|
||||
|
||||
// Emits optimized code to deep-copy the contents of statically known
|
||||
// object graphs (e.g. object literal boilerplate).
|
||||
void EmitDeepCopy(Handle<JSObject> object,
|
||||
|
@ -2478,12 +2478,6 @@ LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
|
||||
HIsConstructCallAndBranch* instr) {
|
||||
return new(zone()) LIsConstructCallAndBranch(TempRegister());
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
|
||||
instr->ReplayEnvironment(current_block_->last_environment());
|
||||
return NULL;
|
||||
|
@ -88,7 +88,6 @@ class LCodeGen;
|
||||
V(InstructionGap) \
|
||||
V(Integer32ToDouble) \
|
||||
V(InvokeFunction) \
|
||||
V(IsConstructCallAndBranch) \
|
||||
V(IsStringAndBranch) \
|
||||
V(IsSmiAndBranch) \
|
||||
V(IsUndetectableAndBranch) \
|
||||
@ -2494,19 +2493,6 @@ class LTypeofIsAndBranch final : public LControlInstruction<1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LIsConstructCallAndBranch final : public LControlInstruction<0, 1> {
|
||||
public:
|
||||
explicit LIsConstructCallAndBranch(LOperand* temp) {
|
||||
temps_[0] = temp;
|
||||
}
|
||||
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
|
||||
"is-construct-call-and-branch")
|
||||
};
|
||||
|
||||
|
||||
class LOsrEntry final : public LTemplateInstruction<0, 0, 0> {
|
||||
public:
|
||||
LOsrEntry() {}
|
||||
|
@ -5650,34 +5650,6 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
|
||||
Register temp1 = ToRegister(instr->temp());
|
||||
|
||||
EmitIsConstructCall(temp1, scratch0());
|
||||
|
||||
EmitBranch(instr, eq, temp1,
|
||||
Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) {
|
||||
DCHECK(!temp1.is(temp2));
|
||||
// Get the frame pointer for the calling frame.
|
||||
__ ld(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Skip the arguments adaptor frame if it exists.
|
||||
Label check_frame_marker;
|
||||
__ ld(temp2, MemOperand(temp1, StandardFrameConstants::kContextOffset));
|
||||
__ Branch(&check_frame_marker, ne, temp2,
|
||||
Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ ld(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Check the marker in the calling frame.
|
||||
__ bind(&check_frame_marker);
|
||||
__ ld(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset));
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
|
||||
if (info()->ShouldEnsureSpaceForLazyDeopt()) {
|
||||
// Ensure that we have enough space after the previous lazy-bailout
|
||||
|
@ -313,10 +313,6 @@ class LCodeGen: public LCodeGenBase {
|
||||
Label* is_not_string,
|
||||
SmiCheck check_needed);
|
||||
|
||||
// Emits optimized code for %_IsConstructCall().
|
||||
// Caller should branch on equal condition.
|
||||
void EmitIsConstructCall(Register temp1, Register temp2);
|
||||
|
||||
// Emits optimized code to deep-copy the contents of statically known
|
||||
// object graphs (e.g. object literal boilerplate).
|
||||
void EmitDeepCopy(Handle<JSObject> object,
|
||||
|
@ -2483,12 +2483,6 @@ LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
|
||||
HIsConstructCallAndBranch* instr) {
|
||||
return new(zone()) LIsConstructCallAndBranch(TempRegister());
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
|
||||
instr->ReplayEnvironment(current_block_->last_environment());
|
||||
return NULL;
|
||||
|
@ -90,7 +90,6 @@ class LCodeGen;
|
||||
V(InstructionGap) \
|
||||
V(Integer32ToDouble) \
|
||||
V(InvokeFunction) \
|
||||
V(IsConstructCallAndBranch) \
|
||||
V(IsStringAndBranch) \
|
||||
V(IsSmiAndBranch) \
|
||||
V(IsUndetectableAndBranch) \
|
||||
@ -2540,19 +2539,6 @@ class LTypeofIsAndBranch final : public LControlInstruction<1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LIsConstructCallAndBranch final : public LControlInstruction<0, 1> {
|
||||
public:
|
||||
explicit LIsConstructCallAndBranch(LOperand* temp) {
|
||||
temps_[0] = temp;
|
||||
}
|
||||
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
|
||||
"is-construct-call-and-branch")
|
||||
};
|
||||
|
||||
|
||||
class LOsrEntry final : public LTemplateInstruction<0, 0, 0> {
|
||||
public:
|
||||
LOsrEntry() {}
|
||||
|
@ -5701,33 +5701,6 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, Label* false_label,
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
|
||||
Register temp1 = ToRegister(instr->temp());
|
||||
|
||||
EmitIsConstructCall(temp1, scratch0());
|
||||
EmitBranch(instr, eq);
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) {
|
||||
DCHECK(!temp1.is(temp2));
|
||||
// Get the frame pointer for the calling frame.
|
||||
__ LoadP(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Skip the arguments adaptor frame if it exists.
|
||||
Label check_frame_marker;
|
||||
__ LoadP(temp2, MemOperand(temp1, StandardFrameConstants::kContextOffset));
|
||||
__ CmpSmiLiteral(temp2, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0);
|
||||
__ bne(&check_frame_marker);
|
||||
__ LoadP(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Check the marker in the calling frame.
|
||||
__ bind(&check_frame_marker);
|
||||
__ LoadP(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset));
|
||||
__ CmpSmiLiteral(temp1, Smi::FromInt(StackFrame::CONSTRUCT), r0);
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
|
||||
if (info()->ShouldEnsureSpaceForLazyDeopt()) {
|
||||
// Ensure that we have enough space after the previous lazy-bailout
|
||||
|
@ -259,10 +259,6 @@ class LCodeGen : public LCodeGenBase {
|
||||
Condition EmitIsString(Register input, Register temp1, Label* is_not_string,
|
||||
SmiCheck check_needed);
|
||||
|
||||
// Emits optimized code for %_IsConstructCall().
|
||||
// Caller should branch on equal condition.
|
||||
void EmitIsConstructCall(Register temp1, Register temp2);
|
||||
|
||||
// Emits optimized code to deep-copy the contents of statically known
|
||||
// object graphs (e.g. object literal boilerplate).
|
||||
void EmitDeepCopy(Handle<JSObject> object, Register result, Register source,
|
||||
|
@ -2484,12 +2484,6 @@ LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
|
||||
HIsConstructCallAndBranch* instr) {
|
||||
return new (zone()) LIsConstructCallAndBranch(TempRegister());
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
|
||||
instr->ReplayEnvironment(current_block_->last_environment());
|
||||
return NULL;
|
||||
|
@ -88,7 +88,6 @@ class LCodeGen;
|
||||
V(InstructionGap) \
|
||||
V(Integer32ToDouble) \
|
||||
V(InvokeFunction) \
|
||||
V(IsConstructCallAndBranch) \
|
||||
V(IsStringAndBranch) \
|
||||
V(IsSmiAndBranch) \
|
||||
V(IsUndetectableAndBranch) \
|
||||
@ -2427,17 +2426,6 @@ class LTypeofIsAndBranch final : public LControlInstruction<1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LIsConstructCallAndBranch final : public LControlInstruction<0, 1> {
|
||||
public:
|
||||
explicit LIsConstructCallAndBranch(LOperand* temp) { temps_[0] = temp; }
|
||||
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
|
||||
"is-construct-call-and-branch")
|
||||
};
|
||||
|
||||
|
||||
class LOsrEntry final : public LTemplateInstruction<0, 0, 0> {
|
||||
public:
|
||||
LOsrEntry() {}
|
||||
|
@ -5499,32 +5499,6 @@ Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
|
||||
Register temp = ToRegister(instr->temp());
|
||||
|
||||
EmitIsConstructCall(temp);
|
||||
EmitBranch(instr, equal);
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::EmitIsConstructCall(Register temp) {
|
||||
// Get the frame pointer for the calling frame.
|
||||
__ movp(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Skip the arguments adaptor frame if it exists.
|
||||
Label check_frame_marker;
|
||||
__ Cmp(Operand(temp, StandardFrameConstants::kContextOffset),
|
||||
Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
||||
__ j(not_equal, &check_frame_marker, Label::kNear);
|
||||
__ movp(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Check the marker in the calling frame.
|
||||
__ bind(&check_frame_marker);
|
||||
__ Cmp(Operand(temp, StandardFrameConstants::kMarkerOffset),
|
||||
Smi::FromInt(StackFrame::CONSTRUCT));
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
|
||||
if (info()->ShouldEnsureSpaceForLazyDeopt()) {
|
||||
// Ensure that we have enough space after the previous lazy-bailout
|
||||
|
@ -273,10 +273,6 @@ class LCodeGen: public LCodeGenBase {
|
||||
Label* is_not_string,
|
||||
SmiCheck check_needed);
|
||||
|
||||
// Emits optimized code for %_IsConstructCall().
|
||||
// Caller should branch on equal condition.
|
||||
void EmitIsConstructCall(Register temp);
|
||||
|
||||
// Emits code for pushing either a tagged constant, a (non-double)
|
||||
// register, or a stack slot operand.
|
||||
void EmitPushTaggedOperand(LOperand* operand);
|
||||
|
@ -2574,12 +2574,6 @@ LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
|
||||
HIsConstructCallAndBranch* instr) {
|
||||
return new(zone()) LIsConstructCallAndBranch(TempRegister());
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
|
||||
instr->ReplayEnvironment(current_block_->last_environment());
|
||||
return NULL;
|
||||
|
@ -88,7 +88,6 @@ class LCodeGen;
|
||||
V(InstructionGap) \
|
||||
V(Integer32ToDouble) \
|
||||
V(InvokeFunction) \
|
||||
V(IsConstructCallAndBranch) \
|
||||
V(IsStringAndBranch) \
|
||||
V(IsSmiAndBranch) \
|
||||
V(IsUndetectableAndBranch) \
|
||||
@ -2504,20 +2503,6 @@ class LTypeofIsAndBranch final : public LControlInstruction<1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LIsConstructCallAndBranch final : public LControlInstruction<0, 1> {
|
||||
public:
|
||||
explicit LIsConstructCallAndBranch(LOperand* temp) {
|
||||
temps_[0] = temp;
|
||||
}
|
||||
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
|
||||
"is-construct-call-and-branch")
|
||||
DECLARE_HYDROGEN_ACCESSOR(IsConstructCallAndBranch)
|
||||
};
|
||||
|
||||
|
||||
class LOsrEntry final : public LTemplateInstruction<0, 0, 0> {
|
||||
public:
|
||||
LOsrEntry() {}
|
||||
|
@ -5855,32 +5855,6 @@ Condition LCodeGen::EmitTypeofIs(LTypeofIsAndBranch* instr, Register input) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
|
||||
Register temp = ToRegister(instr->temp());
|
||||
|
||||
EmitIsConstructCall(temp);
|
||||
EmitBranch(instr, equal);
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::EmitIsConstructCall(Register temp) {
|
||||
// Get the frame pointer for the calling frame.
|
||||
__ mov(temp, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Skip the arguments adaptor frame if it exists.
|
||||
Label check_frame_marker;
|
||||
__ cmp(Operand(temp, StandardFrameConstants::kContextOffset),
|
||||
Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ j(not_equal, &check_frame_marker, Label::kNear);
|
||||
__ mov(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Check the marker in the calling frame.
|
||||
__ bind(&check_frame_marker);
|
||||
__ cmp(Operand(temp, StandardFrameConstants::kMarkerOffset),
|
||||
Immediate(Smi::FromInt(StackFrame::CONSTRUCT)));
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
|
||||
if (info()->ShouldEnsureSpaceForLazyDeopt()) {
|
||||
// Ensure that we have enough space after the previous lazy-bailout
|
||||
|
@ -306,10 +306,6 @@ class LCodeGen: public LCodeGenBase {
|
||||
Label* is_not_string,
|
||||
SmiCheck check_needed);
|
||||
|
||||
// Emits optimized code for %_IsConstructCall().
|
||||
// Caller should branch on equal condition.
|
||||
void EmitIsConstructCall(Register temp);
|
||||
|
||||
// Emits optimized code to deep-copy the contents of statically known
|
||||
// object graphs (e.g. object literal boilerplate).
|
||||
void EmitDeepCopy(Handle<JSObject> object,
|
||||
|
@ -2591,12 +2591,6 @@ LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
|
||||
HIsConstructCallAndBranch* instr) {
|
||||
return new(zone()) LIsConstructCallAndBranch(TempRegister());
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
|
||||
instr->ReplayEnvironment(current_block_->last_environment());
|
||||
return NULL;
|
||||
|
@ -93,7 +93,6 @@ class LCodeGen;
|
||||
V(InstructionGap) \
|
||||
V(Integer32ToDouble) \
|
||||
V(InvokeFunction) \
|
||||
V(IsConstructCallAndBranch) \
|
||||
V(IsStringAndBranch) \
|
||||
V(IsSmiAndBranch) \
|
||||
V(IsUndetectableAndBranch) \
|
||||
@ -1123,19 +1122,6 @@ class LHasCachedArrayIndexAndBranch final : public LControlInstruction<1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LIsConstructCallAndBranch final : public LControlInstruction<0, 1> {
|
||||
public:
|
||||
explicit LIsConstructCallAndBranch(LOperand* temp) {
|
||||
temps_[0] = temp;
|
||||
}
|
||||
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
|
||||
"is-construct-call-and-branch")
|
||||
};
|
||||
|
||||
|
||||
class LClassOfTestAndBranch final : public LControlInstruction<1, 2> {
|
||||
public:
|
||||
LClassOfTestAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) {
|
||||
|
@ -3275,34 +3275,6 @@ void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
|
||||
DCHECK(expr->arguments()->length() == 0);
|
||||
|
||||
Label materialize_true, materialize_false;
|
||||
Label* if_true = NULL;
|
||||
Label* if_false = NULL;
|
||||
Label* fall_through = NULL;
|
||||
context()->PrepareTest(&materialize_true, &materialize_false,
|
||||
&if_true, &if_false, &fall_through);
|
||||
|
||||
// Get the frame pointer for the calling frame.
|
||||
__ ldr(r2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Skip the arguments adaptor frame if it exists.
|
||||
__ ldr(r1, MemOperand(r2, StandardFrameConstants::kContextOffset));
|
||||
__ cmp(r1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ ldr(r2, MemOperand(r2, StandardFrameConstants::kCallerFPOffset), eq);
|
||||
|
||||
// Check the marker in the calling frame.
|
||||
__ ldr(r1, MemOperand(r2, StandardFrameConstants::kMarkerOffset));
|
||||
__ cmp(r1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
|
||||
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||
Split(eq, if_true, if_false, fall_through);
|
||||
|
||||
context()->Plug(if_true, if_false);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
|
@ -2989,37 +2989,6 @@ void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
|
||||
DCHECK(expr->arguments()->length() == 0);
|
||||
|
||||
Label materialize_true, materialize_false;
|
||||
Label* if_true = NULL;
|
||||
Label* if_false = NULL;
|
||||
Label* fall_through = NULL;
|
||||
context()->PrepareTest(&materialize_true, &materialize_false,
|
||||
&if_true, &if_false, &fall_through);
|
||||
|
||||
// Get the frame pointer for the calling frame.
|
||||
__ Ldr(x2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Skip the arguments adaptor frame if it exists.
|
||||
Label check_frame_marker;
|
||||
__ Ldr(x1, MemOperand(x2, StandardFrameConstants::kContextOffset));
|
||||
__ Cmp(x1, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
||||
__ B(ne, &check_frame_marker);
|
||||
__ Ldr(x2, MemOperand(x2, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Check the marker in the calling frame.
|
||||
__ Bind(&check_frame_marker);
|
||||
__ Ldr(x1, MemOperand(x2, StandardFrameConstants::kMarkerOffset));
|
||||
__ Cmp(x1, Smi::FromInt(StackFrame::CONSTRUCT));
|
||||
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||
Split(eq, if_true, if_false, fall_through);
|
||||
|
||||
context()->Plug(if_true, if_false);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
|
@ -477,7 +477,6 @@ class FullCodeGenerator: public AstVisitor {
|
||||
F(IsTypedArray) \
|
||||
F(IsRegExp) \
|
||||
F(IsJSProxy) \
|
||||
F(IsConstructCall) \
|
||||
F(Call) \
|
||||
F(DefaultConstructorCallSuper) \
|
||||
F(ArgumentsLength) \
|
||||
|
@ -3161,37 +3161,6 @@ void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
|
||||
DCHECK(expr->arguments()->length() == 0);
|
||||
|
||||
Label materialize_true, materialize_false;
|
||||
Label* if_true = NULL;
|
||||
Label* if_false = NULL;
|
||||
Label* fall_through = NULL;
|
||||
context()->PrepareTest(&materialize_true, &materialize_false,
|
||||
&if_true, &if_false, &fall_through);
|
||||
|
||||
// Get the frame pointer for the calling frame.
|
||||
__ mov(eax, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Skip the arguments adaptor frame if it exists.
|
||||
Label check_frame_marker;
|
||||
__ cmp(Operand(eax, StandardFrameConstants::kContextOffset),
|
||||
Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ j(not_equal, &check_frame_marker);
|
||||
__ mov(eax, Operand(eax, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Check the marker in the calling frame.
|
||||
__ bind(&check_frame_marker);
|
||||
__ cmp(Operand(eax, StandardFrameConstants::kMarkerOffset),
|
||||
Immediate(Smi::FromInt(StackFrame::CONSTRUCT)));
|
||||
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||
Split(equal, if_true, if_false, fall_through);
|
||||
|
||||
context()->Plug(if_true, if_false);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
|
@ -3276,37 +3276,6 @@ void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
|
||||
DCHECK(expr->arguments()->length() == 0);
|
||||
|
||||
Label materialize_true, materialize_false;
|
||||
Label* if_true = NULL;
|
||||
Label* if_false = NULL;
|
||||
Label* fall_through = NULL;
|
||||
context()->PrepareTest(&materialize_true, &materialize_false,
|
||||
&if_true, &if_false, &fall_through);
|
||||
|
||||
// Get the frame pointer for the calling frame.
|
||||
__ lw(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Skip the arguments adaptor frame if it exists.
|
||||
Label check_frame_marker;
|
||||
__ lw(a1, MemOperand(a2, StandardFrameConstants::kContextOffset));
|
||||
__ Branch(&check_frame_marker, ne,
|
||||
a1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ lw(a2, MemOperand(a2, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Check the marker in the calling frame.
|
||||
__ bind(&check_frame_marker);
|
||||
__ lw(a1, MemOperand(a2, StandardFrameConstants::kMarkerOffset));
|
||||
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||
Split(eq, a1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)),
|
||||
if_true, if_false, fall_through);
|
||||
|
||||
context()->Plug(if_true, if_false);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
|
@ -3280,37 +3280,6 @@ void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
|
||||
DCHECK(expr->arguments()->length() == 0);
|
||||
|
||||
Label materialize_true, materialize_false;
|
||||
Label* if_true = NULL;
|
||||
Label* if_false = NULL;
|
||||
Label* fall_through = NULL;
|
||||
context()->PrepareTest(&materialize_true, &materialize_false,
|
||||
&if_true, &if_false, &fall_through);
|
||||
|
||||
// Get the frame pointer for the calling frame.
|
||||
__ ld(a2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Skip the arguments adaptor frame if it exists.
|
||||
Label check_frame_marker;
|
||||
__ ld(a1, MemOperand(a2, StandardFrameConstants::kContextOffset));
|
||||
__ Branch(&check_frame_marker, ne,
|
||||
a1, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ ld(a2, MemOperand(a2, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Check the marker in the calling frame.
|
||||
__ bind(&check_frame_marker);
|
||||
__ ld(a1, MemOperand(a2, StandardFrameConstants::kMarkerOffset));
|
||||
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||
Split(eq, a1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)),
|
||||
if_true, if_false, fall_through);
|
||||
|
||||
context()->Plug(if_true, if_false);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
|
@ -3280,38 +3280,6 @@ void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
|
||||
DCHECK(expr->arguments()->length() == 0);
|
||||
|
||||
Label materialize_true, materialize_false;
|
||||
Label* if_true = NULL;
|
||||
Label* if_false = NULL;
|
||||
Label* fall_through = NULL;
|
||||
context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
|
||||
&if_false, &fall_through);
|
||||
|
||||
// Get the frame pointer for the calling frame.
|
||||
__ LoadP(r5, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Skip the arguments adaptor frame if it exists.
|
||||
Label check_frame_marker;
|
||||
__ LoadP(r4, MemOperand(r5, StandardFrameConstants::kContextOffset));
|
||||
__ CmpSmiLiteral(r4, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0);
|
||||
__ bne(&check_frame_marker);
|
||||
__ LoadP(r5, MemOperand(r5, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Check the marker in the calling frame.
|
||||
__ bind(&check_frame_marker);
|
||||
__ LoadP(r4, MemOperand(r5, StandardFrameConstants::kMarkerOffset));
|
||||
STATIC_ASSERT(StackFrame::CONSTRUCT < 0x4000);
|
||||
__ CmpSmiLiteral(r4, Smi::FromInt(StackFrame::CONSTRUCT), r0);
|
||||
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||
Split(eq, if_true, if_false, fall_through);
|
||||
|
||||
context()->Plug(if_true, if_false);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
|
@ -3145,37 +3145,6 @@ void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
|
||||
DCHECK(expr->arguments()->length() == 0);
|
||||
|
||||
Label materialize_true, materialize_false;
|
||||
Label* if_true = NULL;
|
||||
Label* if_false = NULL;
|
||||
Label* fall_through = NULL;
|
||||
context()->PrepareTest(&materialize_true, &materialize_false,
|
||||
&if_true, &if_false, &fall_through);
|
||||
|
||||
// Get the frame pointer for the calling frame.
|
||||
__ movp(rax, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Skip the arguments adaptor frame if it exists.
|
||||
Label check_frame_marker;
|
||||
__ Cmp(Operand(rax, StandardFrameConstants::kContextOffset),
|
||||
Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
||||
__ j(not_equal, &check_frame_marker);
|
||||
__ movp(rax, Operand(rax, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Check the marker in the calling frame.
|
||||
__ bind(&check_frame_marker);
|
||||
__ Cmp(Operand(rax, StandardFrameConstants::kMarkerOffset),
|
||||
Smi::FromInt(StackFrame::CONSTRUCT));
|
||||
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||
Split(equal, if_true, if_false, fall_through);
|
||||
|
||||
context()->Plug(if_true, if_false);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
|
@ -3153,37 +3153,6 @@ void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
|
||||
DCHECK(expr->arguments()->length() == 0);
|
||||
|
||||
Label materialize_true, materialize_false;
|
||||
Label* if_true = NULL;
|
||||
Label* if_false = NULL;
|
||||
Label* fall_through = NULL;
|
||||
context()->PrepareTest(&materialize_true, &materialize_false,
|
||||
&if_true, &if_false, &fall_through);
|
||||
|
||||
// Get the frame pointer for the calling frame.
|
||||
__ mov(eax, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Skip the arguments adaptor frame if it exists.
|
||||
Label check_frame_marker;
|
||||
__ cmp(Operand(eax, StandardFrameConstants::kContextOffset),
|
||||
Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ j(not_equal, &check_frame_marker);
|
||||
__ mov(eax, Operand(eax, StandardFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Check the marker in the calling frame.
|
||||
__ bind(&check_frame_marker);
|
||||
__ cmp(Operand(eax, StandardFrameConstants::kMarkerOffset),
|
||||
Immediate(Smi::FromInt(StackFrame::CONSTRUCT)));
|
||||
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||
Split(equal, if_true, if_false, fall_through);
|
||||
|
||||
context()->Plug(if_true, if_false);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
|
@ -602,17 +602,6 @@ RUNTIME_FUNCTION(Runtime_ConvertReceiver) {
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_IsConstructCall) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 0);
|
||||
JavaScriptFrameIterator it(isolate);
|
||||
List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
|
||||
it.frame()->Summarize(&frames);
|
||||
FrameSummary& summary = frames.last();
|
||||
return isolate->heap()->ToBoolean(summary.is_constructor());
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_IsFunction) {
|
||||
SealHandleScope shs(isolate);
|
||||
DCHECK(args.length() == 1);
|
||||
|
@ -261,7 +261,6 @@ namespace internal {
|
||||
F(TailCall, -1 /* >= 2 */, 1) \
|
||||
F(Apply, 5, 1) \
|
||||
F(ConvertReceiver, 1, 1) \
|
||||
F(IsConstructCall, 0, 1) \
|
||||
F(IsFunction, 1, 1)
|
||||
|
||||
|
||||
|
@ -21,7 +21,7 @@ function checkPrototypeChain(object, constructors) {
|
||||
(function() {
|
||||
class A extends Object {
|
||||
constructor(...args) {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super(...args);
|
||||
this.a = 42;
|
||||
this.d = 4.2;
|
||||
@ -76,7 +76,7 @@ function checkPrototypeChain(object, constructors) {
|
||||
(function() {
|
||||
class A extends Function {
|
||||
constructor(...args) {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super(...args);
|
||||
this.a = 42;
|
||||
this.d = 4.2;
|
||||
@ -106,7 +106,7 @@ function checkPrototypeChain(object, constructors) {
|
||||
(function() {
|
||||
class A extends Boolean {
|
||||
constructor(...args) {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super(...args);
|
||||
this.a = 42;
|
||||
this.d = 4.2;
|
||||
@ -135,7 +135,7 @@ function checkPrototypeChain(object, constructors) {
|
||||
function TestErrorSubclassing(error) {
|
||||
class A extends error {
|
||||
constructor(...args) {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super(...args);
|
||||
this.a = 42;
|
||||
this.d = 4.2;
|
||||
@ -181,7 +181,7 @@ function TestErrorSubclassing(error) {
|
||||
(function() {
|
||||
class A extends Number {
|
||||
constructor(...args) {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super(...args);
|
||||
this.a = 42;
|
||||
this.d = 4.2;
|
||||
@ -210,7 +210,7 @@ function TestErrorSubclassing(error) {
|
||||
(function() {
|
||||
class A extends Date {
|
||||
constructor(...args) {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super(...args);
|
||||
this.a = 42;
|
||||
this.d = 4.2;
|
||||
@ -242,7 +242,7 @@ function TestErrorSubclassing(error) {
|
||||
(function() {
|
||||
class A extends String {
|
||||
constructor(...args) {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super(...args);
|
||||
this.a = 42;
|
||||
this.d = 4.2;
|
||||
@ -272,7 +272,7 @@ function TestErrorSubclassing(error) {
|
||||
(function() {
|
||||
class A extends RegExp {
|
||||
constructor(...args) {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super(...args);
|
||||
this.a = 42;
|
||||
this.d = 4.2;
|
||||
@ -307,7 +307,7 @@ function TestErrorSubclassing(error) {
|
||||
function TestArraySubclassing(array) {
|
||||
class A extends array {
|
||||
constructor(...args) {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super(...args);
|
||||
this.a = 42;
|
||||
this.d = 4.2;
|
||||
@ -357,7 +357,7 @@ function TestMapSetSubclassing(container, is_map) {
|
||||
|
||||
class A extends container {
|
||||
constructor(...args) {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super(...args);
|
||||
this.a = 42;
|
||||
this.d = 4.2;
|
||||
@ -416,7 +416,7 @@ function TestMapSetSubclassing(container, is_map) {
|
||||
(function() {
|
||||
class A extends ArrayBuffer {
|
||||
constructor(...args) {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super(...args);
|
||||
this.a = 42;
|
||||
this.d = 4.2;
|
||||
@ -474,7 +474,7 @@ function TestMapSetSubclassing(container, is_map) {
|
||||
(function() {
|
||||
class A extends DataView {
|
||||
constructor(...args) {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super(...args);
|
||||
this.a = 42;
|
||||
this.d = 4.2;
|
||||
@ -509,7 +509,7 @@ function TestMapSetSubclassing(container, is_map) {
|
||||
var GeneratorFunction = (function*() {}).__proto__.constructor;
|
||||
class A extends GeneratorFunction {
|
||||
constructor(...args) {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super(...args);
|
||||
this.a = 42;
|
||||
this.d = 4.2;
|
||||
@ -549,7 +549,7 @@ function TestMapSetSubclassing(container, is_map) {
|
||||
(function() {
|
||||
class A extends Promise {
|
||||
constructor(...args) {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super(...args);
|
||||
this.a = 42;
|
||||
this.d = 4.2;
|
||||
@ -589,7 +589,7 @@ function TestMapSetSubclassing(container, is_map) {
|
||||
(function() {
|
||||
class A extends Boolean {
|
||||
constructor() {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super(true);
|
||||
this.a00 = 0
|
||||
this.a01 = 0
|
||||
@ -616,7 +616,7 @@ function TestMapSetSubclassing(container, is_map) {
|
||||
|
||||
class B extends A {
|
||||
constructor() {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super();
|
||||
this.b00 = 0
|
||||
this.b01 = 0
|
||||
@ -643,7 +643,7 @@ function TestMapSetSubclassing(container, is_map) {
|
||||
|
||||
class C extends B {
|
||||
constructor() {
|
||||
assertTrue(%IsConstructCall());
|
||||
assertFalse(new.target === undefined);
|
||||
super();
|
||||
this.c00 = 0
|
||||
this.c01 = 0
|
||||
|
@ -123,11 +123,11 @@ invoke(h1, [6, 4]);
|
||||
invoke(h2, [6, 4, 8]);
|
||||
invoke(h3, [8, 6, 4]);
|
||||
|
||||
// Check that %_IsConstructCall returns correct value when inlined
|
||||
// Check that new.target returns correct value when inlined
|
||||
var NON_CONSTRUCT_MARKER = {};
|
||||
var CONSTRUCT_MARKER = {};
|
||||
function baz(x) {
|
||||
return (!%_IsConstructCall()) ? NON_CONSTRUCT_MARKER : CONSTRUCT_MARKER;
|
||||
return (new.target === undefined) ? NON_CONSTRUCT_MARKER : CONSTRUCT_MARKER;
|
||||
}
|
||||
|
||||
function bar(x, y, z) {
|
||||
|
Loading…
Reference in New Issue
Block a user