X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fv8%2Fsrc%2Farm64%2Flithium-arm64.cc;h=3eb2778764796335a88dd7b28ddd998339006cde;hb=004985e17e624662a4c85c76a7654039dc83f028;hp=60bf51ebbdc7d33170faff92dcf106d777a1f7c4;hpb=2f108dbacb161091e42a3479f4e171339b7e7623;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/v8/src/arm64/lithium-arm64.cc b/src/v8/src/arm64/lithium-arm64.cc index 60bf51e..3eb2778 100644 --- a/src/v8/src/arm64/lithium-arm64.cc +++ b/src/v8/src/arm64/lithium-arm64.cc @@ -1,29 +1,6 @@ // Copyright 2013 the V8 project authors. All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. #include "v8.h" @@ -515,6 +492,8 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, !hinstr->HasObservableSideEffects(); if (needs_environment && !instr->HasEnvironment()) { instr = AssignEnvironment(instr); + // We can't really figure out if the environment is needed or not. + instr->environment()->set_has_been_used(); } return instr; @@ -702,7 +681,8 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { // the it was just a plain use), so it is free to move the split child into // the same register that is used for the use-at-start. // See https://code.google.com/p/chromium/issues/detail?id=201590 - if (!(instr->ClobbersRegisters() && instr->ClobbersDoubleRegisters())) { + if (!(instr->ClobbersRegisters() && + instr->ClobbersDoubleRegisters(isolate()))) { int fixed = 0; int used_at_start = 0; for (UseIterator it(instr); !it.Done(); it.Advance()) { @@ -947,9 +927,16 @@ LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) { LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { - LOperand* value = UseRegisterOrConstantAtStart(instr->index()); - LOperand* length = UseRegister(instr->length()); - return AssignEnvironment(new(zone()) LBoundsCheck(value, length)); + if (!FLAG_debug_code && instr->skip_check()) return NULL; + LOperand* index = UseRegisterOrConstantAtStart(instr->index()); + LOperand* length = !index->IsConstantOperand() + ? UseRegisterOrConstantAtStart(instr->length()) + : UseRegisterAtStart(instr->length()); + LInstruction* result = new(zone()) LBoundsCheck(index, length); + if (!FLAG_debug_code || !instr->skip_check()) { + result = AssignEnvironment(result); + } + return result; } @@ -1074,63 +1061,58 @@ LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) { LInstruction* LChunkBuilder::DoChange(HChange* instr) { Representation from = instr->from(); Representation to = instr->to(); - + HValue* val = instr->value(); if (from.IsSmi()) { if (to.IsTagged()) { - LOperand* value = UseRegister(instr->value()); + LOperand* value = UseRegister(val); return DefineSameAsFirst(new(zone()) LDummyUse(value)); } from = Representation::Tagged(); } - if (from.IsTagged()) { if (to.IsDouble()) { - LOperand* value = UseRegister(instr->value()); + LOperand* value = UseRegister(val); LOperand* temp = TempRegister(); - LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp); - return AssignEnvironment(DefineAsRegister(res)); + LInstruction* result = + DefineAsRegister(new(zone()) LNumberUntagD(value, temp)); + if (!val->representation().IsSmi()) result = AssignEnvironment(result); + return result; } else if (to.IsSmi()) { - LOperand* value = UseRegister(instr->value()); - if (instr->value()->type().IsSmi()) { + LOperand* value = UseRegister(val); + if (val->type().IsSmi()) { return DefineSameAsFirst(new(zone()) LDummyUse(value)); } return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); } else { ASSERT(to.IsInteger32()); - LInstruction* res = NULL; - - if (instr->value()->type().IsSmi() || - instr->value()->representation().IsSmi()) { - LOperand* value = UseRegisterAtStart(instr->value()); - res = DefineAsRegister(new(zone()) LSmiUntag(value, false)); + if (val->type().IsSmi() || val->representation().IsSmi()) { + LOperand* value = UseRegisterAtStart(val); + return DefineAsRegister(new(zone()) LSmiUntag(value, false)); } else { - LOperand* value = UseRegister(instr->value()); + LOperand* value = UseRegister(val); LOperand* temp1 = TempRegister(); LOperand* temp2 = instr->CanTruncateToInt32() ? NULL : FixedTemp(d24); - res = DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2)); - res = AssignEnvironment(res); + LInstruction* result = + DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2)); + if (!val->representation().IsSmi()) result = AssignEnvironment(result); + return result; } - - return res; } } else if (from.IsDouble()) { if (to.IsTagged()) { info()->MarkAsDeferredCalling(); - LOperand* value = UseRegister(instr->value()); + LOperand* value = UseRegister(val); LOperand* temp1 = TempRegister(); LOperand* temp2 = TempRegister(); - LNumberTagD* result = new(zone()) LNumberTagD(value, temp1, temp2); return AssignPointerMap(DefineAsRegister(result)); } else { ASSERT(to.IsSmi() || to.IsInteger32()); - LOperand* value = UseRegister(instr->value()); - if (instr->CanTruncateToInt32()) { - LTruncateDoubleToIntOrSmi* result = - new(zone()) LTruncateDoubleToIntOrSmi(value); - return DefineAsRegister(result); + LOperand* value = UseRegister(val); + return DefineAsRegister(new(zone()) LTruncateDoubleToIntOrSmi(value)); } else { + LOperand* value = UseRegister(val); LDoubleToIntOrSmi* result = new(zone()) LDoubleToIntOrSmi(value); return AssignEnvironment(DefineAsRegister(result)); } @@ -1138,37 +1120,35 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { } else if (from.IsInteger32()) { info()->MarkAsDeferredCalling(); if (to.IsTagged()) { - if (instr->value()->CheckFlag(HInstruction::kUint32)) { - LOperand* value = UseRegister(instr->value()); - LNumberTagU* result = new(zone()) LNumberTagU(value, - TempRegister(), - TempRegister()); - return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); + if (val->CheckFlag(HInstruction::kUint32)) { + LOperand* value = UseRegister(val); + LNumberTagU* result = + new(zone()) LNumberTagU(value, TempRegister(), TempRegister()); + return AssignPointerMap(DefineAsRegister(result)); } else { STATIC_ASSERT((kMinInt == Smi::kMinValue) && (kMaxInt == Smi::kMaxValue)); - LOperand* value = UseRegisterAtStart(instr->value()); + LOperand* value = UseRegisterAtStart(val); return DefineAsRegister(new(zone()) LSmiTag(value)); } } else if (to.IsSmi()) { - LOperand* value = UseRegisterAtStart(instr->value()); + LOperand* value = UseRegisterAtStart(val); LInstruction* result = DefineAsRegister(new(zone()) LSmiTag(value)); - if (instr->value()->CheckFlag(HInstruction::kUint32)) { + if (val->CheckFlag(HInstruction::kUint32)) { result = AssignEnvironment(result); } return result; } else { ASSERT(to.IsDouble()); - if (instr->value()->CheckFlag(HInstruction::kUint32)) { + if (val->CheckFlag(HInstruction::kUint32)) { return DefineAsRegister( - new(zone()) LUint32ToDouble(UseRegisterAtStart(instr->value()))); + new(zone()) LUint32ToDouble(UseRegisterAtStart(val))); } else { return DefineAsRegister( - new(zone()) LInteger32ToDouble(UseRegisterAtStart(instr->value()))); + new(zone()) LInteger32ToDouble(UseRegisterAtStart(val))); } } } - UNREACHABLE(); return NULL; } @@ -1189,27 +1169,23 @@ LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) { - if (instr->CanOmitMapChecks()) { - // LCheckMaps does nothing in this case. - return new(zone()) LCheckMaps(NULL); - } else { - LOperand* value = UseRegisterAtStart(instr->value()); - LOperand* temp = TempRegister(); - - if (instr->has_migration_target()) { - info()->MarkAsDeferredCalling(); - LInstruction* result = new(zone()) LCheckMaps(value, temp); - return AssignPointerMap(AssignEnvironment(result)); - } else { - return AssignEnvironment(new(zone()) LCheckMaps(value, temp)); - } + if (instr->IsStabilityCheck()) return new(zone()) LCheckMaps; + LOperand* value = UseRegisterAtStart(instr->value()); + LOperand* temp = TempRegister(); + LInstruction* result = AssignEnvironment(new(zone()) LCheckMaps(value, temp)); + if (instr->HasMigrationTarget()) { + info()->MarkAsDeferredCalling(); + result = AssignPointerMap(result); } + return result; } LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) { LOperand* value = UseRegisterAtStart(instr->value()); - return AssignEnvironment(new(zone()) LCheckNonSmi(value)); + LInstruction* result = new(zone()) LCheckNonSmi(value); + if (!instr->value()->IsHeapObject()) result = AssignEnvironment(result); + return result; } @@ -1249,8 +1225,9 @@ LInstruction* LChunkBuilder::DoClassOfTestAndBranch( LInstruction* LChunkBuilder::DoCompareNumericAndBranch( HCompareNumericAndBranch* instr) { + LInstruction* goto_instr = CheckElideControlInstruction(instr); + if (goto_instr != NULL) return goto_instr; Representation r = instr->representation(); - if (r.IsSmiOrInteger32()) { ASSERT(instr->left()->representation().Equals(r)); ASSERT(instr->right()->representation().Equals(r)); @@ -1418,8 +1395,12 @@ LInstruction* LChunkBuilder::DoDivI(HBinaryOperation* instr) { LOperand* divisor = UseRegister(instr->right()); LOperand* temp = instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) ? NULL : TempRegister(); - LDivI* div = new(zone()) LDivI(dividend, divisor, temp); - return AssignEnvironment(DefineAsRegister(div)); + LInstruction* result = + DefineAsRegister(new(zone()) LDivI(dividend, divisor, temp)); + if (!instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { + result = AssignEnvironment(result); + } + return result; } @@ -1447,6 +1428,7 @@ LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) { LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) { HEnvironment* outer = current_block_->last_environment(); + outer->set_ast_id(instr->ReturnId()); HConstant* undefined = graph()->GetConstantUndefined(); HEnvironment* inner = outer->CopyForInlining(instr->closure(), instr->arguments_count(), @@ -1622,7 +1604,10 @@ LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) { LOperand* context = UseRegisterAtStart(instr->value()); LInstruction* result = DefineAsRegister(new(zone()) LLoadContextSlot(context)); - return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; + if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) { + result = AssignEnvironment(result); + } + return result; } @@ -1656,9 +1641,10 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { ASSERT(instr->key()->representation().IsSmiOrInteger32()); ElementsKind elements_kind = instr->elements_kind(); LOperand* elements = UseRegister(instr->elements()); - LOperand* key = UseRegisterOrConstantAtStart(instr->key()); if (!instr->is_typed_elements()) { + LOperand* key = UseRegisterOrConstantAtStart(instr->key()); + if (instr->representation().IsDouble()) { LOperand* temp = (!instr->key()->IsConstant() || instr->RequiresHoleCheck()) @@ -1686,18 +1672,16 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { (instr->representation().IsDouble() && IsDoubleOrFloatElementsKind(instr->elements_kind()))); + LOperand* key = UseRegisterOrConstant(instr->key()); LOperand* temp = instr->key()->IsConstant() ? NULL : TempRegister(); - LLoadKeyedExternal* result = - new(zone()) LLoadKeyedExternal(elements, key, temp); - // An unsigned int array load might overflow and cause a deopt. Make sure it - // has an environment. - if (instr->RequiresHoleCheck() || - elements_kind == EXTERNAL_UINT32_ELEMENTS || - elements_kind == UINT32_ELEMENTS) { - return AssignEnvironment(DefineAsRegister(result)); - } else { - return DefineAsRegister(result); + LInstruction* result = DefineAsRegister( + new(zone()) LLoadKeyedExternal(elements, key, temp)); + if ((elements_kind == EXTERNAL_UINT32_ELEMENTS || + elements_kind == UINT32_ELEMENTS) && + !instr->CheckFlag(HInstruction::kUint32)) { + result = AssignEnvironment(result); } + return result; } } @@ -1885,13 +1869,10 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) { bool can_overflow = instr->CheckFlag(HValue::kCanOverflow); bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero); - bool needs_environment = can_overflow || bailout_on_minus_zero; HValue* least_const = instr->BetterLeftOperand(); HValue* most_const = instr->BetterRightOperand(); - LOperand* left; - // LMulConstI can handle a subset of constants: // With support for overflow detection: // -1, 0, 1, 2 @@ -1911,26 +1892,27 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) { IsPowerOf2(constant_abs - 1))))) { LConstantOperand* right = UseConstant(most_const); bool need_register = IsPowerOf2(constant_abs) && !small_constant; - left = need_register ? UseRegister(least_const) - : UseRegisterAtStart(least_const); - LMulConstIS* mul = new(zone()) LMulConstIS(left, right); - if (needs_environment) AssignEnvironment(mul); - return DefineAsRegister(mul); + LOperand* left = need_register ? UseRegister(least_const) + : UseRegisterAtStart(least_const); + LInstruction* result = + DefineAsRegister(new(zone()) LMulConstIS(left, right)); + if ((bailout_on_minus_zero && constant <= 0) || can_overflow) { + result = AssignEnvironment(result); + } + return result; } } - left = UseRegisterAtStart(least_const); // LMulI/S can handle all cases, but it requires that a register is // allocated for the second operand. - LInstruction* result; - if (instr->representation().IsSmi()) { - LOperand* right = UseRegisterAtStart(most_const); - result = DefineAsRegister(new(zone()) LMulS(left, right)); - } else { - LOperand* right = UseRegisterAtStart(most_const); - result = DefineAsRegister(new(zone()) LMulI(left, right)); + LOperand* left = UseRegisterAtStart(least_const); + LOperand* right = UseRegisterAtStart(most_const); + LInstruction* result = instr->representation().IsSmi() + ? DefineAsRegister(new(zone()) LMulS(left, right)) + : DefineAsRegister(new(zone()) LMulI(left, right)); + if ((bailout_on_minus_zero && least_const != most_const) || can_overflow) { + result = AssignEnvironment(result); } - if (needs_environment) AssignEnvironment(result); return result; } else if (instr->representation().IsDouble()) { return DoArithmeticD(Token::MUL, instr); @@ -1956,7 +1938,7 @@ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { } else { ASSERT(info()->IsStub()); CodeStubInterfaceDescriptor* descriptor = - info()->code_stub()->GetInterfaceDescriptor(info()->isolate()); + info()->code_stub()->GetInterfaceDescriptor(); int index = static_cast(instr->index()); Register reg = descriptor->GetParameterRegister(index); return DefineFixed(result, reg); @@ -2160,7 +2142,10 @@ LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) { value = UseRegister(instr->value()); } LInstruction* result = new(zone()) LStoreContextSlot(context, value, temp); - return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result; + if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) { + result = AssignEnvironment(result); + } + return result; } @@ -2180,7 +2165,6 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { LOperand* temp = NULL; LOperand* elements = NULL; LOperand* val = NULL; - LOperand* key = UseRegisterOrConstantAtStart(instr->key()); if (!instr->is_typed_elements() && instr->value()->representation().IsTagged() && @@ -2204,16 +2188,19 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { instr->elements()->representation().IsTagged()) || (instr->is_external() && instr->elements()->representation().IsExternal())); + LOperand* key = UseRegisterOrConstant(instr->key()); return new(zone()) LStoreKeyedExternal(elements, key, val, temp); } else if (instr->value()->representation().IsDouble()) { ASSERT(instr->elements()->representation().IsTagged()); + LOperand* key = UseRegisterOrConstantAtStart(instr->key()); return new(zone()) LStoreKeyedFixedDouble(elements, key, val, temp); } else { ASSERT(instr->elements()->representation().IsTagged()); ASSERT(instr->value()->representation().IsSmiOrTagged() || instr->value()->representation().IsInteger32()); + LOperand* key = UseRegisterOrConstantAtStart(instr->key()); return new(zone()) LStoreKeyedFixed(elements, key, val, temp); } } @@ -2294,7 +2281,7 @@ LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { LOperand* context = UseAny(instr->context()); LStringCharCodeAt* result = new(zone()) LStringCharCodeAt(context, string, index); - return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); + return AssignPointerMap(DefineAsRegister(result)); } @@ -2365,17 +2352,18 @@ LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) { LInstruction* LChunkBuilder::DoTransitionElementsKind( HTransitionElementsKind* instr) { - LOperand* object = UseRegister(instr->object()); if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { + LOperand* object = UseRegister(instr->object()); LTransitionElementsKind* result = new(zone()) LTransitionElementsKind(object, NULL, TempRegister(), TempRegister()); return result; } else { + LOperand* object = UseFixed(instr->object(), x0); LOperand* context = UseFixed(instr->context(), cp); LTransitionElementsKind* result = - new(zone()) LTransitionElementsKind(object, context, TempRegister()); - return AssignPointerMap(result); + new(zone()) LTransitionElementsKind(object, context, NULL, NULL); + return MarkAsCall(result, instr); } } @@ -2429,21 +2417,14 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { LOperand* temp1 = TempRegister(); LOperand* temp2 = TempRegister(); LOperand* temp3 = TempRegister(); - LMathAbsTagged* result = - new(zone()) LMathAbsTagged(context, input, temp1, temp2, temp3); - return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); + LInstruction* result = DefineAsRegister( + new(zone()) LMathAbsTagged(context, input, temp1, temp2, temp3)); + return AssignEnvironment(AssignPointerMap(result)); } else { LOperand* input = UseRegisterAtStart(instr->value()); - LMathAbs* result = new(zone()) LMathAbs(input); - if (r.IsDouble()) { - // The Double case can never fail so it doesn't need an environment. - return DefineAsRegister(result); - } else { - ASSERT(r.IsInteger32() || r.IsSmi()); - // The Integer32 and Smi cases need an environment because they can - // deoptimize on minimum representable number. - return AssignEnvironment(DefineAsRegister(result)); - } + LInstruction* result = DefineAsRegister(new(zone()) LMathAbs(input)); + if (!r.IsDouble()) result = AssignEnvironment(result); + return result; } } case kMathExp: { @@ -2460,14 +2441,16 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { return DefineAsRegister(result); } case kMathFloor: { - ASSERT(instr->representation().IsInteger32()); ASSERT(instr->value()->representation().IsDouble()); - // TODO(jbramley): ARM64 can easily handle a double argument with frintm, - // but we're never asked for it here. At the moment, we fall back to the - // runtime if the result doesn't fit, like the other architectures. LOperand* input = UseRegisterAtStart(instr->value()); - LMathFloor* result = new(zone()) LMathFloor(input); - return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); + if (instr->representation().IsInteger32()) { + LMathFloorI* result = new(zone()) LMathFloorI(input); + return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); + } else { + ASSERT(instr->representation().IsDouble()); + LMathFloorD* result = new(zone()) LMathFloorD(input); + return DefineAsRegister(result); + } } case kMathLog: { ASSERT(instr->representation().IsDouble()); @@ -2483,14 +2466,16 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { return DefineAsRegister(new(zone()) LMathPowHalf(input)); } case kMathRound: { - ASSERT(instr->representation().IsInteger32()); ASSERT(instr->value()->representation().IsDouble()); - // TODO(jbramley): As with kMathFloor, we can probably handle double - // results fairly easily, but we are never asked for them. LOperand* input = UseRegister(instr->value()); - LOperand* temp = FixedTemp(d24); // Choosen arbitrarily. - LMathRound* result = new(zone()) LMathRound(input, temp); - return AssignEnvironment(DefineAsRegister(result)); + if (instr->representation().IsInteger32()) { + LMathRoundI* result = new(zone()) LMathRoundI(input, FixedTemp(d24)); + return AssignEnvironment(DefineAsRegister(result)); + } else { + ASSERT(instr->representation().IsDouble()); + LMathRoundD* result = new(zone()) LMathRoundD(input); + return DefineAsRegister(result); + } } case kMathSqrt: { ASSERT(instr->representation().IsDouble()); @@ -2560,8 +2545,10 @@ LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) { LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { LOperand* object = UseRegisterAtStart(instr->object()); - LOperand* index = UseRegister(instr->index()); - return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); + LOperand* index = UseRegisterAndClobber(instr->index()); + LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); + LInstruction* result = DefineSameAsFirst(load); + return AssignPointerMap(result); }