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, |