Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Unified Diff: runtime/vm/intermediate_language_x64.cc

Issue 10651008: Minimize differences between ia32 and x64 sources to facilitate maintenance. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/intermediate_language_x64.cc
===================================================================
--- runtime/vm/intermediate_language_x64.cc (revision 9010)
+++ runtime/vm/intermediate_language_x64.cc (working copy)
@@ -21,6 +21,15 @@
DECLARE_FLAG(int, optimization_counter_threshold);
DECLARE_FLAG(bool, trace_functions);
+// 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::kCall);
+ result->set_out(Location::RegisterLocation(RAX));
+ return result;
+}
+
+
void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
computation()->EmitNativeCode(compiler);
if (locs()->out().kind() == Location::kRegister) {
@@ -70,10 +79,10 @@
}
}
if (FLAG_trace_functions) {
- __ pushq(result); // Preserve result.
const Function& function =
Function::ZoneHandle(compiler->parsed_function().function().raw());
__ LoadObject(temp, function);
+ __ pushq(result); // Preserve result.
__ pushq(temp);
compiler->GenerateCallRuntime(AstNode::kNoId,
0,
@@ -87,6 +96,7 @@
// Generate 8 bytes of NOPs so that the debugger can patch the
// return pattern with a call to the debug stub.
+ // Note that the nop(8) byte pattern is not recognized by the debugger.
__ nop(1);
__ nop(1);
__ nop(1);
@@ -102,15 +112,6 @@
}
-// 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::kCall);
- result->set_out(Location::RegisterLocation(RAX));
- return result;
-}
-
-
LocationSummary* ClosureCallComp::MakeLocationSummary() const {
const intptr_t kNumInputs = 0;
const intptr_t kNumTemps = 1;
@@ -388,10 +389,10 @@
// type by type check (either === or static call to the operator.
static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler,
EqualityCompareComp* comp) {
- const Immediate raw_null =
- Immediate(reinterpret_cast<intptr_t>(Object::null()));
Register left = comp->locs()->in(0).reg();
Register right = comp->locs()->in(1).reg();
+ const Immediate raw_null =
+ Immediate(reinterpret_cast<intptr_t>(Object::null()));
Label done, non_null_compare;
__ cmpq(left, raw_null);
__ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump);
@@ -549,7 +550,7 @@
} else {
Register result = comp->locs()->out().reg();
Label is_false, is_true, done;
- __ j(PARITY_EVEN, &is_false, Assembler::kNearJump);
+ __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false;
__ j(true_condition, &is_true, Assembler::kNearJump);
__ Bind(&is_false);
__ LoadObject(result, compiler->bool_false());
@@ -642,7 +643,8 @@
locs->set_temp(0, Location::RequiresRegister());
locs->set_out(Location::RequiresRegister());
return locs;
- } else if (receiver_type() == kArray || receiver_type() == kImmutableArray) {
+ } else if ((receiver_type() == kArray) ||
+ (receiver_type() == kImmutableArray)) {
return LocationSummary::Make(kNumInputs, Location::RequiresRegister());
} else {
ASSERT(receiver_type() == kIllegalObjectKind);
@@ -685,7 +687,6 @@
}
-
void LoadIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) {
if (receiver_type() == kIllegalObjectKind) {
if (HasICData()) {
@@ -769,7 +770,6 @@
}
-
static void EmitStoreIndexedGeneric(FlowGraphCompiler* compiler,
StoreIndexedComp* comp) {
const String& function_name =
@@ -787,7 +787,7 @@
comp->try_index(),
function_name,
kNumArguments,
- Array::ZoneHandle(), // No names arguments.
+ Array::ZoneHandle(), // No named arguments.
kNumArgsChecked);
}
@@ -840,10 +840,6 @@
Register index = locs()->in(1).reg();
Register value = locs()->in(2).reg();
- const Class& receiver_class =
- Class::ZoneHandle(Isolate::Current()->class_table()->At(
- receiver_type()));
-
Label* deopt = compiler->AddDeoptStub(cid(),
token_index(),
try_index(),
@@ -854,7 +850,7 @@
__ testq(receiver, Immediate(kSmiTagMask)); // Deoptimize if Smi.
__ j(ZERO, deopt);
- __ CompareClassId(receiver, receiver_class.id());
+ __ CompareClassId(receiver, receiver_type());
__ j(NOT_EQUAL, deopt);
__ testq(index, Immediate(kSmiTagMask));
@@ -1032,7 +1028,7 @@
Register temp_reg = locs()->temp(0).reg();
Register result_reg = locs()->out().reg();
- // 1. Allocate the array. R10 = length, RBX = element type.
+ // Allocate the array. R10 = length, RBX = element type.
ASSERT(temp_reg == R10);
ASSERT(locs()->in(0).reg() == RBX);
__ movq(temp_reg, Immediate(Smi::RawValue(ElementCount())));
@@ -1041,7 +1037,8 @@
&StubCode::AllocateArrayLabel(),
PcDescriptors::kOther);
ASSERT(result_reg == RAX);
- // 2. Initialize the array in result_reg with the element values.
+
+ // Pop the element values from the stack into the array.
__ leaq(temp_reg, FieldAddress(result_reg, Array::data_offset()));
for (int i = ElementCount() - 1; i >= 0; --i) {
ASSERT(ElementAt(i)->IsUse());
@@ -1050,8 +1047,8 @@
}
-LocationSummary* AllocateObjectWithBoundsCheckComp::
- MakeLocationSummary() const {
+LocationSummary*
+ AllocateObjectWithBoundsCheckComp::MakeLocationSummary() const {
return LocationSummary::Make(2,
Location::RequiresRegister(),
LocationSummary::kCall);
@@ -1140,12 +1137,12 @@
}
// Instantiate non-null type arguments.
if (type_arguments().IsUninstantiatedIdentity()) {
- Label type_arguments_uninstantiated;
// Check if the instantiator type argument vector is a TypeArguments of a
// matching length and, if so, use it as the instantiated type_arguments.
// No need to check the instantiator ('instantiator_reg') for null here,
// because a null instantiator will have the wrong class (Null instead of
// TypeArguments).
+ Label type_arguments_uninstantiated;
__ CompareClassId(instantiator_reg, kTypeArguments);
__ j(NOT_EQUAL, &type_arguments_uninstantiated, Assembler::kNearJump);
__ cmpq(FieldAddress(instantiator_reg, TypeArguments::length_offset()),
@@ -1169,8 +1166,8 @@
}
-LocationSummary* ExtractConstructorTypeArgumentsComp::
- MakeLocationSummary() const {
+LocationSummary*
+ ExtractConstructorTypeArgumentsComp::MakeLocationSummary() const {
const intptr_t kNumInputs = 1;
const intptr_t kNumTemps = 0;
LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
@@ -1224,8 +1221,8 @@
}
-LocationSummary* ExtractConstructorInstantiatorComp::
- MakeLocationSummary() const {
+LocationSummary*
+ ExtractConstructorInstantiatorComp::MakeLocationSummary() const {
const intptr_t kNumInputs = 1;
const intptr_t kNumTemps = 0;
LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
@@ -1303,6 +1300,7 @@
void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT(locs()->temp(0).reg() == R10);
+ ASSERT(locs()->out().reg() == RAX);
__ movq(R10, Immediate(num_context_variables()));
const ExternalLabel label("alloc_context",
@@ -1428,9 +1426,11 @@
summary->set_temp(0, Location::RequiresRegister());
return summary;
} else if (op_kind() == Token::kSHL) {
+ // Two Smi operands can easily overflow into Mint.
const intptr_t kNumTemps = 2;
- LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
- summary->set_in(0, Location::RequiresRegister());
+ LocationSummary* summary =
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
+ summary->set_in(0, Location::RegisterLocation(RAX));
summary->set_in(1, Location::RequiresRegister());
summary->set_out(Location::SameAsFirstInput());
summary->set_temp(0, Location::RequiresRegister());
@@ -1460,6 +1460,8 @@
kDeoptSmiBinaryOp,
temp,
right);
+ // TODO(vegorov): for many binary operations this pattern can be rearranged
+ // to save one move.
__ movq(temp, left);
__ orq(left, right);
__ testq(left, Immediate(kSmiTagMask));
@@ -1538,10 +1540,11 @@
break;
}
case Token::kSHL: {
+ Label call_method, done;
// Check if count too large for handling it inlined.
__ cmpq(right,
Immediate(reinterpret_cast<int64_t>(Smi::New(Smi::kBits))));
- __ j(ABOVE_EQUAL, deopt);
+ __ j(ABOVE_EQUAL, &call_method, Assembler::kNearJump);
Register right_temp = comp->locs()->temp(1).reg();
ASSERT(right_temp == RCX); // Count must be in RCX
__ movq(right_temp, right);
@@ -1550,9 +1553,27 @@
__ shlq(left, right_temp);
__ sarq(left, right_temp);
__ cmpq(left, temp);
- __ j(NOT_EQUAL, deopt); // Overflow.
+ __ j(NOT_EQUAL, &call_method, Assembler::kNearJump); // Overflow.
// Shift for result now we know there is no overflow.
__ shlq(left, right_temp);
+ __ jmp(&done);
+ {
+ __ Bind(&call_method);
+ Function& target = Function::ZoneHandle(
+ comp->ic_data()->GetTargetForReceiverClassId(kSmi));
+ ASSERT(!target.IsNull());
+ const intptr_t kArgumentCount = 2;
+ __ pushq(temp);
+ __ pushq(right);
+ compiler->GenerateStaticCall(comp->instance_call()->cid(),
+ comp->instance_call()->token_index(),
+ comp->instance_call()->try_index(),
+ target,
+ kArgumentCount,
+ Array::Handle()); // No argument names.
+ ASSERT(result == RAX);
+ }
+ __ Bind(&done);
break;
}
case Token::kDIV: {
@@ -1853,7 +1874,7 @@
return locs;
} else {
ASSERT(from() == kSmi);
- return MakeCallSummary();
+ return MakeCallSummary(); // Calls a stub to allocate result.
}
}
@@ -1886,7 +1907,7 @@
Code::Handle(StubCode::GetAllocationStubForClass(double_class));
const ExternalLabel label(double_class.ToCString(), stub.EntryPoint());
- // TODO(vegorov): allocate box in the driver loop to avoid pushing and poping.
+ // TODO(vegorov): allocate box in the driver loop to avoid spilling.
compiler->GenerateCall(instance_call()->token_index(),
instance_call()->try_index(),
&label,
@@ -1922,6 +1943,7 @@
Label handle_smi;
Label* is_smi_label =
ic_data()->GetReceiverClassIdAt(0) == kSmi ? &handle_smi : deopt;
+
// Load receiver into RAX.
__ movq(RAX,
Address(RSP, (instance_call()->ArgumentCount() - 1) * kWordSize));
« runtime/vm/intermediate_language_ia32.cc ('K') | « runtime/vm/intermediate_language_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698