diff options
Diffstat (limited to 'deps/v8/src/arm/lithium-arm.cc')
-rw-r--r-- | deps/v8/src/arm/lithium-arm.cc | 423 |
1 files changed, 229 insertions, 194 deletions
diff --git a/deps/v8/src/arm/lithium-arm.cc b/deps/v8/src/arm/lithium-arm.cc index 59a8818ac6..86d5d2b329 100644 --- a/deps/v8/src/arm/lithium-arm.cc +++ b/deps/v8/src/arm/lithium-arm.cc @@ -412,18 +412,19 @@ void LTransitionElementsKind::PrintDataTo(StringStream* stream) { } -int LPlatformChunk::GetNextSpillIndex(bool is_double) { +int LPlatformChunk::GetNextSpillIndex(RegisterKind kind) { // Skip a slot if for a double-width slot. - if (is_double) spill_slot_count_++; + if (kind == DOUBLE_REGISTERS) spill_slot_count_++; return spill_slot_count_++; } -LOperand* LPlatformChunk::GetNextSpillSlot(bool is_double) { - int index = GetNextSpillIndex(is_double); - if (is_double) { +LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) { + int index = GetNextSpillIndex(kind); + if (kind == DOUBLE_REGISTERS) { return LDoubleStackSlot::Create(index, zone()); } else { + ASSERT(kind == GENERAL_REGISTERS); return LStackSlot::Create(index, zone()); } } @@ -439,7 +440,7 @@ LPlatformChunk* LChunkBuilder::Build() { // which will be subsumed into this frame. if (graph()->has_osr()) { for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) { - chunk_->GetNextSpillIndex(false); + chunk_->GetNextSpillIndex(GENERAL_REGISTERS); } } @@ -655,7 +656,7 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { ASSERT(!instr->HasPointerMap()); - instr->set_pointer_map(new(zone()) LPointerMap(position_, zone())); + instr->set_pointer_map(new(zone()) LPointerMap(zone())); return instr; } @@ -710,51 +711,44 @@ LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { LInstruction* LChunkBuilder::DoShift(Token::Value op, HBitwiseBinaryOperation* instr) { - if (instr->representation().IsTagged()) { - ASSERT(instr->left()->representation().IsTagged()); - ASSERT(instr->right()->representation().IsTagged()); - - LOperand* left = UseFixed(instr->left(), r1); - LOperand* right = UseFixed(instr->right(), r0); - LArithmeticT* result = new(zone()) LArithmeticT(op, left, right); - return MarkAsCall(DefineFixed(result, r0), instr); - } - - ASSERT(instr->representation().IsSmiOrInteger32()); - ASSERT(instr->left()->representation().Equals(instr->representation())); - ASSERT(instr->right()->representation().Equals(instr->representation())); - LOperand* left = UseRegisterAtStart(instr->left()); + if (instr->representation().IsSmiOrInteger32()) { + ASSERT(instr->left()->representation().Equals(instr->representation())); + ASSERT(instr->right()->representation().Equals(instr->representation())); + LOperand* left = UseRegisterAtStart(instr->left()); - HValue* right_value = instr->right(); - LOperand* right = NULL; - int constant_value = 0; - bool does_deopt = false; - if (right_value->IsConstant()) { - HConstant* constant = HConstant::cast(right_value); - right = chunk_->DefineConstantOperand(constant); - constant_value = constant->Integer32Value() & 0x1f; - // Left shifts can deoptimize if we shift by > 0 and the result cannot be - // truncated to smi. - if (instr->representation().IsSmi() && constant_value > 0) { - does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi); + HValue* right_value = instr->right(); + LOperand* right = NULL; + int constant_value = 0; + bool does_deopt = false; + if (right_value->IsConstant()) { + HConstant* constant = HConstant::cast(right_value); + right = chunk_->DefineConstantOperand(constant); + constant_value = constant->Integer32Value() & 0x1f; + // Left shifts can deoptimize if we shift by > 0 and the result cannot be + // truncated to smi. + if (instr->representation().IsSmi() && constant_value > 0) { + does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi); + } + } else { + right = UseRegisterAtStart(right_value); } - } else { - right = UseRegisterAtStart(right_value); - } - // Shift operations can only deoptimize if we do a logical shift - // by 0 and the result cannot be truncated to int32. - if (op == Token::SHR && constant_value == 0) { - if (FLAG_opt_safe_uint32_operations) { - does_deopt = !instr->CheckFlag(HInstruction::kUint32); - } else { - does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32); + // Shift operations can only deoptimize if we do a logical shift + // by 0 and the result cannot be truncated to int32. + if (op == Token::SHR && constant_value == 0) { + if (FLAG_opt_safe_uint32_operations) { + does_deopt = !instr->CheckFlag(HInstruction::kUint32); + } else { + does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32); + } } - } - LInstruction* result = - DefineAsRegister(new(zone()) LShiftI(op, left, right, does_deopt)); - return does_deopt ? AssignEnvironment(result) : result; + LInstruction* result = + DefineAsRegister(new(zone()) LShiftI(op, left, right, does_deopt)); + return does_deopt ? AssignEnvironment(result) : result; + } else { + return DoArithmeticT(op, instr); + } } @@ -763,29 +757,34 @@ LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, ASSERT(instr->representation().IsDouble()); ASSERT(instr->left()->representation().IsDouble()); ASSERT(instr->right()->representation().IsDouble()); - ASSERT(op != Token::MOD); - LOperand* left = UseRegisterAtStart(instr->left()); - LOperand* right = UseRegisterAtStart(instr->right()); - LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); - return DefineAsRegister(result); + if (op == Token::MOD) { + LOperand* left = UseFixedDouble(instr->left(), d1); + LOperand* right = UseFixedDouble(instr->right(), d2); + LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); + // We call a C function for double modulo. It can't trigger a GC. We need + // to use fixed result register for the call. + // TODO(fschneider): Allow any register as input registers. + return MarkAsCall(DefineFixedDouble(result, d1), instr); + } else { + LOperand* left = UseRegisterAtStart(instr->left()); + LOperand* right = UseRegisterAtStart(instr->right()); + LArithmeticD* result = new(zone()) LArithmeticD(op, left, right); + return DefineAsRegister(result); + } } LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, - HArithmeticBinaryOperation* instr) { - ASSERT(op == Token::ADD || - op == Token::DIV || - op == Token::MOD || - op == Token::MUL || - op == Token::SUB); + HBinaryOperation* instr) { HValue* left = instr->left(); HValue* right = instr->right(); ASSERT(left->representation().IsTagged()); ASSERT(right->representation().IsTagged()); + LOperand* context = UseFixed(instr->context(), cp); LOperand* left_operand = UseFixed(left, r1); LOperand* right_operand = UseFixed(right, r0); LArithmeticT* result = - new(zone()) LArithmeticT(op, left_operand, right_operand); + new(zone()) LArithmeticT(op, context, left_operand, right_operand); return MarkAsCall(DefineFixed(result, r0), instr); } @@ -861,9 +860,31 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { HInstruction* old_current = current_instruction_; current_instruction_ = current; if (current->has_position()) position_ = current->position(); - LInstruction* instr = current->CompileToLithium(this); + + LInstruction* instr = NULL; + if (current->CanReplaceWithDummyUses()) { + HValue* first_operand = current->OperandCount() == 0 + ? graph()->GetConstant1() + : current->OperandAt(0); + instr = DefineAsRegister(new(zone()) LDummyUse(UseAny(first_operand))); + for (int i = 1; i < current->OperandCount(); ++i) { + LInstruction* dummy = + new(zone()) LDummyUse(UseAny(current->OperandAt(i))); + dummy->set_hydrogen_value(current); + chunk_->AddInstruction(dummy, current_block_); + } + } else { + instr = current->CompileToLithium(this); + } + + argument_count_ += current->argument_delta(); + ASSERT(argument_count_ >= 0); if (instr != NULL) { + // Associate the hydrogen instruction first, since we may need it for + // the ClobbersRegisters() or ClobbersDoubleRegisters() calls below. + instr->set_hydrogen_value(current); + #if DEBUG // Make sure that the lithium instruction has either no fixed register // constraints in temps or the result OR no uses that are only used at @@ -893,14 +914,12 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { } #endif - instr->set_position(position_); if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { instr = AssignPointerMap(instr); } if (FLAG_stress_environments && !instr->HasEnvironment()) { instr = AssignEnvironment(instr); } - instr->set_hydrogen_value(current); chunk_->AddInstruction(instr, current_block_); } current_instruction_ = old_current; @@ -992,19 +1011,15 @@ LEnvironment* LChunkBuilder::CreateEnvironment( LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { - return new(zone()) LGoto(instr->FirstSuccessor()->block_id()); + return new(zone()) LGoto(instr->FirstSuccessor()); } LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { - HValue* value = instr->value(); - if (value->EmitAtUses()) { - HBasicBlock* successor = HConstant::cast(value)->BooleanValue() - ? instr->FirstSuccessor() - : instr->SecondSuccessor(); - return new(zone()) LGoto(successor->block_id()); - } + LInstruction* goto_instr = CheckElideControlInstruction(instr); + if (goto_instr != NULL) return goto_instr; + HValue* value = instr->value(); LBranch* result = new(zone()) LBranch(UseRegister(value)); // Tagged values that are not known smis or booleans require a // deoptimization environment. If the instruction is generic no @@ -1047,9 +1062,10 @@ LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { + LOperand* context = UseFixed(instr->context(), cp); LInstanceOf* result = - new(zone()) LInstanceOf(UseFixed(instr->left(), r0), - UseFixed(instr->right(), r1)); + new(zone()) LInstanceOf(context, UseFixed(instr->left(), r0), + UseFixed(instr->right(), r1)); return MarkAsCall(DefineFixed(result, r0), instr); } @@ -1057,18 +1073,14 @@ LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( HInstanceOfKnownGlobal* instr) { LInstanceOfKnownGlobal* result = - new(zone()) LInstanceOfKnownGlobal(UseFixed(instr->left(), r0), - FixedTemp(r4)); + new(zone()) LInstanceOfKnownGlobal( + UseFixed(instr->context(), cp), + UseFixed(instr->left(), r0), + FixedTemp(r4)); return MarkAsCall(DefineFixed(result, r0), instr); } -LInstruction* LChunkBuilder::DoInstanceSize(HInstanceSize* instr) { - LOperand* object = UseRegisterAtStart(instr->object()); - return DefineAsRegister(new(zone()) LInstanceSize(object)); -} - - LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) { LOperand* receiver = UseRegisterAtStart(instr->receiver()); LOperand* function = UseRegisterAtStart(instr->function()); @@ -1091,7 +1103,6 @@ LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { - ++argument_count_; LOperand* argument = Use(instr->argument()); return new(zone()) LPushArgument(argument); } @@ -1122,14 +1133,13 @@ LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) { LInstruction* LChunkBuilder::DoContext(HContext* instr) { - // If there is a non-return use, the context must be allocated in a register. - for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) { - if (!it.value()->IsReturn()) { - return DefineAsRegister(new(zone()) LContext); - } + if (instr->HasNoUses()) return NULL; + + if (info()->IsStub()) { + return DefineFixed(new(zone()) LContext, cp); } - return NULL; + return DefineAsRegister(new(zone()) LContext); } @@ -1140,7 +1150,8 @@ LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) { LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) { - return MarkAsCall(new(zone()) LDeclareGlobals, instr); + LOperand* context = UseFixed(instr->context(), cp); + return MarkAsCall(new(zone()) LDeclareGlobals(context), instr); } @@ -1158,15 +1169,14 @@ LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { LInstruction* LChunkBuilder::DoCallConstantFunction( HCallConstantFunction* instr) { - argument_count_ -= instr->argument_count(); return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, r0), instr); } LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { + LOperand* context = UseFixed(instr->context(), cp); LOperand* function = UseFixed(instr->function(), r1); - argument_count_ -= instr->argument_count(); - LInvokeFunction* result = new(zone()) LInvokeFunction(function); + LInvokeFunction* result = new(zone()) LInvokeFunction(context, function); return MarkAsCall(DefineFixed(result, r0), instr, CANNOT_DEOPTIMIZE_EAGERLY); } @@ -1206,8 +1216,12 @@ LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) { LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) { + Representation r = instr->value()->representation(); + LOperand* context = (r.IsDouble() || r.IsSmiOrInteger32()) + ? NULL + : UseFixed(instr->context(), cp); LOperand* input = UseRegister(instr->value()); - LMathAbs* result = new(zone()) LMathAbs(input); + LMathAbs* result = new(zone()) LMathAbs(context, input); return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); } @@ -1243,7 +1257,7 @@ LInstruction* LChunkBuilder::DoMathTan(HUnaryMathOperation* instr) { LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) { ASSERT(instr->representation().IsDouble()); ASSERT(instr->value()->representation().IsDouble()); - LOperand* input = UseTempRegister(instr->value()); + LOperand* input = UseRegister(instr->value()); LOperand* temp1 = TempRegister(); LOperand* temp2 = TempRegister(); LOperand* double_temp = FixedTemp(d3); // Chosen by fair dice roll. @@ -1269,57 +1283,57 @@ LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) { LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { ASSERT(instr->key()->representation().IsTagged()); - argument_count_ -= instr->argument_count(); + LOperand* context = UseFixed(instr->context(), cp); LOperand* key = UseFixed(instr->key(), r2); - return MarkAsCall(DefineFixed(new(zone()) LCallKeyed(key), r0), instr); + return MarkAsCall( + DefineFixed(new(zone()) LCallKeyed(context, key), r0), instr); } LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { - argument_count_ -= instr->argument_count(); - return MarkAsCall(DefineFixed(new(zone()) LCallNamed, r0), instr); + LOperand* context = UseFixed(instr->context(), cp); + return MarkAsCall(DefineFixed(new(zone()) LCallNamed(context), r0), instr); } LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { - argument_count_ -= instr->argument_count(); - return MarkAsCall(DefineFixed(new(zone()) LCallGlobal, r0), instr); + LOperand* context = UseFixed(instr->context(), cp); + return MarkAsCall(DefineFixed(new(zone()) LCallGlobal(context), r0), instr); } LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { - argument_count_ -= instr->argument_count(); return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, r0), instr); } LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { + LOperand* context = UseFixed(instr->context(), cp); LOperand* constructor = UseFixed(instr->constructor(), r1); - argument_count_ -= instr->argument_count(); - LCallNew* result = new(zone()) LCallNew(constructor); + LCallNew* result = new(zone()) LCallNew(context, constructor); return MarkAsCall(DefineFixed(result, r0), instr); } LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) { + LOperand* context = UseFixed(instr->context(), cp); LOperand* constructor = UseFixed(instr->constructor(), r1); - argument_count_ -= instr->argument_count(); - LCallNewArray* result = new(zone()) LCallNewArray(constructor); + LCallNewArray* result = new(zone()) LCallNewArray(context, constructor); return MarkAsCall(DefineFixed(result, r0), instr); } LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { + LOperand* context = UseFixed(instr->context(), cp); LOperand* function = UseFixed(instr->function(), r1); - argument_count_ -= instr->argument_count(); - return MarkAsCall(DefineFixed(new(zone()) LCallFunction(function), r0), - instr); + return MarkAsCall( + DefineFixed(new(zone()) LCallFunction(context, function), r0), instr); } LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { - argument_count_ -= instr->argument_count(); - return MarkAsCall(DefineFixed(new(zone()) LCallRuntime, r0), instr); + LOperand* context = UseFixed(instr->context(), cp); + return MarkAsCall(DefineFixed(new(zone()) LCallRuntime(context), r0), instr); } @@ -1347,41 +1361,34 @@ LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) { if (instr->representation().IsSmiOrInteger32()) { ASSERT(instr->left()->representation().Equals(instr->representation())); ASSERT(instr->right()->representation().Equals(instr->representation())); + ASSERT(instr->CheckFlag(HValue::kTruncatingToInt32)); LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand()); LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand()); return DefineAsRegister(new(zone()) LBitI(left, right)); } else { - ASSERT(instr->representation().IsTagged()); - ASSERT(instr->left()->representation().IsTagged()); - ASSERT(instr->right()->representation().IsTagged()); - - LOperand* left = UseFixed(instr->left(), r1); - LOperand* right = UseFixed(instr->right(), r0); - LArithmeticT* result = new(zone()) LArithmeticT(instr->op(), left, right); - return MarkAsCall(DefineFixed(result, r0), instr); + return DoArithmeticT(instr->op(), instr); } } LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { - if (instr->representation().IsDouble()) { - return DoArithmeticD(Token::DIV, instr); - } else if (instr->representation().IsSmiOrInteger32()) { + if (instr->representation().IsSmiOrInteger32()) { ASSERT(instr->left()->representation().Equals(instr->representation())); ASSERT(instr->right()->representation().Equals(instr->representation())); if (instr->HasPowerOf2Divisor()) { ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero)); LOperand* value = UseRegisterAtStart(instr->left()); - LDivI* div = - new(zone()) LDivI(value, UseOrConstant(instr->right()), NULL); - return AssignEnvironment(DefineSameAsFirst(div)); + LDivI* div = new(zone()) LDivI(value, UseConstant(instr->right()), NULL); + return AssignEnvironment(DefineAsRegister(div)); } LOperand* dividend = UseRegister(instr->left()); LOperand* divisor = UseRegister(instr->right()); LOperand* temp = CpuFeatures::IsSupported(SUDIV) ? NULL : FixedTemp(d4); LDivI* div = new(zone()) LDivI(dividend, divisor, temp); return AssignEnvironment(DefineAsRegister(div)); + } else if (instr->representation().IsDouble()) { + return DoArithmeticD(Token::DIV, instr); } else { return DoArithmeticT(Token::DIV, instr); } @@ -1502,17 +1509,10 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) { ? AssignEnvironment(result) : result; } - } else if (instr->representation().IsTagged()) { - return DoArithmeticT(Token::MOD, instr); + } else if (instr->representation().IsDouble()) { + return DoArithmeticD(Token::MOD, instr); } else { - ASSERT(instr->representation().IsDouble()); - // We call a C function for double modulo. It can't trigger a GC. We need - // to use fixed result register for the call. - // TODO(fschneider): Allow any register as input registers. - LArithmeticD* mod = new(zone()) LArithmeticD(Token::MOD, - UseFixedDouble(left, d1), - UseFixedDouble(right, d2)); - return MarkAsCall(DefineFixedDouble(mod, d1), instr); + return DoArithmeticT(Token::MOD, instr); } } @@ -1679,7 +1679,6 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) { return DoArithmeticD(Token::ADD, instr); } else { - ASSERT(instr->representation().IsTagged()); return DoArithmeticT(Token::ADD, instr); } } @@ -1737,9 +1736,10 @@ LInstruction* LChunkBuilder::DoRandom(HRandom* instr) { LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { ASSERT(instr->left()->representation().IsTagged()); ASSERT(instr->right()->representation().IsTagged()); + LOperand* context = UseFixed(instr->context(), cp); LOperand* left = UseFixed(instr->left(), r1); LOperand* right = UseFixed(instr->right(), r0); - LCmpT* result = new(zone()) LCmpT(left, right); + LCmpT* result = new(zone()) LCmpT(context, left, right); return MarkAsCall(DefineFixed(result, r0), instr); } @@ -1766,6 +1766,8 @@ LInstruction* LChunkBuilder::DoCompareNumericAndBranch( LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( HCompareObjectEqAndBranch* instr) { + LInstruction* goto_instr = CheckElideControlInstruction(instr); + if (goto_instr != NULL) return goto_instr; LOperand* left = UseRegisterAtStart(instr->left()); LOperand* right = UseRegisterAtStart(instr->right()); return new(zone()) LCmpObjectEqAndBranch(left, right); @@ -1774,8 +1776,8 @@ LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch( LInstruction* LChunkBuilder::DoCompareHoleAndBranch( HCompareHoleAndBranch* instr) { - LOperand* object = UseRegisterAtStart(instr->object()); - return new(zone()) LCmpHoleAndBranch(object); + LOperand* value = UseRegisterAtStart(instr->value()); + return new(zone()) LCmpHoleAndBranch(value); } @@ -1813,10 +1815,11 @@ LInstruction* LChunkBuilder::DoStringCompareAndBranch( HStringCompareAndBranch* instr) { ASSERT(instr->left()->representation().IsTagged()); ASSERT(instr->right()->representation().IsTagged()); + LOperand* context = UseFixed(instr->context(), cp); LOperand* left = UseFixed(instr->left(), r1); LOperand* right = UseFixed(instr->right(), r0); LStringCompareAndBranch* result = - new(zone()) LStringCompareAndBranch(left, right); + new(zone()) LStringCompareAndBranch(context, left, right); return MarkAsCall(result, instr); } @@ -1883,11 +1886,9 @@ LInstruction* LChunkBuilder::DoDateField(HDateField* instr) { LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) { LOperand* string = UseRegister(instr->string()); - LOperand* index = UseRegister(instr->index()); - LOperand* value = UseTempRegister(instr->value()); - LSeqStringSetChar* result = - new(zone()) LSeqStringSetChar(instr->encoding(), string, index, value); - return DefineAsRegister(result); + LOperand* index = UseRegisterOrConstant(instr->index()); + LOperand* value = UseRegister(instr->value()); + return new(zone()) LSeqStringSetChar(instr->encoding(), string, index, value); } @@ -1905,9 +1906,17 @@ LInstruction* LChunkBuilder::DoBoundsCheckBaseIndexInformation( } +LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { + // The control instruction marking the end of a block that completed + // abruptly (e.g., threw an exception). There is nothing specific to do. + return NULL; +} + + LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { + LOperand* context = UseFixed(instr->context(), cp); LOperand* value = UseFixed(instr->value(), r0); - return MarkAsCall(new(zone()) LThrow(value), instr); + return MarkAsCall(new(zone()) LThrow(context, value), instr); } @@ -1936,7 +1945,6 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { } if (from.IsTagged()) { if (to.IsDouble()) { - info()->MarkAsDeferredCalling(); LOperand* value = UseRegister(instr->value()); LNumberUntagD* res = new(zone()) LNumberUntagD(value); return AssignEnvironment(DefineAsRegister(res)); @@ -2006,8 +2014,9 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { } else if (to.IsSmi()) { HValue* val = instr->value(); LOperand* value = UseRegister(val); - LInstruction* result = - DefineSameAsFirst(new(zone()) LInteger32ToSmi(value)); + LInstruction* result = val->CheckFlag(HInstruction::kUint32) + ? DefineSameAsFirst(new(zone()) LUint32ToSmi(value)) + : DefineSameAsFirst(new(zone()) LInteger32ToSmi(value)); if (val->HasRange() && val->range()->IsInSmiRange()) { return result; } @@ -2040,12 +2049,6 @@ LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { } -LInstruction* LChunkBuilder::DoIsNumberAndBranch(HIsNumberAndBranch* instr) { - return new(zone()) - LIsNumberAndBranch(UseRegisterOrConstantAtStart(instr->value())); -} - - LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { LOperand* value = UseRegisterAtStart(instr->value()); LInstruction* result = new(zone()) LCheckInstanceType(value); @@ -2093,8 +2096,11 @@ LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { + LOperand* context = info()->IsStub() + ? UseFixed(instr->context(), cp) + : NULL; LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count()); - return new(zone()) LReturn(UseFixed(instr->value(), r0), + return new(zone()) LReturn(UseFixed(instr->value(), r0), context, parameter_count); } @@ -2127,8 +2133,10 @@ LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { + LOperand* context = UseFixed(instr->context(), cp); LOperand* global_object = UseFixed(instr->global_object(), r0); - LLoadGlobalGeneric* result = new(zone()) LLoadGlobalGeneric(global_object); + LLoadGlobalGeneric* result = + new(zone()) LLoadGlobalGeneric(context, global_object); return MarkAsCall(DefineFixed(result, r0), instr); } @@ -2144,10 +2152,11 @@ LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) { LInstruction* LChunkBuilder::DoStoreGlobalGeneric(HStoreGlobalGeneric* instr) { + LOperand* context = UseFixed(instr->context(), cp); LOperand* global_object = UseFixed(instr->global_object(), r1); LOperand* value = UseFixed(instr->value(), r0); LStoreGlobalGeneric* result = - new(zone()) LStoreGlobalGeneric(global_object, value); + new(zone()) LStoreGlobalGeneric(context, global_object, value); return MarkAsCall(result, instr); } @@ -2182,8 +2191,10 @@ LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { + LOperand* context = UseFixed(instr->context(), cp); LOperand* object = UseFixed(instr->object(), r0); - LInstruction* result = DefineFixed(new(zone()) LLoadNamedGeneric(object), r0); + LInstruction* result = + DefineFixed(new(zone()) LLoadNamedGeneric(context, object), r0); return MarkAsCall(result, instr); } @@ -2195,6 +2206,11 @@ LInstruction* LChunkBuilder::DoLoadFunctionPrototype( } +LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) { + return DefineAsRegister(new(zone()) LLoadRoot); +} + + LInstruction* LChunkBuilder::DoLoadExternalArrayPointer( HLoadExternalArrayPointer* instr) { LOperand* input = UseRegisterAtStart(instr->value()); @@ -2211,7 +2227,7 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { if (!instr->is_external()) { LOperand* obj = NULL; if (instr->representation().IsDouble()) { - obj = UseTempRegister(instr->elements()); + obj = UseRegister(instr->elements()); } else { ASSERT(instr->representation().IsSmiOrTagged()); obj = UseRegisterAtStart(instr->elements()); @@ -2239,18 +2255,17 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) { LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { + LOperand* context = UseFixed(instr->context(), cp); LOperand* object = UseFixed(instr->object(), r1); LOperand* key = UseFixed(instr->key(), r0); LInstruction* result = - DefineFixed(new(zone()) LLoadKeyedGeneric(object, key), r0); + DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), r0); return MarkAsCall(result, instr); } LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { - ElementsKind elements_kind = instr->elements_kind(); - if (!instr->is_external()) { ASSERT(instr->elements()->representation().IsTagged()); bool needs_write_barrier = instr->NeedsWriteBarrier(); @@ -2260,15 +2275,19 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { if (instr->value()->representation().IsDouble()) { object = UseRegisterAtStart(instr->elements()); - val = UseTempRegister(instr->value()); + val = UseRegister(instr->value()); key = UseRegisterOrConstantAtStart(instr->key()); } else { ASSERT(instr->value()->representation().IsSmiOrTagged()); - object = UseTempRegister(instr->elements()); - val = needs_write_barrier ? UseTempRegister(instr->value()) - : UseRegisterAtStart(instr->value()); - key = needs_write_barrier ? UseTempRegister(instr->key()) - : UseRegisterOrConstantAtStart(instr->key()); + if (needs_write_barrier) { + object = UseTempRegister(instr->elements()); + val = UseTempRegister(instr->value()); + key = UseTempRegister(instr->key()); + } else { + object = UseRegisterAtStart(instr->elements()); + val = UseRegisterAtStart(instr->value()); + key = UseRegisterOrConstantAtStart(instr->key()); + } } return new(zone()) LStoreKeyed(object, key, val); @@ -2276,17 +2295,13 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { ASSERT( (instr->value()->representation().IsInteger32() && - (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && - (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || + (instr->elements_kind() != EXTERNAL_FLOAT_ELEMENTS) && + (instr->elements_kind() != EXTERNAL_DOUBLE_ELEMENTS)) || (instr->value()->representation().IsDouble() && - ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || - (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); + ((instr->elements_kind() == EXTERNAL_FLOAT_ELEMENTS) || + (instr->elements_kind() == EXTERNAL_DOUBLE_ELEMENTS)))); ASSERT(instr->elements()->representation().IsExternal()); - bool val_is_temp_register = - elements_kind == EXTERNAL_PIXEL_ELEMENTS || - elements_kind == EXTERNAL_FLOAT_ELEMENTS; - LOperand* val = val_is_temp_register ? UseTempRegister(instr->value()) - : UseRegister(instr->value()); + LOperand* val = UseRegister(instr->value()); LOperand* key = UseRegisterOrConstantAtStart(instr->key()); LOperand* external_pointer = UseRegister(instr->elements()); return new(zone()) LStoreKeyed(external_pointer, key, val); @@ -2294,6 +2309,7 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { + LOperand* context = UseFixed(instr->context(), cp); LOperand* obj = UseFixed(instr->object(), r2); LOperand* key = UseFixed(instr->key(), r1); LOperand* val = UseFixed(instr->value(), r0); @@ -2302,7 +2318,8 @@ LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) { ASSERT(instr->key()->representation().IsTagged()); ASSERT(instr->value()->representation().IsTagged()); - return MarkAsCall(new(zone()) LStoreKeyedGeneric(obj, key, val), instr); + return MarkAsCall( + new(zone()) LStoreKeyedGeneric(context, obj, key, val), instr); } @@ -2312,11 +2329,12 @@ LInstruction* LChunkBuilder::DoTransitionElementsKind( if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) { LOperand* new_map_reg = TempRegister(); LTransitionElementsKind* result = - new(zone()) LTransitionElementsKind(object, new_map_reg); + new(zone()) LTransitionElementsKind(object, NULL, new_map_reg); return result; } else { + LOperand* context = UseFixed(instr->context(), cp); LTransitionElementsKind* result = - new(zone()) LTransitionElementsKind(object, NULL); + new(zone()) LTransitionElementsKind(object, context, NULL); return AssignPointerMap(result); } } @@ -2375,56 +2393,68 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { + LOperand* context = UseFixed(instr->context(), cp); LOperand* obj = UseFixed(instr->object(), r1); LOperand* val = UseFixed(instr->value(), r0); - LInstruction* result = new(zone()) LStoreNamedGeneric(obj, val); + LInstruction* result = new(zone()) LStoreNamedGeneric(context, obj, val); return MarkAsCall(result, instr); } LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { + LOperand* context = UseFixed(instr->context(), cp); LOperand* left = UseRegisterAtStart(instr->left()); LOperand* right = UseRegisterAtStart(instr->right()); - return MarkAsCall(DefineFixed(new(zone()) LStringAdd(left, right), r0), - instr); + return MarkAsCall( + DefineFixed(new(zone()) LStringAdd(context, left, right), r0), + instr); } LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { LOperand* string = UseTempRegister(instr->string()); LOperand* index = UseTempRegister(instr->index()); - LStringCharCodeAt* result = new(zone()) LStringCharCodeAt(string, index); + LOperand* context = UseAny(instr->context()); + LStringCharCodeAt* result = + new(zone()) LStringCharCodeAt(context, string, index); return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); } LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { LOperand* char_code = UseRegister(instr->value()); - LStringCharFromCode* result = new(zone()) LStringCharFromCode(char_code); + LOperand* context = UseAny(instr->context()); + LStringCharFromCode* result = + new(zone()) LStringCharFromCode(context, char_code); return AssignPointerMap(DefineAsRegister(result)); } LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) { info()->MarkAsDeferredCalling(); + LOperand* context = UseAny(instr->context()); LOperand* size = instr->size()->IsConstant() ? UseConstant(instr->size()) : UseTempRegister(instr->size()); LOperand* temp1 = TempRegister(); LOperand* temp2 = TempRegister(); - LAllocate* result = new(zone()) LAllocate(size, temp1, temp2); + LAllocate* result = new(zone()) LAllocate(context, size, temp1, temp2); return AssignPointerMap(DefineAsRegister(result)); } LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { - return MarkAsCall(DefineFixed(new(zone()) LRegExpLiteral, r0), instr); + LOperand* context = UseFixed(instr->context(), cp); + return MarkAsCall( + DefineFixed(new(zone()) LRegExpLiteral(context), r0), instr); } LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { - return MarkAsCall(DefineFixed(new(zone()) LFunctionLiteral, r0), instr); + LOperand* context = UseFixed(instr->context(), cp); + return MarkAsCall( + DefineFixed(new(zone()) LFunctionLiteral(context), r0), instr); } @@ -2471,8 +2501,8 @@ LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) { LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) { - argument_count_ -= instr->argument_count(); - return MarkAsCall(DefineFixed(new(zone()) LCallStub, r0), instr); + LOperand* context = UseFixed(instr->context(), cp); + return MarkAsCall(DefineFixed(new(zone()) LCallStub(context), r0), instr); } @@ -2517,7 +2547,8 @@ LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) { LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { - LTypeof* result = new(zone()) LTypeof(UseFixed(instr->value(), r0)); + LOperand* context = UseFixed(instr->context(), cp); + LTypeof* result = new(zone()) LTypeof(context, UseFixed(instr->value(), r0)); return MarkAsCall(DefineFixed(result, r0), instr); } @@ -2556,10 +2587,13 @@ LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { if (instr->is_function_entry()) { - return MarkAsCall(new(zone()) LStackCheck, instr); + LOperand* context = UseFixed(instr->context(), cp); + return MarkAsCall(new(zone()) LStackCheck(context), instr); } else { ASSERT(instr->is_backwards_branch()); - return AssignEnvironment(AssignPointerMap(new(zone()) LStackCheck)); + LOperand* context = UseAny(instr->context()); + return AssignEnvironment( + AssignPointerMap(new(zone()) LStackCheck(context))); } } @@ -2592,7 +2626,7 @@ LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { if (env->entry()->arguments_pushed()) { int argument_count = env->arguments_environment()->parameter_count(); pop = new(zone()) LDrop(argument_count); - argument_count_ -= argument_count; + ASSERT(instr->argument_delta() == -argument_count); } HEnvironment* outer = current_block_->last_environment()-> @@ -2604,8 +2638,9 @@ LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) { + LOperand* context = UseFixed(instr->context(), cp); LOperand* object = UseFixed(instr->enumerable(), r0); - LForInPrepareMap* result = new(zone()) LForInPrepareMap(object); + LForInPrepareMap* result = new(zone()) LForInPrepareMap(context, object); return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY); } |