From: svenpanne@chromium.org Date: Wed, 24 Sep 2014 10:47:29 +0000 (+0000) Subject: Make the detailed reason for deopts mandatory on all platforms. X-Git-Tag: upstream/4.7.83~6736 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=82e5de6bddb640cca239931939965f4de1387ed2;p=platform%2Fupstream%2Fv8.git Make the detailed reason for deopts mandatory on all platforms. Boring semi-mechanical stuff... R=jarin@chromium.org Review URL: https://codereview.chromium.org/598953002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24178 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index a06ed73..1474096 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -1158,7 +1158,7 @@ void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) { __ and_(dividend, dividend, Operand(mask)); __ rsb(dividend, dividend, Operand::Zero(), SetCC); if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "minus zero"); } __ b(&done); } @@ -1176,7 +1176,7 @@ void LCodeGen::DoModByConstI(LModByConstI* instr) { DCHECK(!dividend.is(result)); if (divisor == 0) { - DeoptimizeIf(al, instr); + DeoptimizeIf(al, instr, "division by zero"); return; } @@ -1191,7 +1191,7 @@ void LCodeGen::DoModByConstI(LModByConstI* instr) { Label remainder_not_zero; __ b(ne, &remainder_not_zero); __ cmp(dividend, Operand::Zero()); - DeoptimizeIf(lt, instr); + DeoptimizeIf(lt, instr, "minus zero"); __ bind(&remainder_not_zero); } } @@ -1211,7 +1211,7 @@ void LCodeGen::DoModI(LModI* instr) { // case because we can't return a NaN. if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { __ cmp(right_reg, Operand::Zero()); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "division by zero"); } // Check for kMinInt % -1, sdiv will return kMinInt, which is not what we @@ -1222,7 +1222,7 @@ void LCodeGen::DoModI(LModI* instr) { __ b(ne, &no_overflow_possible); __ cmp(right_reg, Operand(-1)); if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "minus zero"); } else { __ b(ne, &no_overflow_possible); __ mov(result_reg, Operand::Zero()); @@ -1243,7 +1243,7 @@ void LCodeGen::DoModI(LModI* instr) { __ cmp(result_reg, Operand::Zero()); __ b(ne, &done); __ cmp(left_reg, Operand::Zero()); - DeoptimizeIf(lt, instr); + DeoptimizeIf(lt, instr, "minus zero"); } __ bind(&done); @@ -1268,7 +1268,7 @@ void LCodeGen::DoModI(LModI* instr) { // NaN. if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { __ cmp(right_reg, Operand::Zero()); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "division by zero"); } __ Move(result_reg, left_reg); @@ -1298,7 +1298,7 @@ void LCodeGen::DoModI(LModI* instr) { if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { __ b(ne, &done); __ cmp(left_reg, Operand::Zero()); - DeoptimizeIf(mi, instr); + DeoptimizeIf(mi, instr, "minus zero"); } __ bind(&done); } @@ -1316,19 +1316,19 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { HDiv* hdiv = instr->hydrogen(); if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { __ cmp(dividend, Operand::Zero()); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "minus zero"); } // Check for (kMinInt / -1). if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { __ cmp(dividend, Operand(kMinInt)); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "overflow"); } // 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); __ tst(dividend, Operand(mask)); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "lost precision"); } if (divisor == -1) { // Nice shortcut, not needed for correctness. @@ -1356,7 +1356,7 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) { DCHECK(!dividend.is(result)); if (divisor == 0) { - DeoptimizeIf(al, instr); + DeoptimizeIf(al, instr, "division by zero"); return; } @@ -1364,7 +1364,7 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) { HDiv* hdiv = instr->hydrogen(); if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { __ cmp(dividend, Operand::Zero()); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "minus zero"); } __ TruncatingDiv(result, dividend, Abs(divisor)); @@ -1374,7 +1374,7 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) { __ mov(ip, Operand(divisor)); __ smull(scratch0(), ip, result, ip); __ sub(scratch0(), scratch0(), dividend, SetCC); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "lost precision"); } } @@ -1389,7 +1389,7 @@ void LCodeGen::DoDivI(LDivI* instr) { // Check for x / 0. if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { __ cmp(divisor, Operand::Zero()); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "division by zero"); } // Check for (0 / -x) that will produce negative zero. @@ -1401,7 +1401,7 @@ void LCodeGen::DoDivI(LDivI* instr) { } __ b(pl, &positive); __ cmp(dividend, Operand::Zero()); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "minus zero"); __ bind(&positive); } @@ -1413,7 +1413,7 @@ void LCodeGen::DoDivI(LDivI* instr) { // support because, on ARM, sdiv kMinInt, -1 -> kMinInt. __ cmp(dividend, Operand(kMinInt)); __ cmp(divisor, Operand(-1), eq); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "overflow"); } if (CpuFeatures::IsSupported(SUDIV)) { @@ -1436,7 +1436,7 @@ void LCodeGen::DoDivI(LDivI* instr) { Register remainder = scratch0(); __ Mls(remainder, result, divisor, dividend); __ cmp(remainder, Operand::Zero()); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "lost precision"); } } @@ -1487,13 +1487,13 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { // If the divisor is negative, we have to negate and handle edge cases. __ rsb(result, dividend, Operand::Zero(), SetCC); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "minus zero"); } // Dividing by -1 is basically negation, unless we overflow. if (divisor == -1) { if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } return; } @@ -1516,7 +1516,7 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { DCHECK(!dividend.is(result)); if (divisor == 0) { - DeoptimizeIf(al, instr); + DeoptimizeIf(al, instr, "division by zero"); return; } @@ -1524,7 +1524,7 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { HMathFloorOfDiv* hdiv = instr->hydrogen(); if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { __ cmp(dividend, Operand::Zero()); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "minus zero"); } // Easy case: We need no dynamic check for the dividend and the flooring @@ -1565,7 +1565,7 @@ void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { // Check for x / 0. if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { __ cmp(right, Operand::Zero()); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "division by zero"); } // Check for (0 / -x) that will produce negative zero. @@ -1577,7 +1577,7 @@ void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { } __ b(pl, &positive); __ cmp(left, Operand::Zero()); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "minus zero"); __ bind(&positive); } @@ -1589,7 +1589,7 @@ void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { // support because, on ARM, sdiv kMinInt, -1 -> kMinInt. __ cmp(left, Operand(kMinInt)); __ cmp(right, Operand(-1), eq); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "overflow"); } if (CpuFeatures::IsSupported(SUDIV)) { @@ -1635,14 +1635,14 @@ void LCodeGen::DoMulI(LMulI* instr) { // The case of a null constant will be handled separately. // If constant is negative and left is null, the result should be -0. __ cmp(left, Operand::Zero()); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "minus zero"); } switch (constant) { case -1: if (overflow) { __ rsb(result, left, Operand::Zero(), SetCC); - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } else { __ rsb(result, left, Operand::Zero()); } @@ -1652,7 +1652,7 @@ void LCodeGen::DoMulI(LMulI* instr) { // If left is strictly negative and the constant is null, the // result is -0. Deoptimize if required, otherwise return 0. __ cmp(left, Operand::Zero()); - DeoptimizeIf(mi, instr); + DeoptimizeIf(mi, instr, "minus zero"); } __ mov(result, Operand::Zero()); break; @@ -1702,7 +1702,7 @@ void LCodeGen::DoMulI(LMulI* instr) { __ smull(result, scratch, left, right); } __ cmp(scratch, Operand(result, ASR, 31)); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "overflow"); } else { if (instr->hydrogen()->representation().IsSmi()) { __ SmiUntag(result, left); @@ -1718,7 +1718,7 @@ void LCodeGen::DoMulI(LMulI* instr) { __ b(pl, &done); // Bail out if the result is minus zero. __ cmp(result, Operand::Zero()); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "minus zero"); __ bind(&done); } } @@ -1781,7 +1781,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) { case Token::SHR: if (instr->can_deopt()) { __ mov(result, Operand(left, LSR, scratch), SetCC); - DeoptimizeIf(mi, instr); + DeoptimizeIf(mi, instr, "negative value"); } else { __ mov(result, Operand(left, LSR, scratch)); } @@ -1818,7 +1818,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) { } else { if (instr->can_deopt()) { __ tst(left, Operand(0x80000000)); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "negative value"); } __ Move(result, left); } @@ -1833,7 +1833,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) { } else { __ SmiTag(result, left, SetCC); } - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } else { __ mov(result, Operand(left, LSL, shift_count)); } @@ -1865,7 +1865,7 @@ void LCodeGen::DoSubI(LSubI* instr) { } if (can_overflow) { - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } } @@ -1886,7 +1886,7 @@ void LCodeGen::DoRSubI(LRSubI* instr) { } if (can_overflow) { - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } } @@ -1940,9 +1940,9 @@ void LCodeGen::DoDateField(LDateField* instr) { DCHECK(!scratch.is(object)); __ SmiTst(object); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "Smi"); __ CompareObjectType(object, scratch, scratch, JS_DATE_TYPE); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "not a date object"); if (index->value() == 0) { __ ldr(result, FieldMemOperand(object, JSDate::kValueOffset)); @@ -2059,7 +2059,7 @@ void LCodeGen::DoAddI(LAddI* instr) { } if (can_overflow) { - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } } @@ -2285,7 +2285,7 @@ void LCodeGen::DoBranch(LBranch* instr) { } else if (expected.NeedsMap()) { // If we need a map later and have a Smi -> deopt. __ SmiTst(reg); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "Smi"); } const Register map = scratch0(); @@ -2341,7 +2341,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(al, instr); + DeoptimizeIf(al, instr, "unexpected object"); } } } @@ -2986,7 +2986,7 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { if (instr->hydrogen()->RequiresHoleCheck()) { __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); __ cmp(result, ip); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "hole"); } } @@ -3036,7 +3036,7 @@ void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { Register payload = ToRegister(instr->temp()); __ ldr(payload, FieldMemOperand(cell, Cell::kValueOffset)); __ CompareRoot(payload, Heap::kTheHoleValueRootIndex); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "hole"); } // Store the value. @@ -3053,7 +3053,7 @@ void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); __ cmp(result, ip); if (instr->hydrogen()->DeoptimizesOnHole()) { - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "hole"); } else { __ mov(result, Operand(factory()->undefined_value()), LeaveCC, eq); } @@ -3074,7 +3074,7 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); __ cmp(scratch, ip); if (instr->hydrogen()->DeoptimizesOnHole()) { - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "hole"); } else { __ b(ne, &skip_assignment); } @@ -3154,7 +3154,7 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { // Check that the function has a prototype or an initial map. __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); __ cmp(result, ip); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "hole"); // If the function does not have an initial map, we're done. Label done; @@ -3280,7 +3280,7 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { __ ldr(result, mem_operand); if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { __ cmp(result, Operand(0x80000000)); - DeoptimizeIf(cs, instr); + DeoptimizeIf(cs, instr, "negative value"); } break; case FLOAT32_ELEMENTS: @@ -3333,7 +3333,7 @@ void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { if (instr->hydrogen()->RequiresHoleCheck()) { __ ldr(scratch, MemOperand(scratch, sizeof(kHoleNanLower32))); __ cmp(scratch, Operand(kHoleNanUpper32)); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "hole"); } } @@ -3367,11 +3367,11 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { if (instr->hydrogen()->RequiresHoleCheck()) { if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { __ SmiTst(result); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "not a Smi"); } else { __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); __ cmp(result, scratch); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "hole"); } } } @@ -3513,9 +3513,9 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { // Deoptimize if the receiver is not a JS object. __ SmiTst(receiver); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "Smi"); __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE); - DeoptimizeIf(lt, instr); + DeoptimizeIf(lt, instr, "not a JavaScript object"); __ b(&result_in_receiver); __ bind(&global_object); @@ -3550,7 +3550,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { // adaptor frame below it. const uint32_t kArgumentsLimit = 1 * KB; __ cmp(length, Operand(kArgumentsLimit)); - DeoptimizeIf(hi, instr); + DeoptimizeIf(hi, instr, "too many arguments"); // Push the receiver and use the register to keep the original // number of arguments. @@ -3680,7 +3680,7 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); __ cmp(scratch, Operand(ip)); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "not a heap number"); Label done; Register exponent = scratch0(); @@ -3748,7 +3748,7 @@ void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { // if input is positive. __ rsb(result, input, Operand::Zero(), SetCC, mi); // Deoptimize on overflow. - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } @@ -3794,7 +3794,7 @@ void LCodeGen::DoMathFloor(LMathFloor* instr) { Label done, exact; __ TryInt32Floor(result, input, input_high, double_scratch0(), &done, &exact); - DeoptimizeIf(al, instr); + DeoptimizeIf(al, instr, "lost precision or NaN"); __ bind(&exact); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { @@ -3802,7 +3802,7 @@ void LCodeGen::DoMathFloor(LMathFloor* instr) { __ cmp(result, Operand::Zero()); __ b(ne, &done); __ cmp(input_high, Operand::Zero()); - DeoptimizeIf(mi, instr); + DeoptimizeIf(mi, instr, "minus zero"); } __ bind(&done); } @@ -3827,7 +3827,8 @@ void LCodeGen::DoMathRound(LMathRound* instr) { if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { __ VmovHigh(input_high, input); __ cmp(input_high, Operand::Zero()); - DeoptimizeIf(mi, instr); // [-0.5, -0]. + // [-0.5, -0]. + DeoptimizeIf(mi, instr, "minus zero"); } __ VFPCompareAndSetFlags(input, dot_five); __ mov(result, Operand(1), LeaveCC, eq); // +0.5. @@ -3841,7 +3842,7 @@ void LCodeGen::DoMathRound(LMathRound* instr) { // Reuse dot_five (double_scratch0) as we no longer need this value. __ TryInt32Floor(result, input_plus_dot_five, input_high, double_scratch0(), &done, &done); - DeoptimizeIf(al, instr); + DeoptimizeIf(al, instr, "lost precision or NaN"); __ bind(&done); } @@ -3905,7 +3906,7 @@ void LCodeGen::DoPower(LPower* instr) { __ ldr(r6, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset)); __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); __ cmp(r6, Operand(ip)); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "not a heap number"); __ bind(&no_deopt); MathPowStub stub(isolate(), MathPowStub::TAGGED); __ CallStub(&stub); @@ -4257,7 +4258,7 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { __ stop("eliminated bounds check failed"); __ bind(&done); } else { - DeoptimizeIf(cc, instr); + DeoptimizeIf(cc, instr, "out of bounds"); } } @@ -4505,7 +4506,7 @@ void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { Register temp = ToRegister(instr->temp()); Label no_memento_found; __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "memento found"); __ bind(&no_memento_found); } @@ -4839,12 +4840,12 @@ void LCodeGen::DoSmiTag(LSmiTag* instr) { if (hchange->CheckFlag(HValue::kCanOverflow) && hchange->value()->CheckFlag(HValue::kUint32)) { __ tst(input, Operand(0xc0000000)); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "overflow"); } if (hchange->CheckFlag(HValue::kCanOverflow) && !hchange->value()->CheckFlag(HValue::kUint32)) { __ SmiTag(output, input, SetCC); - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } else { __ SmiTag(output, input); } @@ -4858,7 +4859,7 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) { STATIC_ASSERT(kHeapObjectTag == 1); // If the input is a HeapObject, SmiUntag will set the carry flag. __ SmiUntag(result, input, SetCC); - DeoptimizeIf(cs, instr); + DeoptimizeIf(cs, instr, "not a Smi"); } else { __ SmiUntag(result, input); } @@ -4886,7 +4887,7 @@ void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg, if (can_convert_undefined_to_nan) { __ b(ne, &convert); } else { - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "not a heap number"); } // load heap number __ vldr(result_reg, input_reg, HeapNumber::kValueOffset - kHeapObjectTag); @@ -4896,7 +4897,7 @@ void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg, __ b(ne, &done); __ VmovHigh(scratch, result_reg); __ cmp(scratch, Operand(HeapNumber::kSignMask)); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "minus zero"); } __ jmp(&done); if (can_convert_undefined_to_nan) { @@ -4904,7 +4905,7 @@ void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg, // Convert undefined (and hole) to NaN. __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); __ cmp(input_reg, Operand(ip)); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "not a heap number/undefined"); __ LoadRoot(scratch, Heap::kNanValueRootIndex); __ vldr(result_reg, scratch, HeapNumber::kValueOffset - kHeapObjectTag); __ jmp(&done); @@ -4972,7 +4973,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { __ bind(&check_false); __ LoadRoot(ip, Heap::kFalseValueRootIndex); __ cmp(scratch2, Operand(ip)); - DeoptimizeIf(ne, instr, "cannot truncate"); + DeoptimizeIf(ne, instr, "not a heap number/undefined/true/false"); __ mov(input_reg, Operand::Zero()); } else { DeoptimizeIf(ne, instr, "not a heap number"); @@ -5057,14 +5058,14 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) { } else { __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch); // Deoptimize if the input wasn't a int32 (inside a double). - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "lost precision or NaN"); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { Label done; __ cmp(result_reg, Operand::Zero()); __ b(ne, &done); __ VmovHigh(scratch1, double_input); __ tst(scratch1, Operand(HeapNumber::kSignMask)); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "minus zero"); __ bind(&done); } } @@ -5082,26 +5083,26 @@ void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { } else { __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch); // Deoptimize if the input wasn't a int32 (inside a double). - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "lost precision or NaN"); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { Label done; __ cmp(result_reg, Operand::Zero()); __ b(ne, &done); __ VmovHigh(scratch1, double_input); __ tst(scratch1, Operand(HeapNumber::kSignMask)); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "minus zero"); __ bind(&done); } } __ SmiTag(result_reg, SetCC); - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } void LCodeGen::DoCheckSmi(LCheckSmi* instr) { LOperand* input = instr->value(); __ SmiTst(ToRegister(input)); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "not a Smi"); } @@ -5109,7 +5110,7 @@ void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { if (!instr->hydrogen()->value()->type().IsHeapObject()) { LOperand* input = instr->value(); __ SmiTst(ToRegister(input)); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "Smi"); } } @@ -5130,13 +5131,13 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { // If there is only one type in the interval check for equality. if (first == last) { - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "wrong instance type"); } else { - DeoptimizeIf(lo, instr); + DeoptimizeIf(lo, instr, "wrong instance type"); // Omit check for the last type. if (last != LAST_TYPE) { __ cmp(scratch, Operand(last)); - DeoptimizeIf(hi, instr); + DeoptimizeIf(hi, instr, "wrong instance type"); } } } else { @@ -5147,11 +5148,11 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { if (base::bits::IsPowerOfTwo32(mask)) { DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag)); __ tst(scratch, Operand(mask)); - DeoptimizeIf(tag == 0 ? ne : eq, instr); + DeoptimizeIf(tag == 0 ? ne : eq, instr, "wrong instance type"); } else { __ and_(scratch, scratch, Operand(mask)); __ cmp(scratch, Operand(tag)); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "wrong instance type"); } } } @@ -5170,7 +5171,7 @@ void LCodeGen::DoCheckValue(LCheckValue* instr) { } else { __ cmp(reg, Operand(object)); } - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "value mismatch"); } @@ -5185,7 +5186,7 @@ void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { __ StoreToSafepointRegisterSlot(r0, scratch0()); } __ tst(scratch0(), Operand(kSmiTagMask)); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "instance migration failed"); } @@ -5242,7 +5243,7 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) { if (instr->hydrogen()->HasMigrationTarget()) { __ b(ne, deferred->entry()); } else { - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "wrong map"); } __ bind(&success); @@ -5281,7 +5282,7 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { // Check for undefined. Undefined is converted to zero for clamping // conversions. __ cmp(input_reg, Operand(factory()->undefined_value())); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "not a heap number/undefined"); __ mov(result_reg, Operand::Zero()); __ jmp(&done); @@ -5751,19 +5752,19 @@ void LCodeGen::DoOsrEntry(LOsrEntry* instr) { void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); __ cmp(r0, ip); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "undefined"); Register null_value = r5; __ LoadRoot(null_value, Heap::kNullValueRootIndex); __ cmp(r0, null_value); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "null"); __ SmiTst(r0); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "Smi"); STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); __ CompareObjectType(r0, r1, r1, LAST_JS_PROXY_TYPE); - DeoptimizeIf(le, instr); + DeoptimizeIf(le, instr, "wrong instance type"); Label use_cache, call_runtime; __ CheckEnumCache(null_value, &call_runtime); @@ -5779,7 +5780,7 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset)); __ LoadRoot(ip, Heap::kMetaMapRootIndex); __ cmp(r1, ip); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "wrong map"); __ bind(&use_cache); } @@ -5801,7 +5802,7 @@ void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { __ ldr(result, FieldMemOperand(result, FixedArray::SizeFor(instr->idx()))); __ cmp(result, Operand::Zero()); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "no cache"); __ bind(&done); } @@ -5812,7 +5813,7 @@ void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { Register map = ToRegister(instr->map()); __ ldr(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset)); __ cmp(map, scratch0()); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "wrong map"); } diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h index cb137d1..65cc213 100644 --- a/src/arm/lithium-codegen-arm.h +++ b/src/arm/lithium-codegen-arm.h @@ -237,7 +237,7 @@ class LCodeGen: public LCodeGenBase { void DeoptimizeIf(Condition condition, LInstruction* instr, const char* detail, Deoptimizer::BailoutType bailout_type); void DeoptimizeIf(Condition condition, LInstruction* instr, - const char* detail = NULL); + const char* detail); void AddToTranslation(LEnvironment* environment, Translation* translation, diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc index 2998642..b9b67d9 100644 --- a/src/arm64/lithium-codegen-arm64.cc +++ b/src/arm64/lithium-codegen-arm64.cc @@ -1063,9 +1063,8 @@ void LCodeGen::DeoptimizeBranch( } -void LCodeGen::Deoptimize(LInstruction* instr, - Deoptimizer::BailoutType* override_bailout_type, - const char* detail) { +void LCodeGen::Deoptimize(LInstruction* instr, const char* detail, + Deoptimizer::BailoutType* override_bailout_type) { DeoptimizeBranch(instr, detail, always, NoReg, -1, override_bailout_type); } @@ -1516,7 +1515,7 @@ void LCodeGen::DoAddI(LAddI* instr) { if (can_overflow) { __ Adds(result, left, right); - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } else { __ Add(result, left, right); } @@ -1530,7 +1529,7 @@ void LCodeGen::DoAddS(LAddS* instr) { Operand right = ToOperand(instr->right()); if (can_overflow) { __ Adds(result, left, right); - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } else { __ Add(result, left, right); } @@ -1656,7 +1655,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { // adaptor frame below it. const uint32_t kArgumentsLimit = 1 * KB; __ Cmp(length, kArgumentsLimit); - DeoptimizeIf(hi, instr); + DeoptimizeIf(hi, instr, "too many arguments"); // Push the receiver and use the register to keep the original // number of arguments. @@ -1838,7 +1837,7 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck *instr) { if (FLAG_debug_code && instr->hydrogen()->skip_check()) { __ Assert(NegateCondition(cond), kEliminatedBoundsCheckFailed); } else { - DeoptimizeIf(cond, instr); + DeoptimizeIf(cond, instr, "out of bounds"); } } @@ -1917,7 +1916,7 @@ void LCodeGen::DoBranch(LBranch* instr) { __ JumpIfSmi(value, true_label); } else if (expected.NeedsMap()) { // If we need a map later and have a smi, deopt. - DeoptimizeIfSmi(value, instr); + DeoptimizeIfSmi(value, instr, "Smi"); } Register map = NoReg; @@ -1978,7 +1977,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. - Deoptimize(instr); + Deoptimize(instr, "unexpected object"); } } } @@ -2163,7 +2162,7 @@ void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { instr->pointer_map(), 1, Safepoint::kNoLazyDeopt); __ StoreToSafepointRegisterSlot(x0, temp); } - DeoptimizeIfSmi(temp, instr); + DeoptimizeIfSmi(temp, instr, "instance migration failed"); } @@ -2218,7 +2217,7 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) { if (instr->hydrogen()->HasMigrationTarget()) { __ B(ne, deferred->entry()); } else { - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "wrong map"); } __ Bind(&success); @@ -2227,7 +2226,7 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) { void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { if (!instr->hydrogen()->value()->type().IsHeapObject()) { - DeoptimizeIfSmi(ToRegister(instr->value()), instr); + DeoptimizeIfSmi(ToRegister(instr->value()), instr, "Smi"); } } @@ -2235,7 +2234,7 @@ void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { void LCodeGen::DoCheckSmi(LCheckSmi* instr) { Register value = ToRegister(instr->value()); DCHECK(!instr->result() || ToRegister(instr->result()).Is(value)); - DeoptimizeIfNotSmi(value, instr); + DeoptimizeIfNotSmi(value, instr, "not a Smi"); } @@ -2253,15 +2252,15 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { __ Cmp(scratch, first); if (first == last) { // If there is only one type in the interval check for equality. - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "wrong instance type"); } else if (last == LAST_TYPE) { // We don't need to compare with the higher bound of the interval. - DeoptimizeIf(lo, instr); + DeoptimizeIf(lo, instr, "wrong instance type"); } else { // If we are below the lower bound, set the C flag and clear the Z flag // to force a deopt. __ Ccmp(scratch, last, CFlag, hs); - DeoptimizeIf(hi, instr); + DeoptimizeIf(hi, instr, "wrong instance type"); } } else { uint8_t mask; @@ -2271,9 +2270,11 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { if (base::bits::IsPowerOfTwo32(mask)) { DCHECK((tag == 0) || (tag == mask)); if (tag == 0) { - DeoptimizeIfBitSet(scratch, MaskToBit(mask), instr); + DeoptimizeIfBitSet(scratch, MaskToBit(mask), instr, + "wrong instance type"); } else { - DeoptimizeIfBitClear(scratch, MaskToBit(mask), instr); + DeoptimizeIfBitClear(scratch, MaskToBit(mask), instr, + "wrong instance type"); } } else { if (tag == 0) { @@ -2282,7 +2283,7 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { __ And(scratch, scratch, mask); __ Cmp(scratch, tag); } - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "wrong instance type"); } } } @@ -2321,7 +2322,8 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { __ JumpIfHeapNumber(input, &is_heap_number); // Check for undefined. Undefined is coverted to zero for clamping conversion. - DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr); + DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr, + "not a heap number/undefined"); __ Mov(result, 0); __ B(&done); @@ -2626,7 +2628,7 @@ void LCodeGen::DoCheckValue(LCheckValue* instr) { } else { __ Cmp(reg, Operand(object)); } - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "value mismatch"); } @@ -2650,9 +2652,9 @@ void LCodeGen::DoDateField(LDateField* instr) { DCHECK(object.is(result) && object.Is(x0)); DCHECK(instr->IsMarkedAsCall()); - DeoptimizeIfSmi(object, instr); + DeoptimizeIfSmi(object, instr, "Smi"); __ CompareObjectType(object, temp1, temp1, JS_DATE_TYPE); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "not a date object"); if (index->value() == 0) { __ Ldr(result, FieldMemOperand(object, JSDate::kValueOffset)); @@ -2688,7 +2690,7 @@ void LCodeGen::DoDeoptimize(LDeoptimize* instr) { type = Deoptimizer::LAZY; } - Deoptimize(instr, &type, instr->hydrogen()->reason()); + Deoptimize(instr, instr->hydrogen()->reason(), &type); } @@ -2702,21 +2704,21 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { // Check for (0 / -x) that will produce negative zero. HDiv* hdiv = instr->hydrogen(); if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { - DeoptimizeIfZero(dividend, instr); + DeoptimizeIfZero(dividend, instr, "division by zero"); } // Check for (kMinInt / -1). if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { // Test dividend for kMinInt by subtracting one (cmp) and checking for // overflow. __ Cmp(dividend, 1); - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } // 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); __ Tst(dividend, mask); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "lost precision"); } if (divisor == -1) { // Nice shortcut, not needed for correctness. @@ -2744,14 +2746,14 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) { DCHECK(!AreAliased(dividend, result)); if (divisor == 0) { - Deoptimize(instr); + Deoptimize(instr, "division by zero"); return; } // Check for (0 / -x) that will produce negative zero. HDiv* hdiv = instr->hydrogen(); if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { - DeoptimizeIfZero(dividend, instr); + DeoptimizeIfZero(dividend, instr, "minus zero"); } __ TruncatingDiv(result, dividend, Abs(divisor)); @@ -2763,7 +2765,7 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) { __ Sxtw(dividend.X(), dividend); __ Mov(temp, divisor); __ Smsubl(temp.X(), result, temp, dividend.X()); - DeoptimizeIfNotZero(temp, instr); + DeoptimizeIfNotZero(temp, instr, "lost precision"); } } @@ -2786,7 +2788,7 @@ void LCodeGen::DoDivI(LDivI* instr) { // Check for x / 0. if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { - DeoptimizeIfZero(divisor, instr); + DeoptimizeIfZero(divisor, instr, "division by zero"); } // Check for (0 / -x) as that will produce negative zero. @@ -2798,7 +2800,7 @@ void LCodeGen::DoDivI(LDivI* instr) { // If the divisor >= 0 (pl, the opposite of mi) set the flags to // condition ne, so we don't deopt, ie. positive divisor doesn't deopt. __ Ccmp(dividend, 0, NoFlag, mi); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "minus zero"); } // Check for (kMinInt / -1). @@ -2810,13 +2812,13 @@ void LCodeGen::DoDivI(LDivI* instr) { // -1. If overflow is clear, set the flags for condition ne, as the // dividend isn't -1, and thus we shouldn't deopt. __ Ccmp(divisor, -1, NoFlag, vs); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "overflow"); } // Compute remainder and deopt if it's not zero. Register remainder = ToRegister32(instr->temp()); __ Msub(remainder, result, divisor, dividend); - DeoptimizeIfNotZero(remainder, instr); + DeoptimizeIfNotZero(remainder, instr, "lost precision"); } @@ -2825,11 +2827,11 @@ void LCodeGen::DoDoubleToIntOrSmi(LDoubleToIntOrSmi* instr) { Register result = ToRegister32(instr->result()); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIfMinusZero(input, instr); + DeoptimizeIfMinusZero(input, instr, "minus zero"); } __ TryRepresentDoubleAsInt32(result, input, double_scratch()); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "lost precision or NaN"); if (instr->tag_result()) { __ SmiTag(result.X()); @@ -2890,7 +2892,7 @@ void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { __ LoadInstanceDescriptors(map, result); __ Ldr(result, FieldMemOperand(result, DescriptorArray::kEnumCacheOffset)); __ Ldr(result, FieldMemOperand(result, FixedArray::SizeFor(instr->idx()))); - DeoptimizeIfZero(result, instr); + DeoptimizeIfZero(result, instr, "no cache"); __ Bind(&done); } @@ -2903,17 +2905,17 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { DCHECK(instr->IsMarkedAsCall()); DCHECK(object.Is(x0)); - DeoptimizeIfRoot(object, Heap::kUndefinedValueRootIndex, instr); + DeoptimizeIfRoot(object, Heap::kUndefinedValueRootIndex, instr, "undefined"); __ LoadRoot(null_value, Heap::kNullValueRootIndex); __ Cmp(object, null_value); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "null"); - DeoptimizeIfSmi(object, instr); + DeoptimizeIfSmi(object, instr, "Smi"); STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); __ CompareObjectType(object, x1, x1, LAST_JS_PROXY_TYPE); - DeoptimizeIf(le, instr); + DeoptimizeIf(le, instr, "not a JavaScript object"); Label use_cache, call_runtime; __ CheckEnumCache(object, null_value, x1, x2, x3, x4, &call_runtime); @@ -2927,7 +2929,7 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr); __ Ldr(x1, FieldMemOperand(object, HeapObject::kMapOffset)); - DeoptimizeIfNotRoot(x1, Heap::kMetaMapRootIndex, instr); + DeoptimizeIfNotRoot(x1, Heap::kMetaMapRootIndex, instr, "wrong map"); __ Bind(&use_cache); } @@ -3320,7 +3322,7 @@ void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { __ Ldr(result, ContextMemOperand(context, instr->slot_index())); if (instr->hydrogen()->RequiresHoleCheck()) { if (instr->hydrogen()->DeoptimizesOnHole()) { - DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr); + DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr, "hole"); } else { Label not_the_hole; __ JumpIfNotRoot(result, Heap::kTheHoleValueRootIndex, ¬_the_hole); @@ -3341,7 +3343,7 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { JSFunction::kPrototypeOrInitialMapOffset)); // Check that the function has a prototype or an initial map. - DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr); + DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr, "hole"); // If the function does not have an initial map, we're done. Label done; @@ -3361,7 +3363,7 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { __ Mov(result, Operand(Handle(instr->hydrogen()->cell().handle()))); __ Ldr(result, FieldMemOperand(result, Cell::kValueOffset)); if (instr->hydrogen()->RequiresHoleCheck()) { - DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr); + DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr, "hole"); } } @@ -3492,7 +3494,7 @@ void LCodeGen::DoLoadKeyedExternal(LLoadKeyedExternal* instr) { if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { // Deopt if value > 0x80000000. __ Tst(result, 0xFFFFFFFF80000000); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "negative value"); } break; case FLOAT32_ELEMENTS: @@ -3589,7 +3591,7 @@ void LCodeGen::DoLoadKeyedFixedDouble(LLoadKeyedFixedDouble* instr) { STATIC_ASSERT(kHoleNanInt64 == 0x7fffffffffffffff); __ Ldr(scratch, mem_op); __ Cmn(scratch, 1); - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "hole"); } } @@ -3627,9 +3629,9 @@ void LCodeGen::DoLoadKeyedFixed(LLoadKeyedFixed* instr) { if (instr->hydrogen()->RequiresHoleCheck()) { if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { - DeoptimizeIfNotSmi(result, instr); + DeoptimizeIfNotSmi(result, instr, "not a Smi"); } else { - DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr); + DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr, "hole"); } } } @@ -3731,7 +3733,7 @@ void LCodeGen::DoMathAbs(LMathAbs* instr) { Register result = r.IsSmi() ? ToRegister(instr->result()) : ToRegister32(instr->result()); __ Abs(result, input); - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } } @@ -3883,7 +3885,7 @@ void LCodeGen::DoMathFloorI(LMathFloorI* instr) { Register result = ToRegister(instr->result()); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIfMinusZero(input, instr); + DeoptimizeIfMinusZero(input, instr, "minus zero"); } __ Fcvtms(result, input); @@ -3893,7 +3895,7 @@ void LCodeGen::DoMathFloorI(LMathFloorI* instr) { __ Cmp(result, Operand(result, SXTW)); // - The input was not NaN. __ Fccmp(input, input, NoFlag, eq); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "lost precision or NaN"); } @@ -3919,13 +3921,13 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { // If the divisor is negative, we have to negate and handle edge cases. __ Negs(result, dividend); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "minus zero"); } // Dividing by -1 is basically negation, unless we overflow. if (divisor == -1) { if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } return; } @@ -3948,14 +3950,14 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { DCHECK(!AreAliased(dividend, result)); if (divisor == 0) { - Deoptimize(instr); + Deoptimize(instr, "division by zero"); return; } // Check for (0 / -x) that will produce negative zero. HMathFloorOfDiv* hdiv = instr->hydrogen(); if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { - DeoptimizeIfZero(dividend, instr); + DeoptimizeIfZero(dividend, instr, "minus zero"); } // Easy case: We need no dynamic check for the dividend and the flooring @@ -3998,14 +4000,14 @@ void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { __ Sdiv(result, dividend, divisor); // Check for x / 0. - DeoptimizeIfZero(divisor, instr); + DeoptimizeIfZero(divisor, instr, "division by zero"); // Check for (kMinInt / -1). if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { // The V flag will be set iff dividend == kMinInt. __ Cmp(dividend, 1); __ Ccmp(divisor, -1, NoFlag, vs); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "overflow"); } // Check for (0 / -x) that will produce negative zero. @@ -4015,7 +4017,7 @@ void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { // "divisor" can't be null because the code would have already been // deoptimized. The Z flag is set only if (divisor < 0) and (dividend == 0). // In this case we need to deoptimize to produce a -0. - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "minus zero"); } Label done; @@ -4174,18 +4176,18 @@ void LCodeGen::DoMathRoundI(LMathRoundI* instr) { // Deoptimize if the result > 1, as it must be larger than 32 bits. __ Cmp(result, 1); - DeoptimizeIf(hi, instr); + DeoptimizeIf(hi, instr, "overflow"); // Deoptimize for negative inputs, which at this point are only numbers in // the range [-0.5, -0.0] if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { __ Fmov(result, input); - DeoptimizeIfNegative(result, instr); + DeoptimizeIfNegative(result, instr, "minus zero"); } // Deoptimize if the input was NaN. __ Fcmp(input, dot_five); - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "NaN"); // Now, the only unhandled inputs are in the range [0.0, 1.5[ (or [-0.5, 1.5[ // if we didn't generate a -0.0 bailout). If input >= 0.5 then return 1, @@ -4263,7 +4265,7 @@ void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) { __ And(dividend, dividend, mask); __ Negs(dividend, dividend); if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "minus zero"); } __ B(&done); } @@ -4282,7 +4284,7 @@ void LCodeGen::DoModByConstI(LModByConstI* instr) { DCHECK(!AreAliased(dividend, result, temp)); if (divisor == 0) { - Deoptimize(instr); + Deoptimize(instr, "division by zero"); return; } @@ -4296,7 +4298,7 @@ void LCodeGen::DoModByConstI(LModByConstI* instr) { if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { Label remainder_not_zero; __ Cbnz(result, &remainder_not_zero); - DeoptimizeIfNegative(dividend, instr); + DeoptimizeIfNegative(dividend, instr, "minus zero"); __ bind(&remainder_not_zero); } } @@ -4311,12 +4313,12 @@ void LCodeGen::DoModI(LModI* instr) { // modulo = dividend - quotient * divisor __ Sdiv(result, dividend, divisor); if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { - DeoptimizeIfZero(divisor, instr); + DeoptimizeIfZero(divisor, instr, "division by zero"); } __ Msub(result, result, divisor, dividend); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { __ Cbnz(result, &done); - DeoptimizeIfNegative(dividend, instr); + DeoptimizeIfNegative(dividend, instr, "minus zero"); } __ Bind(&done); } @@ -4339,10 +4341,10 @@ void LCodeGen::DoMulConstIS(LMulConstIS* instr) { if (bailout_on_minus_zero) { if (right < 0) { // The result is -0 if right is negative and left is zero. - DeoptimizeIfZero(left, instr); + DeoptimizeIfZero(left, instr, "minus zero"); } else if (right == 0) { // The result is -0 if the right is zero and the left is negative. - DeoptimizeIfNegative(left, instr); + DeoptimizeIfNegative(left, instr, "minus zero"); } } @@ -4352,7 +4354,7 @@ void LCodeGen::DoMulConstIS(LMulConstIS* instr) { if (can_overflow) { // Only 0x80000000 can overflow here. __ Negs(result, left); - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } else { __ Neg(result, left); } @@ -4368,7 +4370,7 @@ void LCodeGen::DoMulConstIS(LMulConstIS* instr) { case 2: if (can_overflow) { __ Adds(result, left, left); - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } else { __ Add(result, left, left); } @@ -4387,7 +4389,7 @@ void LCodeGen::DoMulConstIS(LMulConstIS* instr) { DCHECK(!AreAliased(scratch, left)); __ Cls(scratch, left); __ Cmp(scratch, right_log2); - DeoptimizeIf(lt, instr); + DeoptimizeIf(lt, instr, "overflow"); } if (right >= 0) { @@ -4397,7 +4399,7 @@ void LCodeGen::DoMulConstIS(LMulConstIS* instr) { // result = -left << log2(-right) if (can_overflow) { __ Negs(result, Operand(left, LSL, right_log2)); - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } else { __ Neg(result, Operand(left, LSL, right_log2)); } @@ -4455,13 +4457,13 @@ void LCodeGen::DoMulI(LMulI* instr) { // - If so (eq), set N (mi) if left + right is negative. // - Otherwise, clear N. __ Ccmn(left, right, NoFlag, eq); - DeoptimizeIf(mi, instr); + DeoptimizeIf(mi, instr, "minus zero"); } if (can_overflow) { __ Smull(result.X(), left, right); __ Cmp(result.X(), Operand(result, SXTW)); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "overflow"); } else { __ Mul(result, left, right); } @@ -4485,7 +4487,7 @@ void LCodeGen::DoMulS(LMulS* instr) { // - If so (eq), set N (mi) if left + right is negative. // - Otherwise, clear N. __ Ccmn(left, right, NoFlag, eq); - DeoptimizeIf(mi, instr); + DeoptimizeIf(mi, instr, "minus zero"); } STATIC_ASSERT((kSmiShift == 32) && (kSmiTag == 0)); @@ -4493,7 +4495,7 @@ void LCodeGen::DoMulS(LMulS* instr) { __ Smulh(result, left, right); __ Cmp(result, Operand(result.W(), SXTW)); __ SmiTag(result); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "overflow"); } else { if (AreAliased(result, left, right)) { // All three registers are the same: half untag the input and then @@ -4669,13 +4671,14 @@ void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { // Load heap number. __ Ldr(result, FieldMemOperand(input, HeapNumber::kValueOffset)); if (instr->hydrogen()->deoptimize_on_minus_zero()) { - DeoptimizeIfMinusZero(result, instr); + DeoptimizeIfMinusZero(result, instr, "minus zero"); } __ B(&done); if (can_convert_undefined_to_nan) { __ Bind(&convert_undefined); - DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr); + DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr, + "not a heap number/undefined"); __ LoadRoot(scratch, Heap::kNanValueRootIndex); __ Ldr(result, FieldMemOperand(scratch, HeapNumber::kValueOffset)); @@ -4868,7 +4871,7 @@ void LCodeGen::DoSmiTag(LSmiTag* instr) { Register output = ToRegister(instr->result()); if (hchange->CheckFlag(HValue::kCanOverflow) && hchange->value()->CheckFlag(HValue::kUint32)) { - DeoptimizeIfNegative(input.W(), instr); + DeoptimizeIfNegative(input.W(), instr, "overflow"); } __ SmiTag(output, input); } @@ -4880,7 +4883,7 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) { Label done, untag; if (instr->needs_check()) { - DeoptimizeIfNotSmi(input, instr); + DeoptimizeIfNotSmi(input, instr, "not a Smi"); } __ Bind(&untag); @@ -4905,7 +4908,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) { if (instr->can_deopt()) { // If `left >>> right` >= 0x80000000, the result is not representable // in a signed 32-bit smi. - DeoptimizeIfNegative(result, instr); + DeoptimizeIfNegative(result, instr, "negative value"); } break; default: UNREACHABLE(); @@ -4915,7 +4918,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) { int shift_count = JSShiftAmountFromLConstant(right_op); if (shift_count == 0) { if ((instr->op() == Token::SHR) && instr->can_deopt()) { - DeoptimizeIfNegative(left, instr); + DeoptimizeIfNegative(left, instr, "negative value"); } __ Mov(result, left, kDiscardForSameWReg); } else { @@ -4968,7 +4971,7 @@ void LCodeGen::DoShiftS(LShiftS* instr) { if (instr->can_deopt()) { // If `left >>> right` >= 0x80000000, the result is not representable // in a signed 32-bit smi. - DeoptimizeIfNegative(result, instr); + DeoptimizeIfNegative(result, instr, "negative value"); } break; default: UNREACHABLE(); @@ -4978,7 +4981,7 @@ void LCodeGen::DoShiftS(LShiftS* instr) { int shift_count = JSShiftAmountFromLConstant(right_op); if (shift_count == 0) { if ((instr->op() == Token::SHR) && instr->can_deopt()) { - DeoptimizeIfNegative(left, instr); + DeoptimizeIfNegative(left, instr, "negative value"); } __ Mov(result, left); } else { @@ -5107,7 +5110,7 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { if (instr->hydrogen()->RequiresHoleCheck()) { __ Ldr(scratch, target); if (instr->hydrogen()->DeoptimizesOnHole()) { - DeoptimizeIfRoot(scratch, Heap::kTheHoleValueRootIndex, instr); + DeoptimizeIfRoot(scratch, Heap::kTheHoleValueRootIndex, instr, "hole"); } else { __ JumpIfNotRoot(scratch, Heap::kTheHoleValueRootIndex, &skip_assignment); } @@ -5145,7 +5148,7 @@ void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { if (instr->hydrogen()->RequiresHoleCheck()) { Register payload = ToRegister(instr->temp2()); __ Ldr(payload, FieldMemOperand(cell, Cell::kValueOffset)); - DeoptimizeIfRoot(payload, Heap::kTheHoleValueRootIndex, instr); + DeoptimizeIfRoot(payload, Heap::kTheHoleValueRootIndex, instr, "hole"); } // Store the value. @@ -5562,7 +5565,7 @@ void LCodeGen::DoSubI(LSubI* instr) { if (can_overflow) { __ Subs(result, left, right); - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } else { __ Sub(result, left, right); } @@ -5576,7 +5579,7 @@ void LCodeGen::DoSubS(LSubS* instr) { Operand right = ToOperand(instr->right()); if (can_overflow) { __ Subs(result, left, right); - DeoptimizeIf(vs, instr); + DeoptimizeIf(vs, instr, "overflow"); } else { __ Sub(result, left, right); } @@ -5616,7 +5619,8 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr, // Output contains zero, undefined is converted to zero for truncating // conversions. - DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr); + DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr, + "not a heap number/undefined/true/false"); } else { Register output = ToRegister32(instr->result()); DoubleRegister dbl_scratch2 = ToDoubleRegister(temp2); @@ -5774,7 +5778,7 @@ void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { Label no_memento_found; __ TestJSArrayForAllocationMemento(object, temp1, temp2, &no_memento_found); - DeoptimizeIf(eq, instr); + DeoptimizeIf(eq, instr, "memento found"); __ Bind(&no_memento_found); } @@ -5899,7 +5903,7 @@ void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { Register temp = ToRegister(instr->temp()); __ Ldr(temp, FieldMemOperand(object, HeapObject::kMapOffset)); __ Cmp(map, temp); - DeoptimizeIf(ne, instr); + DeoptimizeIf(ne, instr, "wrong map"); } @@ -5933,10 +5937,10 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex, &global_object); // Deoptimize if the receiver is not a JS object. - DeoptimizeIfSmi(receiver, instr); + DeoptimizeIfSmi(receiver, instr, "Smi"); __ CompareObjectType(receiver, result, result, FIRST_SPEC_OBJECT_TYPE); __ B(ge, ©_receiver); - Deoptimize(instr); + Deoptimize(instr, "not a JavaScript object"); __ Bind(&global_object); __ Ldr(result, FieldMemOperand(function, JSFunction::kContextOffset)); diff --git a/src/arm64/lithium-codegen-arm64.h b/src/arm64/lithium-codegen-arm64.h index a141dfa..a73bb8c 100644 --- a/src/arm64/lithium-codegen-arm64.h +++ b/src/arm64/lithium-codegen-arm64.h @@ -217,32 +217,27 @@ class LCodeGen: public LCodeGenBase { BranchType branch_type, Register reg = NoReg, int bit = -1, Deoptimizer::BailoutType* override_bailout_type = NULL); - void Deoptimize(LInstruction* instr, - Deoptimizer::BailoutType* override_bailout_type = NULL, - const char* detail = NULL); - void DeoptimizeIf(Condition cond, LInstruction* instr, - const char* detail = NULL); - void DeoptimizeIfZero(Register rt, LInstruction* instr, - const char* detail = NULL); + void Deoptimize(LInstruction* instr, const char* detail, + Deoptimizer::BailoutType* override_bailout_type = NULL); + void DeoptimizeIf(Condition cond, LInstruction* instr, const char* detail); + void DeoptimizeIfZero(Register rt, LInstruction* instr, const char* detail); void DeoptimizeIfNotZero(Register rt, LInstruction* instr, - const char* detail = NULL); + const char* detail); void DeoptimizeIfNegative(Register rt, LInstruction* instr, - const char* detail = NULL); - void DeoptimizeIfSmi(Register rt, LInstruction* instr, - const char* detail = NULL); - void DeoptimizeIfNotSmi(Register rt, LInstruction* instr, - const char* detail = NULL); + const char* detail); + void DeoptimizeIfSmi(Register rt, LInstruction* instr, const char* detail); + void DeoptimizeIfNotSmi(Register rt, LInstruction* instr, const char* detail); void DeoptimizeIfRoot(Register rt, Heap::RootListIndex index, - LInstruction* instr, const char* detail = NULL); + LInstruction* instr, const char* detail); void DeoptimizeIfNotRoot(Register rt, Heap::RootListIndex index, - LInstruction* instr, const char* detail = NULL); + LInstruction* instr, const char* detail); void DeoptimizeIfNotHeapNumber(Register object, LInstruction* instr); void DeoptimizeIfMinusZero(DoubleRegister input, LInstruction* instr, - const char* detail = NULL); + const char* detail); void DeoptimizeIfBitSet(Register rt, int bit, LInstruction* instr, - const char* detail = NULL); + const char* detail); void DeoptimizeIfBitClear(Register rt, int bit, LInstruction* instr, - const char* detail = NULL); + const char* detail); MemOperand PrepareKeyedExternalArrayOperand(Register key, Register base, diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 497d10f..ef72560 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -816,8 +816,8 @@ void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment, void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr, Deoptimizer::BailoutType bailout_type, - Register src1, const Operand& src2, - const char* detail) { + const char* detail, Register src1, + const Operand& src2) { LEnvironment* environment = instr->environment(); RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); DCHECK(environment->HasBeenRegistered()); @@ -882,12 +882,12 @@ void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr, void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr, - Register src1, const Operand& src2, - const char* detail) { + const char* detail, Register src1, + const Operand& src2) { Deoptimizer::BailoutType bailout_type = info()->IsStub() ? Deoptimizer::LAZY : Deoptimizer::EAGER; - DeoptimizeIf(condition, instr, bailout_type, src1, src2, detail); + DeoptimizeIf(condition, instr, bailout_type, detail, src1, src2); } @@ -1117,7 +1117,7 @@ void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) { __ subu(dividend, zero_reg, dividend); __ And(dividend, dividend, Operand(mask)); if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIf(eq, instr, dividend, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "minus zero", dividend, Operand(zero_reg)); } __ Branch(USE_DELAY_SLOT, &done); __ subu(dividend, zero_reg, dividend); @@ -1149,7 +1149,7 @@ void LCodeGen::DoModByConstI(LModByConstI* instr) { if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { Label remainder_not_zero; __ Branch(&remainder_not_zero, ne, result, Operand(zero_reg)); - DeoptimizeIf(lt, instr, dividend, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "minus zero", dividend, Operand(zero_reg)); __ bind(&remainder_not_zero); } } @@ -1168,7 +1168,7 @@ void LCodeGen::DoModI(LModI* instr) { // Check for x % 0, we have to deopt in this case because we can't return a // NaN. if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { - DeoptimizeIf(eq, instr, right_reg, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "division by zero", right_reg, Operand(zero_reg)); } // Check for kMinInt % -1, div will return kMinInt, which is not what we @@ -1177,7 +1177,7 @@ void LCodeGen::DoModI(LModI* instr) { Label no_overflow_possible; __ Branch(&no_overflow_possible, ne, left_reg, Operand(kMinInt)); if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIf(eq, instr, right_reg, Operand(-1)); + DeoptimizeIf(eq, instr, "minus zero", right_reg, Operand(-1)); } else { __ Branch(&no_overflow_possible, ne, right_reg, Operand(-1)); __ Branch(USE_DELAY_SLOT, &done); @@ -1189,7 +1189,7 @@ void LCodeGen::DoModI(LModI* instr) { // If we care about -0, test if the dividend is <0 and the result is 0. __ Branch(&done, ge, left_reg, Operand(zero_reg)); if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIf(eq, instr, result_reg, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "minus zero", result_reg, Operand(zero_reg)); } __ bind(&done); } @@ -1205,18 +1205,18 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { // Check for (0 / -x) that will produce negative zero. HDiv* hdiv = instr->hydrogen(); if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { - DeoptimizeIf(eq, instr, dividend, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "minus zero", dividend, Operand(zero_reg)); } // Check for (kMinInt / -1). if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { - DeoptimizeIf(eq, instr, dividend, Operand(kMinInt)); + DeoptimizeIf(eq, instr, "overflow", dividend, Operand(kMinInt)); } // 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); __ And(at, dividend, Operand(mask)); - DeoptimizeIf(ne, instr, at, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "lost precision", at, Operand(zero_reg)); } if (divisor == -1) { // Nice shortcut, not needed for correctness. @@ -1253,7 +1253,7 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) { // Check for (0 / -x) that will produce negative zero. HDiv* hdiv = instr->hydrogen(); if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { - DeoptimizeIf(eq, instr, dividend, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "minus zero", dividend, Operand(zero_reg)); } __ TruncatingDiv(result, dividend, Abs(divisor)); @@ -1262,7 +1262,7 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) { if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { __ Mul(scratch0(), result, Operand(divisor)); __ Subu(scratch0(), scratch0(), dividend); - DeoptimizeIf(ne, instr, scratch0(), Operand(zero_reg)); + DeoptimizeIf(ne, instr, "lost precision", scratch0(), Operand(zero_reg)); } } @@ -1281,14 +1281,14 @@ void LCodeGen::DoDivI(LDivI* instr) { // Check for x / 0. if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { - DeoptimizeIf(eq, instr, divisor, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "division by zero", divisor, Operand(zero_reg)); } // Check for (0 / -x) that will produce negative zero. if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { Label left_not_zero; __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg)); - DeoptimizeIf(lt, instr, divisor, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "minus zero", divisor, Operand(zero_reg)); __ bind(&left_not_zero); } @@ -1297,12 +1297,12 @@ void LCodeGen::DoDivI(LDivI* instr) { !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { Label left_not_min_int; __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt)); - DeoptimizeIf(eq, instr, divisor, Operand(-1)); + DeoptimizeIf(eq, instr, "overflow", divisor, Operand(-1)); __ bind(&left_not_min_int); } if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { - DeoptimizeIf(ne, instr, remainder, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "lost precision", remainder, Operand(zero_reg)); } } @@ -1348,14 +1348,14 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { __ Subu(result, zero_reg, dividend); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIf(eq, instr, result, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "minus zero", result, Operand(zero_reg)); } // Dividing by -1 is basically negation, unless we overflow. __ Xor(scratch, scratch, result); if (divisor == -1) { if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { - DeoptimizeIf(ge, instr, scratch, Operand(zero_reg)); + DeoptimizeIf(ge, instr, "overflow", scratch, Operand(zero_reg)); } return; } @@ -1390,7 +1390,7 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { // Check for (0 / -x) that will produce negative zero. HMathFloorOfDiv* hdiv = instr->hydrogen(); if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { - DeoptimizeIf(eq, instr, dividend, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "minus zero", dividend, Operand(zero_reg)); } // Easy case: We need no dynamic check for the dividend and the flooring @@ -1434,14 +1434,14 @@ void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { // Check for x / 0. if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { - DeoptimizeIf(eq, instr, divisor, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "division by zero", divisor, Operand(zero_reg)); } // Check for (0 / -x) that will produce negative zero. if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { Label left_not_zero; __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg)); - DeoptimizeIf(lt, instr, divisor, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "minus zero", divisor, Operand(zero_reg)); __ bind(&left_not_zero); } @@ -1450,7 +1450,7 @@ void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { Label left_not_min_int; __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt)); - DeoptimizeIf(eq, instr, divisor, Operand(-1)); + DeoptimizeIf(eq, instr, "overflow", divisor, Operand(-1)); __ bind(&left_not_min_int); } @@ -1481,14 +1481,14 @@ void LCodeGen::DoMulI(LMulI* instr) { if (bailout_on_minus_zero && (constant < 0)) { // The case of a null constant will be handled separately. // If constant is negative and left is null, the result should be -0. - DeoptimizeIf(eq, instr, left, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "minus zero", left, Operand(zero_reg)); } switch (constant) { case -1: if (overflow) { __ SubuAndCheckForOverflow(result, zero_reg, left, scratch); - DeoptimizeIf(lt, instr, scratch, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "overflow", scratch, Operand(zero_reg)); } else { __ Subu(result, zero_reg, left); } @@ -1497,7 +1497,7 @@ void LCodeGen::DoMulI(LMulI* instr) { if (bailout_on_minus_zero) { // If left is strictly negative and the constant is null, the // result is -0. Deoptimize if required, otherwise return 0. - DeoptimizeIf(lt, instr, left, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "minus zero", left, Operand(zero_reg)); } __ mov(result, zero_reg); break; @@ -1549,7 +1549,7 @@ void LCodeGen::DoMulI(LMulI* instr) { __ Mul(scratch, result, left, right); } __ sra(at, result, 31); - DeoptimizeIf(ne, instr, scratch, Operand(at)); + DeoptimizeIf(ne, instr, "overflow", scratch, Operand(at)); } else { if (instr->hydrogen()->representation().IsSmi()) { __ SmiUntag(result, left); @@ -1564,7 +1564,7 @@ void LCodeGen::DoMulI(LMulI* instr) { __ Xor(at, left, right); __ Branch(&done, ge, at, Operand(zero_reg)); // Bail out if the result is minus zero. - DeoptimizeIf(eq, instr, result, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "minus zero", result, Operand(zero_reg)); __ bind(&done); } } @@ -1628,7 +1628,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) { case Token::SHR: __ srlv(result, left, ToRegister(right_op)); if (instr->can_deopt()) { - DeoptimizeIf(lt, instr, result, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "negative value", result, Operand(zero_reg)); } break; case Token::SHL: @@ -1663,7 +1663,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) { } else { if (instr->can_deopt()) { __ And(at, left, Operand(0x80000000)); - DeoptimizeIf(ne, instr, at, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "negative value", at, Operand(zero_reg)); } __ Move(result, left); } @@ -1678,7 +1678,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) { } else { __ SmiTagCheckOverflow(result, left, scratch); } - DeoptimizeIf(lt, instr, scratch, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "overflow", scratch, Operand(zero_reg)); } else { __ sll(result, left, shift_count); } @@ -1726,7 +1726,7 @@ void LCodeGen::DoSubI(LSubI* instr) { ToRegister(right), overflow); // Reg at also used as scratch. } - DeoptimizeIf(lt, instr, overflow, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "overflow", overflow, Operand(zero_reg)); } } @@ -1780,9 +1780,9 @@ void LCodeGen::DoDateField(LDateField* instr) { DCHECK(!scratch.is(object)); __ SmiTst(object, at); - DeoptimizeIf(eq, instr, at, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "Smi", at, Operand(zero_reg)); __ GetObjectType(object, scratch, scratch); - DeoptimizeIf(ne, instr, scratch, Operand(JS_DATE_TYPE)); + DeoptimizeIf(ne, instr, "not a date object", scratch, Operand(JS_DATE_TYPE)); if (index->value() == 0) { __ lw(result, FieldMemOperand(object, JSDate::kValueOffset)); @@ -1917,7 +1917,7 @@ void LCodeGen::DoAddI(LAddI* instr) { ToRegister(right), overflow); // Reg at also used as scratch. } - DeoptimizeIf(lt, instr, overflow, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "overflow", overflow, Operand(zero_reg)); } } @@ -2178,7 +2178,7 @@ void LCodeGen::DoBranch(LBranch* instr) { } else if (expected.NeedsMap()) { // If we need a map later and have a Smi -> deopt. __ SmiTst(reg, at); - DeoptimizeIf(eq, instr, at, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "Smi", at, Operand(zero_reg)); } const Register map = scratch0(); @@ -2234,7 +2234,8 @@ 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(al, instr, zero_reg, Operand(zero_reg)); + DeoptimizeIf(al, instr, "unexpected object", zero_reg, + Operand(zero_reg)); } } } @@ -2878,7 +2879,7 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { __ lw(result, FieldMemOperand(at, Cell::kValueOffset)); if (instr->hydrogen()->RequiresHoleCheck()) { __ LoadRoot(at, Heap::kTheHoleValueRootIndex); - DeoptimizeIf(eq, instr, result, Operand(at)); + DeoptimizeIf(eq, instr, "hole", result, Operand(at)); } } @@ -2928,7 +2929,7 @@ void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { Register payload = ToRegister(instr->temp()); __ lw(payload, FieldMemOperand(cell, Cell::kValueOffset)); __ LoadRoot(at, Heap::kTheHoleValueRootIndex); - DeoptimizeIf(eq, instr, payload, Operand(at)); + DeoptimizeIf(eq, instr, "hole", payload, Operand(at)); } // Store the value. @@ -2947,7 +2948,7 @@ void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { __ LoadRoot(at, Heap::kTheHoleValueRootIndex); if (instr->hydrogen()->DeoptimizesOnHole()) { - DeoptimizeIf(eq, instr, result, Operand(at)); + DeoptimizeIf(eq, instr, "hole", result, Operand(at)); } else { Label is_not_hole; __ Branch(&is_not_hole, ne, result, Operand(at)); @@ -2971,7 +2972,7 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { __ LoadRoot(at, Heap::kTheHoleValueRootIndex); if (instr->hydrogen()->DeoptimizesOnHole()) { - DeoptimizeIf(eq, instr, scratch, Operand(at)); + DeoptimizeIf(eq, instr, "hole", scratch, Operand(at)); } else { __ Branch(&skip_assignment, ne, scratch, Operand(at)); } @@ -3050,7 +3051,7 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { // Check that the function has a prototype or an initial map. __ LoadRoot(at, Heap::kTheHoleValueRootIndex); - DeoptimizeIf(eq, instr, result, Operand(at)); + DeoptimizeIf(eq, instr, "hole", result, Operand(at)); // If the function does not have an initial map, we're done. Label done; @@ -3186,7 +3187,8 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { case UINT32_ELEMENTS: __ lw(result, mem_operand); if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { - DeoptimizeIf(Ugreater_equal, instr, result, Operand(0x80000000)); + DeoptimizeIf(Ugreater_equal, instr, "negative value", result, + Operand(0x80000000)); } break; case FLOAT32_ELEMENTS: @@ -3239,7 +3241,7 @@ void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { if (instr->hydrogen()->RequiresHoleCheck()) { __ lw(scratch, MemOperand(scratch, kHoleNanUpper32Offset)); - DeoptimizeIf(eq, instr, scratch, Operand(kHoleNanUpper32)); + DeoptimizeIf(eq, instr, "hole", scratch, Operand(kHoleNanUpper32)); } } @@ -3275,10 +3277,10 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { if (instr->hydrogen()->RequiresHoleCheck()) { if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { __ SmiTst(result, scratch); - DeoptimizeIf(ne, instr, scratch, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "not a Smi", scratch, Operand(zero_reg)); } else { __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); - DeoptimizeIf(eq, instr, result, Operand(scratch)); + DeoptimizeIf(eq, instr, "hole", result, Operand(scratch)); } } } @@ -3424,10 +3426,11 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { // Deoptimize if the receiver is not a JS object. __ SmiTst(receiver, scratch); - DeoptimizeIf(eq, instr, scratch, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "Smi", scratch, Operand(zero_reg)); __ GetObjectType(receiver, scratch, scratch); - DeoptimizeIf(lt, instr, scratch, Operand(FIRST_SPEC_OBJECT_TYPE)); + DeoptimizeIf(lt, instr, "not a JavaScript object", scratch, + Operand(FIRST_SPEC_OBJECT_TYPE)); __ Branch(&result_in_receiver); __ bind(&global_object); @@ -3462,7 +3465,8 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { // Copy the arguments to this function possibly from the // adaptor frame below it. const uint32_t kArgumentsLimit = 1 * KB; - DeoptimizeIf(hi, instr, length, Operand(kArgumentsLimit)); + DeoptimizeIf(hi, instr, "too many arguments", length, + Operand(kArgumentsLimit)); // Push the receiver and use the register to keep the original // number of arguments. @@ -3592,7 +3596,7 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { // Deoptimize if not a heap number. __ lw(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); - DeoptimizeIf(ne, instr, scratch, Operand(at)); + DeoptimizeIf(ne, instr, "not a heap number", scratch, Operand(at)); Label done; Register exponent = scratch0(); @@ -3659,7 +3663,7 @@ void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { __ mov(result, input); __ subu(result, zero_reg, input); // Overflow if result is still negative, i.e. 0x80000000. - DeoptimizeIf(lt, instr, result, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "overflow", result, Operand(zero_reg)); __ bind(&done); } @@ -3713,7 +3717,8 @@ void LCodeGen::DoMathFloor(LMathFloor* instr) { except_flag); // Deopt if the operation did not succeed. - DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag, + Operand(zero_reg)); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { // Test for -0. @@ -3721,7 +3726,7 @@ void LCodeGen::DoMathFloor(LMathFloor* instr) { __ Branch(&done, ne, result, Operand(zero_reg)); __ Mfhc1(scratch1, input); __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); - DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "minus zero", scratch1, Operand(zero_reg)); __ bind(&done); } } @@ -3754,7 +3759,8 @@ void LCodeGen::DoMathRound(LMathRound* instr) { // The following conversion will not work with numbers // outside of ]-2^32, 2^32[. - DeoptimizeIf(ge, instr, scratch, Operand(HeapNumber::kExponentBias + 32)); + DeoptimizeIf(ge, instr, "overflow", scratch, + Operand(HeapNumber::kExponentBias + 32)); // Save the original sign for later comparison. __ And(scratch, result, Operand(HeapNumber::kSignMask)); @@ -3768,7 +3774,7 @@ void LCodeGen::DoMathRound(LMathRound* instr) { __ Xor(result, result, Operand(scratch)); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { // ARM uses 'mi' here, which is 'lt' - DeoptimizeIf(lt, instr, result, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "minus zero", result, Operand(zero_reg)); } else { Label skip2; // ARM uses 'mi' here, which is 'lt' @@ -3787,7 +3793,8 @@ void LCodeGen::DoMathRound(LMathRound* instr) { double_scratch1, except_flag); - DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag, + Operand(zero_reg)); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { // Test for -0. @@ -3795,7 +3802,7 @@ void LCodeGen::DoMathRound(LMathRound* instr) { __ bind(&check_sign_on_zero); __ Mfhc1(scratch, input); __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); - DeoptimizeIf(ne, instr, scratch, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "minus zero", scratch, Operand(zero_reg)); } __ bind(&done); } @@ -3861,7 +3868,7 @@ void LCodeGen::DoPower(LPower* instr) { DCHECK(!t3.is(tagged_exponent)); __ lw(t3, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset)); __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); - DeoptimizeIf(ne, instr, t3, Operand(at)); + DeoptimizeIf(ne, instr, "not a heap number", t3, Operand(at)); __ bind(&no_deopt); MathPowStub stub(isolate(), MathPowStub::TAGGED); __ CallStub(&stub); @@ -4204,7 +4211,7 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { __ stop("eliminated bounds check failed"); __ bind(&done); } else { - DeoptimizeIf(cc, instr, reg, operand); + DeoptimizeIf(cc, instr, "out of bounds", reg, operand); } } @@ -4797,12 +4804,12 @@ void LCodeGen::DoSmiTag(LSmiTag* instr) { if (hchange->CheckFlag(HValue::kCanOverflow) && hchange->value()->CheckFlag(HValue::kUint32)) { __ And(at, input, Operand(0xc0000000)); - DeoptimizeIf(ne, instr, at, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "overflow", at, Operand(zero_reg)); } if (hchange->CheckFlag(HValue::kCanOverflow) && !hchange->value()->CheckFlag(HValue::kUint32)) { __ SmiTagCheckOverflow(output, input, at); - DeoptimizeIf(lt, instr, at, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "overflow", at, Operand(zero_reg)); } else { __ SmiTag(output, input); } @@ -4818,7 +4825,7 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) { // If the input is a HeapObject, value of scratch won't be zero. __ And(scratch, input, Operand(kHeapObjectTag)); __ SmiUntag(result, input); - DeoptimizeIf(ne, instr, scratch, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "not a Smi", scratch, Operand(zero_reg)); } else { __ SmiUntag(result, input); } @@ -4843,7 +4850,7 @@ void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg, if (can_convert_undefined_to_nan) { __ Branch(&convert, ne, scratch, Operand(at)); } else { - DeoptimizeIf(ne, instr, scratch, Operand(at)); + DeoptimizeIf(ne, instr, "not a heap number", scratch, Operand(at)); } // Load heap number. __ ldc1(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset)); @@ -4851,14 +4858,16 @@ void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg, __ mfc1(at, result_reg.low()); __ Branch(&done, ne, at, Operand(zero_reg)); __ Mfhc1(scratch, result_reg); - DeoptimizeIf(eq, instr, scratch, Operand(HeapNumber::kSignMask)); + DeoptimizeIf(eq, instr, "minus zero", scratch, + Operand(HeapNumber::kSignMask)); } __ Branch(&done); if (can_convert_undefined_to_nan) { __ bind(&convert); // Convert undefined (and hole) to NaN. __ LoadRoot(at, Heap::kUndefinedValueRootIndex); - DeoptimizeIf(ne, instr, input_reg, Operand(at)); + DeoptimizeIf(ne, instr, "not a heap number/undefined", input_reg, + Operand(at)); __ LoadRoot(scratch, Heap::kNanValueRootIndex); __ ldc1(result_reg, FieldMemOperand(scratch, HeapNumber::kValueOffset)); __ Branch(&done); @@ -4922,11 +4931,12 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { __ bind(&check_false); __ LoadRoot(at, Heap::kFalseValueRootIndex); - DeoptimizeIf(ne, instr, scratch2, Operand(at), "cannot truncate"); + DeoptimizeIf(ne, instr, "not a heap number/undefined/true/false", scratch2, + Operand(at)); __ Branch(USE_DELAY_SLOT, &done); __ mov(input_reg, zero_reg); // In delay slot. } else { - DeoptimizeIf(ne, instr, scratch1, Operand(at), "not a heap number"); + DeoptimizeIf(ne, instr, "not a heap number", scratch1, Operand(at)); // Load the double value. __ ldc1(double_scratch, @@ -4941,15 +4951,15 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { except_flag, kCheckForInexactConversion); - DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg), - "lost precision or NaN"); + DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag, + Operand(zero_reg)); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { __ Branch(&done, ne, input_reg, Operand(zero_reg)); __ Mfhc1(scratch1, double_scratch); __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); - DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg), "minus zero"); + DeoptimizeIf(ne, instr, "minus zero", scratch1, Operand(zero_reg)); } } __ bind(&done); @@ -5026,14 +5036,15 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) { kCheckForInexactConversion); // Deopt if the operation did not succeed (except_flag != 0). - DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag, + Operand(zero_reg)); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { Label done; __ Branch(&done, ne, result_reg, Operand(zero_reg)); __ Mfhc1(scratch1, double_input); __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); - DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "minus zero", scratch1, Operand(zero_reg)); __ bind(&done); } } @@ -5059,26 +5070,27 @@ void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { kCheckForInexactConversion); // Deopt if the operation did not succeed (except_flag != 0). - DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag, + Operand(zero_reg)); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { Label done; __ Branch(&done, ne, result_reg, Operand(zero_reg)); __ Mfhc1(scratch1, double_input); __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); - DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "minus zero", scratch1, Operand(zero_reg)); __ bind(&done); } } __ SmiTagCheckOverflow(result_reg, result_reg, scratch1); - DeoptimizeIf(lt, instr, scratch1, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "overflow", scratch1, Operand(zero_reg)); } void LCodeGen::DoCheckSmi(LCheckSmi* instr) { LOperand* input = instr->value(); __ SmiTst(ToRegister(input), at); - DeoptimizeIf(ne, instr, at, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "not a Smi", at, Operand(zero_reg)); } @@ -5086,7 +5098,7 @@ void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { if (!instr->hydrogen()->value()->type().IsHeapObject()) { LOperand* input = instr->value(); __ SmiTst(ToRegister(input), at); - DeoptimizeIf(eq, instr, at, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "Smi", at, Operand(zero_reg)); } } @@ -5104,12 +5116,12 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { // If there is only one type in the interval check for equality. if (first == last) { - DeoptimizeIf(ne, instr, scratch, Operand(first)); + DeoptimizeIf(ne, instr, "wrong instance type", scratch, Operand(first)); } else { - DeoptimizeIf(lo, instr, scratch, Operand(first)); + DeoptimizeIf(lo, instr, "wrong instance type", scratch, Operand(first)); // Omit check for the last type. if (last != LAST_TYPE) { - DeoptimizeIf(hi, instr, scratch, Operand(last)); + DeoptimizeIf(hi, instr, "wrong instance type", scratch, Operand(last)); } } } else { @@ -5120,10 +5132,11 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { if (base::bits::IsPowerOfTwo32(mask)) { DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag)); __ And(at, scratch, mask); - DeoptimizeIf(tag == 0 ? ne : eq, instr, at, Operand(zero_reg)); + DeoptimizeIf(tag == 0 ? ne : eq, instr, "wrong instance type", at, + Operand(zero_reg)); } else { __ And(scratch, scratch, Operand(mask)); - DeoptimizeIf(ne, instr, scratch, Operand(tag)); + DeoptimizeIf(ne, instr, "wrong instance type", scratch, Operand(tag)); } } } @@ -5138,9 +5151,9 @@ void LCodeGen::DoCheckValue(LCheckValue* instr) { Handle cell = isolate()->factory()->NewCell(object); __ li(at, Operand(Handle(cell))); __ lw(at, FieldMemOperand(at, Cell::kValueOffset)); - DeoptimizeIf(ne, instr, reg, Operand(at)); + DeoptimizeIf(ne, instr, "value mismatch", reg, Operand(at)); } else { - DeoptimizeIf(ne, instr, reg, Operand(object)); + DeoptimizeIf(ne, instr, "value mismatch", reg, Operand(object)); } } @@ -5156,7 +5169,7 @@ void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { __ StoreToSafepointRegisterSlot(v0, scratch0()); } __ SmiTst(scratch0(), at); - DeoptimizeIf(eq, instr, at, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "instance migration failed", at, Operand(zero_reg)); } @@ -5209,7 +5222,7 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) { if (instr->hydrogen()->HasMigrationTarget()) { __ Branch(deferred->entry(), ne, map_reg, Operand(map)); } else { - DeoptimizeIf(ne, instr, map_reg, Operand(map)); + DeoptimizeIf(ne, instr, "wrong map", map_reg, Operand(map)); } __ bind(&success); @@ -5247,7 +5260,8 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { // Check for undefined. Undefined is converted to zero for clamping // conversions. - DeoptimizeIf(ne, instr, input_reg, Operand(factory()->undefined_value())); + DeoptimizeIf(ne, instr, "not a heap number/undefined", input_reg, + Operand(factory()->undefined_value())); __ mov(result_reg, zero_reg); __ jmp(&done); @@ -5670,8 +5684,8 @@ void LCodeGen::DoDeoptimize(LDeoptimize* instr) { type = Deoptimizer::LAZY; } - DeoptimizeIf(al, instr, type, zero_reg, Operand(zero_reg), - instr->hydrogen()->reason()); + DeoptimizeIf(al, instr, type, instr->hydrogen()->reason(), zero_reg, + Operand(zero_reg)); } @@ -5762,18 +5776,19 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { Register result = ToRegister(instr->result()); Register object = ToRegister(instr->object()); __ LoadRoot(at, Heap::kUndefinedValueRootIndex); - DeoptimizeIf(eq, instr, object, Operand(at)); + DeoptimizeIf(eq, instr, "undefined", object, Operand(at)); Register null_value = t1; __ LoadRoot(null_value, Heap::kNullValueRootIndex); - DeoptimizeIf(eq, instr, object, Operand(null_value)); + DeoptimizeIf(eq, instr, "null", object, Operand(null_value)); __ And(at, object, kSmiTagMask); - DeoptimizeIf(eq, instr, at, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "Smi", at, Operand(zero_reg)); STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); __ GetObjectType(object, a1, a1); - DeoptimizeIf(le, instr, a1, Operand(LAST_JS_PROXY_TYPE)); + DeoptimizeIf(le, instr, "not a JavaScript object", a1, + Operand(LAST_JS_PROXY_TYPE)); Label use_cache, call_runtime; DCHECK(object.is(a0)); @@ -5790,7 +5805,7 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { __ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); DCHECK(result.is(v0)); __ LoadRoot(at, Heap::kMetaMapRootIndex); - DeoptimizeIf(ne, instr, a1, Operand(at)); + DeoptimizeIf(ne, instr, "wrong map", a1, Operand(at)); __ bind(&use_cache); } @@ -5810,7 +5825,7 @@ void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { FieldMemOperand(result, DescriptorArray::kEnumCacheOffset)); __ lw(result, FieldMemOperand(result, FixedArray::SizeFor(instr->idx()))); - DeoptimizeIf(eq, instr, result, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "no cache", result, Operand(zero_reg)); __ bind(&done); } @@ -5820,7 +5835,7 @@ void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { Register object = ToRegister(instr->value()); Register map = ToRegister(instr->map()); __ lw(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset)); - DeoptimizeIf(ne, instr, map, Operand(scratch0())); + DeoptimizeIf(ne, instr, "wrong map", map, Operand(scratch0())); } diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h index 5402c9a..43316e4 100644 --- a/src/mips/lithium-codegen-mips.h +++ b/src/mips/lithium-codegen-mips.h @@ -229,14 +229,12 @@ class LCodeGen: public LCodeGenBase { void RegisterEnvironmentForDeoptimization(LEnvironment* environment, Safepoint::DeoptMode mode); void DeoptimizeIf(Condition condition, LInstruction* instr, - Deoptimizer::BailoutType bailout_type, + Deoptimizer::BailoutType bailout_type, const char* detail, Register src1 = zero_reg, - const Operand& src2 = Operand(zero_reg), - const char* detail = NULL); + const Operand& src2 = Operand(zero_reg)); void DeoptimizeIf(Condition condition, LInstruction* instr, - Register src1 = zero_reg, - const Operand& src2 = Operand(zero_reg), - const char* detail = NULL); + const char* detail = NULL, Register src1 = zero_reg, + const Operand& src2 = Operand(zero_reg)); void AddToTranslation(LEnvironment* environment, Translation* translation, diff --git a/src/mips64/lithium-codegen-mips64.cc b/src/mips64/lithium-codegen-mips64.cc index 8a0a449..2ed9782 100644 --- a/src/mips64/lithium-codegen-mips64.cc +++ b/src/mips64/lithium-codegen-mips64.cc @@ -766,8 +766,8 @@ void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment, void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr, Deoptimizer::BailoutType bailout_type, - Register src1, const Operand& src2, - const char* detail) { + const char* detail, Register src1, + const Operand& src2) { LEnvironment* environment = instr->environment(); RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); DCHECK(environment->HasBeenRegistered()); @@ -832,12 +832,12 @@ void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr, void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr, - Register src1, const Operand& src2, - const char* detail) { + const char* detail, Register src1, + const Operand& src2) { Deoptimizer::BailoutType bailout_type = info()->IsStub() ? Deoptimizer::LAZY : Deoptimizer::EAGER; - DeoptimizeIf(condition, instr, bailout_type, src1, src2, detail); + DeoptimizeIf(condition, instr, bailout_type, detail, src1, src2); } @@ -1067,7 +1067,7 @@ void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) { __ dsubu(dividend, zero_reg, dividend); __ And(dividend, dividend, Operand(mask)); if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIf(eq, instr, dividend, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "minus zero", dividend, Operand(zero_reg)); } __ Branch(USE_DELAY_SLOT, &done); __ dsubu(dividend, zero_reg, dividend); @@ -1086,7 +1086,7 @@ void LCodeGen::DoModByConstI(LModByConstI* instr) { DCHECK(!dividend.is(result)); if (divisor == 0) { - DeoptimizeIf(al, instr); + DeoptimizeIf(al, instr, "division by zero"); return; } @@ -1099,7 +1099,7 @@ void LCodeGen::DoModByConstI(LModByConstI* instr) { if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { Label remainder_not_zero; __ Branch(&remainder_not_zero, ne, result, Operand(zero_reg)); - DeoptimizeIf(lt, instr, dividend, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "minus zero", dividend, Operand(zero_reg)); __ bind(&remainder_not_zero); } } @@ -1118,7 +1118,7 @@ void LCodeGen::DoModI(LModI* instr) { // Check for x % 0, we have to deopt in this case because we can't return a // NaN. if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { - DeoptimizeIf(eq, instr, right_reg, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "division by zero", right_reg, Operand(zero_reg)); } // Check for kMinInt % -1, div will return kMinInt, which is not what we @@ -1127,7 +1127,7 @@ void LCodeGen::DoModI(LModI* instr) { Label no_overflow_possible; __ Branch(&no_overflow_possible, ne, left_reg, Operand(kMinInt)); if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIf(eq, instr, right_reg, Operand(-1)); + DeoptimizeIf(eq, instr, "minus zero", right_reg, Operand(-1)); } else { __ Branch(&no_overflow_possible, ne, right_reg, Operand(-1)); __ Branch(USE_DELAY_SLOT, &done); @@ -1140,7 +1140,7 @@ void LCodeGen::DoModI(LModI* instr) { __ Branch(&done, ge, left_reg, Operand(zero_reg)); if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIf(eq, instr, result_reg, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "minus zero", result_reg, Operand(zero_reg)); } __ bind(&done); } @@ -1156,18 +1156,18 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { // Check for (0 / -x) that will produce negative zero. HDiv* hdiv = instr->hydrogen(); if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { - DeoptimizeIf(eq, instr, dividend, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "minus zero", dividend, Operand(zero_reg)); } // Check for (kMinInt / -1). if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { - DeoptimizeIf(eq, instr, dividend, Operand(kMinInt)); + DeoptimizeIf(eq, instr, "overflow", dividend, Operand(kMinInt)); } // 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); __ And(at, dividend, Operand(mask)); - DeoptimizeIf(ne, instr, at, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "lost precision", at, Operand(zero_reg)); } if (divisor == -1) { // Nice shortcut, not needed for correctness. @@ -1197,14 +1197,14 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) { DCHECK(!dividend.is(result)); if (divisor == 0) { - DeoptimizeIf(al, instr); + DeoptimizeIf(al, instr, "division by zero"); return; } // Check for (0 / -x) that will produce negative zero. HDiv* hdiv = instr->hydrogen(); if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { - DeoptimizeIf(eq, instr, dividend, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "minus zero", dividend, Operand(zero_reg)); } __ TruncatingDiv(result, dividend, Abs(divisor)); @@ -1213,7 +1213,7 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) { if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { __ Dmul(scratch0(), result, Operand(divisor)); __ Dsubu(scratch0(), scratch0(), dividend); - DeoptimizeIf(ne, instr, scratch0(), Operand(zero_reg)); + DeoptimizeIf(ne, instr, "lost precision", scratch0(), Operand(zero_reg)); } } @@ -1231,14 +1231,14 @@ void LCodeGen::DoDivI(LDivI* instr) { // Check for x / 0. if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { - DeoptimizeIf(eq, instr, divisor, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "division by zero", divisor, Operand(zero_reg)); } // Check for (0 / -x) that will produce negative zero. if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { Label left_not_zero; __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg)); - DeoptimizeIf(lt, instr, divisor, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "minus zero", divisor, Operand(zero_reg)); __ bind(&left_not_zero); } @@ -1247,7 +1247,7 @@ void LCodeGen::DoDivI(LDivI* instr) { !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { Label left_not_min_int; __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt)); - DeoptimizeIf(eq, instr, divisor, Operand(-1)); + DeoptimizeIf(eq, instr, "overflow", divisor, Operand(-1)); __ bind(&left_not_min_int); } @@ -1259,7 +1259,7 @@ void LCodeGen::DoDivI(LDivI* instr) { } else { __ dmod(remainder, dividend, divisor); } - DeoptimizeIf(ne, instr, remainder, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "lost precision", remainder, Operand(zero_reg)); } } @@ -1304,14 +1304,14 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { __ Dsubu(result, zero_reg, dividend); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { - DeoptimizeIf(eq, instr, result, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "minus zero", result, Operand(zero_reg)); } __ Xor(scratch, scratch, result); // Dividing by -1 is basically negation, unless we overflow. if (divisor == -1) { if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { - DeoptimizeIf(gt, instr, result, Operand(kMaxInt)); + DeoptimizeIf(gt, instr, "overflow", result, Operand(kMaxInt)); } return; } @@ -1339,14 +1339,14 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { DCHECK(!dividend.is(result)); if (divisor == 0) { - DeoptimizeIf(al, instr); + DeoptimizeIf(al, instr, "division by zero"); return; } // Check for (0 / -x) that will produce negative zero. HMathFloorOfDiv* hdiv = instr->hydrogen(); if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { - DeoptimizeIf(eq, instr, dividend, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "minus zero", dividend, Operand(zero_reg)); } // Easy case: We need no dynamic check for the dividend and the flooring @@ -1390,14 +1390,14 @@ void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { // Check for x / 0. if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { - DeoptimizeIf(eq, instr, divisor, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "division by zero", divisor, Operand(zero_reg)); } // Check for (0 / -x) that will produce negative zero. if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { Label left_not_zero; __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg)); - DeoptimizeIf(lt, instr, divisor, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "minus zero", divisor, Operand(zero_reg)); __ bind(&left_not_zero); } @@ -1406,7 +1406,7 @@ void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { Label left_not_min_int; __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt)); - DeoptimizeIf(eq, instr, divisor, Operand(-1)); + DeoptimizeIf(eq, instr, "overflow", divisor, Operand(-1)); __ bind(&left_not_min_int); } @@ -1443,14 +1443,14 @@ void LCodeGen::DoMulI(LMulI* instr) { if (bailout_on_minus_zero && (constant < 0)) { // The case of a null constant will be handled separately. // If constant is negative and left is null, the result should be -0. - DeoptimizeIf(eq, instr, left, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "minus zero", left, Operand(zero_reg)); } switch (constant) { case -1: if (overflow) { __ SubuAndCheckForOverflow(result, zero_reg, left, scratch); - DeoptimizeIf(gt, instr, scratch, Operand(kMaxInt)); + DeoptimizeIf(gt, instr, "overflow", scratch, Operand(kMaxInt)); } else { __ Dsubu(result, zero_reg, left); } @@ -1459,7 +1459,7 @@ void LCodeGen::DoMulI(LMulI* instr) { if (bailout_on_minus_zero) { // If left is strictly negative and the constant is null, the // result is -0. Deoptimize if required, otherwise return 0. - DeoptimizeIf(lt, instr, left, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "minus zero", left, Operand(zero_reg)); } __ mov(result, zero_reg); break; @@ -1514,7 +1514,7 @@ void LCodeGen::DoMulI(LMulI* instr) { if (instr->hydrogen()->representation().IsSmi()) { __ SmiTag(result); } - DeoptimizeIf(ne, instr, scratch, Operand(at)); + DeoptimizeIf(ne, instr, "overflow", scratch, Operand(at)); } else { if (instr->hydrogen()->representation().IsSmi()) { __ SmiUntag(result, left); @@ -1529,7 +1529,7 @@ void LCodeGen::DoMulI(LMulI* instr) { __ Xor(at, left, right); __ Branch(&done, ge, at, Operand(zero_reg)); // Bail out if the result is minus zero. - DeoptimizeIf(eq, instr, result, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "minus zero", result, Operand(zero_reg)); __ bind(&done); } } @@ -1593,8 +1593,8 @@ void LCodeGen::DoShiftI(LShiftI* instr) { __ srlv(result, left, ToRegister(right_op)); if (instr->can_deopt()) { // TODO(yy): (-1) >>> 0. anything else? - DeoptimizeIf(lt, instr, result, Operand(zero_reg)); - DeoptimizeIf(gt, instr, result, Operand(kMaxInt)); + DeoptimizeIf(lt, instr, "negative value", result, Operand(zero_reg)); + DeoptimizeIf(gt, instr, "negative value", result, Operand(kMaxInt)); } break; case Token::SHL: @@ -1629,7 +1629,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) { } else { if (instr->can_deopt()) { __ And(at, left, Operand(0x80000000)); - DeoptimizeIf(ne, instr, at, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "negative value", at, Operand(zero_reg)); } __ Move(result, left); } @@ -1685,10 +1685,10 @@ void LCodeGen::DoSubI(LSubI* instr) { ToRegister(right), overflow); // Reg at also used as scratch. } - DeoptimizeIf(lt, instr, overflow, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "overflow", overflow, Operand(zero_reg)); if (!instr->hydrogen()->representation().IsSmi()) { - DeoptimizeIf(gt, instr, ToRegister(result), Operand(kMaxInt)); - DeoptimizeIf(lt, instr, ToRegister(result), Operand(kMinInt)); + DeoptimizeIf(gt, instr, "overflow", ToRegister(result), Operand(kMaxInt)); + DeoptimizeIf(lt, instr, "overflow", ToRegister(result), Operand(kMinInt)); } } } @@ -1743,9 +1743,9 @@ void LCodeGen::DoDateField(LDateField* instr) { DCHECK(!scratch.is(object)); __ SmiTst(object, at); - DeoptimizeIf(eq, instr, at, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "Smi", at, Operand(zero_reg)); __ GetObjectType(object, scratch, scratch); - DeoptimizeIf(ne, instr, scratch, Operand(JS_DATE_TYPE)); + DeoptimizeIf(ne, instr, "not a date object", scratch, Operand(JS_DATE_TYPE)); if (index->value() == 0) { __ ld(result, FieldMemOperand(object, JSDate::kValueOffset)); @@ -1880,11 +1880,11 @@ void LCodeGen::DoAddI(LAddI* instr) { ToRegister(right), overflow); // Reg at also used as scratch. } - DeoptimizeIf(lt, instr, overflow, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "overflow", overflow, Operand(zero_reg)); // if not smi, it must int32. if (!instr->hydrogen()->representation().IsSmi()) { - DeoptimizeIf(gt, instr, ToRegister(result), Operand(kMaxInt)); - DeoptimizeIf(lt, instr, ToRegister(result), Operand(kMinInt)); + DeoptimizeIf(gt, instr, "overflow", ToRegister(result), Operand(kMaxInt)); + DeoptimizeIf(lt, instr, "overflow", ToRegister(result), Operand(kMinInt)); } } } @@ -2146,7 +2146,7 @@ void LCodeGen::DoBranch(LBranch* instr) { } else if (expected.NeedsMap()) { // If we need a map later and have a Smi -> deopt. __ SmiTst(reg, at); - DeoptimizeIf(eq, instr, at, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "Smi", at, Operand(zero_reg)); } const Register map = scratch0(); @@ -2202,7 +2202,8 @@ 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(al, instr, zero_reg, Operand(zero_reg)); + DeoptimizeIf(al, instr, "unexpected object", zero_reg, + Operand(zero_reg)); } } } @@ -2848,7 +2849,7 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { __ ld(result, FieldMemOperand(at, Cell::kValueOffset)); if (instr->hydrogen()->RequiresHoleCheck()) { __ LoadRoot(at, Heap::kTheHoleValueRootIndex); - DeoptimizeIf(eq, instr, result, Operand(at)); + DeoptimizeIf(eq, instr, "hole", result, Operand(at)); } } @@ -2898,7 +2899,7 @@ void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { Register payload = ToRegister(instr->temp()); __ ld(payload, FieldMemOperand(cell, Cell::kValueOffset)); __ LoadRoot(at, Heap::kTheHoleValueRootIndex); - DeoptimizeIf(eq, instr, payload, Operand(at)); + DeoptimizeIf(eq, instr, "hole", payload, Operand(at)); } // Store the value. @@ -2916,7 +2917,7 @@ void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { __ LoadRoot(at, Heap::kTheHoleValueRootIndex); if (instr->hydrogen()->DeoptimizesOnHole()) { - DeoptimizeIf(eq, instr, result, Operand(at)); + DeoptimizeIf(eq, instr, "hole", result, Operand(at)); } else { Label is_not_hole; __ Branch(&is_not_hole, ne, result, Operand(at)); @@ -2940,7 +2941,7 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { __ LoadRoot(at, Heap::kTheHoleValueRootIndex); if (instr->hydrogen()->DeoptimizesOnHole()) { - DeoptimizeIf(eq, instr, scratch, Operand(at)); + DeoptimizeIf(eq, instr, "hole", scratch, Operand(at)); } else { __ Branch(&skip_assignment, ne, scratch, Operand(at)); } @@ -3034,7 +3035,7 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { // Check that the function has a prototype or an initial map. __ LoadRoot(at, Heap::kTheHoleValueRootIndex); - DeoptimizeIf(eq, instr, result, Operand(at)); + DeoptimizeIf(eq, instr, "hole", result, Operand(at)); // If the function does not have an initial map, we're done. Label done; @@ -3180,7 +3181,8 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { case UINT32_ELEMENTS: __ lw(result, mem_operand); if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) { - DeoptimizeIf(Ugreater_equal, instr, result, Operand(0x80000000)); + DeoptimizeIf(Ugreater_equal, instr, "negative value", result, + Operand(0x80000000)); } break; case FLOAT32_ELEMENTS: @@ -3240,7 +3242,7 @@ void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { if (instr->hydrogen()->RequiresHoleCheck()) { __ lw(scratch, MemOperand(scratch, sizeof(kHoleNanLower32))); - DeoptimizeIf(eq, instr, scratch, Operand(kHoleNanUpper32)); + DeoptimizeIf(eq, instr, "hole", scratch, Operand(kHoleNanUpper32)); } } @@ -3294,10 +3296,10 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { if (hinstr->RequiresHoleCheck()) { if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) { __ SmiTst(result, scratch); - DeoptimizeIf(ne, instr, scratch, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "not a Smi", scratch, Operand(zero_reg)); } else { __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); - DeoptimizeIf(eq, instr, result, Operand(scratch)); + DeoptimizeIf(eq, instr, "hole", result, Operand(scratch)); } } } @@ -3453,10 +3455,11 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { // Deoptimize if the receiver is not a JS object. __ SmiTst(receiver, scratch); - DeoptimizeIf(eq, instr, scratch, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "Smi", scratch, Operand(zero_reg)); __ GetObjectType(receiver, scratch, scratch); - DeoptimizeIf(lt, instr, scratch, Operand(FIRST_SPEC_OBJECT_TYPE)); + DeoptimizeIf(lt, instr, "not a JavaScript object", scratch, + Operand(FIRST_SPEC_OBJECT_TYPE)); __ Branch(&result_in_receiver); __ bind(&global_object); @@ -3491,7 +3494,8 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { // Copy the arguments to this function possibly from the // adaptor frame below it. const uint32_t kArgumentsLimit = 1 * KB; - DeoptimizeIf(hi, instr, length, Operand(kArgumentsLimit)); + DeoptimizeIf(hi, instr, "too many arguments", length, + Operand(kArgumentsLimit)); // Push the receiver and use the register to keep the original // number of arguments. @@ -3621,7 +3625,7 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { // Deoptimize if not a heap number. __ ld(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); - DeoptimizeIf(ne, instr, scratch, Operand(at)); + DeoptimizeIf(ne, instr, "not a heap number", scratch, Operand(at)); Label done; Register exponent = scratch0(); @@ -3688,7 +3692,7 @@ void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { __ mov(result, input); __ dsubu(result, zero_reg, input); // Overflow if result is still negative, i.e. 0x80000000. - DeoptimizeIf(lt, instr, result, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "overflow", result, Operand(zero_reg)); __ bind(&done); } @@ -3742,7 +3746,8 @@ void LCodeGen::DoMathFloor(LMathFloor* instr) { except_flag); // Deopt if the operation did not succeed. - DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag, + Operand(zero_reg)); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { // Test for -0. @@ -3750,7 +3755,7 @@ void LCodeGen::DoMathFloor(LMathFloor* instr) { __ Branch(&done, ne, result, Operand(zero_reg)); __ mfhc1(scratch1, input); // Get exponent/sign bits. __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); - DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "minus zero", scratch1, Operand(zero_reg)); __ bind(&done); } } @@ -3783,7 +3788,8 @@ void LCodeGen::DoMathRound(LMathRound* instr) { // The following conversion will not work with numbers // outside of ]-2^32, 2^32[. - DeoptimizeIf(ge, instr, scratch, Operand(HeapNumber::kExponentBias + 32)); + DeoptimizeIf(ge, instr, "overflow", scratch, + Operand(HeapNumber::kExponentBias + 32)); // Save the original sign for later comparison. __ And(scratch, result, Operand(HeapNumber::kSignMask)); @@ -3800,7 +3806,7 @@ void LCodeGen::DoMathRound(LMathRound* instr) { __ Xor(result, result, Operand(scratch)); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { // ARM uses 'mi' here, which is 'lt' - DeoptimizeIf(lt, instr, result, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "minus zero", result, Operand(zero_reg)); } else { Label skip2; // ARM uses 'mi' here, which is 'lt' @@ -3819,7 +3825,8 @@ void LCodeGen::DoMathRound(LMathRound* instr) { double_scratch1, except_flag); - DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag, + Operand(zero_reg)); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { // Test for -0. @@ -3827,7 +3834,7 @@ void LCodeGen::DoMathRound(LMathRound* instr) { __ bind(&check_sign_on_zero); __ mfhc1(scratch, input); // Get exponent/sign bits. __ And(scratch, scratch, Operand(HeapNumber::kSignMask)); - DeoptimizeIf(ne, instr, scratch, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "minus zero", scratch, Operand(zero_reg)); } __ bind(&done); } @@ -3893,7 +3900,7 @@ void LCodeGen::DoPower(LPower* instr) { DCHECK(!a7.is(tagged_exponent)); __ lw(a7, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset)); __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); - DeoptimizeIf(ne, instr, a7, Operand(at)); + DeoptimizeIf(ne, instr, "not a heap number", a7, Operand(at)); __ bind(&no_deopt); MathPowStub stub(isolate(), MathPowStub::TAGGED); __ CallStub(&stub); @@ -4235,7 +4242,7 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { __ stop("eliminated bounds check failed"); __ bind(&done); } else { - DeoptimizeIf(cc, instr, reg, operand); + DeoptimizeIf(cc, instr, "out of bounds", reg, operand); } } @@ -4526,7 +4533,7 @@ void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { Label no_memento_found; __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found, ne, &no_memento_found); - DeoptimizeIf(al, instr); + DeoptimizeIf(al, instr, "memento found"); __ bind(&no_memento_found); } @@ -4829,12 +4836,12 @@ void LCodeGen::DoSmiTag(LSmiTag* instr) { if (hchange->CheckFlag(HValue::kCanOverflow) && hchange->value()->CheckFlag(HValue::kUint32)) { __ And(at, input, Operand(0x80000000)); - DeoptimizeIf(ne, instr, at, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "overflow", at, Operand(zero_reg)); } if (hchange->CheckFlag(HValue::kCanOverflow) && !hchange->value()->CheckFlag(HValue::kUint32)) { __ SmiTagCheckOverflow(output, input, at); - DeoptimizeIf(lt, instr, at, Operand(zero_reg)); + DeoptimizeIf(lt, instr, "overflow", at, Operand(zero_reg)); } else { __ SmiTag(output, input); } @@ -4850,7 +4857,7 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) { // If the input is a HeapObject, value of scratch won't be zero. __ And(scratch, input, Operand(kHeapObjectTag)); __ SmiUntag(result, input); - DeoptimizeIf(ne, instr, scratch, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "not a Smi", scratch, Operand(zero_reg)); } else { __ SmiUntag(result, input); } @@ -4875,7 +4882,7 @@ void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg, if (can_convert_undefined_to_nan) { __ Branch(&convert, ne, scratch, Operand(at)); } else { - DeoptimizeIf(ne, instr, scratch, Operand(at)); + DeoptimizeIf(ne, instr, "not a heap number", scratch, Operand(at)); } // Load heap number. __ ldc1(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset)); @@ -4883,14 +4890,16 @@ void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg, __ mfc1(at, result_reg); __ Branch(&done, ne, at, Operand(zero_reg)); __ mfhc1(scratch, result_reg); // Get exponent/sign bits. - DeoptimizeIf(eq, instr, scratch, Operand(HeapNumber::kSignMask)); + DeoptimizeIf(eq, instr, "minus zero", scratch, + Operand(HeapNumber::kSignMask)); } __ Branch(&done); if (can_convert_undefined_to_nan) { __ bind(&convert); // Convert undefined (and hole) to NaN. __ LoadRoot(at, Heap::kUndefinedValueRootIndex); - DeoptimizeIf(ne, instr, input_reg, Operand(at)); + DeoptimizeIf(ne, instr, "not a heap number/undefined", input_reg, + Operand(at)); __ LoadRoot(scratch, Heap::kNanValueRootIndex); __ ldc1(result_reg, FieldMemOperand(scratch, HeapNumber::kValueOffset)); __ Branch(&done); @@ -4954,11 +4963,12 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { __ bind(&check_false); __ LoadRoot(at, Heap::kFalseValueRootIndex); - DeoptimizeIf(ne, instr, scratch2, Operand(at), "cannot truncate"); + DeoptimizeIf(ne, instr, "not a heap number/undefined/true/false", scratch2, + Operand(at)); __ Branch(USE_DELAY_SLOT, &done); __ mov(input_reg, zero_reg); // In delay slot. } else { - DeoptimizeIf(ne, instr, scratch1, Operand(at), "not a heap number"); + DeoptimizeIf(ne, instr, "not a heap number", scratch1, Operand(at)); // Load the double value. __ ldc1(double_scratch, @@ -4973,15 +4983,15 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { except_flag, kCheckForInexactConversion); - DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg), - "lost precision or NaN"); + DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag, + Operand(zero_reg)); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { __ Branch(&done, ne, input_reg, Operand(zero_reg)); __ mfhc1(scratch1, double_scratch); // Get exponent/sign bits. __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); - DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg), "minus zero"); + DeoptimizeIf(ne, instr, "minus zero", scratch1, Operand(zero_reg)); } } __ bind(&done); @@ -5058,14 +5068,15 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) { kCheckForInexactConversion); // Deopt if the operation did not succeed (except_flag != 0). - DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag, + Operand(zero_reg)); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { Label done; __ Branch(&done, ne, result_reg, Operand(zero_reg)); __ mfhc1(scratch1, double_input); // Get exponent/sign bits. __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); - DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "minus zero", scratch1, Operand(zero_reg)); __ bind(&done); } } @@ -5091,14 +5102,15 @@ void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { kCheckForInexactConversion); // Deopt if the operation did not succeed (except_flag != 0). - DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag, + Operand(zero_reg)); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { Label done; __ Branch(&done, ne, result_reg, Operand(zero_reg)); __ mfhc1(scratch1, double_input); // Get exponent/sign bits. __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); - DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "minus zero", scratch1, Operand(zero_reg)); __ bind(&done); } } @@ -5109,7 +5121,7 @@ void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { void LCodeGen::DoCheckSmi(LCheckSmi* instr) { LOperand* input = instr->value(); __ SmiTst(ToRegister(input), at); - DeoptimizeIf(ne, instr, at, Operand(zero_reg)); + DeoptimizeIf(ne, instr, "not a Smi", at, Operand(zero_reg)); } @@ -5117,7 +5129,7 @@ void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { if (!instr->hydrogen()->value()->type().IsHeapObject()) { LOperand* input = instr->value(); __ SmiTst(ToRegister(input), at); - DeoptimizeIf(eq, instr, at, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "Smi", at, Operand(zero_reg)); } } @@ -5135,12 +5147,12 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { // If there is only one type in the interval check for equality. if (first == last) { - DeoptimizeIf(ne, instr, scratch, Operand(first)); + DeoptimizeIf(ne, instr, "wrong instance type", scratch, Operand(first)); } else { - DeoptimizeIf(lo, instr, scratch, Operand(first)); + DeoptimizeIf(lo, instr, "wrong instance type", scratch, Operand(first)); // Omit check for the last type. if (last != LAST_TYPE) { - DeoptimizeIf(hi, instr, scratch, Operand(last)); + DeoptimizeIf(hi, instr, "wrong instance type", scratch, Operand(last)); } } } else { @@ -5151,10 +5163,11 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { if (base::bits::IsPowerOfTwo32(mask)) { DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag)); __ And(at, scratch, mask); - DeoptimizeIf(tag == 0 ? ne : eq, instr, at, Operand(zero_reg)); + DeoptimizeIf(tag == 0 ? ne : eq, instr, "wrong instance type", at, + Operand(zero_reg)); } else { __ And(scratch, scratch, Operand(mask)); - DeoptimizeIf(ne, instr, scratch, Operand(tag)); + DeoptimizeIf(ne, instr, "wrong instance type", scratch, Operand(tag)); } } } @@ -5169,9 +5182,9 @@ void LCodeGen::DoCheckValue(LCheckValue* instr) { Handle cell = isolate()->factory()->NewCell(object); __ li(at, Operand(Handle(cell))); __ ld(at, FieldMemOperand(at, Cell::kValueOffset)); - DeoptimizeIf(ne, instr, reg, Operand(at)); + DeoptimizeIf(ne, instr, "value mismatch", reg, Operand(at)); } else { - DeoptimizeIf(ne, instr, reg, Operand(object)); + DeoptimizeIf(ne, instr, "value mismatch", reg, Operand(object)); } } @@ -5187,7 +5200,7 @@ void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { __ StoreToSafepointRegisterSlot(v0, scratch0()); } __ SmiTst(scratch0(), at); - DeoptimizeIf(eq, instr, at, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "instance migration failed", at, Operand(zero_reg)); } @@ -5240,7 +5253,7 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) { if (instr->hydrogen()->HasMigrationTarget()) { __ Branch(deferred->entry(), ne, map_reg, Operand(map)); } else { - DeoptimizeIf(ne, instr, map_reg, Operand(map)); + DeoptimizeIf(ne, instr, "wrong map", map_reg, Operand(map)); } __ bind(&success); @@ -5278,7 +5291,8 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { // Check for undefined. Undefined is converted to zero for clamping // conversions. - DeoptimizeIf(ne, instr, input_reg, Operand(factory()->undefined_value())); + DeoptimizeIf(ne, instr, "not a heap number/undefined", input_reg, + Operand(factory()->undefined_value())); __ mov(result_reg, zero_reg); __ jmp(&done); @@ -5703,8 +5717,8 @@ void LCodeGen::DoDeoptimize(LDeoptimize* instr) { type = Deoptimizer::LAZY; } - DeoptimizeIf(al, instr, type, zero_reg, Operand(zero_reg), - instr->hydrogen()->reason()); + DeoptimizeIf(al, instr, type, instr->hydrogen()->reason(), zero_reg, + Operand(zero_reg)); } @@ -5795,18 +5809,19 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { Register result = ToRegister(instr->result()); Register object = ToRegister(instr->object()); __ LoadRoot(at, Heap::kUndefinedValueRootIndex); - DeoptimizeIf(eq, instr, object, Operand(at)); + DeoptimizeIf(eq, instr, "undefined", object, Operand(at)); Register null_value = a5; __ LoadRoot(null_value, Heap::kNullValueRootIndex); - DeoptimizeIf(eq, instr, object, Operand(null_value)); + DeoptimizeIf(eq, instr, "null", object, Operand(null_value)); __ And(at, object, kSmiTagMask); - DeoptimizeIf(eq, instr, at, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "Smi", at, Operand(zero_reg)); STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); __ GetObjectType(object, a1, a1); - DeoptimizeIf(le, instr, a1, Operand(LAST_JS_PROXY_TYPE)); + DeoptimizeIf(le, instr, "not a JavaScript object", a1, + Operand(LAST_JS_PROXY_TYPE)); Label use_cache, call_runtime; DCHECK(object.is(a0)); @@ -5823,7 +5838,7 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) { __ ld(a1, FieldMemOperand(v0, HeapObject::kMapOffset)); DCHECK(result.is(v0)); __ LoadRoot(at, Heap::kMetaMapRootIndex); - DeoptimizeIf(ne, instr, a1, Operand(at)); + DeoptimizeIf(ne, instr, "wrong map", a1, Operand(at)); __ bind(&use_cache); } @@ -5843,7 +5858,7 @@ void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) { FieldMemOperand(result, DescriptorArray::kEnumCacheOffset)); __ ld(result, FieldMemOperand(result, FixedArray::SizeFor(instr->idx()))); - DeoptimizeIf(eq, instr, result, Operand(zero_reg)); + DeoptimizeIf(eq, instr, "no cache", result, Operand(zero_reg)); __ bind(&done); } @@ -5853,7 +5868,7 @@ void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) { Register object = ToRegister(instr->value()); Register map = ToRegister(instr->map()); __ ld(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset)); - DeoptimizeIf(ne, instr, map, Operand(scratch0())); + DeoptimizeIf(ne, instr, "wrong map", map, Operand(scratch0())); } diff --git a/src/mips64/lithium-codegen-mips64.h b/src/mips64/lithium-codegen-mips64.h index a4b7adb..b320dcb 100644 --- a/src/mips64/lithium-codegen-mips64.h +++ b/src/mips64/lithium-codegen-mips64.h @@ -230,14 +230,12 @@ class LCodeGen: public LCodeGenBase { void RegisterEnvironmentForDeoptimization(LEnvironment* environment, Safepoint::DeoptMode mode); void DeoptimizeIf(Condition condition, LInstruction* instr, - Deoptimizer::BailoutType bailout_type, + Deoptimizer::BailoutType bailout_type, const char* detail, Register src1 = zero_reg, - const Operand& src2 = Operand(zero_reg), - const char* detail = NULL); + const Operand& src2 = Operand(zero_reg)); void DeoptimizeIf(Condition condition, LInstruction* instr, - Register src1 = zero_reg, - const Operand& src2 = Operand(zero_reg), - const char* detail = NULL); + const char* detail, Register src1 = zero_reg, + const Operand& src2 = Operand(zero_reg)); void AddToTranslation(LEnvironment* environment, Translation* translation,