diff options
Diffstat (limited to 'deps/v8/src/crankshaft/ia32/lithium-codegen-ia32.cc')
-rw-r--r-- | deps/v8/src/crankshaft/ia32/lithium-codegen-ia32.cc | 515 |
1 files changed, 252 insertions, 263 deletions
diff --git a/deps/v8/src/crankshaft/ia32/lithium-codegen-ia32.cc b/deps/v8/src/crankshaft/ia32/lithium-codegen-ia32.cc index d8b20c87a7..8233659ddb 100644 --- a/deps/v8/src/crankshaft/ia32/lithium-codegen-ia32.cc +++ b/deps/v8/src/crankshaft/ia32/lithium-codegen-ia32.cc @@ -15,7 +15,6 @@ #include "src/ia32/frames-ia32.h" #include "src/ic/ic.h" #include "src/ic/stub-cache.h" -#include "src/profiler/cpu-profiler.h" namespace v8 { namespace internal { @@ -165,25 +164,24 @@ void LCodeGen::DoPrologue(LPrologue* instr) { Comment(";;; Prologue begin"); // Possibly allocate a local context. - if (info_->num_heap_slots() > 0) { + if (info_->scope()->num_heap_slots() > 0) { Comment(";;; Allocate local context"); bool need_write_barrier = true; // Argument to NewContext is the function, which is still in edi. - int slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; + int slots = info_->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; Safepoint::DeoptMode deopt_mode = Safepoint::kNoLazyDeopt; if (info()->scope()->is_script_scope()) { __ push(edi); __ Push(info()->scope()->GetScopeInfo(info()->isolate())); __ CallRuntime(Runtime::kNewScriptContext); deopt_mode = Safepoint::kLazyDeopt; - } else if (slots <= FastNewContextStub::kMaximumSlots) { - FastNewContextStub stub(isolate(), slots); + } else { + FastNewFunctionContextStub stub(isolate()); + __ mov(FastNewFunctionContextDescriptor::SlotsRegister(), + Immediate(slots)); __ CallStub(&stub); - // Result of FastNewContextStub is always in new space. + // Result of FastNewFunctionContextStub is always in new space. need_write_barrier = false; - } else { - __ push(edi); - __ CallRuntime(Runtime::kNewFunctionContext); } RecordSafepoint(deopt_mode); @@ -193,10 +191,11 @@ void LCodeGen::DoPrologue(LPrologue* instr) { __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), eax); // Copy parameters into context if necessary. - int num_parameters = scope()->num_parameters(); - int first_parameter = scope()->has_this_declaration() ? -1 : 0; + int num_parameters = info()->scope()->num_parameters(); + int first_parameter = info()->scope()->has_this_declaration() ? -1 : 0; for (int i = first_parameter; i < num_parameters; i++) { - Variable* var = (i == -1) ? scope()->receiver() : scope()->parameter(i); + Variable* var = (i == -1) ? info()->scope()->receiver() + : info()->scope()->parameter(i); if (var->IsContextSlot()) { int parameter_offset = StandardFrameConstants::kCallerSPOffset + (num_parameters - 1 - i) * kPointerSize; @@ -274,8 +273,6 @@ bool LCodeGen::GenerateJumpTable() { if (info()->saves_caller_doubles()) RestoreCallerDoubles(); __ call(entry, RelocInfo::RUNTIME_ENTRY); } - info()->LogDeoptCallPosition(masm()->pc_offset(), - table_entry->deopt_info.inlining_id); } if (needs_frame.is_linked()) { __ bind(&needs_frame); @@ -682,9 +679,8 @@ void LCodeGen::RegisterEnvironmentForDeoptimization( } } - void LCodeGen::DeoptimizeIf(Condition cc, LInstruction* instr, - Deoptimizer::DeoptReason deopt_reason, + DeoptimizeReason deopt_reason, Deoptimizer::BailoutType bailout_type) { LEnvironment* environment = instr->environment(); RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); @@ -725,19 +721,18 @@ void LCodeGen::DeoptimizeIf(Condition cc, LInstruction* instr, __ bind(&done); } - Deoptimizer::DeoptInfo deopt_info = MakeDeoptInfo(instr, deopt_reason); + Deoptimizer::DeoptInfo deopt_info = MakeDeoptInfo(instr, deopt_reason, id); DCHECK(info()->IsStub() || frame_is_built_); if (cc == no_condition && frame_is_built_) { DeoptComment(deopt_info); __ call(entry, RelocInfo::RUNTIME_ENTRY); - info()->LogDeoptCallPosition(masm()->pc_offset(), deopt_info.inlining_id); } else { Deoptimizer::JumpTableEntry table_entry(entry, deopt_info, bailout_type, !frame_is_built_); // We often have several deopts to the same entry, reuse the last // jump entry if this is the case. - if (FLAG_trace_deopt || isolate()->cpu_profiler()->is_profiling() || + if (FLAG_trace_deopt || isolate()->is_profiling() || jump_table_.is_empty() || !table_entry.IsEquivalentTo(jump_table_.last())) { jump_table_.Add(table_entry, zone()); @@ -750,9 +745,8 @@ void LCodeGen::DeoptimizeIf(Condition cc, LInstruction* instr, } } - void LCodeGen::DeoptimizeIf(Condition cc, LInstruction* instr, - Deoptimizer::DeoptReason deopt_reason) { + DeoptimizeReason deopt_reason) { Deoptimizer::BailoutType bailout_type = info()->IsStub() ? Deoptimizer::LAZY : Deoptimizer::EAGER; @@ -811,13 +805,6 @@ void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, } -void LCodeGen::RecordAndWritePosition(int position) { - if (position == RelocInfo::kNoPosition) return; - masm()->positions_recorder()->RecordPosition(position); - masm()->positions_recorder()->WriteRecordedPositions(); -} - - static const char* LabelType(LLabel* label) { if (label->is_loop_header()) return " (loop header)"; if (label->is_osr_entry()) return " (OSR entry)"; @@ -890,7 +877,7 @@ void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) { __ and_(dividend, mask); __ neg(dividend); if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIf(zero, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(zero, instr, DeoptimizeReason::kMinusZero); } __ jmp(&done, Label::kNear); } @@ -907,7 +894,7 @@ void LCodeGen::DoModByConstI(LModByConstI* instr) { DCHECK(ToRegister(instr->result()).is(eax)); if (divisor == 0) { - DeoptimizeIf(no_condition, instr, Deoptimizer::kDivisionByZero); + DeoptimizeIf(no_condition, instr, DeoptimizeReason::kDivisionByZero); return; } @@ -922,7 +909,7 @@ void LCodeGen::DoModByConstI(LModByConstI* instr) { Label remainder_not_zero; __ j(not_zero, &remainder_not_zero, Label::kNear); __ cmp(dividend, Immediate(0)); - DeoptimizeIf(less, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(less, instr, DeoptimizeReason::kMinusZero); __ bind(&remainder_not_zero); } } @@ -944,7 +931,7 @@ void LCodeGen::DoModI(LModI* instr) { // deopt in this case because we can't return a NaN. if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { __ test(right_reg, Operand(right_reg)); - DeoptimizeIf(zero, instr, Deoptimizer::kDivisionByZero); + DeoptimizeIf(zero, instr, DeoptimizeReason::kDivisionByZero); } // Check for kMinInt % -1, idiv would signal a divide error. We @@ -955,7 +942,7 @@ void LCodeGen::DoModI(LModI* instr) { __ j(not_equal, &no_overflow_possible, Label::kNear); __ cmp(right_reg, -1); if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIf(equal, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(equal, instr, DeoptimizeReason::kMinusZero); } else { __ j(not_equal, &no_overflow_possible, Label::kNear); __ Move(result_reg, Immediate(0)); @@ -974,7 +961,7 @@ void LCodeGen::DoModI(LModI* instr) { __ j(not_sign, &positive_left, Label::kNear); __ idiv(right_reg); __ test(result_reg, Operand(result_reg)); - DeoptimizeIf(zero, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(zero, instr, DeoptimizeReason::kMinusZero); __ jmp(&done, Label::kNear); __ bind(&positive_left); } @@ -994,19 +981,19 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { HDiv* hdiv = instr->hydrogen(); if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { __ test(dividend, dividend); - DeoptimizeIf(zero, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(zero, instr, DeoptimizeReason::kMinusZero); } // Check for (kMinInt / -1). if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { __ cmp(dividend, kMinInt); - DeoptimizeIf(zero, instr, Deoptimizer::kOverflow); + DeoptimizeIf(zero, instr, DeoptimizeReason::kOverflow); } // Deoptimize if remainder will not be 0. if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && divisor != 1 && divisor != -1) { int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); __ test(dividend, Immediate(mask)); - DeoptimizeIf(not_zero, instr, Deoptimizer::kLostPrecision); + DeoptimizeIf(not_zero, instr, DeoptimizeReason::kLostPrecision); } __ Move(result, dividend); int32_t shift = WhichPowerOf2Abs(divisor); @@ -1027,7 +1014,7 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) { DCHECK(ToRegister(instr->result()).is(edx)); if (divisor == 0) { - DeoptimizeIf(no_condition, instr, Deoptimizer::kDivisionByZero); + DeoptimizeIf(no_condition, instr, DeoptimizeReason::kDivisionByZero); return; } @@ -1035,7 +1022,7 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) { HDiv* hdiv = instr->hydrogen(); if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { __ test(dividend, dividend); - DeoptimizeIf(zero, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(zero, instr, DeoptimizeReason::kMinusZero); } __ TruncatingDiv(dividend, Abs(divisor)); @@ -1045,7 +1032,7 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) { __ mov(eax, edx); __ imul(eax, eax, divisor); __ sub(eax, dividend); - DeoptimizeIf(not_equal, instr, Deoptimizer::kLostPrecision); + DeoptimizeIf(not_equal, instr, DeoptimizeReason::kLostPrecision); } } @@ -1065,7 +1052,7 @@ void LCodeGen::DoDivI(LDivI* instr) { // Check for x / 0. if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { __ test(divisor, divisor); - DeoptimizeIf(zero, instr, Deoptimizer::kDivisionByZero); + DeoptimizeIf(zero, instr, DeoptimizeReason::kDivisionByZero); } // Check for (0 / -x) that will produce negative zero. @@ -1074,7 +1061,7 @@ void LCodeGen::DoDivI(LDivI* instr) { __ test(dividend, dividend); __ j(not_zero, ÷nd_not_zero, Label::kNear); __ test(divisor, divisor); - DeoptimizeIf(sign, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(sign, instr, DeoptimizeReason::kMinusZero); __ bind(÷nd_not_zero); } @@ -1084,7 +1071,7 @@ void LCodeGen::DoDivI(LDivI* instr) { __ cmp(dividend, kMinInt); __ j(not_zero, ÷nd_not_min_int, Label::kNear); __ cmp(divisor, -1); - DeoptimizeIf(zero, instr, Deoptimizer::kOverflow); + DeoptimizeIf(zero, instr, DeoptimizeReason::kOverflow); __ bind(÷nd_not_min_int); } @@ -1095,7 +1082,7 @@ void LCodeGen::DoDivI(LDivI* instr) { if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { // Deoptimize if remainder is not 0. __ test(remainder, remainder); - DeoptimizeIf(not_zero, instr, Deoptimizer::kLostPrecision); + DeoptimizeIf(not_zero, instr, DeoptimizeReason::kLostPrecision); } } @@ -1117,13 +1104,13 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { // If the divisor is negative, we have to negate and handle edge cases. __ neg(dividend); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIf(zero, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(zero, instr, DeoptimizeReason::kMinusZero); } // Dividing by -1 is basically negation, unless we overflow. if (divisor == -1) { if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { - DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); + DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow); } return; } @@ -1150,7 +1137,7 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { DCHECK(ToRegister(instr->result()).is(edx)); if (divisor == 0) { - DeoptimizeIf(no_condition, instr, Deoptimizer::kDivisionByZero); + DeoptimizeIf(no_condition, instr, DeoptimizeReason::kDivisionByZero); return; } @@ -1158,7 +1145,7 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { HMathFloorOfDiv* hdiv = instr->hydrogen(); if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { __ test(dividend, dividend); - DeoptimizeIf(zero, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(zero, instr, DeoptimizeReason::kMinusZero); } // Easy case: We need no dynamic check for the dividend and the flooring @@ -1205,7 +1192,7 @@ void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { // Check for x / 0. if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { __ test(divisor, divisor); - DeoptimizeIf(zero, instr, Deoptimizer::kDivisionByZero); + DeoptimizeIf(zero, instr, DeoptimizeReason::kDivisionByZero); } // Check for (0 / -x) that will produce negative zero. @@ -1214,7 +1201,7 @@ void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { __ test(dividend, dividend); __ j(not_zero, ÷nd_not_zero, Label::kNear); __ test(divisor, divisor); - DeoptimizeIf(sign, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(sign, instr, DeoptimizeReason::kMinusZero); __ bind(÷nd_not_zero); } @@ -1224,7 +1211,7 @@ void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { __ cmp(dividend, kMinInt); __ j(not_zero, ÷nd_not_min_int, Label::kNear); __ cmp(divisor, -1); - DeoptimizeIf(zero, instr, Deoptimizer::kOverflow); + DeoptimizeIf(zero, instr, DeoptimizeReason::kOverflow); __ bind(÷nd_not_min_int); } @@ -1302,7 +1289,7 @@ void LCodeGen::DoMulI(LMulI* instr) { } if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { - DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); + DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow); } if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { @@ -1312,15 +1299,15 @@ void LCodeGen::DoMulI(LMulI* instr) { __ j(not_zero, &done, Label::kNear); if (right->IsConstantOperand()) { if (ToInteger32(LConstantOperand::cast(right)) < 0) { - DeoptimizeIf(no_condition, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(no_condition, instr, DeoptimizeReason::kMinusZero); } else if (ToInteger32(LConstantOperand::cast(right)) == 0) { __ cmp(ToRegister(instr->temp()), Immediate(0)); - DeoptimizeIf(less, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(less, instr, DeoptimizeReason::kMinusZero); } } else { // Test the non-zero operand for negative sign. __ or_(ToRegister(instr->temp()), ToOperand(right)); - DeoptimizeIf(sign, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(sign, instr, DeoptimizeReason::kMinusZero); } __ bind(&done); } @@ -1393,7 +1380,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) { __ shr_cl(ToRegister(left)); if (instr->can_deopt()) { __ test(ToRegister(left), ToRegister(left)); - DeoptimizeIf(sign, instr, Deoptimizer::kNegativeValue); + DeoptimizeIf(sign, instr, DeoptimizeReason::kNegativeValue); } break; case Token::SHL: @@ -1410,7 +1397,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) { case Token::ROR: if (shift_count == 0 && instr->can_deopt()) { __ test(ToRegister(left), ToRegister(left)); - DeoptimizeIf(sign, instr, Deoptimizer::kNegativeValue); + DeoptimizeIf(sign, instr, DeoptimizeReason::kNegativeValue); } else { __ ror(ToRegister(left), shift_count); } @@ -1425,7 +1412,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) { __ shr(ToRegister(left), shift_count); } else if (instr->can_deopt()) { __ test(ToRegister(left), ToRegister(left)); - DeoptimizeIf(sign, instr, Deoptimizer::kNegativeValue); + DeoptimizeIf(sign, instr, DeoptimizeReason::kNegativeValue); } break; case Token::SHL: @@ -1436,7 +1423,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) { __ shl(ToRegister(left), shift_count - 1); } __ SmiTag(ToRegister(left)); - DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); + DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow); } else { __ shl(ToRegister(left), shift_count); } @@ -1462,7 +1449,7 @@ void LCodeGen::DoSubI(LSubI* instr) { __ sub(ToRegister(left), ToOperand(right)); } if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { - DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); + DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow); } } @@ -1634,7 +1621,7 @@ void LCodeGen::DoAddI(LAddI* instr) { __ add(ToRegister(left), ToOperand(right)); } if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { - DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); + DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow); } } } @@ -1893,7 +1880,7 @@ void LCodeGen::DoBranch(LBranch* instr) { } else if (expected.NeedsMap()) { // If we need a map later and have a Smi -> deopt. __ test(reg, Immediate(kSmiTagMask)); - DeoptimizeIf(zero, instr, Deoptimizer::kSmi); + DeoptimizeIf(zero, instr, DeoptimizeReason::kSmi); } Register map = no_reg; // Keep the compiler happy. @@ -1956,7 +1943,7 @@ void LCodeGen::DoBranch(LBranch* instr) { if (!expected.IsGeneric()) { // We've seen something for the first time -> deopt. // This can only happen if we are not generic already. - DeoptimizeIf(no_condition, instr, Deoptimizer::kUnexpectedObject); + DeoptimizeIf(no_condition, instr, DeoptimizeReason::kUnexpectedObject); } } } @@ -2291,16 +2278,6 @@ void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { } -void LCodeGen::DoInstanceOf(LInstanceOf* instr) { - DCHECK(ToRegister(instr->context()).is(esi)); - DCHECK(ToRegister(instr->left()).is(InstanceOfDescriptor::LeftRegister())); - DCHECK(ToRegister(instr->right()).is(InstanceOfDescriptor::RightRegister())); - DCHECK(ToRegister(instr->result()).is(eax)); - InstanceOfStub stub(isolate()); - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); -} - - void LCodeGen::DoHasInPrototypeChainAndBranch( LHasInPrototypeChainAndBranch* instr) { Register const object = ToRegister(instr->object()); @@ -2324,16 +2301,16 @@ void LCodeGen::DoHasInPrototypeChainAndBranch( // Deoptimize if the object needs to be access checked. __ test_b(FieldOperand(object_map, Map::kBitFieldOffset), Immediate(1 << Map::kIsAccessCheckNeeded)); - DeoptimizeIf(not_zero, instr, Deoptimizer::kAccessCheck); + DeoptimizeIf(not_zero, instr, DeoptimizeReason::kAccessCheck); // Deoptimize for proxies. __ CmpInstanceType(object_map, JS_PROXY_TYPE); - DeoptimizeIf(equal, instr, Deoptimizer::kProxy); + DeoptimizeIf(equal, instr, DeoptimizeReason::kProxy); __ mov(object_prototype, FieldOperand(object_map, Map::kPrototypeOffset)); - __ cmp(object_prototype, prototype); - EmitTrueBranch(instr, equal); __ cmp(object_prototype, factory()->null_value()); EmitFalseBranch(instr, equal); + __ cmp(object_prototype, prototype); + EmitTrueBranch(instr, equal); __ mov(object_map, FieldOperand(object_prototype, HeapObject::kMapOffset)); __ jmp(&loop); } @@ -2431,15 +2408,12 @@ void LCodeGen::EmitVectorStoreICRegisters(T* instr) { void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { DCHECK(ToRegister(instr->context()).is(esi)); - DCHECK(ToRegister(instr->global_object()) - .is(LoadDescriptor::ReceiverRegister())); DCHECK(ToRegister(instr->result()).is(eax)); - __ mov(LoadDescriptor::NameRegister(), instr->name()); EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr); - Handle<Code> ic = CodeFactory::LoadICInOptimizedCode( - isolate(), instr->typeof_mode(), PREMONOMORPHIC) - .code(); + Handle<Code> ic = + CodeFactory::LoadGlobalICInOptimizedCode(isolate(), instr->typeof_mode()) + .code(); CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -2452,7 +2426,7 @@ void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { if (instr->hydrogen()->RequiresHoleCheck()) { __ cmp(result, factory()->the_hole_value()); if (instr->hydrogen()->DeoptimizesOnHole()) { - DeoptimizeIf(equal, instr, Deoptimizer::kHole); + DeoptimizeIf(equal, instr, DeoptimizeReason::kHole); } else { Label is_not_hole; __ j(not_equal, &is_not_hole, Label::kNear); @@ -2473,7 +2447,7 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { if (instr->hydrogen()->RequiresHoleCheck()) { __ cmp(target, factory()->the_hole_value()); if (instr->hydrogen()->DeoptimizesOnHole()) { - DeoptimizeIf(equal, instr, Deoptimizer::kHole); + DeoptimizeIf(equal, instr, DeoptimizeReason::kHole); } else { __ j(not_equal, &skip_assignment, Label::kNear); } @@ -2554,10 +2528,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { __ mov(LoadDescriptor::NameRegister(), instr->name()); EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr); - Handle<Code> ic = CodeFactory::LoadICInOptimizedCode( - isolate(), NOT_INSIDE_TYPEOF, - instr->hydrogen()->initialization_state()) - .code(); + Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate()).code(); CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -2573,7 +2544,7 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { // Check that the function has a prototype or an initial map. __ cmp(Operand(result), Immediate(factory()->the_hole_value())); - DeoptimizeIf(equal, instr, Deoptimizer::kHole); + DeoptimizeIf(equal, instr, DeoptimizeReason::kHole); // If the function does not have an initial map, we're done. Label done; @@ -2657,7 +2628,7 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { __ mov(result, operand); if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { __ test(result, Operand(result)); - DeoptimizeIf(negative, instr, Deoptimizer::kNegativeValue); + DeoptimizeIf(negative, instr, DeoptimizeReason::kNegativeValue); } break; case FLOAT32_ELEMENTS: @@ -2689,7 +2660,7 @@ void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { FAST_DOUBLE_ELEMENTS, instr->base_offset() + sizeof(kHoleNanLower32)); __ cmp(hole_check_operand, Immediate(kHoleNanUpper32)); - DeoptimizeIf(equal, instr, Deoptimizer::kHole); + DeoptimizeIf(equal, instr, DeoptimizeReason::kHole); } Operand double_load_operand = BuildFastArrayOperand( @@ -2716,10 +2687,10 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { if (instr->hydrogen()->RequiresHoleCheck()) { if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { __ test(result, Immediate(kSmiTagMask)); - DeoptimizeIf(not_equal, instr, Deoptimizer::kNotASmi); + DeoptimizeIf(not_equal, instr, DeoptimizeReason::kNotASmi); } else { __ cmp(result, factory()->the_hole_value()); - DeoptimizeIf(equal, instr, Deoptimizer::kHole); + DeoptimizeIf(equal, instr, DeoptimizeReason::kHole); } } else if (instr->hydrogen()->hole_mode() == CONVERT_HOLE_TO_UNDEFINED) { DCHECK(instr->hydrogen()->elements_kind() == FAST_HOLEY_ELEMENTS); @@ -2728,12 +2699,12 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { __ j(not_equal, &done); if (info()->IsStub()) { // A stub can safely convert the hole to undefined only if the array - // protector cell contains (Smi) Isolate::kArrayProtectorValid. Otherwise - // it needs to bail out. - __ mov(result, isolate()->factory()->array_protector()); + // protector cell contains (Smi) Isolate::kArrayProtectorValid. + // Otherwise it needs to bail out. + __ LoadRoot(result, Heap::kArrayProtectorRootIndex); __ cmp(FieldOperand(result, PropertyCell::kValueOffset), Immediate(Smi::FromInt(Isolate::kArrayProtectorValid))); - DeoptimizeIf(not_equal, instr, Deoptimizer::kHole); + DeoptimizeIf(not_equal, instr, DeoptimizeReason::kHole); } __ mov(result, isolate()->factory()->undefined_value()); __ bind(&done); @@ -2788,13 +2759,9 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister())); DCHECK(ToRegister(instr->key()).is(LoadDescriptor::NameRegister())); - if (instr->hydrogen()->HasVectorAndSlot()) { - EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr); - } + EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr); - Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode( - isolate(), instr->hydrogen()->initialization_state()) - .code(); + Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate()).code(); CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -2887,9 +2854,9 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { // The receiver should be a JS object. __ test(receiver, Immediate(kSmiTagMask)); - DeoptimizeIf(equal, instr, Deoptimizer::kSmi); + DeoptimizeIf(equal, instr, DeoptimizeReason::kSmi); __ CmpObjectType(receiver, FIRST_JS_RECEIVER_TYPE, scratch); - DeoptimizeIf(below, instr, Deoptimizer::kNotAJavaScriptObject); + DeoptimizeIf(below, instr, DeoptimizeReason::kNotAJavaScriptObject); __ jmp(&receiver_ok, Label::kNear); __ bind(&global_object); @@ -2913,7 +2880,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { // adaptor frame below it. const uint32_t kArgumentsLimit = 1 * KB; __ cmp(length, kArgumentsLimit); - DeoptimizeIf(above, instr, Deoptimizer::kTooManyArguments); + DeoptimizeIf(above, instr, DeoptimizeReason::kTooManyArguments); __ push(receiver); __ mov(receiver, length); @@ -2990,6 +2957,7 @@ void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { DCHECK(ToRegister(instr->context()).is(esi)); __ push(Immediate(instr->hydrogen()->pairs())); __ push(Immediate(Smi::FromInt(instr->hydrogen()->flags()))); + __ push(Immediate(instr->hydrogen()->feedback_vector())); CallRuntime(Runtime::kDeclareGlobals, instr); } @@ -3088,7 +3056,7 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { Register input_reg = ToRegister(instr->value()); __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), factory()->heap_number_map()); - DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumber); + DeoptimizeIf(not_equal, instr, DeoptimizeReason::kNotAHeapNumber); Label slow, allocated, done; uint32_t available_regs = eax.bit() | ecx.bit() | edx.bit() | ebx.bit(); @@ -3146,7 +3114,7 @@ void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { Label is_positive; __ j(not_sign, &is_positive, Label::kNear); __ neg(input_reg); // Sets flags. - DeoptimizeIf(negative, instr, Deoptimizer::kOverflow); + DeoptimizeIf(negative, instr, DeoptimizeReason::kOverflow); __ bind(&is_positive); } @@ -3211,20 +3179,20 @@ void LCodeGen::DoMathFloorI(LMathFloorI* instr) { __ j(not_equal, &non_zero, Label::kNear); __ movmskpd(output_reg, input_reg); __ test(output_reg, Immediate(1)); - DeoptimizeIf(not_zero, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(not_zero, instr, DeoptimizeReason::kMinusZero); __ bind(&non_zero); } __ roundsd(xmm_scratch, input_reg, kRoundDown); __ cvttsd2si(output_reg, Operand(xmm_scratch)); // Overflow is signalled with minint. __ cmp(output_reg, 0x1); - DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); + DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow); } else { Label negative_sign, done; // Deoptimize on unordered. __ xorps(xmm_scratch, xmm_scratch); // Zero the register. __ ucomisd(input_reg, xmm_scratch); - DeoptimizeIf(parity_even, instr, Deoptimizer::kNaN); + DeoptimizeIf(parity_even, instr, DeoptimizeReason::kNaN); __ j(below, &negative_sign, Label::kNear); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { @@ -3233,7 +3201,7 @@ void LCodeGen::DoMathFloorI(LMathFloorI* instr) { __ j(above, &positive_sign, Label::kNear); __ movmskpd(output_reg, input_reg); __ test(output_reg, Immediate(1)); - DeoptimizeIf(not_zero, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(not_zero, instr, DeoptimizeReason::kMinusZero); __ Move(output_reg, Immediate(0)); __ jmp(&done, Label::kNear); __ bind(&positive_sign); @@ -3243,7 +3211,7 @@ void LCodeGen::DoMathFloorI(LMathFloorI* instr) { __ cvttsd2si(output_reg, Operand(input_reg)); // Overflow is signalled with minint. __ cmp(output_reg, 0x1); - DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); + DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow); __ jmp(&done, Label::kNear); // Non-zero negative reaches here. @@ -3254,7 +3222,7 @@ void LCodeGen::DoMathFloorI(LMathFloorI* instr) { __ ucomisd(input_reg, xmm_scratch); __ j(equal, &done, Label::kNear); __ sub(output_reg, Immediate(1)); - DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); + DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow); __ bind(&done); } @@ -3297,7 +3265,7 @@ void LCodeGen::DoMathRoundI(LMathRoundI* instr) { __ cvttsd2si(output_reg, Operand(xmm_scratch)); // Overflow is signalled with minint. __ cmp(output_reg, 0x1); - DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); + DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow); __ jmp(&done, dist); __ bind(&below_one_half); @@ -3312,7 +3280,7 @@ void LCodeGen::DoMathRoundI(LMathRoundI* instr) { __ cvttsd2si(output_reg, Operand(input_temp)); // Catch minint due to overflow, and to prevent overflow when compensating. __ cmp(output_reg, 0x1); - DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); + DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow); __ Cvtsi2sd(xmm_scratch, output_reg); __ ucomisd(xmm_scratch, input_temp); @@ -3328,7 +3296,7 @@ void LCodeGen::DoMathRoundI(LMathRoundI* instr) { // If the sign is positive, we return +0. __ movmskpd(output_reg, input_reg); __ test(output_reg, Immediate(1)); - DeoptimizeIf(not_zero, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(not_zero, instr, DeoptimizeReason::kMinusZero); } __ Move(output_reg, Immediate(0)); __ bind(&done); @@ -3404,7 +3372,7 @@ void LCodeGen::DoPower(LPower* instr) { __ JumpIfSmi(tagged_exponent, &no_deopt); DCHECK(!ecx.is(tagged_exponent)); __ CmpObjectType(tagged_exponent, HEAP_NUMBER_TYPE, ecx); - DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumber); + DeoptimizeIf(not_equal, instr, DeoptimizeReason::kNotAHeapNumber); __ bind(&no_deopt); MathPowStub stub(isolate(), MathPowStub::TAGGED); __ CallStub(&stub); @@ -3420,31 +3388,18 @@ void LCodeGen::DoPower(LPower* instr) { void LCodeGen::DoMathLog(LMathLog* instr) { - DCHECK(instr->value()->Equals(instr->result())); - XMMRegister input_reg = ToDoubleRegister(instr->value()); - XMMRegister xmm_scratch = double_scratch0(); - Label positive, done, zero; - __ xorps(xmm_scratch, xmm_scratch); - __ ucomisd(input_reg, xmm_scratch); - __ j(above, &positive, Label::kNear); - __ j(not_carry, &zero, Label::kNear); - __ pcmpeqd(input_reg, input_reg); - __ jmp(&done, Label::kNear); - __ bind(&zero); - ExternalReference ninf = - ExternalReference::address_of_negative_infinity(); - __ movsd(input_reg, Operand::StaticVariable(ninf)); - __ jmp(&done, Label::kNear); - __ bind(&positive); - __ fldln2(); - __ sub(Operand(esp), Immediate(kDoubleSize)); - __ movsd(Operand(esp, 0), input_reg); - __ fld_d(Operand(esp, 0)); - __ fyl2x(); + XMMRegister input = ToDoubleRegister(instr->value()); + XMMRegister result = ToDoubleRegister(instr->result()); + // Pass one double as argument on the stack. + __ PrepareCallCFunction(2, eax); + __ movsd(Operand(esp, 0 * kDoubleSize), input); + __ CallCFunction(ExternalReference::ieee754_log_function(isolate()), 2); + // Return value is in st(0) on ia32. + // Store it into the result register. + __ sub(esp, Immediate(kDoubleSize)); __ fstp_d(Operand(esp, 0)); - __ movsd(input_reg, Operand(esp, 0)); - __ add(Operand(esp), Immediate(kDoubleSize)); - __ bind(&done); + __ movsd(result, Operand(esp, 0)); + __ add(esp, Immediate(kDoubleSize)); } @@ -3455,15 +3410,49 @@ void LCodeGen::DoMathClz32(LMathClz32* instr) { __ Lzcnt(result, input); } +void LCodeGen::DoMathCos(LMathCos* instr) { + XMMRegister input = ToDoubleRegister(instr->value()); + XMMRegister result = ToDoubleRegister(instr->result()); + // Pass one double as argument on the stack. + __ PrepareCallCFunction(2, eax); + __ movsd(Operand(esp, 0 * kDoubleSize), input); + __ CallCFunction(ExternalReference::ieee754_cos_function(isolate()), 2); + // Return value is in st(0) on ia32. + // Store it into the result register. + __ sub(esp, Immediate(kDoubleSize)); + __ fstp_d(Operand(esp, 0)); + __ movsd(result, Operand(esp, 0)); + __ add(esp, Immediate(kDoubleSize)); +} + +void LCodeGen::DoMathSin(LMathSin* instr) { + XMMRegister input = ToDoubleRegister(instr->value()); + XMMRegister result = ToDoubleRegister(instr->result()); + // Pass one double as argument on the stack. + __ PrepareCallCFunction(2, eax); + __ movsd(Operand(esp, 0 * kDoubleSize), input); + __ CallCFunction(ExternalReference::ieee754_sin_function(isolate()), 2); + // Return value is in st(0) on ia32. + // Store it into the result register. + __ sub(esp, Immediate(kDoubleSize)); + __ fstp_d(Operand(esp, 0)); + __ movsd(result, Operand(esp, 0)); + __ add(esp, Immediate(kDoubleSize)); +} void LCodeGen::DoMathExp(LMathExp* instr) { XMMRegister input = ToDoubleRegister(instr->value()); XMMRegister result = ToDoubleRegister(instr->result()); - XMMRegister temp0 = double_scratch0(); - Register temp1 = ToRegister(instr->temp1()); - Register temp2 = ToRegister(instr->temp2()); - - MathExpGenerator::EmitMathExp(masm(), input, result, temp0, temp1, temp2); + // Pass one double as argument on the stack. + __ PrepareCallCFunction(2, eax); + __ movsd(Operand(esp, 0 * kDoubleSize), input); + __ CallCFunction(ExternalReference::ieee754_exp_function(isolate()), 2); + // Return value is in st(0) on ia32. + // Store it into the result register. + __ sub(esp, Immediate(kDoubleSize)); + __ fstp_d(Operand(esp, 0)); + __ movsd(result, Operand(esp, 0)); + __ add(esp, Immediate(kDoubleSize)); } void LCodeGen::PrepareForTailCall(const ParameterCount& actual, @@ -3478,7 +3467,9 @@ void LCodeGen::PrepareForTailCall(const ParameterCount& actual, #endif if (FLAG_code_comments) { if (actual.is_reg()) { - Comment(";;; PrepareForTailCall, actual: %s {", actual.reg().ToString()); + Comment(";;; PrepareForTailCall, actual: %s {", + RegisterConfiguration::Crankshaft()->GetGeneralRegisterName( + actual.reg().code())); } else { Comment(";;; PrepareForTailCall, actual: %d {", actual.immediate()); } @@ -3548,14 +3539,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) { DCHECK(ToRegister(instr->result()).is(eax)); __ Move(eax, Immediate(instr->arity())); - if (instr->arity() == 1) { - // We only need the allocation site for the case we have a length argument. - // The case may bail out to the runtime, which will determine the correct - // elements kind with the site. - __ mov(ebx, instr->hydrogen()->site()); - } else { - __ mov(ebx, isolate()->factory()->undefined_value()); - } + __ mov(ebx, instr->hydrogen()->site()); ElementsKind kind = instr->hydrogen()->elements_kind(); AllocationSiteOverrideMode override_mode = @@ -3589,7 +3573,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) { CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); __ bind(&done); } else { - ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode); + ArrayNArgumentsConstructorStub stub(isolate()); CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); } } @@ -3719,14 +3703,12 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister())); DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister())); - if (instr->hydrogen()->HasVectorAndSlot()) { - EmitVectorStoreICRegisters<LStoreNamedGeneric>(instr); - } + EmitVectorStoreICRegisters<LStoreNamedGeneric>(instr); __ mov(StoreDescriptor::NameRegister(), instr->name()); - Handle<Code> ic = CodeFactory::StoreICInOptimizedCode( - isolate(), instr->language_mode(), - instr->hydrogen()->initialization_state()).code(); + Handle<Code> ic = + CodeFactory::StoreICInOptimizedCode(isolate(), instr->language_mode()) + .code(); CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -3751,7 +3733,7 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { __ int3(); __ bind(&done); } else { - DeoptimizeIf(cc, instr, Deoptimizer::kOutOfBounds); + DeoptimizeIf(cc, instr, DeoptimizeReason::kOutOfBounds); } } @@ -3896,13 +3878,11 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { DCHECK(ToRegister(instr->key()).is(StoreDescriptor::NameRegister())); DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister())); - if (instr->hydrogen()->HasVectorAndSlot()) { - EmitVectorStoreICRegisters<LStoreKeyedGeneric>(instr); - } + EmitVectorStoreICRegisters<LStoreKeyedGeneric>(instr); Handle<Code> ic = CodeFactory::KeyedStoreICInOptimizedCode( - isolate(), instr->language_mode(), - instr->hydrogen()->initialization_state()).code(); + isolate(), instr->language_mode()) + .code(); CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -3912,7 +3892,7 @@ void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { Register temp = ToRegister(instr->temp()); Label no_memento_found; __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found); - DeoptimizeIf(equal, instr, Deoptimizer::kMementoFound); + DeoptimizeIf(equal, instr, DeoptimizeReason::kMementoFound); __ bind(&no_memento_found); } @@ -3986,14 +3966,21 @@ void LCodeGen::DoDeferredMaybeGrowElements(LMaybeGrowElements* instr) { LOperand* key = instr->key(); if (key->IsConstantOperand()) { - __ mov(ebx, ToImmediate(key, Representation::Smi())); + LConstantOperand* constant_key = LConstantOperand::cast(key); + int32_t int_key = ToInteger32(constant_key); + if (Smi::IsValid(int_key)) { + __ mov(ebx, Immediate(Smi::FromInt(int_key))); + } else { + // We should never get here at runtime because there is a smi check on + // the key before this point. + __ int3(); + } } else { __ Move(ebx, ToRegister(key)); __ SmiTag(ebx); } - GrowArrayElementsStub stub(isolate(), instr->hydrogen()->is_js_array(), - instr->hydrogen()->kind()); + GrowArrayElementsStub stub(isolate(), instr->hydrogen()->kind()); __ CallStub(&stub); RecordSafepointWithLazyDeopt( instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); @@ -4002,7 +3989,7 @@ void LCodeGen::DoDeferredMaybeGrowElements(LMaybeGrowElements* instr) { // Deopt on smi, which means the elements array changed to dictionary mode. __ test(result, Immediate(kSmiTagMask)); - DeoptimizeIf(equal, instr, Deoptimizer::kSmi); + DeoptimizeIf(equal, instr, DeoptimizeReason::kSmi); } @@ -4035,8 +4022,7 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { DCHECK(object_reg.is(eax)); PushSafepointRegistersScope scope(this); __ mov(ebx, to_map); - bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE; - TransitionElementsKindStub stub(isolate(), from_kind, to_kind, is_js_array); + TransitionElementsKindStub stub(isolate(), from_kind, to_kind); __ CallStub(&stub); RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); @@ -4273,13 +4259,10 @@ void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr, // Preserve the value of all registers. PushSafepointRegistersScope scope(this); - - // NumberTagI and NumberTagD use the context from the frame, rather than - // the environment's HContext or HInlinedContext value. - // They only call Runtime::kAllocateHeapNumber. - // The corresponding HChange instructions are added in a phase that does - // not have easy access to the local context. - __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); + // Reset the context register. + if (!reg.is(esi)) { + __ Move(esi, Immediate(0)); + } __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); RecordSafepointWithRegisters( instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); @@ -4329,12 +4312,10 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { __ Move(reg, Immediate(0)); PushSafepointRegistersScope scope(this); - // NumberTagI and NumberTagD use the context from the frame, rather than - // the environment's HContext or HInlinedContext value. - // They only call Runtime::kAllocateHeapNumber. - // The corresponding HChange instructions are added in a phase that does - // not have easy access to the local context. - __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); + // Reset the context register. + if (!reg.is(esi)) { + __ Move(esi, Immediate(0)); + } __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); RecordSafepointWithRegisters( instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); @@ -4348,12 +4329,12 @@ void LCodeGen::DoSmiTag(LSmiTag* instr) { if (hchange->CheckFlag(HValue::kCanOverflow) && hchange->value()->CheckFlag(HValue::kUint32)) { __ test(input, Immediate(0xc0000000)); - DeoptimizeIf(not_zero, instr, Deoptimizer::kOverflow); + DeoptimizeIf(not_zero, instr, DeoptimizeReason::kOverflow); } __ SmiTag(input); if (hchange->CheckFlag(HValue::kCanOverflow) && !hchange->value()->CheckFlag(HValue::kUint32)) { - DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); + DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow); } } @@ -4364,7 +4345,7 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) { DCHECK(input->IsRegister() && input->Equals(instr->result())); if (instr->needs_check()) { __ test(result, Immediate(kSmiTagMask)); - DeoptimizeIf(not_zero, instr, Deoptimizer::kNotASmi); + DeoptimizeIf(not_zero, instr, DeoptimizeReason::kNotASmi); } else { __ AssertSmi(result); } @@ -4391,7 +4372,7 @@ void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg, if (can_convert_undefined_to_nan) { __ j(not_equal, &convert, Label::kNear); } else { - DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumber); + DeoptimizeIf(not_equal, instr, DeoptimizeReason::kNotAHeapNumber); } // Heap number to XMM conversion. @@ -4404,7 +4385,7 @@ void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg, __ j(not_zero, &done, Label::kNear); __ movmskpd(temp_reg, result_reg); __ test_b(temp_reg, Immediate(1)); - DeoptimizeIf(not_zero, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(not_zero, instr, DeoptimizeReason::kMinusZero); } __ jmp(&done, Label::kNear); @@ -4413,9 +4394,11 @@ void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg, // Convert undefined to NaN. __ cmp(input_reg, factory()->undefined_value()); - DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumberUndefined); + DeoptimizeIf(not_equal, instr, + DeoptimizeReason::kNotAHeapNumberUndefined); - __ pcmpeqd(result_reg, result_reg); + __ xorpd(result_reg, result_reg); + __ divsd(result_reg, result_reg); __ jmp(&done, Label::kNear); } } else { @@ -4466,26 +4449,26 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, Label* done) { __ bind(&check_false); __ cmp(input_reg, factory()->false_value()); DeoptimizeIf(not_equal, instr, - Deoptimizer::kNotAHeapNumberUndefinedBoolean); + DeoptimizeReason::kNotAHeapNumberUndefinedBoolean); __ Move(input_reg, Immediate(0)); } else { XMMRegister scratch = ToDoubleRegister(instr->temp()); DCHECK(!scratch.is(xmm0)); __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), isolate()->factory()->heap_number_map()); - DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumber); + DeoptimizeIf(not_equal, instr, DeoptimizeReason::kNotAHeapNumber); __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); __ cvttsd2si(input_reg, Operand(xmm0)); __ Cvtsi2sd(scratch, Operand(input_reg)); __ ucomisd(xmm0, scratch); - DeoptimizeIf(not_equal, instr, Deoptimizer::kLostPrecision); - DeoptimizeIf(parity_even, instr, Deoptimizer::kNaN); + DeoptimizeIf(not_equal, instr, DeoptimizeReason::kLostPrecision); + DeoptimizeIf(parity_even, instr, DeoptimizeReason::kNaN); if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) { __ test(input_reg, Operand(input_reg)); __ j(not_zero, done); __ movmskpd(input_reg, xmm0); __ and_(input_reg, 1); - DeoptimizeIf(not_zero, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(not_zero, instr, DeoptimizeReason::kMinusZero); } } } @@ -4565,11 +4548,11 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) { &is_nan, &minus_zero, dist); __ jmp(&done, dist); __ bind(&lost_precision); - DeoptimizeIf(no_condition, instr, Deoptimizer::kLostPrecision); + DeoptimizeIf(no_condition, instr, DeoptimizeReason::kLostPrecision); __ bind(&is_nan); - DeoptimizeIf(no_condition, instr, Deoptimizer::kNaN); + DeoptimizeIf(no_condition, instr, DeoptimizeReason::kNaN); __ bind(&minus_zero); - DeoptimizeIf(no_condition, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(no_condition, instr, DeoptimizeReason::kMinusZero); __ bind(&done); } } @@ -4591,21 +4574,21 @@ void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { &minus_zero, dist); __ jmp(&done, dist); __ bind(&lost_precision); - DeoptimizeIf(no_condition, instr, Deoptimizer::kLostPrecision); + DeoptimizeIf(no_condition, instr, DeoptimizeReason::kLostPrecision); __ bind(&is_nan); - DeoptimizeIf(no_condition, instr, Deoptimizer::kNaN); + DeoptimizeIf(no_condition, instr, DeoptimizeReason::kNaN); __ bind(&minus_zero); - DeoptimizeIf(no_condition, instr, Deoptimizer::kMinusZero); + DeoptimizeIf(no_condition, instr, DeoptimizeReason::kMinusZero); __ bind(&done); __ SmiTag(result_reg); - DeoptimizeIf(overflow, instr, Deoptimizer::kOverflow); + DeoptimizeIf(overflow, instr, DeoptimizeReason::kOverflow); } void LCodeGen::DoCheckSmi(LCheckSmi* instr) { LOperand* input = instr->value(); __ test(ToOperand(input), Immediate(kSmiTagMask)); - DeoptimizeIf(not_zero, instr, Deoptimizer::kNotASmi); + DeoptimizeIf(not_zero, instr, DeoptimizeReason::kNotASmi); } @@ -4613,7 +4596,7 @@ void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { if (!instr->hydrogen()->value()->type().IsHeapObject()) { LOperand* input = instr->value(); __ test(ToOperand(input), Immediate(kSmiTagMask)); - DeoptimizeIf(zero, instr, Deoptimizer::kSmi); + DeoptimizeIf(zero, instr, DeoptimizeReason::kSmi); } } @@ -4626,7 +4609,7 @@ void LCodeGen::DoCheckArrayBufferNotNeutered( __ mov(scratch, FieldOperand(view, JSArrayBufferView::kBufferOffset)); __ test_b(FieldOperand(scratch, JSArrayBuffer::kBitFieldOffset), Immediate(1 << JSArrayBuffer::WasNeutered::kShift)); - DeoptimizeIf(not_zero, instr, Deoptimizer::kOutOfBounds); + DeoptimizeIf(not_zero, instr, DeoptimizeReason::kOutOfBounds); } @@ -4645,13 +4628,13 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { // If there is only one type in the interval check for equality. if (first == last) { - DeoptimizeIf(not_equal, instr, Deoptimizer::kWrongInstanceType); + DeoptimizeIf(not_equal, instr, DeoptimizeReason::kWrongInstanceType); } else { - DeoptimizeIf(below, instr, Deoptimizer::kWrongInstanceType); + DeoptimizeIf(below, instr, DeoptimizeReason::kWrongInstanceType); // Omit check for the last type. if (last != LAST_TYPE) { __ cmpb(FieldOperand(temp, Map::kInstanceTypeOffset), Immediate(last)); - DeoptimizeIf(above, instr, Deoptimizer::kWrongInstanceType); + DeoptimizeIf(above, instr, DeoptimizeReason::kWrongInstanceType); } } } else { @@ -4663,12 +4646,12 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag)); __ test_b(FieldOperand(temp, Map::kInstanceTypeOffset), Immediate(mask)); DeoptimizeIf(tag == 0 ? not_zero : zero, instr, - Deoptimizer::kWrongInstanceType); + DeoptimizeReason::kWrongInstanceType); } else { __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset)); __ and_(temp, mask); __ cmp(temp, tag); - DeoptimizeIf(not_equal, instr, Deoptimizer::kWrongInstanceType); + DeoptimizeIf(not_equal, instr, DeoptimizeReason::kWrongInstanceType); } } } @@ -4684,7 +4667,7 @@ void LCodeGen::DoCheckValue(LCheckValue* instr) { Operand operand = ToOperand(instr->value()); __ cmp(operand, object); } - DeoptimizeIf(not_equal, instr, Deoptimizer::kValueMismatch); + DeoptimizeIf(not_equal, instr, DeoptimizeReason::kValueMismatch); } @@ -4699,7 +4682,7 @@ void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { __ test(eax, Immediate(kSmiTagMask)); } - DeoptimizeIf(zero, instr, Deoptimizer::kInstanceMigrationFailed); + DeoptimizeIf(zero, instr, DeoptimizeReason::kInstanceMigrationFailed); } @@ -4753,7 +4736,7 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) { if (instr->hydrogen()->HasMigrationTarget()) { __ j(not_equal, deferred->entry()); } else { - DeoptimizeIf(not_equal, instr, Deoptimizer::kWrongMap); + DeoptimizeIf(not_equal, instr, DeoptimizeReason::kWrongMap); } __ bind(&success); @@ -4792,7 +4775,7 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { // Check for undefined. Undefined is converted to zero for clamping // conversions. __ cmp(input_reg, factory()->undefined_value()); - DeoptimizeIf(not_equal, instr, Deoptimizer::kNotAHeapNumberUndefined); + DeoptimizeIf(not_equal, instr, DeoptimizeReason::kNotAHeapNumberUndefined); __ mov(input_reg, 0); __ jmp(&done, Label::kNear); @@ -4810,43 +4793,6 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { } -void LCodeGen::DoDoubleBits(LDoubleBits* instr) { - XMMRegister value_reg = ToDoubleRegister(instr->value()); - Register result_reg = ToRegister(instr->result()); - if (instr->hydrogen()->bits() == HDoubleBits::HIGH) { - if (CpuFeatures::IsSupported(SSE4_1)) { - CpuFeatureScope scope2(masm(), SSE4_1); - __ pextrd(result_reg, value_reg, 1); - } else { - XMMRegister xmm_scratch = double_scratch0(); - __ pshufd(xmm_scratch, value_reg, 1); - __ movd(result_reg, xmm_scratch); - } - } else { - __ movd(result_reg, value_reg); - } -} - - -void LCodeGen::DoConstructDouble(LConstructDouble* instr) { - Register hi_reg = ToRegister(instr->hi()); - Register lo_reg = ToRegister(instr->lo()); - XMMRegister result_reg = ToDoubleRegister(instr->result()); - - if (CpuFeatures::IsSupported(SSE4_1)) { - CpuFeatureScope scope2(masm(), SSE4_1); - __ movd(result_reg, lo_reg); - __ pinsrd(result_reg, hi_reg, 1); - } else { - XMMRegister xmm_scratch = double_scratch0(); - __ movd(result_reg, hi_reg); - __ psllq(result_reg, 32); - __ movd(xmm_scratch, lo_reg); - __ orps(result_reg, xmm_scratch); - } -} - - void LCodeGen::DoAllocate(LAllocate* instr) { class DeferredAllocate final : public LDeferredCode { public: @@ -4865,7 +4811,7 @@ void LCodeGen::DoAllocate(LAllocate* instr) { Register temp = ToRegister(instr->temp()); // Allocate memory for the object. - AllocationFlags flags = TAG_OBJECT; + AllocationFlags flags = NO_ALLOCATION_FLAGS; if (instr->hydrogen()->MustAllocateDoubleAligned()) { flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); } @@ -4873,6 +4819,10 @@ void LCodeGen::DoAllocate(LAllocate* instr) { DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); flags = static_cast<AllocationFlags>(flags | PRETENURE); } + if (instr->hydrogen()->IsAllocationFoldingDominator()) { + flags = static_cast<AllocationFlags>(flags | ALLOCATION_FOLDING_DOMINATOR); + } + DCHECK(!instr->hydrogen()->IsAllocationFolded()); if (instr->size()->IsConstantOperand()) { int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); @@ -4903,6 +4853,29 @@ void LCodeGen::DoAllocate(LAllocate* instr) { } } +void LCodeGen::DoFastAllocate(LFastAllocate* instr) { + DCHECK(instr->hydrogen()->IsAllocationFolded()); + DCHECK(!instr->hydrogen()->IsAllocationFoldingDominator()); + Register result = ToRegister(instr->result()); + Register temp = ToRegister(instr->temp()); + + AllocationFlags flags = ALLOCATION_FOLDED; + if (instr->hydrogen()->MustAllocateDoubleAligned()) { + flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); + } + if (instr->hydrogen()->IsOldSpaceAllocation()) { + DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); + flags = static_cast<AllocationFlags>(flags | PRETENURE); + } + if (instr->size()->IsConstantOperand()) { + int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); + CHECK(size <= Page::kMaxRegularHeapObjectSize); + __ FastAllocate(size, result, temp, flags); + } else { + Register size = ToRegister(instr->size()); + __ FastAllocate(size, result, temp, flags); + } +} void LCodeGen::DoDeferredAllocate(LAllocate* instr) { Register result = ToRegister(instr->result()); @@ -4942,6 +4915,22 @@ void LCodeGen::DoDeferredAllocate(LAllocate* instr) { CallRuntimeFromDeferred( Runtime::kAllocateInTargetSpace, 2, instr, instr->context()); __ StoreToSafepointRegisterSlot(result, eax); + + if (instr->hydrogen()->IsAllocationFoldingDominator()) { + AllocationFlags allocation_flags = NO_ALLOCATION_FLAGS; + if (instr->hydrogen()->IsOldSpaceAllocation()) { + DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); + allocation_flags = static_cast<AllocationFlags>(flags | PRETENURE); + } + // If the allocation folding dominator allocate triggered a GC, allocation + // happend in the runtime. We have to reset the top pointer to virtually + // undo the allocation. + ExternalReference allocation_top = + AllocationUtils::GetAllocationTopReference(isolate(), allocation_flags); + __ sub(eax, Immediate(kHeapObjectTag)); + __ mov(Operand::StaticVariable(allocation_top), eax); + __ add(eax, Immediate(kHeapObjectTag)); + } } @@ -4954,8 +4943,8 @@ void LCodeGen::DoTypeof(LTypeof* instr) { __ mov(eax, Immediate(isolate()->factory()->number_string())); __ jmp(&end); __ bind(&do_call); - TypeofStub stub(isolate()); - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); + Callable callable = CodeFactory::Typeof(isolate()); + CallCode(callable.code(), RelocInfo::CODE_TARGET, instr); __ bind(&end); } @@ -5211,7 +5200,7 @@ void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { FieldOperand(result, FixedArray::SizeFor(instr->idx()))); __ bind(&done); __ test(result, result); - DeoptimizeIf(equal, instr, Deoptimizer::kNoCache); + DeoptimizeIf(equal, instr, DeoptimizeReason::kNoCache); } @@ -5219,7 +5208,7 @@ void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { Register object = ToRegister(instr->value()); __ cmp(ToRegister(instr->map()), FieldOperand(object, HeapObject::kMapOffset)); - DeoptimizeIf(not_equal, instr, Deoptimizer::kWrongMap); + DeoptimizeIf(not_equal, instr, DeoptimizeReason::kWrongMap); } |