Index: runtime/vm/intermediate_language.cc |
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc |
index 4f4032fce706c7db24ec99c1057b89e3c0d63174..efb05ca2a0b1f9acae19dd7634f8f5e95772640e 100644 |
--- a/runtime/vm/intermediate_language.cc |
+++ b/runtime/vm/intermediate_language.cc |
@@ -33,7 +33,7 @@ DEFINE_FLAG(bool, propagate_ic_data, true, |
"Propagate IC data from unoptimized to optimized IC calls."); |
DEFINE_FLAG(bool, two_args_smi_icd, true, |
"Generate special IC stubs for two args Smi operations"); |
-DEFINE_FLAG(bool, unbox_numeric_fields, true, |
+DEFINE_FLAG(bool, unbox_numeric_fields, !USING_DBC, |
"Support unboxed double and float32x4 fields."); |
DECLARE_FLAG(bool, eliminate_type_checks); |
@@ -2755,9 +2755,12 @@ LocationSummary* TargetEntryInstr::MakeLocationSummary(Zone* zone, |
void TargetEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
__ Bind(compiler->GetJumpLabel(this)); |
if (!compiler->is_optimizing()) { |
+#if !defined(TARGET_ARCH_DBC) |
if (compiler->NeedsEdgeCounter(this)) { |
compiler->EmitEdgeCounter(preorder_number()); |
} |
+#endif |
+ |
// The deoptimization descriptor points after the edge counter code for |
// uniformity with ARM and MIPS, where we can reuse pattern matching |
// code that matches backwards from the end of the pattern. |
@@ -2957,10 +2960,19 @@ LocationSummary* DropTempsInstr::MakeLocationSummary(Zone* zone, |
void DropTempsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+#if defined(TARGET_ARCH_DBC) |
+ ASSERT(!compiler->is_optimizing()); |
+ if (InputCount() != 0 && HasTemp()) { |
+ __ DropR(num_temps()); |
+ } else { |
+ __ Drop(num_temps() + ((InputCount() != 0) ? 1 : 0)); |
+ } |
+#else |
ASSERT(!compiler->is_optimizing()); |
// Assert that register assignment is correct. |
ASSERT((InputCount() == 0) || (locs()->out(0).reg() == locs()->in(0).reg())); |
__ Drop(num_temps()); |
+#endif |
} |
@@ -2985,6 +2997,7 @@ LocationSummary* InstanceCallInstr::MakeLocationSummary(Zone* zone, |
} |
+#if !defined(TARGET_ARCH_DBC) |
static const StubEntry* TwoArgsSmiOpInlineCacheEntry(Token::Kind kind) { |
if (!FLAG_two_args_smi_icd) { |
return 0; |
@@ -2996,6 +3009,7 @@ static const StubEntry* TwoArgsSmiOpInlineCacheEntry(Token::Kind kind) { |
default: return NULL; |
} |
} |
+#endif |
void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
@@ -3012,6 +3026,8 @@ void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
} else { |
call_ic_data = &ICData::ZoneHandle(zone, ic_data()->raw()); |
} |
+ |
+#if !defined(TARGET_ARCH_DBC) |
if (compiler->is_optimizing() && HasICData()) { |
ASSERT(HasICData()); |
if (ic_data()->NumberOfUsedChecks() > 0) { |
@@ -3085,6 +3101,44 @@ void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
*call_ic_data); |
} |
} |
+#else |
+ // Emit smi fast path instruction. If fast-path succeeds it skips the next |
+ // instruction otherwise it fall through. |
+ if (function_name().raw() == Symbols::Plus().raw()) { |
+ __ AddTOS(); |
+ } else if (function_name().raw() == Symbols::EqualOperator().raw()) { |
+ __ EqualTOS(); |
+ } else if (function_name().raw() == Symbols::LAngleBracket().raw()) { |
+ __ LessThanTOS(); |
+ } else if (function_name().raw() == Symbols::RAngleBracket().raw()) { |
+ __ GreaterThanTOS(); |
+ } else if (function_name().raw() == Symbols::BitAnd().raw()) { |
+ __ BitAndTOS(); |
+ } else if (function_name().raw() == Symbols::BitOr().raw()) { |
+ __ BitOrTOS(); |
+ } else if (function_name().raw() == Symbols::Star().raw()) { |
+ __ MulTOS(); |
+ } |
+ |
+ const intptr_t call_ic_data_kidx = __ AddConstant(*call_ic_data); |
+ switch (call_ic_data->NumArgsTested()) { |
+ case 1: |
+ __ InstanceCall(ArgumentCount(), call_ic_data_kidx); |
+ break; |
+ case 2: |
+ __ InstanceCall2(ArgumentCount(), call_ic_data_kidx); |
+ break; |
+ case 3: |
+ __ InstanceCall3(ArgumentCount(), call_ic_data_kidx); |
+ break; |
+ default: |
+ UNIMPLEMENTED(); |
+ break; |
+ } |
+ compiler->AddCurrentDescriptor(RawPcDescriptors::kIcCall, |
+ deopt_id(), |
+ token_pos()); |
+#endif // !defined(TARGET_ARCH_DBC) |
} |
@@ -3107,6 +3161,8 @@ bool PolymorphicInstanceCallInstr::HasOnlyDispatcherTargets() const { |
return true; |
} |
+ |
+#if !defined(TARGET_ARCH_DBC) |
void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
ASSERT(ic_data().NumArgsTested() == 1); |
if (!with_checks()) { |
@@ -3129,6 +3185,7 @@ void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
instance_call()->token_pos(), |
locs()); |
} |
+#endif |
LocationSummary* StaticCallInstr::MakeLocationSummary(Zone* zone, |
@@ -3138,6 +3195,7 @@ LocationSummary* StaticCallInstr::MakeLocationSummary(Zone* zone, |
void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+#if !defined(TARGET_ARCH_DBC) |
const ICData* call_ic_data = NULL; |
if (!FLAG_propagate_ic_data || !compiler->is_optimizing() || |
(ic_data() == NULL)) { |
@@ -3170,6 +3228,20 @@ void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
argument_names(), |
locs(), |
*call_ic_data); |
+#else |
+ const Array& arguments_descriptor = |
+ (ic_data() == NULL) ? |
+ Array::Handle(ArgumentsDescriptor::New(ArgumentCount(), |
+ argument_names())) : |
+ Array::Handle(ic_data()->arguments_descriptor()); |
+ const intptr_t argdesc_kidx = __ AddConstant(arguments_descriptor); |
+ |
+ __ PushConstant(function()); |
+ __ StaticCall(ArgumentCount(), argdesc_kidx); |
+ compiler->AddCurrentDescriptor(RawPcDescriptors::kUnoptStaticCall, |
+ deopt_id(), |
+ token_pos()); |
+#endif // !defined(TARGET_ARCH_DBC) |
} |
@@ -3179,7 +3251,9 @@ void AssertAssignableInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
dst_type(), |
dst_name(), |
locs()); |
+#if !defined(TARGET_ARCH_DBC) |
ASSERT(locs()->in(0).reg() == locs()->out(0).reg()); |
+#endif |
} |
@@ -3290,11 +3364,6 @@ void Environment::DeepCopyToOuter(Zone* zone, Instruction* instr) const { |
} |
-static bool BindsToSmiConstant(Value* value) { |
- return value->BindsToConstant() && value->BoundConstant().IsSmi(); |
-} |
- |
- |
ComparisonInstr* EqualityCompareInstr::CopyWithNewOperands(Value* new_left, |
Value* new_right) { |
return new EqualityCompareInstr(token_pos(), |
@@ -3362,9 +3431,17 @@ bool TestCidsInstr::AttributesEqual(Instruction* other) const { |
} |
+#if !defined(TARGET_ARCH_DBC) |
+static bool BindsToSmiConstant(Value* value) { |
+ return value->BindsToConstant() && value->BoundConstant().IsSmi(); |
+} |
+#endif |
+ |
+ |
bool IfThenElseInstr::Supports(ComparisonInstr* comparison, |
Value* v1, |
Value* v2) { |
+#if !defined(TARGET_ARCH_DBC) |
bool is_smi_result = BindsToSmiConstant(v1) && BindsToSmiConstant(v2); |
if (comparison->IsStrictCompare()) { |
// Strict comparison with number checks calls a stub and is not supported |
@@ -3377,6 +3454,9 @@ bool IfThenElseInstr::Supports(ComparisonInstr* comparison, |
return false; |
} |
return is_smi_result; |
+#else |
+ return false; |
+#endif // !defined(TARGET_ARCH_DBC) |
} |