Index: runtime/vm/intermediate_language_dbc.cc |
diff --git a/runtime/vm/intermediate_language_dbc.cc b/runtime/vm/intermediate_language_dbc.cc |
index d28bbb2c30aff544c47e1e37ad46739edb5d8879..624109c75162901c42aae6502dc36b9b28604ac0 100644 |
--- a/runtime/vm/intermediate_language_dbc.cc |
+++ b/runtime/vm/intermediate_language_dbc.cc |
@@ -105,7 +105,6 @@ DECLARE_FLAG(int, optimization_counter_threshold); |
M(UnboxInteger32) \ |
M(CheckedSmiOp) \ |
M(CheckArrayBound) \ |
- M(CheckClass) \ |
M(TestSmi) \ |
M(RelationalOp) \ |
M(EqualityCompare) \ |
@@ -481,6 +480,13 @@ void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
EMIT_NATIVE_CODE(Goto, 0) { |
+ if (!compiler->is_optimizing()) { |
+ // Add a deoptimization descriptor for deoptimizing instructions that |
+ // may be inserted before this instruction. |
+ compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, |
+ GetDeoptId(), |
+ TokenPosition::kNoSource); |
+ } |
if (HasParallelMove()) { |
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); |
} |
@@ -945,6 +951,52 @@ EMIT_NATIVE_CODE(CheckClassId, 1) { |
} |
+EMIT_NATIVE_CODE(CheckClass, 1) { |
+ const Register value = locs()->in(0).reg(); |
+ if (IsNullCheck()) { |
+ ASSERT(DeoptIfNull() || DeoptIfNotNull()); |
+ if (DeoptIfNull()) { |
+ __ IfEqNull(value); |
+ } else { |
+ __ IfNeNull(value); |
+ } |
+ } else { |
+ ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) || |
+ (unary_checks().NumberOfChecks() > 1)); |
+ const intptr_t may_be_smi = |
+ (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) ? 1 : 0; |
+ if (IsDenseSwitch()) { |
+ ASSERT(cids_[0] < cids_[cids_.length() - 1]); |
+ __ CheckDenseSwitch(value, may_be_smi); |
+ __ Nop(__ AddConstant(Smi::Handle(Smi::New(cids_[0])))); |
+ __ Nop(__ AddConstant(Smi::Handle(Smi::New(ComputeCidMask())))); |
+ } else { |
+ GrowableArray<CidTarget> sorted_ic_data; |
+ FlowGraphCompiler::SortICDataByCount(unary_checks(), |
+ &sorted_ic_data, |
+ /* drop_smi = */ true); |
+ ASSERT(sorted_ic_data.length() >= 1); |
+ if (sorted_ic_data.length() == 1) { |
+ __ CheckCid(value, may_be_smi); |
+ __ Nop(__ AddConstant(Smi::Handle(Smi::New(sorted_ic_data[0].cid)))); |
+ } else { |
+ const Array& sorted_smi_cids = |
+ Array::Handle(Array::New(sorted_ic_data.length(), Heap::kOld)); |
+ for (intptr_t i = 0; i < sorted_ic_data.length(); i++) { |
+ sorted_smi_cids.SetAt(i, |
+ Smi::Handle(Smi::New(sorted_ic_data[i].cid))); |
+ } |
+ __ CheckCids(value, may_be_smi); |
+ __ Nop(__ AddConstant(sorted_smi_cids)); |
Vyacheslav Egorov (Google)
2016/06/29 17:11:06
I suggest just embedding them into the code instea
zra
2016/06/29 22:19:18
Done.
|
+ } |
+ } |
+ } |
+ compiler->EmitDeopt(deopt_id(), |
+ ICData::kDeoptCheckClass, |
Vyacheslav Egorov (Google)
2016/06/29 17:11:06
indentation
zra
2016/06/29 22:19:17
Done.
|
+ licm_hoisted_ ? ICData::kHoisted : 0); |
+} |
+ |
+ |
EMIT_NATIVE_CODE(BinarySmiOp, 2, Location::RequiresRegister()) { |
const Register left = locs()->in(0).reg(); |
const Register right = locs()->in(1).reg(); |
@@ -998,7 +1050,7 @@ EMIT_NATIVE_CODE(BinarySmiOp, 2, Location::RequiresRegister()) { |
if (can_deopt) { |
compiler->EmitDeopt(deopt_id(), ICData::kDeoptBinarySmiOp); |
} else if (needs_nop) { |
- __ Nop(); |
+ __ Nop(0); |
} |
} |