| Index: src/x64/lithium-x64.cc
|
| diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
|
| index a5b8417e957ebfd0a80d98416b9c604eb14e685a..9b9ac04222923d8947e4e6cc6e11bd8b4c636ef6 100644
|
| --- a/src/x64/lithium-x64.cc
|
| +++ b/src/x64/lithium-x64.cc
|
| @@ -353,19 +353,20 @@ void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
|
| }
|
|
|
|
|
| -int LPlatformChunk::GetNextSpillIndex(bool is_double) {
|
| +int LPlatformChunk::GetNextSpillIndex(RegisterKind kind) {
|
| return spill_slot_count_++;
|
| }
|
|
|
|
|
| -LOperand* LPlatformChunk::GetNextSpillSlot(bool is_double) {
|
| +LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) {
|
| // All stack slots are Double stack slots on x64.
|
| // Alternatively, at some point, start using half-size
|
| // stack slots for int32 values.
|
| - int index = GetNextSpillIndex(is_double);
|
| - if (is_double) {
|
| + int index = GetNextSpillIndex(kind);
|
| + if (kind == DOUBLE_REGISTERS) {
|
| return LDoubleStackSlot::Create(index, zone());
|
| } else {
|
| + ASSERT(kind == GENERAL_REGISTERS);
|
| return LStackSlot::Create(index, zone());
|
| }
|
| }
|
| @@ -445,7 +446,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);
|
| }
|
| }
|
|
|
| @@ -859,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
|
| @@ -898,7 +921,6 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) {
|
| if (FLAG_stress_environments && !instr->HasEnvironment()) {
|
| instr = AssignEnvironment(instr);
|
| }
|
| - instr->set_hydrogen_value(current);
|
| chunk_->AddInstruction(instr, current_block_);
|
| }
|
| current_instruction_ = old_current;
|
| @@ -990,7 +1012,7 @@ LEnvironment* LChunkBuilder::CreateEnvironment(
|
|
|
|
|
| LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
|
| - return new(zone()) LGoto(instr->FirstSuccessor()->block_id());
|
| + return new(zone()) LGoto(instr->FirstSuccessor());
|
| }
|
|
|
|
|
| @@ -1000,16 +1022,10 @@ LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) {
|
|
|
|
|
| LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
|
| - HValue* value = instr->value();
|
| - if (value->EmitAtUses()) {
|
| - ASSERT(value->IsConstant());
|
| - ASSERT(!value->representation().IsDouble());
|
| - 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
|
| @@ -1089,7 +1105,6 @@ LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
|
|
|
|
|
| LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
|
| - ++argument_count_;
|
| LOperand* argument = UseOrConstant(instr->argument());
|
| return new(zone()) LPushArgument(argument);
|
| }
|
| @@ -1155,14 +1170,12 @@ LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) {
|
|
|
| LInstruction* LChunkBuilder::DoCallConstantFunction(
|
| HCallConstantFunction* instr) {
|
| - argument_count_ -= instr->argument_count();
|
| return MarkAsCall(DefineFixed(new(zone()) LCallConstantFunction, rax), instr);
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
|
| LOperand* function = UseFixed(instr->function(), rdi);
|
| - argument_count_ -= instr->argument_count();
|
| LInvokeFunction* result = new(zone()) LInvokeFunction(function);
|
| return MarkAsCall(DefineFixed(result, rax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
|
| }
|
| @@ -1264,33 +1277,28 @@ LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) {
|
| LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) {
|
| ASSERT(instr->key()->representation().IsTagged());
|
| LOperand* key = UseFixed(instr->key(), rcx);
|
| - argument_count_ -= instr->argument_count();
|
| LCallKeyed* result = new(zone()) LCallKeyed(key);
|
| return MarkAsCall(DefineFixed(result, rax), instr);
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) {
|
| - argument_count_ -= instr->argument_count();
|
| return MarkAsCall(DefineFixed(new(zone()) LCallNamed, rax), instr);
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) {
|
| - argument_count_ -= instr->argument_count();
|
| return MarkAsCall(DefineFixed(new(zone()) LCallGlobal, rax), instr);
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) {
|
| - argument_count_ -= instr->argument_count();
|
| return MarkAsCall(DefineFixed(new(zone()) LCallKnownGlobal, rax), instr);
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
|
| LOperand* constructor = UseFixed(instr->constructor(), rdi);
|
| - argument_count_ -= instr->argument_count();
|
| LCallNew* result = new(zone()) LCallNew(constructor);
|
| return MarkAsCall(DefineFixed(result, rax), instr);
|
| }
|
| @@ -1298,7 +1306,6 @@ LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
|
|
|
| LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
|
| LOperand* constructor = UseFixed(instr->constructor(), rdi);
|
| - argument_count_ -= instr->argument_count();
|
| LCallNewArray* result = new(zone()) LCallNewArray(constructor);
|
| return MarkAsCall(DefineFixed(result, rax), instr);
|
| }
|
| @@ -1306,14 +1313,12 @@ LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
|
|
|
| LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
|
| LOperand* function = UseFixed(instr->function(), rdi);
|
| - argument_count_ -= instr->argument_count();
|
| LCallFunction* result = new(zone()) LCallFunction(function);
|
| return MarkAsCall(DefineFixed(result, rax), instr);
|
| }
|
|
|
|
|
| LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
|
| - argument_count_ -= instr->argument_count();
|
| return MarkAsCall(DefineFixed(new(zone()) LCallRuntime, rax), instr);
|
| }
|
|
|
| @@ -1639,6 +1644,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 = UseRegisterOrConstantAtStart(instr->right());
|
| return new(zone()) LCmpObjectEqAndBranch(left, right);
|
| @@ -2053,7 +2060,14 @@ LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
|
|
|
|
|
| LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
|
| - if (instr->access().IsExternalMemory() && instr->access().offset() == 0) {
|
| + // Use the special mov rax, moffs64 encoding for external
|
| + // memory accesses with 64-bit word-sized values.
|
| + if (instr->access().IsExternalMemory() &&
|
| + instr->access().offset() == 0 &&
|
| + (instr->access().representation().IsSmi() ||
|
| + instr->access().representation().IsTagged() ||
|
| + instr->access().representation().IsHeapObject() ||
|
| + instr->access().representation().IsExternal())) {
|
| LOperand* obj = UseRegisterOrConstantAtStart(instr->object());
|
| return DefineFixed(new(zone()) LLoadNamedField(obj), rax);
|
| }
|
| @@ -2374,7 +2388,6 @@ LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
|
|
|
|
|
| LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
|
| - argument_count_ -= instr->argument_count();
|
| return MarkAsCall(DefineFixed(new(zone()) LCallStub, rax), instr);
|
| }
|
|
|
| @@ -2496,7 +2509,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()->
|
|
|