[strong] Refactor ObjectStrength into a replacement for strong boolean args
Boolean "is_strong" parameters have begun to proliferate across areas where strong mode semantics are different. This CL repurposes the existing ObjectStrength enum as a replacement for them. BUG=v8:3956 LOG=N Review URL: https://codereview.chromium.org/1144183004 Cr-Commit-Position: refs/heads/master@{#28839}
This commit is contained in:
parent
ed13ea1e32
commit
dd85444951
@ -94,7 +94,7 @@ void InternalArrayNArgumentsConstructorStub::InitializeDescriptor(
|
|||||||
|
|
||||||
|
|
||||||
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
||||||
Condition cond, bool strong);
|
Condition cond, Strength strength);
|
||||||
static void EmitSmiNonsmiComparison(MacroAssembler* masm,
|
static void EmitSmiNonsmiComparison(MacroAssembler* masm,
|
||||||
Register lhs,
|
Register lhs,
|
||||||
Register rhs,
|
Register rhs,
|
||||||
@ -238,7 +238,7 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
|
|||||||
// Equality is almost reflexive (everything but NaN), so this is a test
|
// Equality is almost reflexive (everything but NaN), so this is a test
|
||||||
// for "identity and not NaN".
|
// for "identity and not NaN".
|
||||||
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
||||||
Condition cond, bool strong) {
|
Condition cond, Strength strength) {
|
||||||
Label not_identical;
|
Label not_identical;
|
||||||
Label heap_number, return_equal;
|
Label heap_number, return_equal;
|
||||||
__ cmp(r0, r1);
|
__ cmp(r0, r1);
|
||||||
@ -255,7 +255,7 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
|||||||
// Call runtime on identical symbols since we need to throw a TypeError.
|
// Call runtime on identical symbols since we need to throw a TypeError.
|
||||||
__ cmp(r4, Operand(SYMBOL_TYPE));
|
__ cmp(r4, Operand(SYMBOL_TYPE));
|
||||||
__ b(eq, slow);
|
__ b(eq, slow);
|
||||||
if (strong) {
|
if (is_strong(strength)) {
|
||||||
// Call the runtime on anything that is converted in the semantics, since
|
// Call the runtime on anything that is converted in the semantics, since
|
||||||
// we need to throw a TypeError. Smis have already been ruled out.
|
// we need to throw a TypeError. Smis have already been ruled out.
|
||||||
__ cmp(r4, Operand(HEAP_NUMBER_TYPE));
|
__ cmp(r4, Operand(HEAP_NUMBER_TYPE));
|
||||||
@ -273,7 +273,7 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
|||||||
// Call runtime on identical symbols since we need to throw a TypeError.
|
// Call runtime on identical symbols since we need to throw a TypeError.
|
||||||
__ cmp(r4, Operand(SYMBOL_TYPE));
|
__ cmp(r4, Operand(SYMBOL_TYPE));
|
||||||
__ b(eq, slow);
|
__ b(eq, slow);
|
||||||
if (strong) {
|
if (is_strong(strength)) {
|
||||||
// Call the runtime on anything that is converted in the semantics,
|
// Call the runtime on anything that is converted in the semantics,
|
||||||
// since we need to throw a TypeError. Smis and heap numbers have
|
// since we need to throw a TypeError. Smis and heap numbers have
|
||||||
// already been ruled out.
|
// already been ruled out.
|
||||||
@ -577,7 +577,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
|
|
||||||
// Handle the case where the objects are identical. Either returns the answer
|
// Handle the case where the objects are identical. Either returns the answer
|
||||||
// or goes to slow. Only falls through if the objects were not identical.
|
// or goes to slow. Only falls through if the objects were not identical.
|
||||||
EmitIdenticalObjectComparison(masm, &slow, cc, strong());
|
EmitIdenticalObjectComparison(masm, &slow, cc, strength());
|
||||||
|
|
||||||
// If either is a Smi (we know that not both are), then they can only
|
// If either is a Smi (we know that not both are), then they can only
|
||||||
// be strictly equal if the other is a HeapNumber.
|
// be strictly equal if the other is a HeapNumber.
|
||||||
@ -679,7 +679,8 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
if (cc == eq) {
|
if (cc == eq) {
|
||||||
native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
|
native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
|
||||||
} else {
|
} else {
|
||||||
native = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
native =
|
||||||
|
is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
||||||
int ncr; // NaN compare result
|
int ncr; // NaN compare result
|
||||||
if (cc == lt || cc == le) {
|
if (cc == lt || cc == le) {
|
||||||
ncr = GREATER;
|
ncr = GREATER;
|
||||||
@ -3582,7 +3583,7 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
|
|||||||
|
|
||||||
__ bind(&unordered);
|
__ bind(&unordered);
|
||||||
__ bind(&generic_stub);
|
__ bind(&generic_stub);
|
||||||
CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
|
CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC,
|
||||||
CompareICState::GENERIC, CompareICState::GENERIC);
|
CompareICState::GENERIC, CompareICState::GENERIC);
|
||||||
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
|
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
|
||||||
|
|
||||||
|
@ -1080,7 +1080,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
|||||||
// Record position before stub call for type feedback.
|
// Record position before stub call for type feedback.
|
||||||
SetSourcePosition(clause->position());
|
SetSourcePosition(clause->position());
|
||||||
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
|
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
|
||||||
language_mode()).code();
|
strength(language_mode())).code();
|
||||||
CallIC(ic, clause->CompareId());
|
CallIC(ic, clause->CompareId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
|
|
||||||
@ -2480,8 +2480,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
|||||||
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
|
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
|
||||||
|
|
||||||
__ bind(&stub_call);
|
__ bind(&stub_call);
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), op, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
|
||||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
__ jmp(&done);
|
__ jmp(&done);
|
||||||
@ -2634,8 +2634,8 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
|
|||||||
|
|
||||||
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
||||||
__ pop(r1);
|
__ pop(r1);
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), op, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
|
||||||
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
||||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
@ -5044,8 +5044,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|||||||
// Record position before stub call.
|
// Record position before stub call.
|
||||||
SetSourcePosition(expr->position());
|
SetSourcePosition(expr->position());
|
||||||
|
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD,
|
||||||
isolate(), Token::ADD, language_mode()).code();
|
strength(language_mode())).code();
|
||||||
CallIC(code, expr->CountBinOpFeedbackId());
|
CallIC(code, expr->CountBinOpFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
@ -5311,8 +5311,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
|||||||
|
|
||||||
// Record position and call the compare IC.
|
// Record position and call the compare IC.
|
||||||
SetSourcePosition(expr->position());
|
SetSourcePosition(expr->position());
|
||||||
Handle<Code> ic =
|
Handle<Code> ic = CodeFactory::CompareIC(
|
||||||
CodeFactory::CompareIC(isolate(), op, language_mode()).code();
|
isolate(), op, strength(language_mode())).code();
|
||||||
CallIC(ic, expr->CompareOperationFeedbackId());
|
CallIC(ic, expr->CompareOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||||
|
@ -1176,7 +1176,7 @@ class LCmpT final : public LTemplateInstruction<1, 3, 0> {
|
|||||||
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
|
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
|
||||||
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
|
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
|
||||||
|
|
||||||
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
Strength strength() { return hydrogen()->strength(); }
|
||||||
|
|
||||||
Token::Value op() const { return hydrogen()->token(); }
|
Token::Value op() const { return hydrogen()->token(); }
|
||||||
};
|
};
|
||||||
@ -1549,7 +1549,7 @@ class LArithmeticT final : public LTemplateInstruction<1, 3, 0> {
|
|||||||
|
|
||||||
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
|
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
|
||||||
|
|
||||||
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
Strength strength() { return hydrogen()->strength(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Token::Value op_;
|
Token::Value op_;
|
||||||
|
@ -2159,8 +2159,8 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
|
|||||||
DCHECK(ToRegister(instr->right()).is(r0));
|
DCHECK(ToRegister(instr->right()).is(r0));
|
||||||
DCHECK(ToRegister(instr->result()).is(r0));
|
DCHECK(ToRegister(instr->result()).is(r0));
|
||||||
|
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), instr->op(), instr->language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), instr->op(), instr->strength()).code();
|
||||||
// Block literal pool emission to ensure nop indicating no inlined smi code
|
// Block literal pool emission to ensure nop indicating no inlined smi code
|
||||||
// is in the correct position.
|
// is in the correct position.
|
||||||
Assembler::BlockConstPoolScope block_const_pool(masm());
|
Assembler::BlockConstPoolScope block_const_pool(masm());
|
||||||
@ -2596,7 +2596,8 @@ void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
|
|||||||
DCHECK(ToRegister(instr->context()).is(cp));
|
DCHECK(ToRegister(instr->context()).is(cp));
|
||||||
Token::Value op = instr->op();
|
Token::Value op = instr->op();
|
||||||
|
|
||||||
Handle<Code> ic = CodeFactory::CompareIC(isolate(), op, SLOPPY).code();
|
Handle<Code> ic =
|
||||||
|
CodeFactory::CompareIC(isolate(), op, Strength::WEAK).code();
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
// This instruction also signals no smi code inlined.
|
// This instruction also signals no smi code inlined.
|
||||||
__ cmp(r0, Operand::Zero());
|
__ cmp(r0, Operand::Zero());
|
||||||
@ -2914,7 +2915,7 @@ void LCodeGen::DoCmpT(LCmpT* instr) {
|
|||||||
Token::Value op = instr->op();
|
Token::Value op = instr->op();
|
||||||
|
|
||||||
Handle<Code> ic =
|
Handle<Code> ic =
|
||||||
CodeFactory::CompareIC(isolate(), op, instr->language_mode()).code();
|
CodeFactory::CompareIC(isolate(), op, instr->strength()).code();
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
// This instruction also signals no smi code inlined.
|
// This instruction also signals no smi code inlined.
|
||||||
__ cmp(r0, Operand::Zero());
|
__ cmp(r0, Operand::Zero());
|
||||||
|
@ -207,7 +207,7 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm, Register left,
|
|||||||
Register right, Register scratch,
|
Register right, Register scratch,
|
||||||
FPRegister double_scratch,
|
FPRegister double_scratch,
|
||||||
Label* slow, Condition cond,
|
Label* slow, Condition cond,
|
||||||
bool strong) {
|
Strength strength) {
|
||||||
DCHECK(!AreAliased(left, right, scratch));
|
DCHECK(!AreAliased(left, right, scratch));
|
||||||
Label not_identical, return_equal, heap_number;
|
Label not_identical, return_equal, heap_number;
|
||||||
Register result = x0;
|
Register result = x0;
|
||||||
@ -227,7 +227,7 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm, Register left,
|
|||||||
// Call runtime on identical symbols since we need to throw a TypeError.
|
// Call runtime on identical symbols since we need to throw a TypeError.
|
||||||
__ Cmp(right_type, SYMBOL_TYPE);
|
__ Cmp(right_type, SYMBOL_TYPE);
|
||||||
__ B(eq, slow);
|
__ B(eq, slow);
|
||||||
if (strong) {
|
if (is_strong(strength)) {
|
||||||
// Call the runtime on anything that is converted in the semantics, since
|
// Call the runtime on anything that is converted in the semantics, since
|
||||||
// we need to throw a TypeError. Smis have already been ruled out.
|
// we need to throw a TypeError. Smis have already been ruled out.
|
||||||
__ Cmp(right_type, Operand(HEAP_NUMBER_TYPE));
|
__ Cmp(right_type, Operand(HEAP_NUMBER_TYPE));
|
||||||
@ -246,7 +246,7 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm, Register left,
|
|||||||
// Call runtime on identical symbols since we need to throw a TypeError.
|
// Call runtime on identical symbols since we need to throw a TypeError.
|
||||||
__ Cmp(right_type, SYMBOL_TYPE);
|
__ Cmp(right_type, SYMBOL_TYPE);
|
||||||
__ B(eq, slow);
|
__ B(eq, slow);
|
||||||
if (strong) {
|
if (is_strong(strength)) {
|
||||||
// Call the runtime on anything that is converted in the semantics,
|
// Call the runtime on anything that is converted in the semantics,
|
||||||
// since we need to throw a TypeError. Smis and heap numbers have
|
// since we need to throw a TypeError. Smis and heap numbers have
|
||||||
// already been ruled out.
|
// already been ruled out.
|
||||||
@ -529,7 +529,8 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
|
|
||||||
// Handle the case where the objects are identical. Either returns the answer
|
// Handle the case where the objects are identical. Either returns the answer
|
||||||
// or goes to slow. Only falls through if the objects were not identical.
|
// or goes to slow. Only falls through if the objects were not identical.
|
||||||
EmitIdenticalObjectComparison(masm, lhs, rhs, x10, d0, &slow, cond, strong());
|
EmitIdenticalObjectComparison(masm, lhs, rhs, x10, d0, &slow, cond,
|
||||||
|
strength());
|
||||||
|
|
||||||
// If either is a smi (we know that at least one is not a smi), then they can
|
// If either is a smi (we know that at least one is not a smi), then they can
|
||||||
// only be strictly equal if the other is a HeapNumber.
|
// only be strictly equal if the other is a HeapNumber.
|
||||||
@ -648,7 +649,8 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
if (cond == eq) {
|
if (cond == eq) {
|
||||||
native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
|
native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
|
||||||
} else {
|
} else {
|
||||||
native = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
native =
|
||||||
|
is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
||||||
int ncr; // NaN compare result
|
int ncr; // NaN compare result
|
||||||
if ((cond == lt) || (cond == le)) {
|
if ((cond == lt) || (cond == le)) {
|
||||||
ncr = GREATER;
|
ncr = GREATER;
|
||||||
@ -3502,7 +3504,7 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
|
|||||||
__ Ret();
|
__ Ret();
|
||||||
|
|
||||||
__ Bind(&unordered);
|
__ Bind(&unordered);
|
||||||
CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
|
CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC,
|
||||||
CompareICState::GENERIC, CompareICState::GENERIC);
|
CompareICState::GENERIC, CompareICState::GENERIC);
|
||||||
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
|
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
|
||||||
|
|
||||||
|
@ -1074,7 +1074,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
|||||||
// Record position before stub call for type feedback.
|
// Record position before stub call for type feedback.
|
||||||
SetSourcePosition(clause->position());
|
SetSourcePosition(clause->position());
|
||||||
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
|
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
|
||||||
language_mode()).code();
|
strength(language_mode())).code();
|
||||||
CallIC(ic, clause->CompareId());
|
CallIC(ic, clause->CompareId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
|
|
||||||
@ -2148,8 +2148,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
|||||||
|
|
||||||
__ Bind(&stub_call);
|
__ Bind(&stub_call);
|
||||||
|
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), op, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
|
||||||
{
|
{
|
||||||
Assembler::BlockPoolsScope scope(masm_);
|
Assembler::BlockPoolsScope scope(masm_);
|
||||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||||
@ -2231,8 +2231,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
|||||||
|
|
||||||
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
||||||
__ Pop(x1);
|
__ Pop(x1);
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), op, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
|
||||||
JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code.
|
JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code.
|
||||||
{
|
{
|
||||||
Assembler::BlockPoolsScope scope(masm_);
|
Assembler::BlockPoolsScope scope(masm_);
|
||||||
@ -4722,8 +4722,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|||||||
|
|
||||||
{
|
{
|
||||||
Assembler::BlockPoolsScope scope(masm_);
|
Assembler::BlockPoolsScope scope(masm_);
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), Token::ADD, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), Token::ADD,
|
||||||
|
strength(language_mode())).code();
|
||||||
CallIC(code, expr->CountBinOpFeedbackId());
|
CallIC(code, expr->CountBinOpFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
}
|
}
|
||||||
@ -4998,8 +4999,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
|||||||
|
|
||||||
// Record position and call the compare IC.
|
// Record position and call the compare IC.
|
||||||
SetSourcePosition(expr->position());
|
SetSourcePosition(expr->position());
|
||||||
Handle<Code> ic =
|
Handle<Code> ic = CodeFactory::CompareIC(
|
||||||
CodeFactory::CompareIC(isolate(), op, language_mode()).code();
|
isolate(), op, strength(language_mode())).code();
|
||||||
CallIC(ic, expr->CompareOperationFeedbackId());
|
CallIC(ic, expr->CompareOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||||
|
@ -719,7 +719,7 @@ class LArithmeticT final : public LTemplateInstruction<1, 3, 0> {
|
|||||||
|
|
||||||
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
|
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
|
||||||
|
|
||||||
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
Strength strength() { return hydrogen()->strength(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Token::Value op_;
|
Token::Value op_;
|
||||||
@ -1161,7 +1161,7 @@ class LCmpT final : public LTemplateInstruction<1, 3, 0> {
|
|||||||
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
|
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
|
||||||
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
|
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
|
||||||
|
|
||||||
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
Strength strength() { return hydrogen()->strength(); }
|
||||||
|
|
||||||
Token::Value op() const { return hydrogen()->token(); }
|
Token::Value op() const { return hydrogen()->token(); }
|
||||||
};
|
};
|
||||||
|
@ -1769,8 +1769,8 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
|
|||||||
DCHECK(ToRegister(instr->right()).is(x0));
|
DCHECK(ToRegister(instr->right()).is(x0));
|
||||||
DCHECK(ToRegister(instr->result()).is(x0));
|
DCHECK(ToRegister(instr->result()).is(x0));
|
||||||
|
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), instr->op(), instr->language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), instr->op(), instr->strength()).code();
|
||||||
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2529,7 +2529,7 @@ void LCodeGen::DoCmpT(LCmpT* instr) {
|
|||||||
DCHECK(ToRegister(instr->left()).Is(x1));
|
DCHECK(ToRegister(instr->left()).Is(x1));
|
||||||
DCHECK(ToRegister(instr->right()).Is(x0));
|
DCHECK(ToRegister(instr->right()).Is(x0));
|
||||||
Handle<Code> ic =
|
Handle<Code> ic =
|
||||||
CodeFactory::CompareIC(isolate(), op, instr->language_mode()).code();
|
CodeFactory::CompareIC(isolate(), op, instr->strength()).code();
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
// Signal that we don't inline smi code before this stub.
|
// Signal that we don't inline smi code before this stub.
|
||||||
InlineSmiCheckInfo::EmitNotInlined(masm());
|
InlineSmiCheckInfo::EmitNotInlined(masm());
|
||||||
@ -5593,7 +5593,8 @@ void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
|
|||||||
DCHECK(ToRegister(instr->context()).is(cp));
|
DCHECK(ToRegister(instr->context()).is(cp));
|
||||||
Token::Value op = instr->op();
|
Token::Value op = instr->op();
|
||||||
|
|
||||||
Handle<Code> ic = CodeFactory::CompareIC(isolate(), op, SLOPPY).code();
|
Handle<Code> ic =
|
||||||
|
CodeFactory::CompareIC(isolate(), op, Strength::WEAK).code();
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
InlineSmiCheckInfo::EmitNotInlined(masm());
|
InlineSmiCheckInfo::EmitNotInlined(masm());
|
||||||
|
|
||||||
|
@ -989,7 +989,7 @@ BUILTIN(ArrayConcat) {
|
|||||||
has_double && IsFastObjectElementsKind(elements_kind)
|
has_double && IsFastObjectElementsKind(elements_kind)
|
||||||
? INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE : DONT_INITIALIZE_ARRAY_ELEMENTS;
|
? INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE : DONT_INITIALIZE_ARRAY_ELEMENTS;
|
||||||
Handle<JSArray> result_array = isolate->factory()->NewJSArray(
|
Handle<JSArray> result_array = isolate->factory()->NewJSArray(
|
||||||
elements_kind, result_len, result_len, WEAK, mode);
|
elements_kind, result_len, result_len, Strength::WEAK, mode);
|
||||||
if (result_len == 0) return *result_array;
|
if (result_len == 0) return *result_array;
|
||||||
|
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
@ -95,17 +95,16 @@ Callable CodeFactory::KeyedStoreICInOptimizedCode(
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
Callable CodeFactory::CompareIC(Isolate* isolate, Token::Value op,
|
Callable CodeFactory::CompareIC(Isolate* isolate, Token::Value op,
|
||||||
LanguageMode language_mode) {
|
Strength strength) {
|
||||||
Handle<Code> code =
|
Handle<Code> code = CompareIC::GetUninitialized(isolate, op, strength);
|
||||||
CompareIC::GetUninitialized(isolate, op, is_strong(language_mode));
|
|
||||||
return Callable(code, CompareDescriptor(isolate));
|
return Callable(code, CompareDescriptor(isolate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op,
|
Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op,
|
||||||
LanguageMode language_mode) {
|
Strength strength) {
|
||||||
BinaryOpICStub stub(isolate, op, language_mode);
|
BinaryOpICStub stub(isolate, op, strength);
|
||||||
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
|
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,10 +49,10 @@ class CodeFactory final {
|
|||||||
InlineCacheState initialization_state);
|
InlineCacheState initialization_state);
|
||||||
|
|
||||||
static Callable CompareIC(Isolate* isolate, Token::Value op,
|
static Callable CompareIC(Isolate* isolate, Token::Value op,
|
||||||
LanguageMode language_mode);
|
Strength strength);
|
||||||
|
|
||||||
static Callable BinaryOpIC(Isolate* isolate, Token::Value op,
|
static Callable BinaryOpIC(Isolate* isolate, Token::Value op,
|
||||||
LanguageMode language_mode);
|
Strength strength);
|
||||||
|
|
||||||
// Code stubs. Add methods here as needed to reduce dependency on
|
// Code stubs. Add methods here as needed to reduce dependency on
|
||||||
// code-stubs.h.
|
// code-stubs.h.
|
||||||
|
@ -1361,19 +1361,16 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
|
|||||||
if_leftisstring.If<HIsStringAndBranch>(left);
|
if_leftisstring.If<HIsStringAndBranch>(left);
|
||||||
if_leftisstring.Then();
|
if_leftisstring.Then();
|
||||||
{
|
{
|
||||||
Push(BuildBinaryOperation(
|
Push(BuildBinaryOperation(state.op(), left, right, Type::String(zone()),
|
||||||
state.op(), left, right,
|
right_type, result_type,
|
||||||
Type::String(zone()), right_type,
|
state.fixed_right_arg(), allocation_mode,
|
||||||
result_type, state.fixed_right_arg(),
|
state.strength()));
|
||||||
allocation_mode, state.language_mode()));
|
|
||||||
}
|
}
|
||||||
if_leftisstring.Else();
|
if_leftisstring.Else();
|
||||||
{
|
{
|
||||||
Push(BuildBinaryOperation(
|
Push(BuildBinaryOperation(
|
||||||
state.op(), left, right,
|
state.op(), left, right, left_type, right_type, result_type,
|
||||||
left_type, right_type, result_type,
|
state.fixed_right_arg(), allocation_mode, state.strength()));
|
||||||
state.fixed_right_arg(), allocation_mode,
|
|
||||||
state.language_mode()));
|
|
||||||
}
|
}
|
||||||
if_leftisstring.End();
|
if_leftisstring.End();
|
||||||
result = Pop();
|
result = Pop();
|
||||||
@ -1382,28 +1379,24 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
|
|||||||
if_rightisstring.If<HIsStringAndBranch>(right);
|
if_rightisstring.If<HIsStringAndBranch>(right);
|
||||||
if_rightisstring.Then();
|
if_rightisstring.Then();
|
||||||
{
|
{
|
||||||
Push(BuildBinaryOperation(
|
Push(BuildBinaryOperation(state.op(), left, right, left_type,
|
||||||
state.op(), left, right,
|
Type::String(zone()), result_type,
|
||||||
left_type, Type::String(zone()),
|
state.fixed_right_arg(), allocation_mode,
|
||||||
result_type, state.fixed_right_arg(),
|
state.strength()));
|
||||||
allocation_mode, state.language_mode()));
|
|
||||||
}
|
}
|
||||||
if_rightisstring.Else();
|
if_rightisstring.Else();
|
||||||
{
|
{
|
||||||
Push(BuildBinaryOperation(
|
Push(BuildBinaryOperation(
|
||||||
state.op(), left, right,
|
state.op(), left, right, left_type, right_type, result_type,
|
||||||
left_type, right_type, result_type,
|
state.fixed_right_arg(), allocation_mode, state.strength()));
|
||||||
state.fixed_right_arg(), allocation_mode,
|
|
||||||
state.language_mode()));
|
|
||||||
}
|
}
|
||||||
if_rightisstring.End();
|
if_rightisstring.End();
|
||||||
result = Pop();
|
result = Pop();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result = BuildBinaryOperation(
|
result = BuildBinaryOperation(
|
||||||
state.op(), left, right,
|
state.op(), left, right, left_type, right_type, result_type,
|
||||||
left_type, right_type, result_type,
|
state.fixed_right_arg(), allocation_mode, state.strength());
|
||||||
state.fixed_right_arg(), allocation_mode, state.language_mode());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we encounter a generic argument, the number conversion is
|
// If we encounter a generic argument, the number conversion is
|
||||||
@ -1435,10 +1428,9 @@ HValue* CodeStubGraphBuilder<BinaryOpWithAllocationSiteStub>::BuildCodeStub() {
|
|||||||
Type* result_type = state.GetResultType(zone());
|
Type* result_type = state.GetResultType(zone());
|
||||||
HAllocationMode allocation_mode(allocation_site);
|
HAllocationMode allocation_mode(allocation_site);
|
||||||
|
|
||||||
return BuildBinaryOperation(state.op(), left, right,
|
return BuildBinaryOperation(state.op(), left, right, left_type, right_type,
|
||||||
left_type, right_type, result_type,
|
result_type, state.fixed_right_arg(),
|
||||||
state.fixed_right_arg(), allocation_mode,
|
allocation_mode, state.strength());
|
||||||
state.language_mode());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -269,8 +269,7 @@ MaybeHandle<Code> CodeStub::GetCode(Isolate* isolate, uint32_t key) {
|
|||||||
void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate) {
|
void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate) {
|
||||||
// Generate the uninitialized versions of the stub.
|
// Generate the uninitialized versions of the stub.
|
||||||
for (int op = Token::BIT_OR; op <= Token::MOD; ++op) {
|
for (int op = Token::BIT_OR; op <= Token::MOD; ++op) {
|
||||||
BinaryOpICStub stub(isolate, static_cast<Token::Value>(op),
|
BinaryOpICStub stub(isolate, static_cast<Token::Value>(op), Strength::WEAK);
|
||||||
LanguageMode::SLOPPY);
|
|
||||||
stub.GetCode();
|
stub.GetCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1421,9 +1421,9 @@ class CallApiGetterStub : public PlatformCodeStub {
|
|||||||
|
|
||||||
class BinaryOpICStub : public HydrogenCodeStub {
|
class BinaryOpICStub : public HydrogenCodeStub {
|
||||||
public:
|
public:
|
||||||
BinaryOpICStub(Isolate* isolate, Token::Value op, LanguageMode language_mode)
|
BinaryOpICStub(Isolate* isolate, Token::Value op, Strength strength)
|
||||||
: HydrogenCodeStub(isolate, UNINITIALIZED) {
|
: HydrogenCodeStub(isolate, UNINITIALIZED) {
|
||||||
BinaryOpICState state(isolate, op, language_mode);
|
BinaryOpICState state(isolate, op, strength);
|
||||||
set_sub_minor_key(state.GetExtraICState());
|
set_sub_minor_key(state.GetExtraICState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1505,8 +1505,8 @@ class BinaryOpICWithAllocationSiteStub final : public PlatformCodeStub {
|
|||||||
class BinaryOpWithAllocationSiteStub final : public BinaryOpICStub {
|
class BinaryOpWithAllocationSiteStub final : public BinaryOpICStub {
|
||||||
public:
|
public:
|
||||||
BinaryOpWithAllocationSiteStub(Isolate* isolate, Token::Value op,
|
BinaryOpWithAllocationSiteStub(Isolate* isolate, Token::Value op,
|
||||||
LanguageMode language_mode)
|
Strength strength)
|
||||||
: BinaryOpICStub(isolate, op, language_mode) {}
|
: BinaryOpICStub(isolate, op, strength) {}
|
||||||
|
|
||||||
BinaryOpWithAllocationSiteStub(Isolate* isolate, const BinaryOpICState& state)
|
BinaryOpWithAllocationSiteStub(Isolate* isolate, const BinaryOpICState& state)
|
||||||
: BinaryOpICStub(isolate, state) {}
|
: BinaryOpICStub(isolate, state) {}
|
||||||
@ -1557,12 +1557,13 @@ class StringAddStub final : public HydrogenCodeStub {
|
|||||||
|
|
||||||
class CompareICStub : public PlatformCodeStub {
|
class CompareICStub : public PlatformCodeStub {
|
||||||
public:
|
public:
|
||||||
CompareICStub(Isolate* isolate, Token::Value op, bool strong,
|
CompareICStub(Isolate* isolate, Token::Value op, Strength strength,
|
||||||
CompareICState::State left, CompareICState::State right,
|
CompareICState::State left, CompareICState::State right,
|
||||||
CompareICState::State state)
|
CompareICState::State state)
|
||||||
: PlatformCodeStub(isolate) {
|
: PlatformCodeStub(isolate) {
|
||||||
DCHECK(Token::IsCompareOp(op));
|
DCHECK(Token::IsCompareOp(op));
|
||||||
minor_key_ = OpBits::encode(op - Token::EQ) | StrongBits::encode(strong) |
|
minor_key_ = OpBits::encode(op - Token::EQ) |
|
||||||
|
StrengthBits::encode(is_strong(strength)) |
|
||||||
LeftStateBits::encode(left) | RightStateBits::encode(right) |
|
LeftStateBits::encode(left) | RightStateBits::encode(right) |
|
||||||
StateBits::encode(state);
|
StateBits::encode(state);
|
||||||
}
|
}
|
||||||
@ -1575,7 +1576,9 @@ class CompareICStub : public PlatformCodeStub {
|
|||||||
return static_cast<Token::Value>(Token::EQ + OpBits::decode(minor_key_));
|
return static_cast<Token::Value>(Token::EQ + OpBits::decode(minor_key_));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool strong() const { return StrongBits::decode(minor_key_); }
|
Strength strength() const {
|
||||||
|
return StrengthBits::decode(minor_key_) ? Strength::STRONG : Strength::WEAK;
|
||||||
|
}
|
||||||
|
|
||||||
CompareICState::State left() const {
|
CompareICState::State left() const {
|
||||||
return LeftStateBits::decode(minor_key_);
|
return LeftStateBits::decode(minor_key_);
|
||||||
@ -1608,7 +1611,7 @@ class CompareICStub : public PlatformCodeStub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class OpBits : public BitField<int, 0, 3> {};
|
class OpBits : public BitField<int, 0, 3> {};
|
||||||
class StrongBits : public BitField<bool, 3, 1> {};
|
class StrengthBits : public BitField<bool, 3, 1> {};
|
||||||
class LeftStateBits : public BitField<CompareICState::State, 4, 4> {};
|
class LeftStateBits : public BitField<CompareICState::State, 4, 4> {};
|
||||||
class RightStateBits : public BitField<CompareICState::State, 8, 4> {};
|
class RightStateBits : public BitField<CompareICState::State, 8, 4> {};
|
||||||
class StateBits : public BitField<CompareICState::State, 12, 4> {};
|
class StateBits : public BitField<CompareICState::State, 12, 4> {};
|
||||||
|
@ -65,13 +65,13 @@ Reduction JSGenericLowering::Reduce(Node* node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define REPLACE_BINARY_OP_IC_CALL(op, token) \
|
#define REPLACE_BINARY_OP_IC_CALL(op, token) \
|
||||||
void JSGenericLowering::Lower##op(Node* node) { \
|
void JSGenericLowering::Lower##op(Node* node) { \
|
||||||
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); \
|
CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); \
|
||||||
ReplaceWithStubCall( \
|
ReplaceWithStubCall(node, CodeFactory::BinaryOpIC( \
|
||||||
node, CodeFactory::BinaryOpIC(isolate(), token, \
|
isolate(), token, \
|
||||||
OpParameter<LanguageMode>(node)), \
|
strength(OpParameter<LanguageMode>(node))), \
|
||||||
CallDescriptor::kPatchableCallSiteWithNop | flags); \
|
CallDescriptor::kPatchableCallSiteWithNop | flags); \
|
||||||
}
|
}
|
||||||
REPLACE_BINARY_OP_IC_CALL(JSBitwiseOr, Token::BIT_OR)
|
REPLACE_BINARY_OP_IC_CALL(JSBitwiseOr, Token::BIT_OR)
|
||||||
REPLACE_BINARY_OP_IC_CALL(JSBitwiseXor, Token::BIT_XOR)
|
REPLACE_BINARY_OP_IC_CALL(JSBitwiseXor, Token::BIT_XOR)
|
||||||
@ -131,8 +131,8 @@ static CallDescriptor::Flags FlagsForNode(Node* node) {
|
|||||||
|
|
||||||
|
|
||||||
void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token) {
|
void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token) {
|
||||||
Callable callable =
|
Callable callable = CodeFactory::CompareIC(
|
||||||
CodeFactory::CompareIC(isolate(), token, OpParameter<LanguageMode>(node));
|
isolate(), token, strength(OpParameter<LanguageMode>(node)));
|
||||||
|
|
||||||
// Create a new call node asking a CompareIC for help.
|
// Create a new call node asking a CompareIC for help.
|
||||||
NodeVector inputs(zone());
|
NodeVector inputs(zone());
|
||||||
|
@ -1609,11 +1609,11 @@ Handle<JSObject> Factory::NewJSObjectFromMap(
|
|||||||
|
|
||||||
|
|
||||||
Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind,
|
Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind,
|
||||||
ObjectStrength strength,
|
Strength strength,
|
||||||
PretenureFlag pretenure) {
|
PretenureFlag pretenure) {
|
||||||
Map* map = isolate()->get_initial_js_array_map(elements_kind, strength);
|
Map* map = isolate()->get_initial_js_array_map(elements_kind, strength);
|
||||||
if (map == nullptr) {
|
if (map == nullptr) {
|
||||||
DCHECK(strength == WEAK);
|
DCHECK(strength == Strength::WEAK);
|
||||||
Context* native_context = isolate()->context()->native_context();
|
Context* native_context = isolate()->context()->native_context();
|
||||||
JSFunction* array_function = native_context->array_function();
|
JSFunction* array_function = native_context->array_function();
|
||||||
map = array_function->initial_map();
|
map = array_function->initial_map();
|
||||||
@ -1623,7 +1623,7 @@ Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind,
|
|||||||
|
|
||||||
|
|
||||||
Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind, int length,
|
Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind, int length,
|
||||||
int capacity, ObjectStrength strength,
|
int capacity, Strength strength,
|
||||||
ArrayStorageAllocationMode mode,
|
ArrayStorageAllocationMode mode,
|
||||||
PretenureFlag pretenure) {
|
PretenureFlag pretenure) {
|
||||||
Handle<JSArray> array = NewJSArray(elements_kind, strength, pretenure);
|
Handle<JSArray> array = NewJSArray(elements_kind, strength, pretenure);
|
||||||
@ -1634,8 +1634,7 @@ Handle<JSArray> Factory::NewJSArray(ElementsKind elements_kind, int length,
|
|||||||
|
|
||||||
Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements,
|
Handle<JSArray> Factory::NewJSArrayWithElements(Handle<FixedArrayBase> elements,
|
||||||
ElementsKind elements_kind,
|
ElementsKind elements_kind,
|
||||||
int length,
|
int length, Strength strength,
|
||||||
ObjectStrength strength,
|
|
||||||
PretenureFlag pretenure) {
|
PretenureFlag pretenure) {
|
||||||
DCHECK(length <= elements->length());
|
DCHECK(length <= elements->length());
|
||||||
Handle<JSArray> array = NewJSArray(elements_kind, strength, pretenure);
|
Handle<JSArray> array = NewJSArray(elements_kind, strength, pretenure);
|
||||||
|
@ -390,23 +390,21 @@ class Factory final {
|
|||||||
// JS arrays are pretenured when allocated by the parser.
|
// JS arrays are pretenured when allocated by the parser.
|
||||||
|
|
||||||
// Create a JSArray with no elements.
|
// Create a JSArray with no elements.
|
||||||
Handle<JSArray> NewJSArray(
|
Handle<JSArray> NewJSArray(ElementsKind elements_kind,
|
||||||
ElementsKind elements_kind,
|
Strength strength = Strength::WEAK,
|
||||||
ObjectStrength strength = WEAK,
|
PretenureFlag pretenure = NOT_TENURED);
|
||||||
PretenureFlag pretenure = NOT_TENURED);
|
|
||||||
|
|
||||||
// Create a JSArray with a specified length and elements initialized
|
// Create a JSArray with a specified length and elements initialized
|
||||||
// according to the specified mode.
|
// according to the specified mode.
|
||||||
Handle<JSArray> NewJSArray(
|
Handle<JSArray> NewJSArray(
|
||||||
ElementsKind elements_kind, int length, int capacity,
|
ElementsKind elements_kind, int length, int capacity,
|
||||||
ObjectStrength strength = WEAK,
|
Strength strength = Strength::WEAK,
|
||||||
ArrayStorageAllocationMode mode = DONT_INITIALIZE_ARRAY_ELEMENTS,
|
ArrayStorageAllocationMode mode = DONT_INITIALIZE_ARRAY_ELEMENTS,
|
||||||
PretenureFlag pretenure = NOT_TENURED);
|
PretenureFlag pretenure = NOT_TENURED);
|
||||||
|
|
||||||
Handle<JSArray> NewJSArray(
|
Handle<JSArray> NewJSArray(
|
||||||
int capacity,
|
int capacity, ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
|
||||||
ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
|
Strength strength = Strength::WEAK,
|
||||||
ObjectStrength strength = WEAK,
|
|
||||||
PretenureFlag pretenure = NOT_TENURED) {
|
PretenureFlag pretenure = NOT_TENURED) {
|
||||||
if (capacity != 0) {
|
if (capacity != 0) {
|
||||||
elements_kind = GetHoleyElementsKind(elements_kind);
|
elements_kind = GetHoleyElementsKind(elements_kind);
|
||||||
@ -416,17 +414,15 @@ class Factory final {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a JSArray with the given elements.
|
// Create a JSArray with the given elements.
|
||||||
Handle<JSArray> NewJSArrayWithElements(
|
Handle<JSArray> NewJSArrayWithElements(Handle<FixedArrayBase> elements,
|
||||||
Handle<FixedArrayBase> elements,
|
ElementsKind elements_kind, int length,
|
||||||
ElementsKind elements_kind,
|
Strength strength = Strength::WEAK,
|
||||||
int length,
|
PretenureFlag pretenure = NOT_TENURED);
|
||||||
ObjectStrength strength = WEAK,
|
|
||||||
PretenureFlag pretenure = NOT_TENURED);
|
|
||||||
|
|
||||||
Handle<JSArray> NewJSArrayWithElements(
|
Handle<JSArray> NewJSArrayWithElements(
|
||||||
Handle<FixedArrayBase> elements,
|
Handle<FixedArrayBase> elements,
|
||||||
ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
|
ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND,
|
||||||
ObjectStrength strength = WEAK,
|
Strength strength = Strength::WEAK,
|
||||||
PretenureFlag pretenure = NOT_TENURED) {
|
PretenureFlag pretenure = NOT_TENURED) {
|
||||||
return NewJSArrayWithElements(elements, elements_kind, elements->length(),
|
return NewJSArrayWithElements(elements, elements_kind, elements->length(),
|
||||||
strength, pretenure);
|
strength, pretenure);
|
||||||
|
@ -233,11 +233,6 @@ template <typename T, class P = FreeStoreAllocationPolicy> class List;
|
|||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// Declarations for use in both the preparser and the rest of V8.
|
// Declarations for use in both the preparser and the rest of V8.
|
||||||
|
|
||||||
enum ObjectStrength {
|
|
||||||
WEAK,
|
|
||||||
FIRM // strong object
|
|
||||||
};
|
|
||||||
|
|
||||||
// The Strict Mode (ECMA-262 5th edition, 4.2.2).
|
// The Strict Mode (ECMA-262 5th edition, 4.2.2).
|
||||||
|
|
||||||
enum LanguageMode {
|
enum LanguageMode {
|
||||||
@ -297,8 +292,32 @@ inline LanguageMode construct_language_mode(bool strict_bit, bool strong_bit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline ObjectStrength strength(LanguageMode language_mode) {
|
// Strong mode behaviour must sometimes be signalled by a two valued enum where
|
||||||
return is_strong(language_mode) ? FIRM : WEAK;
|
// caching is involved, to prevent sloppy and strict mode from being incorrectly
|
||||||
|
// differentiated.
|
||||||
|
enum class Strength : bool {
|
||||||
|
WEAK, // sloppy, strict behaviour
|
||||||
|
STRONG // strong behaviour
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline bool is_strong(Strength strength) {
|
||||||
|
return strength == Strength::STRONG;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& os, const Strength& strength) {
|
||||||
|
return os << (is_strong(strength) ? "strong" : "weak");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Strength strength(LanguageMode language_mode) {
|
||||||
|
return is_strong(language_mode) ? Strength::STRONG : Strength::WEAK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline size_t hash_value(Strength strength) {
|
||||||
|
return static_cast<size_t>(strength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3971,22 +3971,21 @@ bool HStoreKeyed::NeedsCanonicalization() {
|
|||||||
#define H_CONSTANT_DOUBLE(val) \
|
#define H_CONSTANT_DOUBLE(val) \
|
||||||
HConstant::New(isolate, zone, context, static_cast<double>(val))
|
HConstant::New(isolate, zone, context, static_cast<double>(val))
|
||||||
|
|
||||||
#define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \
|
#define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \
|
||||||
HInstruction* HInstr::New(Isolate* isolate, Zone* zone, HValue* context, \
|
HInstruction* HInstr::New(Isolate* isolate, Zone* zone, HValue* context, \
|
||||||
HValue* left, HValue* right, \
|
HValue* left, HValue* right, Strength strength) { \
|
||||||
LanguageMode language_mode) { \
|
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \
|
||||||
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \
|
HConstant* c_left = HConstant::cast(left); \
|
||||||
HConstant* c_left = HConstant::cast(left); \
|
HConstant* c_right = HConstant::cast(right); \
|
||||||
HConstant* c_right = HConstant::cast(right); \
|
if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \
|
||||||
if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \
|
double double_res = c_left->DoubleValue() op c_right->DoubleValue(); \
|
||||||
double double_res = c_left->DoubleValue() op c_right->DoubleValue(); \
|
if (IsInt32Double(double_res)) { \
|
||||||
if (IsInt32Double(double_res)) { \
|
return H_CONSTANT_INT(double_res); \
|
||||||
return H_CONSTANT_INT(double_res); \
|
} \
|
||||||
} \
|
return H_CONSTANT_DOUBLE(double_res); \
|
||||||
return H_CONSTANT_DOUBLE(double_res); \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
return new (zone) HInstr(context, left, right, strength); \
|
||||||
return new (zone) HInstr(context, left, right, language_mode); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3998,8 +3997,7 @@ DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HSub, -)
|
|||||||
|
|
||||||
|
|
||||||
HInstruction* HStringAdd::New(Isolate* isolate, Zone* zone, HValue* context,
|
HInstruction* HStringAdd::New(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
HValue* left, HValue* right,
|
HValue* left, HValue* right, Strength strength,
|
||||||
LanguageMode language_mode,
|
|
||||||
PretenureFlag pretenure_flag,
|
PretenureFlag pretenure_flag,
|
||||||
StringAddFlags flags,
|
StringAddFlags flags,
|
||||||
Handle<AllocationSite> allocation_site) {
|
Handle<AllocationSite> allocation_site) {
|
||||||
@ -4017,9 +4015,8 @@ HInstruction* HStringAdd::New(Isolate* isolate, Zone* zone, HValue* context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new(zone) HStringAdd(
|
return new (zone) HStringAdd(context, left, right, strength, pretenure_flag,
|
||||||
context, left, right, language_mode, pretenure_flag, flags,
|
flags, allocation_site);
|
||||||
allocation_site);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4217,8 +4214,7 @@ HInstruction* HMathMinMax::New(Isolate* isolate, Zone* zone, HValue* context,
|
|||||||
|
|
||||||
|
|
||||||
HInstruction* HMod::New(Isolate* isolate, Zone* zone, HValue* context,
|
HInstruction* HMod::New(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
HValue* left, HValue* right,
|
HValue* left, HValue* right, Strength strength) {
|
||||||
LanguageMode language_mode) {
|
|
||||||
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
|
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
|
||||||
HConstant* c_left = HConstant::cast(left);
|
HConstant* c_left = HConstant::cast(left);
|
||||||
HConstant* c_right = HConstant::cast(right);
|
HConstant* c_right = HConstant::cast(right);
|
||||||
@ -4237,13 +4233,12 @@ HInstruction* HMod::New(Isolate* isolate, Zone* zone, HValue* context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new(zone) HMod(context, left, right, language_mode);
|
return new (zone) HMod(context, left, right, strength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HInstruction* HDiv::New(Isolate* isolate, Zone* zone, HValue* context,
|
HInstruction* HDiv::New(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
HValue* left, HValue* right,
|
HValue* left, HValue* right, Strength strength) {
|
||||||
LanguageMode language_mode) {
|
|
||||||
// If left and right are constant values, try to return a constant value.
|
// If left and right are constant values, try to return a constant value.
|
||||||
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
|
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
|
||||||
HConstant* c_left = HConstant::cast(left);
|
HConstant* c_left = HConstant::cast(left);
|
||||||
@ -4262,13 +4257,13 @@ HInstruction* HDiv::New(Isolate* isolate, Zone* zone, HValue* context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new(zone) HDiv(context, left, right, language_mode);
|
return new (zone) HDiv(context, left, right, strength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HInstruction* HBitwise::New(Isolate* isolate, Zone* zone, HValue* context,
|
HInstruction* HBitwise::New(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
Token::Value op, HValue* left, HValue* right,
|
Token::Value op, HValue* left, HValue* right,
|
||||||
LanguageMode language_mode) {
|
Strength strength) {
|
||||||
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
|
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
|
||||||
HConstant* c_left = HConstant::cast(left);
|
HConstant* c_left = HConstant::cast(left);
|
||||||
HConstant* c_right = HConstant::cast(right);
|
HConstant* c_right = HConstant::cast(right);
|
||||||
@ -4293,22 +4288,21 @@ HInstruction* HBitwise::New(Isolate* isolate, Zone* zone, HValue* context,
|
|||||||
return H_CONSTANT_INT(result);
|
return H_CONSTANT_INT(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new(zone) HBitwise(context, op, left, right, language_mode);
|
return new (zone) HBitwise(context, op, left, right, strength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define DEFINE_NEW_H_BITWISE_INSTR(HInstr, result) \
|
#define DEFINE_NEW_H_BITWISE_INSTR(HInstr, result) \
|
||||||
HInstruction* HInstr::New(Isolate* isolate, Zone* zone, HValue* context, \
|
HInstruction* HInstr::New(Isolate* isolate, Zone* zone, HValue* context, \
|
||||||
HValue* left, HValue* right, \
|
HValue* left, HValue* right, Strength strength) { \
|
||||||
LanguageMode language_mode) { \
|
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \
|
||||||
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \
|
HConstant* c_left = HConstant::cast(left); \
|
||||||
HConstant* c_left = HConstant::cast(left); \
|
HConstant* c_right = HConstant::cast(right); \
|
||||||
HConstant* c_right = HConstant::cast(right); \
|
if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \
|
||||||
if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \
|
return H_CONSTANT_INT(result); \
|
||||||
return H_CONSTANT_INT(result); \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
return new (zone) HInstr(context, left, right, strength); \
|
||||||
return new (zone) HInstr(context, left, right, language_mode); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4321,8 +4315,7 @@ c_left->NumberValueAsInteger32() << (c_right->NumberValueAsInteger32() & 0x1f))
|
|||||||
|
|
||||||
|
|
||||||
HInstruction* HShr::New(Isolate* isolate, Zone* zone, HValue* context,
|
HInstruction* HShr::New(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
HValue* left, HValue* right,
|
HValue* left, HValue* right, Strength strength) {
|
||||||
LanguageMode language_mode) {
|
|
||||||
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
|
if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) {
|
||||||
HConstant* c_left = HConstant::cast(left);
|
HConstant* c_left = HConstant::cast(left);
|
||||||
HConstant* c_right = HConstant::cast(right);
|
HConstant* c_right = HConstant::cast(right);
|
||||||
@ -4335,7 +4328,7 @@ HInstruction* HShr::New(Isolate* isolate, Zone* zone, HValue* context,
|
|||||||
return H_CONSTANT_INT(static_cast<uint32_t>(left_val) >> right_val);
|
return H_CONSTANT_INT(static_cast<uint32_t>(left_val) >> right_val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new(zone) HShr(context, left, right, language_mode);
|
return new (zone) HShr(context, left, right, strength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3780,8 +3780,9 @@ class HConstant final : public HTemplateInstruction<0> {
|
|||||||
class HBinaryOperation : public HTemplateInstruction<3> {
|
class HBinaryOperation : public HTemplateInstruction<3> {
|
||||||
public:
|
public:
|
||||||
HBinaryOperation(HValue* context, HValue* left, HValue* right,
|
HBinaryOperation(HValue* context, HValue* left, HValue* right,
|
||||||
LanguageMode language_mode, HType type = HType::Tagged())
|
Strength strength, HType type = HType::Tagged())
|
||||||
: HTemplateInstruction<3>(type), language_mode_(language_mode),
|
: HTemplateInstruction<3>(type),
|
||||||
|
strength_(strength),
|
||||||
observed_output_representation_(Representation::None()) {
|
observed_output_representation_(Representation::None()) {
|
||||||
DCHECK(left != NULL && right != NULL);
|
DCHECK(left != NULL && right != NULL);
|
||||||
SetOperandAt(0, context);
|
SetOperandAt(0, context);
|
||||||
@ -3794,7 +3795,7 @@ class HBinaryOperation : public HTemplateInstruction<3> {
|
|||||||
HValue* context() const { return OperandAt(0); }
|
HValue* context() const { return OperandAt(0); }
|
||||||
HValue* left() const { return OperandAt(1); }
|
HValue* left() const { return OperandAt(1); }
|
||||||
HValue* right() const { return OperandAt(2); }
|
HValue* right() const { return OperandAt(2); }
|
||||||
LanguageMode language_mode() const { return language_mode_; }
|
Strength strength() const { return strength_; }
|
||||||
|
|
||||||
// True if switching left and right operands likely generates better code.
|
// True if switching left and right operands likely generates better code.
|
||||||
bool AreOperandsBetterSwitched() {
|
bool AreOperandsBetterSwitched() {
|
||||||
@ -3870,15 +3871,13 @@ class HBinaryOperation : public HTemplateInstruction<3> {
|
|||||||
return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(value));
|
return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
LanguageMode language_mode() {
|
Strength strength() { return strength_; }
|
||||||
return language_mode_;
|
|
||||||
}
|
|
||||||
|
|
||||||
DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation)
|
DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool IgnoreObservedOutputRepresentation(Representation current_rep);
|
bool IgnoreObservedOutputRepresentation(Representation current_rep);
|
||||||
LanguageMode language_mode_;
|
Strength strength_;
|
||||||
|
|
||||||
Representation observed_input_representation_[2];
|
Representation observed_input_representation_[2];
|
||||||
Representation observed_output_representation_;
|
Representation observed_output_representation_;
|
||||||
@ -4148,9 +4147,8 @@ class HBoundsCheckBaseIndexInformation final : public HTemplateInstruction<2> {
|
|||||||
class HBitwiseBinaryOperation : public HBinaryOperation {
|
class HBitwiseBinaryOperation : public HBinaryOperation {
|
||||||
public:
|
public:
|
||||||
HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right,
|
HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right,
|
||||||
LanguageMode language_mode,
|
Strength strength, HType type = HType::TaggedNumber())
|
||||||
HType type = HType::TaggedNumber())
|
: HBinaryOperation(context, left, right, strength, type) {
|
||||||
: HBinaryOperation(context, left, right, language_mode, type) {
|
|
||||||
SetFlag(kFlexibleRepresentation);
|
SetFlag(kFlexibleRepresentation);
|
||||||
SetFlag(kTruncatingToInt32);
|
SetFlag(kTruncatingToInt32);
|
||||||
SetFlag(kAllowUndefinedAsNaN);
|
SetFlag(kAllowUndefinedAsNaN);
|
||||||
@ -4209,7 +4207,7 @@ class HMathFloorOfDiv final : public HBinaryOperation {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
HMathFloorOfDiv(HValue* context, HValue* left, HValue* right)
|
HMathFloorOfDiv(HValue* context, HValue* left, HValue* right)
|
||||||
: HBinaryOperation(context, left, right, SLOPPY) {
|
: HBinaryOperation(context, left, right, Strength::WEAK) {
|
||||||
set_representation(Representation::Integer32());
|
set_representation(Representation::Integer32());
|
||||||
SetFlag(kUseGVN);
|
SetFlag(kUseGVN);
|
||||||
SetFlag(kCanOverflow);
|
SetFlag(kCanOverflow);
|
||||||
@ -4229,8 +4227,8 @@ class HMathFloorOfDiv final : public HBinaryOperation {
|
|||||||
class HArithmeticBinaryOperation : public HBinaryOperation {
|
class HArithmeticBinaryOperation : public HBinaryOperation {
|
||||||
public:
|
public:
|
||||||
HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right,
|
HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right,
|
||||||
LanguageMode language_mode)
|
Strength strength)
|
||||||
: HBinaryOperation(context, left, right, language_mode,
|
: HBinaryOperation(context, left, right, strength,
|
||||||
HType::TaggedNumber()) {
|
HType::TaggedNumber()) {
|
||||||
SetAllSideEffects();
|
SetAllSideEffects();
|
||||||
SetFlag(kFlexibleRepresentation);
|
SetFlag(kFlexibleRepresentation);
|
||||||
@ -4259,10 +4257,9 @@ class HArithmeticBinaryOperation : public HBinaryOperation {
|
|||||||
class HCompareGeneric final : public HBinaryOperation {
|
class HCompareGeneric final : public HBinaryOperation {
|
||||||
public:
|
public:
|
||||||
static HCompareGeneric* New(Isolate* isolate, Zone* zone, HValue* context,
|
static HCompareGeneric* New(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
HValue* left, HValue* right, Token::Value token,
|
HValue* left, HValue* right, Token::Value token,
|
||||||
LanguageMode language_mode = SLOPPY) {
|
Strength strength = Strength::WEAK) {
|
||||||
return new(zone) HCompareGeneric(context, left, right, token,
|
return new (zone) HCompareGeneric(context, left, right, token, strength);
|
||||||
language_mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Representation RequiredInputRepresentation(int index) override {
|
Representation RequiredInputRepresentation(int index) override {
|
||||||
@ -4277,12 +4274,9 @@ class HCompareGeneric final : public HBinaryOperation {
|
|||||||
DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
|
DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HCompareGeneric(HValue* context,
|
HCompareGeneric(HValue* context, HValue* left, HValue* right,
|
||||||
HValue* left,
|
Token::Value token, Strength strength)
|
||||||
HValue* right,
|
: HBinaryOperation(context, left, right, strength, HType::Boolean()),
|
||||||
Token::Value token,
|
|
||||||
LanguageMode language_mode)
|
|
||||||
: HBinaryOperation(context, left, right, language_mode, HType::Boolean()),
|
|
||||||
token_(token) {
|
token_(token) {
|
||||||
DCHECK(Token::IsCompareOp(token));
|
DCHECK(Token::IsCompareOp(token));
|
||||||
set_representation(Representation::Tagged());
|
set_representation(Representation::Tagged());
|
||||||
@ -4741,7 +4735,8 @@ class HInstanceOf final : public HBinaryOperation {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
HInstanceOf(HValue* context, HValue* left, HValue* right)
|
HInstanceOf(HValue* context, HValue* left, HValue* right)
|
||||||
: HBinaryOperation(context, left, right, SLOPPY, HType::Boolean()) {
|
: HBinaryOperation(context, left, right, Strength::WEAK,
|
||||||
|
HType::Boolean()) {
|
||||||
set_representation(Representation::Tagged());
|
set_representation(Representation::Tagged());
|
||||||
SetAllSideEffects();
|
SetAllSideEffects();
|
||||||
}
|
}
|
||||||
@ -4820,7 +4815,7 @@ class HAdd final : public HArithmeticBinaryOperation {
|
|||||||
public:
|
public:
|
||||||
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
HValue* left, HValue* right,
|
HValue* left, HValue* right,
|
||||||
LanguageMode language_mode = SLOPPY);
|
Strength strength = Strength::WEAK);
|
||||||
|
|
||||||
// Add is only commutative if two integer values are added and not if two
|
// Add is only commutative if two integer values are added and not if two
|
||||||
// tagged values are added (because it might be a String concatenation).
|
// tagged values are added (because it might be a String concatenation).
|
||||||
@ -4871,8 +4866,8 @@ class HAdd final : public HArithmeticBinaryOperation {
|
|||||||
Range* InferRange(Zone* zone) override;
|
Range* InferRange(Zone* zone) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HAdd(HValue* context, HValue* left, HValue* right, LanguageMode language_mode)
|
HAdd(HValue* context, HValue* left, HValue* right, Strength strength)
|
||||||
: HArithmeticBinaryOperation(context, left, right, language_mode) {
|
: HArithmeticBinaryOperation(context, left, right, strength) {
|
||||||
SetFlag(kCanOverflow);
|
SetFlag(kCanOverflow);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -4882,7 +4877,7 @@ class HSub final : public HArithmeticBinaryOperation {
|
|||||||
public:
|
public:
|
||||||
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
HValue* left, HValue* right,
|
HValue* left, HValue* right,
|
||||||
LanguageMode language_mode = SLOPPY);
|
Strength strength = Strength::WEAK);
|
||||||
|
|
||||||
HValue* Canonicalize() override;
|
HValue* Canonicalize() override;
|
||||||
|
|
||||||
@ -4903,8 +4898,8 @@ class HSub final : public HArithmeticBinaryOperation {
|
|||||||
Range* InferRange(Zone* zone) override;
|
Range* InferRange(Zone* zone) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HSub(HValue* context, HValue* left, HValue* right, LanguageMode language_mode)
|
HSub(HValue* context, HValue* left, HValue* right, Strength strength)
|
||||||
: HArithmeticBinaryOperation(context, left, right, language_mode) {
|
: HArithmeticBinaryOperation(context, left, right, strength) {
|
||||||
SetFlag(kCanOverflow);
|
SetFlag(kCanOverflow);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -4914,13 +4909,13 @@ class HMul final : public HArithmeticBinaryOperation {
|
|||||||
public:
|
public:
|
||||||
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
HValue* left, HValue* right,
|
HValue* left, HValue* right,
|
||||||
LanguageMode language_mode = SLOPPY);
|
Strength strength = Strength::WEAK);
|
||||||
|
|
||||||
static HInstruction* NewImul(Isolate* isolate, Zone* zone, HValue* context,
|
static HInstruction* NewImul(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
HValue* left, HValue* right,
|
HValue* left, HValue* right,
|
||||||
LanguageMode language_mode = SLOPPY) {
|
Strength strength = Strength::WEAK) {
|
||||||
HInstruction* instr = HMul::New(isolate, zone, context, left, right,
|
HInstruction* instr =
|
||||||
language_mode);
|
HMul::New(isolate, zone, context, left, right, strength);
|
||||||
if (!instr->IsMul()) return instr;
|
if (!instr->IsMul()) return instr;
|
||||||
HMul* mul = HMul::cast(instr);
|
HMul* mul = HMul::cast(instr);
|
||||||
// TODO(mstarzinger): Prevent bailout on minus zero for imul.
|
// TODO(mstarzinger): Prevent bailout on minus zero for imul.
|
||||||
@ -4950,8 +4945,8 @@ class HMul final : public HArithmeticBinaryOperation {
|
|||||||
Range* InferRange(Zone* zone) override;
|
Range* InferRange(Zone* zone) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HMul(HValue* context, HValue* left, HValue* right, LanguageMode language_mode)
|
HMul(HValue* context, HValue* left, HValue* right, Strength strength)
|
||||||
: HArithmeticBinaryOperation(context, left, right, language_mode) {
|
: HArithmeticBinaryOperation(context, left, right, strength) {
|
||||||
SetFlag(kCanOverflow);
|
SetFlag(kCanOverflow);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -4961,7 +4956,7 @@ class HMod final : public HArithmeticBinaryOperation {
|
|||||||
public:
|
public:
|
||||||
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
HValue* left, HValue* right,
|
HValue* left, HValue* right,
|
||||||
LanguageMode language_mode = SLOPPY);
|
Strength strength = Strength::WEAK);
|
||||||
|
|
||||||
HValue* Canonicalize() override;
|
HValue* Canonicalize() override;
|
||||||
|
|
||||||
@ -4980,12 +4975,8 @@ class HMod final : public HArithmeticBinaryOperation {
|
|||||||
Range* InferRange(Zone* zone) override;
|
Range* InferRange(Zone* zone) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HMod(HValue* context,
|
HMod(HValue* context, HValue* left, HValue* right, Strength strength)
|
||||||
HValue* left,
|
: HArithmeticBinaryOperation(context, left, right, strength) {
|
||||||
HValue* right,
|
|
||||||
LanguageMode language_mode) : HArithmeticBinaryOperation(context, left,
|
|
||||||
right,
|
|
||||||
language_mode) {
|
|
||||||
SetFlag(kCanBeDivByZero);
|
SetFlag(kCanBeDivByZero);
|
||||||
SetFlag(kCanOverflow);
|
SetFlag(kCanOverflow);
|
||||||
SetFlag(kLeftCanBeNegative);
|
SetFlag(kLeftCanBeNegative);
|
||||||
@ -4997,7 +4988,7 @@ class HDiv final : public HArithmeticBinaryOperation {
|
|||||||
public:
|
public:
|
||||||
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
HValue* left, HValue* right,
|
HValue* left, HValue* right,
|
||||||
LanguageMode language_mode = SLOPPY);
|
Strength strength = Strength::WEAK);
|
||||||
|
|
||||||
HValue* Canonicalize() override;
|
HValue* Canonicalize() override;
|
||||||
|
|
||||||
@ -5016,8 +5007,8 @@ class HDiv final : public HArithmeticBinaryOperation {
|
|||||||
Range* InferRange(Zone* zone) override;
|
Range* InferRange(Zone* zone) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HDiv(HValue* context, HValue* left, HValue* right, LanguageMode language_mode)
|
HDiv(HValue* context, HValue* left, HValue* right, Strength strength)
|
||||||
: HArithmeticBinaryOperation(context, left, right, language_mode) {
|
: HArithmeticBinaryOperation(context, left, right, strength) {
|
||||||
SetFlag(kCanBeDivByZero);
|
SetFlag(kCanBeDivByZero);
|
||||||
SetFlag(kCanOverflow);
|
SetFlag(kCanOverflow);
|
||||||
}
|
}
|
||||||
@ -5063,8 +5054,8 @@ class HMathMinMax final : public HArithmeticBinaryOperation {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
HMathMinMax(HValue* context, HValue* left, HValue* right, Operation op)
|
HMathMinMax(HValue* context, HValue* left, HValue* right, Operation op)
|
||||||
: HArithmeticBinaryOperation(context, left, right, SLOPPY),
|
: HArithmeticBinaryOperation(context, left, right, Strength::WEAK),
|
||||||
operation_(op) { }
|
operation_(op) {}
|
||||||
|
|
||||||
Operation operation_;
|
Operation operation_;
|
||||||
};
|
};
|
||||||
@ -5074,7 +5065,7 @@ class HBitwise final : public HBitwiseBinaryOperation {
|
|||||||
public:
|
public:
|
||||||
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
Token::Value op, HValue* left, HValue* right,
|
Token::Value op, HValue* left, HValue* right,
|
||||||
LanguageMode language_mode = SLOPPY);
|
Strength strength = Strength::WEAK);
|
||||||
|
|
||||||
Token::Value op() const { return op_; }
|
Token::Value op() const { return op_; }
|
||||||
|
|
||||||
@ -5094,13 +5085,9 @@ class HBitwise final : public HBitwiseBinaryOperation {
|
|||||||
Range* InferRange(Zone* zone) override;
|
Range* InferRange(Zone* zone) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HBitwise(HValue* context,
|
HBitwise(HValue* context, Token::Value op, HValue* left, HValue* right,
|
||||||
Token::Value op,
|
Strength strength)
|
||||||
HValue* left,
|
: HBitwiseBinaryOperation(context, left, right, strength), op_(op) {
|
||||||
HValue* right,
|
|
||||||
LanguageMode language_mode)
|
|
||||||
: HBitwiseBinaryOperation(context, left, right, language_mode),
|
|
||||||
op_(op) {
|
|
||||||
DCHECK(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR);
|
DCHECK(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR);
|
||||||
// BIT_AND with a smi-range positive value will always unset the
|
// BIT_AND with a smi-range positive value will always unset the
|
||||||
// entire sign-extension of the smi-sign.
|
// entire sign-extension of the smi-sign.
|
||||||
@ -5135,7 +5122,7 @@ class HShl final : public HBitwiseBinaryOperation {
|
|||||||
public:
|
public:
|
||||||
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
HValue* left, HValue* right,
|
HValue* left, HValue* right,
|
||||||
LanguageMode language_mode = SLOPPY);
|
Strength strength = Strength::WEAK);
|
||||||
|
|
||||||
Range* InferRange(Zone* zone) override;
|
Range* InferRange(Zone* zone) override;
|
||||||
|
|
||||||
@ -5156,8 +5143,8 @@ class HShl final : public HBitwiseBinaryOperation {
|
|||||||
bool DataEquals(HValue* other) override { return true; }
|
bool DataEquals(HValue* other) override { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HShl(HValue* context, HValue* left, HValue* right, LanguageMode language_mode)
|
HShl(HValue* context, HValue* left, HValue* right, Strength strength)
|
||||||
: HBitwiseBinaryOperation(context, left, right, language_mode) { }
|
: HBitwiseBinaryOperation(context, left, right, strength) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -5165,7 +5152,7 @@ class HShr final : public HBitwiseBinaryOperation {
|
|||||||
public:
|
public:
|
||||||
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
HValue* left, HValue* right,
|
HValue* left, HValue* right,
|
||||||
LanguageMode language_mode = SLOPPY);
|
Strength strength = Strength::WEAK);
|
||||||
|
|
||||||
bool TryDecompose(DecompositionResult* decomposition) override {
|
bool TryDecompose(DecompositionResult* decomposition) override {
|
||||||
if (right()->IsInteger32Constant()) {
|
if (right()->IsInteger32Constant()) {
|
||||||
@ -5194,8 +5181,8 @@ class HShr final : public HBitwiseBinaryOperation {
|
|||||||
bool DataEquals(HValue* other) override { return true; }
|
bool DataEquals(HValue* other) override { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HShr(HValue* context, HValue* left, HValue* right, LanguageMode language_mode)
|
HShr(HValue* context, HValue* left, HValue* right, Strength strength)
|
||||||
: HBitwiseBinaryOperation(context, left, right, language_mode) { }
|
: HBitwiseBinaryOperation(context, left, right, strength) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -5203,7 +5190,7 @@ class HSar final : public HBitwiseBinaryOperation {
|
|||||||
public:
|
public:
|
||||||
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
HValue* left, HValue* right,
|
HValue* left, HValue* right,
|
||||||
LanguageMode language_mode = SLOPPY);
|
Strength strength = Strength::WEAK);
|
||||||
|
|
||||||
bool TryDecompose(DecompositionResult* decomposition) override {
|
bool TryDecompose(DecompositionResult* decomposition) override {
|
||||||
if (right()->IsInteger32Constant()) {
|
if (right()->IsInteger32Constant()) {
|
||||||
@ -5232,8 +5219,8 @@ class HSar final : public HBitwiseBinaryOperation {
|
|||||||
bool DataEquals(HValue* other) override { return true; }
|
bool DataEquals(HValue* other) override { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HSar(HValue* context, HValue* left, HValue* right, LanguageMode language_mode)
|
HSar(HValue* context, HValue* left, HValue* right, Strength strength)
|
||||||
: HBitwiseBinaryOperation(context, left, right, language_mode) { }
|
: HBitwiseBinaryOperation(context, left, right, strength) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -5241,8 +5228,8 @@ class HRor final : public HBitwiseBinaryOperation {
|
|||||||
public:
|
public:
|
||||||
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
||||||
HValue* left, HValue* right,
|
HValue* left, HValue* right,
|
||||||
LanguageMode language_mode = SLOPPY) {
|
Strength strength = Strength::WEAK) {
|
||||||
return new(zone) HRor(context, left, right, language_mode);
|
return new (zone) HRor(context, left, right, strength);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void UpdateRepresentation(Representation new_rep,
|
virtual void UpdateRepresentation(Representation new_rep,
|
||||||
@ -5258,8 +5245,8 @@ class HRor final : public HBitwiseBinaryOperation {
|
|||||||
bool DataEquals(HValue* other) override { return true; }
|
bool DataEquals(HValue* other) override { return true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HRor(HValue* context, HValue* left, HValue* right, LanguageMode language_mode)
|
HRor(HValue* context, HValue* left, HValue* right, Strength strength)
|
||||||
: HBitwiseBinaryOperation(context, left, right, language_mode) {
|
: HBitwiseBinaryOperation(context, left, right, strength) {
|
||||||
ChangeRepresentation(Representation::Integer32());
|
ChangeRepresentation(Representation::Integer32());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -7234,7 +7221,7 @@ class HStringAdd final : public HBinaryOperation {
|
|||||||
public:
|
public:
|
||||||
static HInstruction* New(
|
static HInstruction* New(
|
||||||
Isolate* isolate, Zone* zone, HValue* context, HValue* left,
|
Isolate* isolate, Zone* zone, HValue* context, HValue* left,
|
||||||
HValue* right, LanguageMode language_mode = SLOPPY,
|
HValue* right, Strength strength = Strength::WEAK,
|
||||||
PretenureFlag pretenure_flag = NOT_TENURED,
|
PretenureFlag pretenure_flag = NOT_TENURED,
|
||||||
StringAddFlags flags = STRING_ADD_CHECK_BOTH,
|
StringAddFlags flags = STRING_ADD_CHECK_BOTH,
|
||||||
Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null());
|
Handle<AllocationSite> allocation_site = Handle<AllocationSite>::null());
|
||||||
@ -7257,15 +7244,12 @@ class HStringAdd final : public HBinaryOperation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HStringAdd(HValue* context,
|
HStringAdd(HValue* context, HValue* left, HValue* right, Strength strength,
|
||||||
HValue* left,
|
PretenureFlag pretenure_flag, StringAddFlags flags,
|
||||||
HValue* right,
|
|
||||||
LanguageMode language_mode,
|
|
||||||
PretenureFlag pretenure_flag,
|
|
||||||
StringAddFlags flags,
|
|
||||||
Handle<AllocationSite> allocation_site)
|
Handle<AllocationSite> allocation_site)
|
||||||
: HBinaryOperation(context, left, right, language_mode, HType::String()),
|
: HBinaryOperation(context, left, right, strength, HType::String()),
|
||||||
flags_(flags), pretenure_flag_(pretenure_flag) {
|
flags_(flags),
|
||||||
|
pretenure_flag_(pretenure_flag) {
|
||||||
set_representation(Representation::Tagged());
|
set_representation(Representation::Tagged());
|
||||||
SetFlag(kUseGVN);
|
SetFlag(kUseGVN);
|
||||||
SetDependsOnFlag(kMaps);
|
SetDependsOnFlag(kMaps);
|
||||||
|
@ -10312,8 +10312,8 @@ HInstruction* HOptimizedGraphBuilder::BuildIncrement(
|
|||||||
HConstant* delta = (expr->op() == Token::INC)
|
HConstant* delta = (expr->op() == Token::INC)
|
||||||
? graph()->GetConstant1()
|
? graph()->GetConstant1()
|
||||||
: graph()->GetConstantMinus1();
|
: graph()->GetConstantMinus1();
|
||||||
HInstruction* instr = AddUncasted<HAdd>(Top(), delta,
|
HInstruction* instr =
|
||||||
function_language_mode());
|
AddUncasted<HAdd>(Top(), delta, strength(function_language_mode()));
|
||||||
if (instr->IsAdd()) {
|
if (instr->IsAdd()) {
|
||||||
HAdd* add = HAdd::cast(instr);
|
HAdd* add = HAdd::cast(instr);
|
||||||
add->set_observed_input_representation(1, rep);
|
add->set_observed_input_representation(1, rep);
|
||||||
@ -10607,7 +10607,7 @@ HValue* HOptimizedGraphBuilder::BuildBinaryOperation(
|
|||||||
|
|
||||||
HValue* result = HGraphBuilder::BuildBinaryOperation(
|
HValue* result = HGraphBuilder::BuildBinaryOperation(
|
||||||
expr->op(), left, right, left_type, right_type, result_type,
|
expr->op(), left, right, left_type, right_type, result_type,
|
||||||
fixed_right_arg, allocation_mode, function_language_mode());
|
fixed_right_arg, allocation_mode, strength(function_language_mode()));
|
||||||
// Add a simulate after instructions with observable side effects, and
|
// Add a simulate after instructions with observable side effects, and
|
||||||
// after phis, which are the result of BuildBinaryOperation when we
|
// after phis, which are the result of BuildBinaryOperation when we
|
||||||
// inlined some complex subgraph.
|
// inlined some complex subgraph.
|
||||||
@ -10624,16 +10624,12 @@ HValue* HOptimizedGraphBuilder::BuildBinaryOperation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HValue* HGraphBuilder::BuildBinaryOperation(
|
HValue* HGraphBuilder::BuildBinaryOperation(Token::Value op, HValue* left,
|
||||||
Token::Value op,
|
HValue* right, Type* left_type,
|
||||||
HValue* left,
|
Type* right_type, Type* result_type,
|
||||||
HValue* right,
|
Maybe<int> fixed_right_arg,
|
||||||
Type* left_type,
|
HAllocationMode allocation_mode,
|
||||||
Type* right_type,
|
Strength strength) {
|
||||||
Type* result_type,
|
|
||||||
Maybe<int> fixed_right_arg,
|
|
||||||
HAllocationMode allocation_mode,
|
|
||||||
LanguageMode language_mode) {
|
|
||||||
bool maybe_string_add = false;
|
bool maybe_string_add = false;
|
||||||
if (op == Token::ADD) {
|
if (op == Token::ADD) {
|
||||||
// If we are adding constant string with something for which we don't have
|
// If we are adding constant string with something for which we don't have
|
||||||
@ -10695,27 +10691,27 @@ HValue* HGraphBuilder::BuildBinaryOperation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert left argument as necessary.
|
// Convert left argument as necessary.
|
||||||
if (left_type->Is(Type::Number()) && !is_strong(language_mode)) {
|
if (left_type->Is(Type::Number()) && !is_strong(strength)) {
|
||||||
DCHECK(right_type->Is(Type::String()));
|
DCHECK(right_type->Is(Type::String()));
|
||||||
left = BuildNumberToString(left, left_type);
|
left = BuildNumberToString(left, left_type);
|
||||||
} else if (!left_type->Is(Type::String())) {
|
} else if (!left_type->Is(Type::String())) {
|
||||||
DCHECK(right_type->Is(Type::String()));
|
DCHECK(right_type->Is(Type::String()));
|
||||||
HValue* function = AddLoadJSBuiltin(is_strong(language_mode) ?
|
HValue* function = AddLoadJSBuiltin(
|
||||||
Builtins::STRING_ADD_RIGHT_STRONG :
|
is_strong(strength) ? Builtins::STRING_ADD_RIGHT_STRONG
|
||||||
Builtins::STRING_ADD_RIGHT);
|
: Builtins::STRING_ADD_RIGHT);
|
||||||
Add<HPushArguments>(left, right);
|
Add<HPushArguments>(left, right);
|
||||||
return AddUncasted<HInvokeFunction>(function, 2);
|
return AddUncasted<HInvokeFunction>(function, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert right argument as necessary.
|
// Convert right argument as necessary.
|
||||||
if (right_type->Is(Type::Number()) && !is_strong(language_mode)) {
|
if (right_type->Is(Type::Number()) && !is_strong(strength)) {
|
||||||
DCHECK(left_type->Is(Type::String()));
|
DCHECK(left_type->Is(Type::String()));
|
||||||
right = BuildNumberToString(right, right_type);
|
right = BuildNumberToString(right, right_type);
|
||||||
} else if (!right_type->Is(Type::String())) {
|
} else if (!right_type->Is(Type::String())) {
|
||||||
DCHECK(left_type->Is(Type::String()));
|
DCHECK(left_type->Is(Type::String()));
|
||||||
HValue* function = AddLoadJSBuiltin(is_strong(language_mode) ?
|
HValue* function = AddLoadJSBuiltin(is_strong(strength)
|
||||||
Builtins::STRING_ADD_LEFT_STRONG :
|
? Builtins::STRING_ADD_LEFT_STRONG
|
||||||
Builtins::STRING_ADD_LEFT);
|
: Builtins::STRING_ADD_LEFT);
|
||||||
Add<HPushArguments>(left, right);
|
Add<HPushArguments>(left, right);
|
||||||
return AddUncasted<HInvokeFunction>(function, 2);
|
return AddUncasted<HInvokeFunction>(function, 2);
|
||||||
}
|
}
|
||||||
@ -10733,7 +10729,7 @@ HValue* HGraphBuilder::BuildBinaryOperation(
|
|||||||
if (!right_string.is_null() && right_string->length() == 0) return left;
|
if (!right_string.is_null() && right_string->length() == 0) return left;
|
||||||
if (!left_string.is_null() && !right_string.is_null()) {
|
if (!left_string.is_null() && !right_string.is_null()) {
|
||||||
return AddUncasted<HStringAdd>(
|
return AddUncasted<HStringAdd>(
|
||||||
left, right, language_mode, allocation_mode.GetPretenureMode(),
|
left, right, strength, allocation_mode.GetPretenureMode(),
|
||||||
STRING_ADD_CHECK_NONE, allocation_mode.feedback_site());
|
STRING_ADD_CHECK_NONE, allocation_mode.feedback_site());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10762,7 +10758,7 @@ HValue* HGraphBuilder::BuildBinaryOperation(
|
|||||||
|
|
||||||
// Fallback to using the string add stub.
|
// Fallback to using the string add stub.
|
||||||
return AddUncasted<HStringAdd>(
|
return AddUncasted<HStringAdd>(
|
||||||
left, right, language_mode, allocation_mode.GetPretenureMode(),
|
left, right, strength, allocation_mode.GetPretenureMode(),
|
||||||
STRING_ADD_CHECK_NONE, allocation_mode.feedback_site());
|
STRING_ADD_CHECK_NONE, allocation_mode.feedback_site());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10781,20 +10777,20 @@ HValue* HGraphBuilder::BuildBinaryOperation(
|
|||||||
// inline several instructions (including the two pushes) for every tagged
|
// inline several instructions (including the two pushes) for every tagged
|
||||||
// operation in optimized code, which is more expensive, than a stub call.
|
// operation in optimized code, which is more expensive, than a stub call.
|
||||||
if (graph()->info()->IsStub() && is_non_primitive) {
|
if (graph()->info()->IsStub() && is_non_primitive) {
|
||||||
HValue* function = AddLoadJSBuiltin(
|
HValue* function =
|
||||||
BinaryOpIC::TokenToJSBuiltin(op, language_mode));
|
AddLoadJSBuiltin(BinaryOpIC::TokenToJSBuiltin(op, strength));
|
||||||
Add<HPushArguments>(left, right);
|
Add<HPushArguments>(left, right);
|
||||||
instr = AddUncasted<HInvokeFunction>(function, 2);
|
instr = AddUncasted<HInvokeFunction>(function, 2);
|
||||||
} else {
|
} else {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Token::ADD:
|
case Token::ADD:
|
||||||
instr = AddUncasted<HAdd>(left, right, language_mode);
|
instr = AddUncasted<HAdd>(left, right, strength);
|
||||||
break;
|
break;
|
||||||
case Token::SUB:
|
case Token::SUB:
|
||||||
instr = AddUncasted<HSub>(left, right, language_mode);
|
instr = AddUncasted<HSub>(left, right, strength);
|
||||||
break;
|
break;
|
||||||
case Token::MUL:
|
case Token::MUL:
|
||||||
instr = AddUncasted<HMul>(left, right, language_mode);
|
instr = AddUncasted<HMul>(left, right, strength);
|
||||||
break;
|
break;
|
||||||
case Token::MOD: {
|
case Token::MOD: {
|
||||||
if (fixed_right_arg.IsJust() &&
|
if (fixed_right_arg.IsJust() &&
|
||||||
@ -10807,38 +10803,38 @@ HValue* HGraphBuilder::BuildBinaryOperation(
|
|||||||
if_same.ElseDeopt(Deoptimizer::kUnexpectedRHSOfBinaryOperation);
|
if_same.ElseDeopt(Deoptimizer::kUnexpectedRHSOfBinaryOperation);
|
||||||
right = fixed_right;
|
right = fixed_right;
|
||||||
}
|
}
|
||||||
instr = AddUncasted<HMod>(left, right, language_mode);
|
instr = AddUncasted<HMod>(left, right, strength);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Token::DIV:
|
case Token::DIV:
|
||||||
instr = AddUncasted<HDiv>(left, right, language_mode);
|
instr = AddUncasted<HDiv>(left, right, strength);
|
||||||
break;
|
break;
|
||||||
case Token::BIT_XOR:
|
case Token::BIT_XOR:
|
||||||
case Token::BIT_AND:
|
case Token::BIT_AND:
|
||||||
instr = AddUncasted<HBitwise>(op, left, right, language_mode);
|
instr = AddUncasted<HBitwise>(op, left, right, strength);
|
||||||
break;
|
break;
|
||||||
case Token::BIT_OR: {
|
case Token::BIT_OR: {
|
||||||
HValue* operand, *shift_amount;
|
HValue* operand, *shift_amount;
|
||||||
if (left_type->Is(Type::Signed32()) &&
|
if (left_type->Is(Type::Signed32()) &&
|
||||||
right_type->Is(Type::Signed32()) &&
|
right_type->Is(Type::Signed32()) &&
|
||||||
MatchRotateRight(left, right, &operand, &shift_amount)) {
|
MatchRotateRight(left, right, &operand, &shift_amount)) {
|
||||||
instr = AddUncasted<HRor>(operand, shift_amount, language_mode);
|
instr = AddUncasted<HRor>(operand, shift_amount, strength);
|
||||||
} else {
|
} else {
|
||||||
instr = AddUncasted<HBitwise>(op, left, right, language_mode);
|
instr = AddUncasted<HBitwise>(op, left, right, strength);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Token::SAR:
|
case Token::SAR:
|
||||||
instr = AddUncasted<HSar>(left, right, language_mode);
|
instr = AddUncasted<HSar>(left, right, strength);
|
||||||
break;
|
break;
|
||||||
case Token::SHR:
|
case Token::SHR:
|
||||||
instr = AddUncasted<HShr>(left, right, language_mode);
|
instr = AddUncasted<HShr>(left, right, strength);
|
||||||
if (instr->IsShr() && CanBeZero(right)) {
|
if (instr->IsShr() && CanBeZero(right)) {
|
||||||
graph()->RecordUint32Instruction(instr);
|
graph()->RecordUint32Instruction(instr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Token::SHL:
|
case Token::SHL:
|
||||||
instr = AddUncasted<HShl>(left, right, language_mode);
|
instr = AddUncasted<HShl>(left, right, strength);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
@ -11226,8 +11222,8 @@ HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction(
|
|||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
if (combined_rep.IsTagged() || combined_rep.IsNone()) {
|
if (combined_rep.IsTagged() || combined_rep.IsNone()) {
|
||||||
HCompareGeneric* result =
|
HCompareGeneric* result = Add<HCompareGeneric>(
|
||||||
Add<HCompareGeneric>(left, right, op, function_language_mode());
|
left, right, op, strength(function_language_mode()));
|
||||||
result->set_observed_input_representation(1, left_rep);
|
result->set_observed_input_representation(1, left_rep);
|
||||||
result->set_observed_input_representation(2, right_rep);
|
result->set_observed_input_representation(2, right_rep);
|
||||||
if (result->HasObservableSideEffects()) {
|
if (result->HasObservableSideEffects()) {
|
||||||
@ -12087,8 +12083,8 @@ void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) {
|
|||||||
CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
|
CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
|
||||||
HValue* right = Pop();
|
HValue* right = Pop();
|
||||||
HValue* left = Pop();
|
HValue* left = Pop();
|
||||||
HInstruction* result = NewUncasted<HStringAdd>(left, right,
|
HInstruction* result =
|
||||||
function_language_mode());
|
NewUncasted<HStringAdd>(left, right, strength(function_language_mode()));
|
||||||
return ast_context()->ReturnInstruction(result, call->id());
|
return ast_context()->ReturnInstruction(result, call->id());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1429,15 +1429,11 @@ class HGraphBuilder {
|
|||||||
HValue** operand,
|
HValue** operand,
|
||||||
HValue** shift_amount);
|
HValue** shift_amount);
|
||||||
|
|
||||||
HValue* BuildBinaryOperation(Token::Value op,
|
HValue* BuildBinaryOperation(Token::Value op, HValue* left, HValue* right,
|
||||||
HValue* left,
|
Type* left_type, Type* right_type,
|
||||||
HValue* right,
|
Type* result_type, Maybe<int> fixed_right_arg,
|
||||||
Type* left_type,
|
|
||||||
Type* right_type,
|
|
||||||
Type* result_type,
|
|
||||||
Maybe<int> fixed_right_arg,
|
|
||||||
HAllocationMode allocation_mode,
|
HAllocationMode allocation_mode,
|
||||||
LanguageMode language_mode);
|
Strength strength);
|
||||||
|
|
||||||
HLoadNamedField* AddLoadFixedArrayLength(HValue *object,
|
HLoadNamedField* AddLoadFixedArrayLength(HValue *object,
|
||||||
HValue *dependency = NULL);
|
HValue *dependency = NULL);
|
||||||
|
@ -1696,7 +1696,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
// Check for undefined. undefined OP undefined is false even though
|
// Check for undefined. undefined OP undefined is false even though
|
||||||
// undefined == undefined.
|
// undefined == undefined.
|
||||||
__ cmp(edx, isolate()->factory()->undefined_value());
|
__ cmp(edx, isolate()->factory()->undefined_value());
|
||||||
if (strong()) {
|
if (is_strong(strength())) {
|
||||||
// In strong mode, this comparison must throw, so call the runtime.
|
// In strong mode, this comparison must throw, so call the runtime.
|
||||||
__ j(equal, &runtime_call, Label::kFar);
|
__ j(equal, &runtime_call, Label::kFar);
|
||||||
} else {
|
} else {
|
||||||
@ -1722,7 +1722,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
// Call runtime on identical symbols since we need to throw a TypeError.
|
// Call runtime on identical symbols since we need to throw a TypeError.
|
||||||
__ cmpb(ecx, static_cast<uint8_t>(SYMBOL_TYPE));
|
__ cmpb(ecx, static_cast<uint8_t>(SYMBOL_TYPE));
|
||||||
__ j(equal, &runtime_call, Label::kFar);
|
__ j(equal, &runtime_call, Label::kFar);
|
||||||
if (strong()) {
|
if (is_strong(strength())) {
|
||||||
// We have already tested for smis and heap numbers, so if both
|
// We have already tested for smis and heap numbers, so if both
|
||||||
// arguments are not strings we must proceed to the slow case.
|
// arguments are not strings we must proceed to the slow case.
|
||||||
__ test(ecx, Immediate(kIsNotStringMask));
|
__ test(ecx, Immediate(kIsNotStringMask));
|
||||||
@ -1914,7 +1914,8 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
if (cc == equal) {
|
if (cc == equal) {
|
||||||
builtin = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
|
builtin = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
|
||||||
} else {
|
} else {
|
||||||
builtin = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
builtin =
|
||||||
|
is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
||||||
__ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
|
__ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3645,7 +3646,7 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
|
|||||||
|
|
||||||
__ bind(&unordered);
|
__ bind(&unordered);
|
||||||
__ bind(&generic_stub);
|
__ bind(&generic_stub);
|
||||||
CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
|
CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC,
|
||||||
CompareICState::GENERIC, CompareICState::GENERIC);
|
CompareICState::GENERIC, CompareICState::GENERIC);
|
||||||
__ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
|
__ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
|
||||||
|
|
||||||
|
@ -1016,7 +1016,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
|||||||
// Record position before stub call for type feedback.
|
// Record position before stub call for type feedback.
|
||||||
SetSourcePosition(clause->position());
|
SetSourcePosition(clause->position());
|
||||||
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
|
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
|
||||||
language_mode()).code();
|
strength(language_mode())).code();
|
||||||
CallIC(ic, clause->CompareId());
|
CallIC(ic, clause->CompareId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
|
|
||||||
@ -2386,8 +2386,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
|||||||
|
|
||||||
__ bind(&stub_call);
|
__ bind(&stub_call);
|
||||||
__ mov(eax, ecx);
|
__ mov(eax, ecx);
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), op, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
|
||||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
__ jmp(&done, Label::kNear);
|
__ jmp(&done, Label::kNear);
|
||||||
@ -2540,8 +2540,8 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
|
|||||||
|
|
||||||
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
||||||
__ pop(edx);
|
__ pop(edx);
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), op, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
|
||||||
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
||||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
@ -4968,9 +4968,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|||||||
__ bind(&stub_call);
|
__ bind(&stub_call);
|
||||||
__ mov(edx, eax);
|
__ mov(edx, eax);
|
||||||
__ mov(eax, Immediate(Smi::FromInt(1)));
|
__ mov(eax, Immediate(Smi::FromInt(1)));
|
||||||
Handle<Code> code =
|
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(),
|
||||||
CodeFactory::BinaryOpIC(
|
strength(language_mode())).code();
|
||||||
isolate(), expr->binary_op(), language_mode()).code();
|
|
||||||
CallIC(code, expr->CountBinOpFeedbackId());
|
CallIC(code, expr->CountBinOpFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
@ -5237,8 +5236,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
|||||||
|
|
||||||
// Record position and call the compare IC.
|
// Record position and call the compare IC.
|
||||||
SetSourcePosition(expr->position());
|
SetSourcePosition(expr->position());
|
||||||
Handle<Code> ic =
|
Handle<Code> ic = CodeFactory::CompareIC(
|
||||||
CodeFactory::CompareIC(isolate(), op, language_mode()).code();
|
isolate(), op, strength(language_mode())).code();
|
||||||
CallIC(ic, expr->CompareOperationFeedbackId());
|
CallIC(ic, expr->CompareOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
|
|
||||||
|
@ -2064,8 +2064,8 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
|
|||||||
DCHECK(ToRegister(instr->right()).is(eax));
|
DCHECK(ToRegister(instr->right()).is(eax));
|
||||||
DCHECK(ToRegister(instr->result()).is(eax));
|
DCHECK(ToRegister(instr->result()).is(eax));
|
||||||
|
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), instr->op(), instr->language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), instr->op(), instr->strength()).code();
|
||||||
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2491,7 +2491,8 @@ static Condition ComputeCompareCondition(Token::Value op) {
|
|||||||
void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
|
void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
|
||||||
Token::Value op = instr->op();
|
Token::Value op = instr->op();
|
||||||
|
|
||||||
Handle<Code> ic = CodeFactory::CompareIC(isolate(), op, SLOPPY).code();
|
Handle<Code> ic =
|
||||||
|
CodeFactory::CompareIC(isolate(), op, Strength::WEAK).code();
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
|
|
||||||
Condition condition = ComputeCompareCondition(op);
|
Condition condition = ComputeCompareCondition(op);
|
||||||
@ -2763,7 +2764,7 @@ void LCodeGen::DoCmpT(LCmpT* instr) {
|
|||||||
Token::Value op = instr->op();
|
Token::Value op = instr->op();
|
||||||
|
|
||||||
Handle<Code> ic =
|
Handle<Code> ic =
|
||||||
CodeFactory::CompareIC(isolate(), op, instr->language_mode()).code();
|
CodeFactory::CompareIC(isolate(), op, instr->strength()).code();
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
|
|
||||||
Condition condition = ComputeCompareCondition(op);
|
Condition condition = ComputeCompareCondition(op);
|
||||||
|
@ -1170,7 +1170,7 @@ class LCmpT final : public LTemplateInstruction<1, 3, 0> {
|
|||||||
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
|
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
|
||||||
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
|
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
|
||||||
|
|
||||||
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
Strength strength() { return hydrogen()->strength(); }
|
||||||
|
|
||||||
LOperand* context() { return inputs_[0]; }
|
LOperand* context() { return inputs_[0]; }
|
||||||
Token::Value op() const { return hydrogen()->token(); }
|
Token::Value op() const { return hydrogen()->token(); }
|
||||||
@ -1541,7 +1541,7 @@ class LArithmeticT final : public LTemplateInstruction<1, 3, 0> {
|
|||||||
|
|
||||||
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
|
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
|
||||||
|
|
||||||
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
Strength strength() { return hydrogen()->strength(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Token::Value op_;
|
Token::Value op_;
|
||||||
|
@ -52,7 +52,7 @@ BinaryOpICState::BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state)
|
|||||||
isolate_(isolate) {
|
isolate_(isolate) {
|
||||||
op_ =
|
op_ =
|
||||||
static_cast<Token::Value>(FIRST_TOKEN + OpField::decode(extra_ic_state));
|
static_cast<Token::Value>(FIRST_TOKEN + OpField::decode(extra_ic_state));
|
||||||
strong_ = StrongField::decode(extra_ic_state);
|
strong_ = StrengthField::decode(extra_ic_state);
|
||||||
left_kind_ = LeftKindField::decode(extra_ic_state);
|
left_kind_ = LeftKindField::decode(extra_ic_state);
|
||||||
right_kind_ = fixed_right_arg_.IsJust()
|
right_kind_ = fixed_right_arg_.IsJust()
|
||||||
? (Smi::IsValid(fixed_right_arg_.FromJust()) ? SMI : INT32)
|
? (Smi::IsValid(fixed_right_arg_.FromJust()) ? SMI : INT32)
|
||||||
@ -66,8 +66,7 @@ BinaryOpICState::BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state)
|
|||||||
ExtraICState BinaryOpICState::GetExtraICState() const {
|
ExtraICState BinaryOpICState::GetExtraICState() const {
|
||||||
ExtraICState extra_ic_state =
|
ExtraICState extra_ic_state =
|
||||||
OpField::encode(op_ - FIRST_TOKEN) | LeftKindField::encode(left_kind_) |
|
OpField::encode(op_ - FIRST_TOKEN) | LeftKindField::encode(left_kind_) |
|
||||||
ResultKindField::encode(result_kind_) |
|
ResultKindField::encode(result_kind_) | StrengthField::encode(strong_) |
|
||||||
StrongField::encode(strong_) |
|
|
||||||
HasFixedRightArgField::encode(fixed_right_arg_.IsJust());
|
HasFixedRightArgField::encode(fixed_right_arg_.IsJust());
|
||||||
if (fixed_right_arg_.IsJust()) {
|
if (fixed_right_arg_.IsJust()) {
|
||||||
extra_ic_state = FixedRightArgValueField::update(
|
extra_ic_state = FixedRightArgValueField::update(
|
||||||
@ -86,14 +85,14 @@ void BinaryOpICState::GenerateAheadOfTime(
|
|||||||
// expensive at runtime. When solved we should be able to add most binops to
|
// expensive at runtime. When solved we should be able to add most binops to
|
||||||
// the snapshot instead of hand-picking them.
|
// the snapshot instead of hand-picking them.
|
||||||
// Generated list of commonly used stubs
|
// Generated list of commonly used stubs
|
||||||
#define GENERATE(op, left_kind, right_kind, result_kind) \
|
#define GENERATE(op, left_kind, right_kind, result_kind) \
|
||||||
do { \
|
do { \
|
||||||
BinaryOpICState state(isolate, op, LanguageMode::SLOPPY); \
|
BinaryOpICState state(isolate, op, Strength::WEAK); \
|
||||||
state.left_kind_ = left_kind; \
|
state.left_kind_ = left_kind; \
|
||||||
state.fixed_right_arg_ = Nothing<int>(); \
|
state.fixed_right_arg_ = Nothing<int>(); \
|
||||||
state.right_kind_ = right_kind; \
|
state.right_kind_ = right_kind; \
|
||||||
state.result_kind_ = result_kind; \
|
state.result_kind_ = result_kind; \
|
||||||
Generate(isolate, state); \
|
Generate(isolate, state); \
|
||||||
} while (false)
|
} while (false)
|
||||||
GENERATE(Token::ADD, INT32, INT32, INT32);
|
GENERATE(Token::ADD, INT32, INT32, INT32);
|
||||||
GENERATE(Token::ADD, INT32, INT32, NUMBER);
|
GENERATE(Token::ADD, INT32, INT32, NUMBER);
|
||||||
@ -190,7 +189,7 @@ void BinaryOpICState::GenerateAheadOfTime(
|
|||||||
#undef GENERATE
|
#undef GENERATE
|
||||||
#define GENERATE(op, left_kind, fixed_right_arg_value, result_kind) \
|
#define GENERATE(op, left_kind, fixed_right_arg_value, result_kind) \
|
||||||
do { \
|
do { \
|
||||||
BinaryOpICState state(isolate, op, LanguageMode::SLOPPY); \
|
BinaryOpICState state(isolate, op, Strength::WEAK); \
|
||||||
state.left_kind_ = left_kind; \
|
state.left_kind_ = left_kind; \
|
||||||
state.fixed_right_arg_ = Just(fixed_right_arg_value); \
|
state.fixed_right_arg_ = Just(fixed_right_arg_value); \
|
||||||
state.right_kind_ = SMI; \
|
state.right_kind_ = SMI; \
|
||||||
|
@ -56,9 +56,9 @@ std::ostream& operator<<(std::ostream& os, const CallICState& s);
|
|||||||
class BinaryOpICState final BASE_EMBEDDED {
|
class BinaryOpICState final BASE_EMBEDDED {
|
||||||
public:
|
public:
|
||||||
BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state);
|
BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state);
|
||||||
BinaryOpICState(Isolate* isolate, Token::Value op, LanguageMode language_mode)
|
BinaryOpICState(Isolate* isolate, Token::Value op, Strength strength)
|
||||||
: op_(op),
|
: op_(op),
|
||||||
strong_(is_strong(language_mode)),
|
strong_(is_strong(strength)),
|
||||||
left_kind_(NONE),
|
left_kind_(NONE),
|
||||||
right_kind_(NONE),
|
right_kind_(NONE),
|
||||||
result_kind_(NONE),
|
result_kind_(NONE),
|
||||||
@ -105,8 +105,8 @@ class BinaryOpICState final BASE_EMBEDDED {
|
|||||||
return Max(left_kind_, right_kind_) == GENERIC;
|
return Max(left_kind_, right_kind_) == GENERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
LanguageMode language_mode() const {
|
Strength strength() const {
|
||||||
return strong_ ? LanguageMode::STRONG : LanguageMode::SLOPPY;
|
return strong_ ? Strength::STRONG : Strength::WEAK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the IC should enable the inline smi code (i.e. if either
|
// Returns true if the IC should enable the inline smi code (i.e. if either
|
||||||
@ -147,7 +147,7 @@ class BinaryOpICState final BASE_EMBEDDED {
|
|||||||
class OpField : public BitField<int, 0, 4> {};
|
class OpField : public BitField<int, 0, 4> {};
|
||||||
class ResultKindField : public BitField<Kind, 4, 3> {};
|
class ResultKindField : public BitField<Kind, 4, 3> {};
|
||||||
class LeftKindField : public BitField<Kind, 7, 3> {};
|
class LeftKindField : public BitField<Kind, 7, 3> {};
|
||||||
class StrongField : public BitField<bool, 10, 1> {};
|
class StrengthField : public BitField<bool, 10, 1> {};
|
||||||
// When fixed right arg is set, we don't need to store the right kind.
|
// When fixed right arg is set, we don't need to store the right kind.
|
||||||
// Thus the two fields can overlap.
|
// Thus the two fields can overlap.
|
||||||
class HasFixedRightArgField : public BitField<bool, 11, 1> {};
|
class HasFixedRightArgField : public BitField<bool, 11, 1> {};
|
||||||
|
18
src/ic/ic.cc
18
src/ic/ic.cc
@ -564,7 +564,7 @@ void CompareIC::Clear(Isolate* isolate, Address address, Code* target,
|
|||||||
// Only clear CompareICs that can retain objects.
|
// Only clear CompareICs that can retain objects.
|
||||||
if (stub.state() != CompareICState::KNOWN_OBJECT) return;
|
if (stub.state() != CompareICState::KNOWN_OBJECT) return;
|
||||||
SetTargetAtAddress(address,
|
SetTargetAtAddress(address,
|
||||||
GetRawUninitialized(isolate, stub.op(), stub.strong()),
|
GetRawUninitialized(isolate, stub.op(), stub.strength()),
|
||||||
constant_pool);
|
constant_pool);
|
||||||
PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK);
|
PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK);
|
||||||
}
|
}
|
||||||
@ -2431,7 +2431,7 @@ MaybeHandle<Object> BinaryOpIC::Transition(
|
|||||||
|
|
||||||
// Compute the actual result using the builtin for the binary operation.
|
// Compute the actual result using the builtin for the binary operation.
|
||||||
Object* builtin = isolate()->js_builtins_object()->javascript_builtin(
|
Object* builtin = isolate()->js_builtins_object()->javascript_builtin(
|
||||||
TokenToJSBuiltin(state.op(), state.language_mode()));
|
TokenToJSBuiltin(state.op(), state.strength()));
|
||||||
Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate());
|
Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate());
|
||||||
Handle<Object> result;
|
Handle<Object> result;
|
||||||
ASSIGN_RETURN_ON_EXCEPTION(
|
ASSIGN_RETURN_ON_EXCEPTION(
|
||||||
@ -2532,8 +2532,8 @@ RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite) {
|
|||||||
|
|
||||||
|
|
||||||
Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op,
|
Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op,
|
||||||
bool strong) {
|
Strength strength) {
|
||||||
CompareICStub stub(isolate, op, strong, CompareICState::UNINITIALIZED,
|
CompareICStub stub(isolate, op, strength, CompareICState::UNINITIALIZED,
|
||||||
CompareICState::UNINITIALIZED,
|
CompareICState::UNINITIALIZED,
|
||||||
CompareICState::UNINITIALIZED);
|
CompareICState::UNINITIALIZED);
|
||||||
Code* code = NULL;
|
Code* code = NULL;
|
||||||
@ -2543,8 +2543,8 @@ Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op,
|
|||||||
|
|
||||||
|
|
||||||
Handle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op,
|
Handle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op,
|
||||||
bool strong) {
|
Strength strength) {
|
||||||
CompareICStub stub(isolate, op, strong, CompareICState::UNINITIALIZED,
|
CompareICStub stub(isolate, op, strength, CompareICState::UNINITIALIZED,
|
||||||
CompareICState::UNINITIALIZED,
|
CompareICState::UNINITIALIZED,
|
||||||
CompareICState::UNINITIALIZED);
|
CompareICState::UNINITIALIZED);
|
||||||
return stub.GetCode();
|
return stub.GetCode();
|
||||||
@ -2561,7 +2561,7 @@ Code* CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
|
|||||||
CompareICState::State state = CompareICState::TargetState(
|
CompareICState::State state = CompareICState::TargetState(
|
||||||
old_stub.state(), old_stub.left(), old_stub.right(), op_,
|
old_stub.state(), old_stub.left(), old_stub.right(), op_,
|
||||||
HasInlinedSmiCode(address()), x, y);
|
HasInlinedSmiCode(address()), x, y);
|
||||||
CompareICStub stub(isolate(), op_, old_stub.strong(), new_left, new_right,
|
CompareICStub stub(isolate(), op_, old_stub.strength(), new_left, new_right,
|
||||||
state);
|
state);
|
||||||
if (state == CompareICState::KNOWN_OBJECT) {
|
if (state == CompareICState::KNOWN_OBJECT) {
|
||||||
stub.set_known_map(
|
stub.set_known_map(
|
||||||
@ -2671,8 +2671,8 @@ RUNTIME_FUNCTION(Unreachable) {
|
|||||||
|
|
||||||
|
|
||||||
Builtins::JavaScript BinaryOpIC::TokenToJSBuiltin(Token::Value op,
|
Builtins::JavaScript BinaryOpIC::TokenToJSBuiltin(Token::Value op,
|
||||||
LanguageMode language_mode) {
|
Strength strength) {
|
||||||
if (is_strong(language_mode)) {
|
if (is_strong(strength)) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
default: UNREACHABLE();
|
default: UNREACHABLE();
|
||||||
case Token::ADD: return Builtins::ADD_STRONG;
|
case Token::ADD: return Builtins::ADD_STRONG;
|
||||||
|
@ -652,7 +652,7 @@ class BinaryOpIC : public IC {
|
|||||||
explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
|
explicit BinaryOpIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
|
||||||
|
|
||||||
static Builtins::JavaScript TokenToJSBuiltin(Token::Value op,
|
static Builtins::JavaScript TokenToJSBuiltin(Token::Value op,
|
||||||
LanguageMode language_mode);
|
Strength strength);
|
||||||
|
|
||||||
MaybeHandle<Object> Transition(Handle<AllocationSite> allocation_site,
|
MaybeHandle<Object> Transition(Handle<AllocationSite> allocation_site,
|
||||||
Handle<Object> left,
|
Handle<Object> left,
|
||||||
@ -673,7 +673,7 @@ class CompareIC : public IC {
|
|||||||
|
|
||||||
// Factory method for getting an uninitialized compare stub.
|
// Factory method for getting an uninitialized compare stub.
|
||||||
static Handle<Code> GetUninitialized(Isolate* isolate, Token::Value op,
|
static Handle<Code> GetUninitialized(Isolate* isolate, Token::Value op,
|
||||||
bool strong);
|
Strength strength);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool HasInlinedSmiCode(Address address);
|
static bool HasInlinedSmiCode(Address address);
|
||||||
@ -682,7 +682,7 @@ class CompareIC : public IC {
|
|||||||
Condition GetCondition() const { return ComputeCondition(op_); }
|
Condition GetCondition() const { return ComputeCondition(op_); }
|
||||||
|
|
||||||
static Code* GetRawUninitialized(Isolate* isolate, Token::Value op,
|
static Code* GetRawUninitialized(Isolate* isolate, Token::Value op,
|
||||||
bool strong);
|
Strength strength);
|
||||||
|
|
||||||
static void Clear(Isolate* isolate, Address address, Code* target,
|
static void Clear(Isolate* isolate, Address address, Code* target,
|
||||||
Address constant_pool);
|
Address constant_pool);
|
||||||
|
@ -2370,11 +2370,11 @@ CodeTracer* Isolate::GetCodeTracer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Map* Isolate::get_initial_js_array_map(ElementsKind kind,
|
Map* Isolate::get_initial_js_array_map(ElementsKind kind, Strength strength) {
|
||||||
ObjectStrength strength) {
|
|
||||||
Context* native_context = context()->native_context();
|
Context* native_context = context()->native_context();
|
||||||
Object* maybe_map_array = strength ? native_context->js_array_strong_maps()
|
Object* maybe_map_array = is_strong(strength)
|
||||||
: native_context->js_array_maps();
|
? native_context->js_array_strong_maps()
|
||||||
|
: native_context->js_array_maps();
|
||||||
if (!maybe_map_array->IsUndefined()) {
|
if (!maybe_map_array->IsUndefined()) {
|
||||||
Object* maybe_transitioned_map =
|
Object* maybe_transitioned_map =
|
||||||
FixedArray::cast(maybe_map_array)->get(kind);
|
FixedArray::cast(maybe_map_array)->get(kind);
|
||||||
|
@ -991,7 +991,7 @@ class Isolate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Map* get_initial_js_array_map(ElementsKind kind,
|
Map* get_initial_js_array_map(ElementsKind kind,
|
||||||
ObjectStrength strength = WEAK);
|
Strength strength = Strength::WEAK);
|
||||||
|
|
||||||
static const int kArrayProtectorValid = 1;
|
static const int kArrayProtectorValid = 1;
|
||||||
static const int kArrayProtectorInvalid = 0;
|
static const int kArrayProtectorInvalid = 0;
|
||||||
|
@ -525,7 +525,7 @@ Handle<Object> JsonParser<seq_one_byte>::ParseJsonArray() {
|
|||||||
fast_elements->set(i, *elements[i]);
|
fast_elements->set(i, *elements[i]);
|
||||||
}
|
}
|
||||||
Handle<Object> json_array = factory()->NewJSArrayWithElements(
|
Handle<Object> json_array = factory()->NewJSArrayWithElements(
|
||||||
fast_elements, FAST_ELEMENTS, WEAK, pretenure_);
|
fast_elements, FAST_ELEMENTS, Strength::WEAK, pretenure_);
|
||||||
return scope.CloseAndEscape(json_array);
|
return scope.CloseAndEscape(json_array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ void InternalArrayNArgumentsConstructorStub::InitializeDescriptor(
|
|||||||
|
|
||||||
|
|
||||||
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
||||||
Condition cc, bool strong);
|
Condition cc, Strength strength);
|
||||||
static void EmitSmiNonsmiComparison(MacroAssembler* masm,
|
static void EmitSmiNonsmiComparison(MacroAssembler* masm,
|
||||||
Register lhs,
|
Register lhs,
|
||||||
Register rhs,
|
Register rhs,
|
||||||
@ -276,7 +276,7 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
|
|||||||
// Equality is almost reflexive (everything but NaN), so this is a test
|
// Equality is almost reflexive (everything but NaN), so this is a test
|
||||||
// for "identity and not NaN".
|
// for "identity and not NaN".
|
||||||
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
||||||
Condition cc, bool strong) {
|
Condition cc, Strength strength) {
|
||||||
Label not_identical;
|
Label not_identical;
|
||||||
Label heap_number, return_equal;
|
Label heap_number, return_equal;
|
||||||
Register exp_mask_reg = t5;
|
Register exp_mask_reg = t5;
|
||||||
@ -295,7 +295,7 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
|||||||
__ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE));
|
__ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE));
|
||||||
// Call runtime on identical symbols since we need to throw a TypeError.
|
// Call runtime on identical symbols since we need to throw a TypeError.
|
||||||
__ Branch(slow, eq, t4, Operand(SYMBOL_TYPE));
|
__ Branch(slow, eq, t4, Operand(SYMBOL_TYPE));
|
||||||
if (strong) {
|
if (is_strong(strength)) {
|
||||||
// Call the runtime on anything that is converted in the semantics, since
|
// Call the runtime on anything that is converted in the semantics, since
|
||||||
// we need to throw a TypeError. Smis have already been ruled out.
|
// we need to throw a TypeError. Smis have already been ruled out.
|
||||||
__ Branch(&return_equal, eq, t4, Operand(HEAP_NUMBER_TYPE));
|
__ Branch(&return_equal, eq, t4, Operand(HEAP_NUMBER_TYPE));
|
||||||
@ -309,7 +309,7 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
|||||||
__ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE));
|
__ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE));
|
||||||
// Call runtime on identical symbols since we need to throw a TypeError.
|
// Call runtime on identical symbols since we need to throw a TypeError.
|
||||||
__ Branch(slow, eq, t4, Operand(SYMBOL_TYPE));
|
__ Branch(slow, eq, t4, Operand(SYMBOL_TYPE));
|
||||||
if (strong) {
|
if (is_strong(strength)) {
|
||||||
// Call the runtime on anything that is converted in the semantics,
|
// Call the runtime on anything that is converted in the semantics,
|
||||||
// since we need to throw a TypeError. Smis and heap numbers have
|
// since we need to throw a TypeError. Smis and heap numbers have
|
||||||
// already been ruled out.
|
// already been ruled out.
|
||||||
@ -600,7 +600,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
|
|
||||||
// Handle the case where the objects are identical. Either returns the answer
|
// Handle the case where the objects are identical. Either returns the answer
|
||||||
// or goes to slow. Only falls through if the objects were not identical.
|
// or goes to slow. Only falls through if the objects were not identical.
|
||||||
EmitIdenticalObjectComparison(masm, &slow, cc, strong());
|
EmitIdenticalObjectComparison(masm, &slow, cc, strength());
|
||||||
|
|
||||||
// If either is a Smi (we know that not both are), then they can only
|
// If either is a Smi (we know that not both are), then they can only
|
||||||
// be strictly equal if the other is a HeapNumber.
|
// be strictly equal if the other is a HeapNumber.
|
||||||
@ -728,7 +728,8 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
if (cc == eq) {
|
if (cc == eq) {
|
||||||
native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
|
native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
|
||||||
} else {
|
} else {
|
||||||
native = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
native =
|
||||||
|
is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
||||||
int ncr; // NaN compare result.
|
int ncr; // NaN compare result.
|
||||||
if (cc == lt || cc == le) {
|
if (cc == lt || cc == le) {
|
||||||
ncr = GREATER;
|
ncr = GREATER;
|
||||||
@ -3757,7 +3758,7 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
|
|||||||
|
|
||||||
__ bind(&unordered);
|
__ bind(&unordered);
|
||||||
__ bind(&generic_stub);
|
__ bind(&generic_stub);
|
||||||
CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
|
CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC,
|
||||||
CompareICState::GENERIC, CompareICState::GENERIC);
|
CompareICState::GENERIC, CompareICState::GENERIC);
|
||||||
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
|
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
|
||||||
|
|
||||||
|
@ -1073,7 +1073,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
|||||||
// Record position before stub call for type feedback.
|
// Record position before stub call for type feedback.
|
||||||
SetSourcePosition(clause->position());
|
SetSourcePosition(clause->position());
|
||||||
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
|
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
|
||||||
language_mode()).code();
|
strength(language_mode())).code();
|
||||||
CallIC(ic, clause->CompareId());
|
CallIC(ic, clause->CompareId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
|
|
||||||
@ -2458,8 +2458,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
|||||||
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
|
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
|
||||||
|
|
||||||
__ bind(&stub_call);
|
__ bind(&stub_call);
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), op, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
|
||||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
__ jmp(&done);
|
__ jmp(&done);
|
||||||
@ -2611,8 +2611,8 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
|
|||||||
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
||||||
__ mov(a0, result_register());
|
__ mov(a0, result_register());
|
||||||
__ pop(a1);
|
__ pop(a1);
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), op, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
|
||||||
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
||||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
@ -5052,8 +5052,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|||||||
// Record position before stub call.
|
// Record position before stub call.
|
||||||
SetSourcePosition(expr->position());
|
SetSourcePosition(expr->position());
|
||||||
|
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD,
|
||||||
isolate(), Token::ADD, language_mode()).code();
|
strength(language_mode())).code();
|
||||||
CallIC(code, expr->CountBinOpFeedbackId());
|
CallIC(code, expr->CountBinOpFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
@ -5316,8 +5316,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
|||||||
}
|
}
|
||||||
// Record position and call the compare IC.
|
// Record position and call the compare IC.
|
||||||
SetSourcePosition(expr->position());
|
SetSourcePosition(expr->position());
|
||||||
Handle<Code> ic =
|
Handle<Code> ic = CodeFactory::CompareIC(
|
||||||
CodeFactory::CompareIC(isolate(), op, language_mode()).code();
|
isolate(), op, strength(language_mode())).code();
|
||||||
CallIC(ic, expr->CompareOperationFeedbackId());
|
CallIC(ic, expr->CompareOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||||
|
@ -2047,8 +2047,8 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
|
|||||||
DCHECK(ToRegister(instr->right()).is(a0));
|
DCHECK(ToRegister(instr->right()).is(a0));
|
||||||
DCHECK(ToRegister(instr->result()).is(v0));
|
DCHECK(ToRegister(instr->result()).is(v0));
|
||||||
|
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), instr->op(), instr->language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), instr->op(), instr->strength()).code();
|
||||||
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
||||||
// Other arch use a nop here, to signal that there is no inlined
|
// Other arch use a nop here, to signal that there is no inlined
|
||||||
// patchable code. Mips does not need the nop, since our marker
|
// patchable code. Mips does not need the nop, since our marker
|
||||||
@ -2530,7 +2530,8 @@ void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
|
|||||||
DCHECK(ToRegister(instr->context()).is(cp));
|
DCHECK(ToRegister(instr->context()).is(cp));
|
||||||
Token::Value op = instr->op();
|
Token::Value op = instr->op();
|
||||||
|
|
||||||
Handle<Code> ic = CodeFactory::CompareIC(isolate(), op, SLOPPY).code();
|
Handle<Code> ic =
|
||||||
|
CodeFactory::CompareIC(isolate(), op, Strength::WEAK).code();
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
|
|
||||||
Condition condition = ComputeCompareCondition(op);
|
Condition condition = ComputeCompareCondition(op);
|
||||||
@ -2833,7 +2834,7 @@ void LCodeGen::DoCmpT(LCmpT* instr) {
|
|||||||
Token::Value op = instr->op();
|
Token::Value op = instr->op();
|
||||||
|
|
||||||
Handle<Code> ic =
|
Handle<Code> ic =
|
||||||
CodeFactory::CompareIC(isolate(), op, instr->language_mode()).code();
|
CodeFactory::CompareIC(isolate(), op, instr->strength()).code();
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
// On MIPS there is no need for a "no inlined smi code" marker (nop).
|
// On MIPS there is no need for a "no inlined smi code" marker (nop).
|
||||||
|
|
||||||
|
@ -1154,7 +1154,7 @@ class LCmpT final : public LTemplateInstruction<1, 3, 0> {
|
|||||||
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
|
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
|
||||||
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
|
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
|
||||||
|
|
||||||
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
Strength strength() { return hydrogen()->strength(); }
|
||||||
|
|
||||||
Token::Value op() const { return hydrogen()->token(); }
|
Token::Value op() const { return hydrogen()->token(); }
|
||||||
};
|
};
|
||||||
@ -1512,7 +1512,7 @@ class LArithmeticT final : public LTemplateInstruction<1, 3, 0> {
|
|||||||
|
|
||||||
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
|
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
|
||||||
|
|
||||||
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
Strength strength() { return hydrogen()->strength(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Token::Value op_;
|
Token::Value op_;
|
||||||
|
@ -93,7 +93,7 @@ void InternalArrayNArgumentsConstructorStub::InitializeDescriptor(
|
|||||||
|
|
||||||
|
|
||||||
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
||||||
Condition cc, bool strong);
|
Condition cc, Strength strength);
|
||||||
static void EmitSmiNonsmiComparison(MacroAssembler* masm,
|
static void EmitSmiNonsmiComparison(MacroAssembler* masm,
|
||||||
Register lhs,
|
Register lhs,
|
||||||
Register rhs,
|
Register rhs,
|
||||||
@ -272,7 +272,7 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
|
|||||||
// Equality is almost reflexive (everything but NaN), so this is a test
|
// Equality is almost reflexive (everything but NaN), so this is a test
|
||||||
// for "identity and not NaN".
|
// for "identity and not NaN".
|
||||||
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
||||||
Condition cc, bool strong) {
|
Condition cc, Strength strength) {
|
||||||
Label not_identical;
|
Label not_identical;
|
||||||
Label heap_number, return_equal;
|
Label heap_number, return_equal;
|
||||||
Register exp_mask_reg = t1;
|
Register exp_mask_reg = t1;
|
||||||
@ -291,7 +291,7 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
|||||||
__ Branch(slow, greater, t0, Operand(FIRST_SPEC_OBJECT_TYPE));
|
__ Branch(slow, greater, t0, Operand(FIRST_SPEC_OBJECT_TYPE));
|
||||||
// Call runtime on identical symbols since we need to throw a TypeError.
|
// Call runtime on identical symbols since we need to throw a TypeError.
|
||||||
__ Branch(slow, eq, t0, Operand(SYMBOL_TYPE));
|
__ Branch(slow, eq, t0, Operand(SYMBOL_TYPE));
|
||||||
if (strong) {
|
if (is_strong(strength)) {
|
||||||
// Call the runtime on anything that is converted in the semantics, since
|
// Call the runtime on anything that is converted in the semantics, since
|
||||||
// we need to throw a TypeError. Smis have already been ruled out.
|
// we need to throw a TypeError. Smis have already been ruled out.
|
||||||
__ Branch(&return_equal, eq, t0, Operand(HEAP_NUMBER_TYPE));
|
__ Branch(&return_equal, eq, t0, Operand(HEAP_NUMBER_TYPE));
|
||||||
@ -305,7 +305,7 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
|||||||
__ Branch(slow, greater, t0, Operand(FIRST_SPEC_OBJECT_TYPE));
|
__ Branch(slow, greater, t0, Operand(FIRST_SPEC_OBJECT_TYPE));
|
||||||
// Call runtime on identical symbols since we need to throw a TypeError.
|
// Call runtime on identical symbols since we need to throw a TypeError.
|
||||||
__ Branch(slow, eq, t0, Operand(SYMBOL_TYPE));
|
__ Branch(slow, eq, t0, Operand(SYMBOL_TYPE));
|
||||||
if (strong) {
|
if (is_strong(strength)) {
|
||||||
// Call the runtime on anything that is converted in the semantics,
|
// Call the runtime on anything that is converted in the semantics,
|
||||||
// since we need to throw a TypeError. Smis and heap numbers have
|
// since we need to throw a TypeError. Smis and heap numbers have
|
||||||
// already been ruled out.
|
// already been ruled out.
|
||||||
@ -595,7 +595,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
|
|
||||||
// Handle the case where the objects are identical. Either returns the answer
|
// Handle the case where the objects are identical. Either returns the answer
|
||||||
// or goes to slow. Only falls through if the objects were not identical.
|
// or goes to slow. Only falls through if the objects were not identical.
|
||||||
EmitIdenticalObjectComparison(masm, &slow, cc, strong());
|
EmitIdenticalObjectComparison(masm, &slow, cc, strength());
|
||||||
|
|
||||||
// If either is a Smi (we know that not both are), then they can only
|
// If either is a Smi (we know that not both are), then they can only
|
||||||
// be strictly equal if the other is a HeapNumber.
|
// be strictly equal if the other is a HeapNumber.
|
||||||
@ -723,7 +723,8 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
if (cc == eq) {
|
if (cc == eq) {
|
||||||
native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
|
native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
|
||||||
} else {
|
} else {
|
||||||
native = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
native =
|
||||||
|
is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
||||||
int ncr; // NaN compare result.
|
int ncr; // NaN compare result.
|
||||||
if (cc == lt || cc == le) {
|
if (cc == lt || cc == le) {
|
||||||
ncr = GREATER;
|
ncr = GREATER;
|
||||||
@ -3800,7 +3801,7 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
|
|||||||
|
|
||||||
__ bind(&unordered);
|
__ bind(&unordered);
|
||||||
__ bind(&generic_stub);
|
__ bind(&generic_stub);
|
||||||
CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
|
CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC,
|
||||||
CompareICState::GENERIC, CompareICState::GENERIC);
|
CompareICState::GENERIC, CompareICState::GENERIC);
|
||||||
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
|
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
|
||||||
|
|
||||||
|
@ -1070,7 +1070,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
|||||||
// Record position before stub call for type feedback.
|
// Record position before stub call for type feedback.
|
||||||
SetSourcePosition(clause->position());
|
SetSourcePosition(clause->position());
|
||||||
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
|
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
|
||||||
language_mode()).code();
|
strength(language_mode())).code();
|
||||||
CallIC(ic, clause->CompareId());
|
CallIC(ic, clause->CompareId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
|
|
||||||
@ -2458,8 +2458,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
|||||||
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
|
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
|
||||||
|
|
||||||
__ bind(&stub_call);
|
__ bind(&stub_call);
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), op, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
|
||||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
__ jmp(&done);
|
__ jmp(&done);
|
||||||
@ -2610,8 +2610,8 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
|
|||||||
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
||||||
__ mov(a0, result_register());
|
__ mov(a0, result_register());
|
||||||
__ pop(a1);
|
__ pop(a1);
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), op, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
|
||||||
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
||||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
@ -5055,8 +5055,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|||||||
// Record position before stub call.
|
// Record position before stub call.
|
||||||
SetSourcePosition(expr->position());
|
SetSourcePosition(expr->position());
|
||||||
|
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD,
|
||||||
isolate(), Token::ADD, language_mode()).code();
|
strength(language_mode())).code();
|
||||||
CallIC(code, expr->CountBinOpFeedbackId());
|
CallIC(code, expr->CountBinOpFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
@ -5319,8 +5319,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
|||||||
}
|
}
|
||||||
// Record position and call the compare IC.
|
// Record position and call the compare IC.
|
||||||
SetSourcePosition(expr->position());
|
SetSourcePosition(expr->position());
|
||||||
Handle<Code> ic =
|
Handle<Code> ic = CodeFactory::CompareIC(
|
||||||
CodeFactory::CompareIC(isolate(), op, language_mode()).code();
|
isolate(), op, strength(language_mode())).code();
|
||||||
CallIC(ic, expr->CompareOperationFeedbackId());
|
CallIC(ic, expr->CompareOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||||
|
@ -2043,8 +2043,8 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
|
|||||||
DCHECK(ToRegister(instr->right()).is(a0));
|
DCHECK(ToRegister(instr->right()).is(a0));
|
||||||
DCHECK(ToRegister(instr->result()).is(v0));
|
DCHECK(ToRegister(instr->result()).is(v0));
|
||||||
|
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), instr->op(), instr->language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), instr->op(), instr->strength()).code();
|
||||||
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
||||||
// Other arch use a nop here, to signal that there is no inlined
|
// Other arch use a nop here, to signal that there is no inlined
|
||||||
// patchable code. Mips does not need the nop, since our marker
|
// patchable code. Mips does not need the nop, since our marker
|
||||||
@ -2529,7 +2529,8 @@ void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
|
|||||||
DCHECK(ToRegister(instr->context()).is(cp));
|
DCHECK(ToRegister(instr->context()).is(cp));
|
||||||
Token::Value op = instr->op();
|
Token::Value op = instr->op();
|
||||||
|
|
||||||
Handle<Code> ic = CodeFactory::CompareIC(isolate(), op, SLOPPY).code();
|
Handle<Code> ic =
|
||||||
|
CodeFactory::CompareIC(isolate(), op, Strength::WEAK).code();
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
|
|
||||||
Condition condition = ComputeCompareCondition(op);
|
Condition condition = ComputeCompareCondition(op);
|
||||||
@ -2832,7 +2833,7 @@ void LCodeGen::DoCmpT(LCmpT* instr) {
|
|||||||
Token::Value op = instr->op();
|
Token::Value op = instr->op();
|
||||||
|
|
||||||
Handle<Code> ic =
|
Handle<Code> ic =
|
||||||
CodeFactory::CompareIC(isolate(), op, instr->language_mode()).code();
|
CodeFactory::CompareIC(isolate(), op, instr->strength()).code();
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
// On MIPS there is no need for a "no inlined smi code" marker (nop).
|
// On MIPS there is no need for a "no inlined smi code" marker (nop).
|
||||||
|
|
||||||
|
@ -1153,7 +1153,7 @@ class LCmpT final : public LTemplateInstruction<1, 3, 0> {
|
|||||||
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
|
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
|
||||||
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
|
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
|
||||||
|
|
||||||
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
Strength strength() { return hydrogen()->strength(); }
|
||||||
|
|
||||||
Token::Value op() const { return hydrogen()->token(); }
|
Token::Value op() const { return hydrogen()->token(); }
|
||||||
};
|
};
|
||||||
@ -1510,7 +1510,7 @@ class LArithmeticT final : public LTemplateInstruction<1, 3, 0> {
|
|||||||
|
|
||||||
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
|
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
|
||||||
|
|
||||||
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
Strength strength() { return hydrogen()->strength(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Token::Value op_;
|
Token::Value op_;
|
||||||
|
@ -94,7 +94,7 @@ void InternalArrayNArgumentsConstructorStub::InitializeDescriptor(
|
|||||||
|
|
||||||
|
|
||||||
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
||||||
Condition cond, bool strong);
|
Condition cond, Strength strength);
|
||||||
static void EmitSmiNonsmiComparison(MacroAssembler* masm, Register lhs,
|
static void EmitSmiNonsmiComparison(MacroAssembler* masm, Register lhs,
|
||||||
Register rhs, Label* lhs_not_nan,
|
Register rhs, Label* lhs_not_nan,
|
||||||
Label* slow, bool strict);
|
Label* slow, bool strict);
|
||||||
@ -249,7 +249,7 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
|
|||||||
// Equality is almost reflexive (everything but NaN), so this is a test
|
// Equality is almost reflexive (everything but NaN), so this is a test
|
||||||
// for "identity and not NaN".
|
// for "identity and not NaN".
|
||||||
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
||||||
Condition cond, bool strong) {
|
Condition cond, Strength strength) {
|
||||||
Label not_identical;
|
Label not_identical;
|
||||||
Label heap_number, return_equal;
|
Label heap_number, return_equal;
|
||||||
__ cmp(r3, r4);
|
__ cmp(r3, r4);
|
||||||
@ -266,7 +266,7 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
|||||||
// Call runtime on identical symbols since we need to throw a TypeError.
|
// Call runtime on identical symbols since we need to throw a TypeError.
|
||||||
__ cmpi(r7, Operand(SYMBOL_TYPE));
|
__ cmpi(r7, Operand(SYMBOL_TYPE));
|
||||||
__ beq(slow);
|
__ beq(slow);
|
||||||
if (strong) {
|
if (is_strong(strength)) {
|
||||||
// Call the runtime on anything that is converted in the semantics, since
|
// Call the runtime on anything that is converted in the semantics, since
|
||||||
// we need to throw a TypeError. Smis have already been ruled out.
|
// we need to throw a TypeError. Smis have already been ruled out.
|
||||||
__ cmpi(r7, Operand(HEAP_NUMBER_TYPE));
|
__ cmpi(r7, Operand(HEAP_NUMBER_TYPE));
|
||||||
@ -284,7 +284,7 @@ static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
|
|||||||
// Call runtime on identical symbols since we need to throw a TypeError.
|
// Call runtime on identical symbols since we need to throw a TypeError.
|
||||||
__ cmpi(r7, Operand(SYMBOL_TYPE));
|
__ cmpi(r7, Operand(SYMBOL_TYPE));
|
||||||
__ beq(slow);
|
__ beq(slow);
|
||||||
if (strong) {
|
if (is_strong(strength)) {
|
||||||
// Call the runtime on anything that is converted in the semantics,
|
// Call the runtime on anything that is converted in the semantics,
|
||||||
// since we need to throw a TypeError. Smis and heap numbers have
|
// since we need to throw a TypeError. Smis and heap numbers have
|
||||||
// already been ruled out.
|
// already been ruled out.
|
||||||
@ -594,7 +594,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
|
|
||||||
// Handle the case where the objects are identical. Either returns the answer
|
// Handle the case where the objects are identical. Either returns the answer
|
||||||
// or goes to slow. Only falls through if the objects were not identical.
|
// or goes to slow. Only falls through if the objects were not identical.
|
||||||
EmitIdenticalObjectComparison(masm, &slow, cc, strong());
|
EmitIdenticalObjectComparison(masm, &slow, cc, strength());
|
||||||
|
|
||||||
// If either is a Smi (we know that not both are), then they can only
|
// If either is a Smi (we know that not both are), then they can only
|
||||||
// be strictly equal if the other is a HeapNumber.
|
// be strictly equal if the other is a HeapNumber.
|
||||||
@ -705,7 +705,8 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
if (cc == eq) {
|
if (cc == eq) {
|
||||||
native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
|
native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
|
||||||
} else {
|
} else {
|
||||||
native = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
native =
|
||||||
|
is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
||||||
int ncr; // NaN compare result
|
int ncr; // NaN compare result
|
||||||
if (cc == lt || cc == le) {
|
if (cc == lt || cc == le) {
|
||||||
ncr = GREATER;
|
ncr = GREATER;
|
||||||
@ -3805,7 +3806,7 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
|
|||||||
|
|
||||||
__ bind(&unordered);
|
__ bind(&unordered);
|
||||||
__ bind(&generic_stub);
|
__ bind(&generic_stub);
|
||||||
CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
|
CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC,
|
||||||
CompareICState::GENERIC, CompareICState::GENERIC);
|
CompareICState::GENERIC, CompareICState::GENERIC);
|
||||||
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
|
__ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
|
||||||
|
|
||||||
|
@ -1042,7 +1042,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
|||||||
// Record position before stub call for type feedback.
|
// Record position before stub call for type feedback.
|
||||||
SetSourcePosition(clause->position());
|
SetSourcePosition(clause->position());
|
||||||
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
|
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
|
||||||
language_mode()).code();
|
strength(language_mode())).code();
|
||||||
CallIC(ic, clause->CompareId());
|
CallIC(ic, clause->CompareId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
|
|
||||||
@ -2446,8 +2446,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
|||||||
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
|
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
|
||||||
|
|
||||||
__ bind(&stub_call);
|
__ bind(&stub_call);
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), op, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
|
||||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
__ b(&done);
|
__ b(&done);
|
||||||
@ -2623,8 +2623,8 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
|
|||||||
|
|
||||||
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
||||||
__ pop(r4);
|
__ pop(r4);
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), op, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
|
||||||
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
||||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
@ -5053,8 +5053,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|||||||
// Record position before stub call.
|
// Record position before stub call.
|
||||||
SetSourcePosition(expr->position());
|
SetSourcePosition(expr->position());
|
||||||
|
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD,
|
||||||
isolate(), Token::ADD, language_mode()).code();
|
strength(language_mode())).code();
|
||||||
CallIC(code, expr->CountBinOpFeedbackId());
|
CallIC(code, expr->CountBinOpFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
@ -5323,8 +5323,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
|||||||
|
|
||||||
// Record position and call the compare IC.
|
// Record position and call the compare IC.
|
||||||
SetSourcePosition(expr->position());
|
SetSourcePosition(expr->position());
|
||||||
Handle<Code> ic =
|
Handle<Code> ic = CodeFactory::CompareIC(
|
||||||
CodeFactory::CompareIC(isolate(), op, language_mode()).code();
|
isolate(), op, strength(language_mode())).code();
|
||||||
CallIC(ic, expr->CompareOperationFeedbackId());
|
CallIC(ic, expr->CompareOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
|
||||||
|
@ -2188,8 +2188,8 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
|
|||||||
DCHECK(ToRegister(instr->right()).is(r3));
|
DCHECK(ToRegister(instr->right()).is(r3));
|
||||||
DCHECK(ToRegister(instr->result()).is(r3));
|
DCHECK(ToRegister(instr->result()).is(r3));
|
||||||
|
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), instr->op(), instr->language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), instr->op(), instr->strength()).code();
|
||||||
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2665,7 +2665,8 @@ void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
|
|||||||
DCHECK(ToRegister(instr->context()).is(cp));
|
DCHECK(ToRegister(instr->context()).is(cp));
|
||||||
Token::Value op = instr->op();
|
Token::Value op = instr->op();
|
||||||
|
|
||||||
Handle<Code> ic = CodeFactory::CompareIC(isolate(), op, SLOPPY).code();
|
Handle<Code> ic =
|
||||||
|
CodeFactory::CompareIC(isolate(), op, Strength::WEAK).code();
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
// This instruction also signals no smi code inlined
|
// This instruction also signals no smi code inlined
|
||||||
__ cmpi(r3, Operand::Zero());
|
__ cmpi(r3, Operand::Zero());
|
||||||
@ -2973,7 +2974,7 @@ void LCodeGen::DoCmpT(LCmpT* instr) {
|
|||||||
Token::Value op = instr->op();
|
Token::Value op = instr->op();
|
||||||
|
|
||||||
Handle<Code> ic =
|
Handle<Code> ic =
|
||||||
CodeFactory::CompareIC(isolate(), op, instr->language_mode()).code();
|
CodeFactory::CompareIC(isolate(), op, instr->strength()).code();
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
// This instruction also signals no smi code inlined
|
// This instruction also signals no smi code inlined
|
||||||
__ cmpi(r3, Operand::Zero());
|
__ cmpi(r3, Operand::Zero());
|
||||||
|
@ -1131,7 +1131,7 @@ class LCmpT final : public LTemplateInstruction<1, 3, 0> {
|
|||||||
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
|
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
|
||||||
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
|
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
|
||||||
|
|
||||||
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
Strength strength() { return hydrogen()->strength(); }
|
||||||
|
|
||||||
Token::Value op() const { return hydrogen()->token(); }
|
Token::Value op() const { return hydrogen()->token(); }
|
||||||
};
|
};
|
||||||
@ -1495,7 +1495,7 @@ class LArithmeticT final : public LTemplateInstruction<1, 3, 0> {
|
|||||||
|
|
||||||
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
|
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
|
||||||
|
|
||||||
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
Strength strength() { return hydrogen()->strength(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Token::Value op_;
|
Token::Value op_;
|
||||||
|
@ -1566,7 +1566,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
// Check for undefined. undefined OP undefined is false even though
|
// Check for undefined. undefined OP undefined is false even though
|
||||||
// undefined == undefined.
|
// undefined == undefined.
|
||||||
__ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
|
__ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
|
||||||
if (strong()) {
|
if (is_strong(strength())) {
|
||||||
// In strong mode, this comparison must throw, so call the runtime.
|
// In strong mode, this comparison must throw, so call the runtime.
|
||||||
__ j(equal, &runtime_call, Label::kFar);
|
__ j(equal, &runtime_call, Label::kFar);
|
||||||
} else {
|
} else {
|
||||||
@ -1594,7 +1594,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
// Call runtime on identical symbols since we need to throw a TypeError.
|
// Call runtime on identical symbols since we need to throw a TypeError.
|
||||||
__ cmpb(rcx, Immediate(static_cast<uint8_t>(SYMBOL_TYPE)));
|
__ cmpb(rcx, Immediate(static_cast<uint8_t>(SYMBOL_TYPE)));
|
||||||
__ j(equal, &runtime_call, Label::kFar);
|
__ j(equal, &runtime_call, Label::kFar);
|
||||||
if (strong()) {
|
if (is_strong(strength())) {
|
||||||
// We have already tested for smis and heap numbers, so if both
|
// We have already tested for smis and heap numbers, so if both
|
||||||
// arguments are not strings we must proceed to the slow case.
|
// arguments are not strings we must proceed to the slow case.
|
||||||
__ testb(rcx, Immediate(kIsNotStringMask));
|
__ testb(rcx, Immediate(kIsNotStringMask));
|
||||||
@ -1785,7 +1785,8 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
if (cc == equal) {
|
if (cc == equal) {
|
||||||
builtin = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
|
builtin = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
|
||||||
} else {
|
} else {
|
||||||
builtin = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
builtin =
|
||||||
|
is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
||||||
__ Push(Smi::FromInt(NegativeComparisonResult(cc)));
|
__ Push(Smi::FromInt(NegativeComparisonResult(cc)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3610,7 +3611,7 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
|
|||||||
|
|
||||||
__ bind(&unordered);
|
__ bind(&unordered);
|
||||||
__ bind(&generic_stub);
|
__ bind(&generic_stub);
|
||||||
CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
|
CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC,
|
||||||
CompareICState::GENERIC, CompareICState::GENERIC);
|
CompareICState::GENERIC, CompareICState::GENERIC);
|
||||||
__ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
|
__ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
|
||||||
|
|
||||||
|
@ -1039,7 +1039,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
|||||||
// Record position before stub call for type feedback.
|
// Record position before stub call for type feedback.
|
||||||
SetSourcePosition(clause->position());
|
SetSourcePosition(clause->position());
|
||||||
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
|
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
|
||||||
language_mode()).code();
|
strength(language_mode())).code();
|
||||||
CallIC(ic, clause->CompareId());
|
CallIC(ic, clause->CompareId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
|
|
||||||
@ -2416,8 +2416,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
|||||||
|
|
||||||
__ bind(&stub_call);
|
__ bind(&stub_call);
|
||||||
__ movp(rax, rcx);
|
__ movp(rax, rcx);
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), op, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
|
||||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
__ jmp(&done, Label::kNear);
|
__ jmp(&done, Label::kNear);
|
||||||
@ -2538,8 +2538,8 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
|
|||||||
|
|
||||||
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
||||||
__ Pop(rdx);
|
__ Pop(rdx);
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), op, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
|
||||||
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
||||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
@ -4990,8 +4990,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|||||||
__ bind(&stub_call);
|
__ bind(&stub_call);
|
||||||
__ movp(rdx, rax);
|
__ movp(rdx, rax);
|
||||||
__ Move(rax, Smi::FromInt(1));
|
__ Move(rax, Smi::FromInt(1));
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(),
|
||||||
isolate(), expr->binary_op(), language_mode()).code();
|
strength(language_mode())).code();
|
||||||
CallIC(code, expr->CountBinOpFeedbackId());
|
CallIC(code, expr->CountBinOpFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
@ -5257,8 +5257,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
|||||||
|
|
||||||
// Record position and call the compare IC.
|
// Record position and call the compare IC.
|
||||||
SetSourcePosition(expr->position());
|
SetSourcePosition(expr->position());
|
||||||
Handle<Code> ic =
|
Handle<Code> ic = CodeFactory::CompareIC(
|
||||||
CodeFactory::CompareIC(isolate(), op, language_mode()).code();
|
isolate(), op, strength(language_mode())).code();
|
||||||
CallIC(ic, expr->CompareOperationFeedbackId());
|
CallIC(ic, expr->CompareOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
|
|
||||||
|
@ -2099,8 +2099,8 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
|
|||||||
DCHECK(ToRegister(instr->right()).is(rax));
|
DCHECK(ToRegister(instr->right()).is(rax));
|
||||||
DCHECK(ToRegister(instr->result()).is(rax));
|
DCHECK(ToRegister(instr->result()).is(rax));
|
||||||
|
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), instr->op(), instr->language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), instr->op(), instr->strength()).code();
|
||||||
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2543,7 +2543,8 @@ void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
|
|||||||
DCHECK(ToRegister(instr->context()).is(rsi));
|
DCHECK(ToRegister(instr->context()).is(rsi));
|
||||||
Token::Value op = instr->op();
|
Token::Value op = instr->op();
|
||||||
|
|
||||||
Handle<Code> ic = CodeFactory::CompareIC(isolate(), op, SLOPPY).code();
|
Handle<Code> ic =
|
||||||
|
CodeFactory::CompareIC(isolate(), op, Strength::WEAK).code();
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
|
|
||||||
Condition condition = TokenToCondition(op, false);
|
Condition condition = TokenToCondition(op, false);
|
||||||
@ -2828,7 +2829,7 @@ void LCodeGen::DoCmpT(LCmpT* instr) {
|
|||||||
Token::Value op = instr->op();
|
Token::Value op = instr->op();
|
||||||
|
|
||||||
Handle<Code> ic =
|
Handle<Code> ic =
|
||||||
CodeFactory::CompareIC(isolate(), op, instr->language_mode()).code();
|
CodeFactory::CompareIC(isolate(), op, instr->strength()).code();
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
|
|
||||||
Condition condition = TokenToCondition(op, false);
|
Condition condition = TokenToCondition(op, false);
|
||||||
|
@ -1152,7 +1152,7 @@ class LCmpT final : public LTemplateInstruction<1, 3, 0> {
|
|||||||
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
|
DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
|
||||||
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
|
DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
|
||||||
|
|
||||||
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
Strength strength() { return hydrogen()->strength(); }
|
||||||
|
|
||||||
Token::Value op() const { return hydrogen()->token(); }
|
Token::Value op() const { return hydrogen()->token(); }
|
||||||
};
|
};
|
||||||
@ -1519,7 +1519,7 @@ class LArithmeticT final : public LTemplateInstruction<1, 3, 0> {
|
|||||||
|
|
||||||
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
|
DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
|
||||||
|
|
||||||
LanguageMode language_mode() { return hydrogen()->language_mode(); }
|
Strength strength() { return hydrogen()->strength(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Token::Value op_;
|
Token::Value op_;
|
||||||
|
@ -1371,7 +1371,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
// Check for undefined. undefined OP undefined is false even though
|
// Check for undefined. undefined OP undefined is false even though
|
||||||
// undefined == undefined.
|
// undefined == undefined.
|
||||||
__ cmp(edx, isolate()->factory()->undefined_value());
|
__ cmp(edx, isolate()->factory()->undefined_value());
|
||||||
if (strong()) {
|
if (is_strong(strength())) {
|
||||||
// In strong mode, this comparison must throw, so call the runtime.
|
// In strong mode, this comparison must throw, so call the runtime.
|
||||||
__ j(equal, &runtime_call, Label::kFar);
|
__ j(equal, &runtime_call, Label::kFar);
|
||||||
} else {
|
} else {
|
||||||
@ -1397,7 +1397,7 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
// Call runtime on identical symbols since we need to throw a TypeError.
|
// Call runtime on identical symbols since we need to throw a TypeError.
|
||||||
__ cmpb(ecx, static_cast<uint8_t>(SYMBOL_TYPE));
|
__ cmpb(ecx, static_cast<uint8_t>(SYMBOL_TYPE));
|
||||||
__ j(equal, &runtime_call, Label::kFar);
|
__ j(equal, &runtime_call, Label::kFar);
|
||||||
if (strong()) {
|
if (is_strong(strength())) {
|
||||||
// We have already tested for smis and heap numbers, so if both
|
// We have already tested for smis and heap numbers, so if both
|
||||||
// arguments are not strings we must proceed to the slow case.
|
// arguments are not strings we must proceed to the slow case.
|
||||||
__ test(ecx, Immediate(kIsNotStringMask));
|
__ test(ecx, Immediate(kIsNotStringMask));
|
||||||
@ -1601,7 +1601,8 @@ void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
|
|||||||
if (cc == equal) {
|
if (cc == equal) {
|
||||||
builtin = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
|
builtin = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
|
||||||
} else {
|
} else {
|
||||||
builtin = strong() ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
builtin =
|
||||||
|
is_strong(strength()) ? Builtins::COMPARE_STRONG : Builtins::COMPARE;
|
||||||
__ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
|
__ push(Immediate(Smi::FromInt(NegativeComparisonResult(cc))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3307,7 +3308,7 @@ void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
|
|||||||
|
|
||||||
__ bind(&unordered);
|
__ bind(&unordered);
|
||||||
__ bind(&generic_stub);
|
__ bind(&generic_stub);
|
||||||
CompareICStub stub(isolate(), op(), strong(), CompareICState::GENERIC,
|
CompareICStub stub(isolate(), op(), strength(), CompareICState::GENERIC,
|
||||||
CompareICState::GENERIC, CompareICState::GENERIC);
|
CompareICState::GENERIC, CompareICState::GENERIC);
|
||||||
__ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
|
__ jmp(stub.GetCode(), RelocInfo::CODE_TARGET);
|
||||||
|
|
||||||
|
@ -991,7 +991,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
|
|||||||
// Record position before stub call for type feedback.
|
// Record position before stub call for type feedback.
|
||||||
SetSourcePosition(clause->position());
|
SetSourcePosition(clause->position());
|
||||||
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
|
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
|
||||||
language_mode()).code();
|
strength(language_mode())).code();
|
||||||
CallIC(ic, clause->CompareId());
|
CallIC(ic, clause->CompareId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
|
|
||||||
@ -2357,8 +2357,8 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
|||||||
|
|
||||||
__ bind(&stub_call);
|
__ bind(&stub_call);
|
||||||
__ mov(eax, ecx);
|
__ mov(eax, ecx);
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), op, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
|
||||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
__ jmp(&done, Label::kNear);
|
__ jmp(&done, Label::kNear);
|
||||||
@ -2502,8 +2502,8 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
|
|||||||
|
|
||||||
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
||||||
__ pop(edx);
|
__ pop(edx);
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), op, language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), op, strength(language_mode())).code();
|
||||||
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
||||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
@ -4907,9 +4907,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
|||||||
__ bind(&stub_call);
|
__ bind(&stub_call);
|
||||||
__ mov(edx, eax);
|
__ mov(edx, eax);
|
||||||
__ mov(eax, Immediate(Smi::FromInt(1)));
|
__ mov(eax, Immediate(Smi::FromInt(1)));
|
||||||
Handle<Code> code =
|
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(),
|
||||||
CodeFactory::BinaryOpIC(
|
strength(language_mode())).code();
|
||||||
isolate(), expr->binary_op(), language_mode()).code();
|
|
||||||
CallIC(code, expr->CountBinOpFeedbackId());
|
CallIC(code, expr->CountBinOpFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
__ bind(&done);
|
__ bind(&done);
|
||||||
@ -5176,8 +5175,8 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
|
|||||||
|
|
||||||
// Record position and call the compare IC.
|
// Record position and call the compare IC.
|
||||||
SetSourcePosition(expr->position());
|
SetSourcePosition(expr->position());
|
||||||
Handle<Code> ic =
|
Handle<Code> ic = CodeFactory::CompareIC(
|
||||||
CodeFactory::CompareIC(isolate(), op, language_mode()).code();
|
isolate(), op, strength(language_mode())).code();
|
||||||
CallIC(ic, expr->CompareOperationFeedbackId());
|
CallIC(ic, expr->CompareOperationFeedbackId());
|
||||||
patch_site.EmitPatchInfo();
|
patch_site.EmitPatchInfo();
|
||||||
|
|
||||||
|
@ -2340,8 +2340,8 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
|
|||||||
DCHECK(ToRegister(instr->right()).is(eax));
|
DCHECK(ToRegister(instr->right()).is(eax));
|
||||||
DCHECK(ToRegister(instr->result()).is(eax));
|
DCHECK(ToRegister(instr->result()).is(eax));
|
||||||
|
|
||||||
Handle<Code> code = CodeFactory::BinaryOpIC(
|
Handle<Code> code =
|
||||||
isolate(), instr->op(), instr->language_mode()).code();
|
CodeFactory::BinaryOpIC(isolate(), instr->op(), instr->strength()).code();
|
||||||
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2773,7 +2773,8 @@ static Condition ComputeCompareCondition(Token::Value op) {
|
|||||||
void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
|
void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
|
||||||
Token::Value op = instr->op();
|
Token::Value op = instr->op();
|
||||||
|
|
||||||
Handle<Code> ic = CodeFactory::CompareIC(isolate(), op, SLOPPY).code();
|
Handle<Code> ic =
|
||||||
|
CodeFactory::CompareIC(isolate(), op, Strength::WEAK).code();
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
|
|
||||||
Condition condition = ComputeCompareCondition(op);
|
Condition condition = ComputeCompareCondition(op);
|
||||||
@ -3046,7 +3047,7 @@ void LCodeGen::DoCmpT(LCmpT* instr) {
|
|||||||
Token::Value op = instr->op();
|
Token::Value op = instr->op();
|
||||||
|
|
||||||
Handle<Code> ic =
|
Handle<Code> ic =
|
||||||
CodeFactory::CompareIC(isolate(), op, instr->language_mode()).code();
|
CodeFactory::CompareIC(isolate(), op, instr->strength()).code();
|
||||||
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
CallCode(ic, RelocInfo::CODE_TARGET, instr);
|
||||||
|
|
||||||
Condition condition = ComputeCompareCondition(op);
|
Condition condition = ComputeCompareCondition(op);
|
||||||
|
@ -952,7 +952,7 @@ TEST(Iteration) {
|
|||||||
// Allocate a JS array to OLD_SPACE and NEW_SPACE
|
// Allocate a JS array to OLD_SPACE and NEW_SPACE
|
||||||
objs[next_objs_index++] = factory->NewJSArray(10);
|
objs[next_objs_index++] = factory->NewJSArray(10);
|
||||||
objs[next_objs_index++] =
|
objs[next_objs_index++] =
|
||||||
factory->NewJSArray(10, FAST_HOLEY_ELEMENTS, WEAK, TENURED);
|
factory->NewJSArray(10, FAST_HOLEY_ELEMENTS, Strength::WEAK, TENURED);
|
||||||
|
|
||||||
// Allocate a small string to OLD_DATA_SPACE and NEW_SPACE
|
// Allocate a small string to OLD_DATA_SPACE and NEW_SPACE
|
||||||
objs[next_objs_index++] = factory->NewStringFromStaticChars("abcdefghij");
|
objs[next_objs_index++] = factory->NewStringFromStaticChars("abcdefghij");
|
||||||
@ -2530,8 +2530,8 @@ TEST(PrototypeTransitionClearing) {
|
|||||||
{
|
{
|
||||||
AlwaysAllocateScope always_allocate(isolate);
|
AlwaysAllocateScope always_allocate(isolate);
|
||||||
SimulateFullSpace(space);
|
SimulateFullSpace(space);
|
||||||
prototype =
|
prototype = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS,
|
||||||
factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, WEAK, TENURED);
|
Strength::WEAK, TENURED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a prototype on an evacuation candidate and verify that transition
|
// Add a prototype on an evacuation candidate and verify that transition
|
||||||
|
@ -1035,7 +1035,7 @@ TEST(DoScavenge) {
|
|||||||
CcTest::heap()->CollectGarbage(i::NEW_SPACE);
|
CcTest::heap()->CollectGarbage(i::NEW_SPACE);
|
||||||
|
|
||||||
// Create temp object in the new space.
|
// Create temp object in the new space.
|
||||||
Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, WEAK, NOT_TENURED);
|
Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS);
|
||||||
CHECK(isolate->heap()->new_space()->Contains(*temp));
|
CHECK(isolate->heap()->new_space()->Contains(*temp));
|
||||||
|
|
||||||
// Construct a double value that looks like a pointer to the new space object
|
// Construct a double value that looks like a pointer to the new space object
|
||||||
@ -1088,8 +1088,8 @@ TEST(DoScavengeWithIncrementalWriteBarrier) {
|
|||||||
AlwaysAllocateScope always_allocate(isolate);
|
AlwaysAllocateScope always_allocate(isolate);
|
||||||
// Make sure |obj_value| is placed on an old-space evacuation candidate.
|
// Make sure |obj_value| is placed on an old-space evacuation candidate.
|
||||||
SimulateFullSpace(old_space);
|
SimulateFullSpace(old_space);
|
||||||
obj_value =
|
obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS,
|
||||||
factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, WEAK, TENURED);
|
Strength::WEAK, TENURED);
|
||||||
ec_page = Page::FromAddress(obj_value->address());
|
ec_page = Page::FromAddress(obj_value->address());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1374,7 +1374,7 @@ TEST(StoreBufferScanOnScavenge) {
|
|||||||
CHECK(isolate->heap()->old_space()->Contains(*obj));
|
CHECK(isolate->heap()->old_space()->Contains(*obj));
|
||||||
|
|
||||||
// Create temp object in the new space.
|
// Create temp object in the new space.
|
||||||
Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, WEAK, NOT_TENURED);
|
Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS);
|
||||||
CHECK(isolate->heap()->new_space()->Contains(*temp));
|
CHECK(isolate->heap()->new_space()->Contains(*temp));
|
||||||
|
|
||||||
// Construct a double value that looks like a pointer to the new space object
|
// Construct a double value that looks like a pointer to the new space object
|
||||||
@ -1573,8 +1573,8 @@ static void TestIncrementalWriteBarrier(Handle<Map> map, Handle<Map> new_map,
|
|||||||
|
|
||||||
// Make sure |obj_value| is placed on an old-space evacuation candidate.
|
// Make sure |obj_value| is placed on an old-space evacuation candidate.
|
||||||
SimulateFullSpace(old_space);
|
SimulateFullSpace(old_space);
|
||||||
obj_value =
|
obj_value = factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS,
|
||||||
factory->NewJSArray(32 * KB, FAST_HOLEY_ELEMENTS, WEAK, TENURED);
|
Strength::WEAK, TENURED);
|
||||||
ec_page = Page::FromAddress(obj_value->address());
|
ec_page = Page::FromAddress(obj_value->address());
|
||||||
CHECK_NE(ec_page, Page::FromAddress(obj->address()));
|
CHECK_NE(ec_page, Page::FromAddress(obj->address()));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user