Chromium Code Reviews| Index: runtime/vm/intermediate_language_x64.cc |
| diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc |
| index b44d8a033f91bd3b4c552c2dfdd2dda6549c9931..b56000a2845ae7aae0d8bc80c66d828314f5e424 100644 |
| --- a/runtime/vm/intermediate_language_x64.cc |
| +++ b/runtime/vm/intermediate_language_x64.cc |
| @@ -28,7 +28,7 @@ void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| // with branches. Currrently IR does not provide an easy way to remove |
| // instructions from the graph so we just leave fused comparison in it |
| // but change its result location to be NoLocation. |
| - __ pushq(locs()->out().reg()); |
| + compiler->frame_register_allocator()->Push(locs()->out().reg(), this); |
| } |
| } |
| @@ -105,7 +105,7 @@ void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| // Generic summary for call instructions that have all arguments pushed |
| // on the stack and return the result in a fixed register RAX. |
| LocationSummary* Computation::MakeCallSummary() { |
| - LocationSummary* result = new LocationSummary(0, 0); |
| + LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); |
| result->set_out(Location::RegisterLocation(RAX)); |
| return result; |
| } |
| @@ -114,7 +114,9 @@ LocationSummary* Computation::MakeCallSummary() { |
| LocationSummary* ClosureCallComp::MakeLocationSummary() const { |
| const intptr_t kNumInputs = 0; |
| const intptr_t kNumTemps = 1; |
| - LocationSummary* result = new LocationSummary(kNumInputs, kNumTemps); |
| + LocationSummary* result = new LocationSummary(kNumInputs, |
| + kNumTemps, |
| + LocationSummary::kCall); |
| result->set_out(Location::RegisterLocation(RAX)); |
| result->set_temp(0, Location::RegisterLocation(R10)); // Arg. descriptor. |
| return result; |
| @@ -198,10 +200,17 @@ void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| LocationSummary* EqualityCompareComp::MakeLocationSummary() const { |
| + const LocationSummary::ContainsBranch contains_branch = |
| + is_fused_with_branch() ? LocationSummary::kBranch |
| + : LocationSummary::kNoBranch; |
| + |
| const intptr_t kNumInputs = 2; |
| if ((NumTargets() == 1) && (ClassIdAt(0) == kSmi)) { |
| const intptr_t kNumTemps = 1; |
| - LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| + LocationSummary* locs = new LocationSummary(kNumInputs, |
| + kNumTemps, |
| + LocationSummary::kNoCall, |
| + contains_branch); |
| locs->set_in(0, Location::RequiresRegister()); |
| locs->set_in(1, Location::RequiresRegister()); |
| locs->set_temp(0, Location::RequiresRegister()); |
| @@ -212,7 +221,10 @@ LocationSummary* EqualityCompareComp::MakeLocationSummary() const { |
| } |
| if (NumTargets() > 0) { |
| const intptr_t kNumTemps = 1; |
| - LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| + LocationSummary* locs = new LocationSummary(kNumInputs, |
| + kNumTemps, |
| + LocationSummary::kCall, |
| + contains_branch); |
| locs->set_in(0, Location::RequiresRegister()); |
| locs->set_in(1, Location::RequiresRegister()); |
| locs->set_temp(0, Location::RequiresRegister()); |
| @@ -222,7 +234,10 @@ LocationSummary* EqualityCompareComp::MakeLocationSummary() const { |
| return locs; |
| } |
| const intptr_t kNumTemps = 0; |
| - LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| + LocationSummary* locs = new LocationSummary(kNumInputs, |
| + kNumTemps, |
| + LocationSummary::kCall, |
| + contains_branch); |
| locs->set_in(0, Location::RequiresRegister()); |
| locs->set_in(1, Location::RequiresRegister()); |
| if (!is_fused_with_branch()) { |
| @@ -413,10 +428,17 @@ void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| LocationSummary* RelationalOpComp::MakeLocationSummary() const { |
| + const LocationSummary::ContainsBranch contains_branch = |
| + is_fused_with_branch() ? LocationSummary::kBranch |
| + : LocationSummary::kNoBranch; |
| + |
| if (operands_class_id() == kSmi || operands_class_id() == kDouble) { |
| const intptr_t kNumInputs = 2; |
| const intptr_t kNumTemps = 1; |
| - LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| + LocationSummary* summary = new LocationSummary(kNumInputs, |
| + kNumTemps, |
| + LocationSummary::kCall, |
| + contains_branch); |
| summary->set_in(0, Location::RequiresRegister()); |
| summary->set_in(1, Location::RequiresRegister()); |
| if (!is_fused_with_branch()) { |
| @@ -560,7 +582,11 @@ void RelationalOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| LocationSummary* NativeCallComp::MakeLocationSummary() const { |
| - LocationSummary* locs = new LocationSummary(0, 3); |
| + const intptr_t kNumInputs = 0; |
| + const intptr_t kNumTemps = 3; |
| + LocationSummary* locs = new LocationSummary(kNumInputs, |
| + kNumTemps, |
| + LocationSummary::kCall); |
| locs->set_temp(0, Location::RegisterLocation(RAX)); |
| locs->set_temp(1, Location::RegisterLocation(RBX)); |
| locs->set_temp(2, Location::RegisterLocation(R10)); |
| @@ -779,23 +805,14 @@ void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| LocationSummary* InstanceSetterComp::MakeLocationSummary() const { |
| - const intptr_t kNumInputs = 2; |
| - return LocationSummary::Make(kNumInputs, Location::NoLocation()); |
| - return NULL; |
| + return MakeCallSummary(); |
| } |
| void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| - Register receiver = locs()->in(0).reg(); |
| - Register value = locs()->in(1).reg(); |
| - |
| - // Preserve the value (second argument) under the arguments as the result |
| - // of the computation, then call the setter. |
| const String& function_name = |
| String::ZoneHandle(Field::SetterSymbol(field_name())); |
| - __ pushq(receiver); |
| - __ pushq(value); |
| compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| cid(), |
| token_index(), |
| @@ -911,7 +928,9 @@ LocationSummary* CreateArrayComp::MakeLocationSummary() const { |
| // ArgumentCount getter and an ArgumentAt getter. |
| const intptr_t kNumInputs = 1; |
| const intptr_t kNumTemps = 1; |
| - LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| + LocationSummary* locs = new LocationSummary(kNumInputs, |
| + kNumTemps, |
| + LocationSummary::kCall); |
| locs->set_in(0, Location::RegisterLocation(RBX)); |
| locs->set_temp(0, Location::RegisterLocation(R10)); |
| locs->set_out(Location::RegisterLocation(RAX)); |
| @@ -943,7 +962,9 @@ void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| LocationSummary* AllocateObjectWithBoundsCheckComp:: |
| MakeLocationSummary() const { |
| - return LocationSummary::Make(2, Location::RequiresRegister()); |
| + return LocationSummary::Make(2, |
| + Location::RequiresRegister(), |
| + LocationSummary::kCall); |
| } |
| @@ -999,7 +1020,9 @@ void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { |
| const intptr_t kNumInputs = 1; |
| const intptr_t kNumTemps = 0; |
| - LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| + LocationSummary* locs = new LocationSummary(kNumInputs, |
| + kNumTemps, |
| + LocationSummary::kCall); |
| locs->set_in(0, Location::RequiresRegister()); |
| locs->set_out(Location::SameAsFirstInput()); |
| return locs; |
| @@ -1178,7 +1201,9 @@ void ExtractConstructorInstantiatorComp::EmitNativeCode( |
| LocationSummary* AllocateContextComp::MakeLocationSummary() const { |
| const intptr_t kNumInputs = 0; |
| const intptr_t kNumTemps = 1; |
| - LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps); |
| + LocationSummary* locs = new LocationSummary(kNumInputs, |
| + kNumTemps, |
| + LocationSummary::kCall); |
| locs->set_temp(0, Location::RegisterLocation(R10)); |
| locs->set_out(Location::RegisterLocation(RAX)); |
| return locs; |
| @@ -1199,7 +1224,9 @@ void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| LocationSummary* CloneContextComp::MakeLocationSummary() const { |
| - return LocationSummary::Make(1, Location::RequiresRegister()); |
| + return LocationSummary::Make(1, |
| + Location::RequiresRegister(), |
| + LocationSummary::kCall); |
| } |
| @@ -1246,7 +1273,10 @@ void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| LocationSummary* CheckStackOverflowComp::MakeLocationSummary() const { |
| const intptr_t kNumInputs = 0; |
| const intptr_t kNumTemps = 1; |
| - LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| + // TODO(vegorov): spilling is required only on infrequently executed path. |
|
srdjan
2012/06/18 16:33:20
A quick fix could be to use the deoptimization stu
Vyacheslav Egorov (Google)
2012/06/18 17:51:16
Yes, I agree.
In V8 we have a generic "deferred
|
| + LocationSummary* summary = new LocationSummary(kNumInputs, |
| + kNumTemps, |
| + LocationSummary::kCall); |
| summary->set_temp(0, Location::RequiresRegister()); |
| return summary; |
| } |
| @@ -1271,13 +1301,7 @@ LocationSummary* BinaryOpComp::MakeLocationSummary() const { |
| const intptr_t kNumInputs = 2; |
| if (operands_type() == kDoubleOperands) { |
| - const intptr_t kNumTemps = 1; |
| - LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| - summary->set_in(0, Location::RequiresRegister()); |
| - summary->set_in(1, Location::RequiresRegister()); |
| - summary->set_out(Location::RegisterLocation(RAX)); |
| - summary->set_temp(0, Location::RequiresRegister()); |
| - return summary; |
| + return MakeCallSummary(); // Calls into a stub for allocation. |
| } |
| ASSERT(operands_type() == kSmiOperands); |
| @@ -1456,17 +1480,15 @@ static void EmitSmiBinaryOp(FlowGraphCompiler* compiler, BinaryOpComp* comp) { |
| static void EmitDoubleBinaryOp(FlowGraphCompiler* compiler, |
| BinaryOpComp* comp) { |
| - Register left = comp->locs()->in(0).reg(); |
| - Register right = comp->locs()->in(1).reg(); |
| - Register temp = comp->locs()->temp(0).reg(); |
| + Register left = RBX; |
| + Register right = RCX; |
| + Register temp = RDX; |
| Register result = comp->locs()->out().reg(); |
| const Class& double_class = compiler->double_class(); |
| const Code& stub = |
| Code::Handle(StubCode::GetAllocationStubForClass(double_class)); |
| const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| - __ pushq(left); |
| - __ pushq(right); |
| compiler->GenerateCall(comp->instance_call()->token_index(), |
| comp->instance_call()->try_index(), |
| &label, |
| @@ -1566,7 +1588,9 @@ void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| LocationSummary* NumberNegateComp::MakeLocationSummary() const { |
| const intptr_t kNumInputs = 1; |
| const intptr_t kNumTemps = 1; // Needed for doubles. |
| - LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps); |
| + LocationSummary* summary = new LocationSummary(kNumInputs, |
| + kNumTemps, |
| + LocationSummary::kCall); |
| summary->set_in(0, Location::RequiresRegister()); |
| summary->set_out(Location::SameAsFirstInput()); |
| summary->set_temp(0, Location::RequiresRegister()); |
| @@ -1632,13 +1656,13 @@ LocationSummary* ToDoubleComp::MakeLocationSummary() const { |
| return locs; |
| } else { |
| ASSERT(from() == kSmi); |
| - return LocationSummary::Make(kNumInputs, Location::RegisterLocation(RAX)); |
| + return MakeCallSummary(); |
| } |
| } |
| void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| - Register value = locs()->in(0).reg(); |
| + Register value = (from() == kDouble) ? locs()->in(0).reg() : RBX; |
| Register result = locs()->out().reg(); |
| const DeoptReasonId deopt_reason = (from() == kDouble) ? |
| @@ -1666,7 +1690,6 @@ void ToDoubleComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| const ExternalLabel label(double_class.ToCString(), stub.EntryPoint()); |
| // TODO(vegorov): allocate box in the driver loop to avoid pushing and poping. |
| - __ pushq(value); |
| compiler->GenerateCall(instance_call()->token_index(), |
| instance_call()->try_index(), |
| &label, |