Index: runtime/vm/intermediate_language_x64.cc |
=================================================================== |
--- runtime/vm/intermediate_language_x64.cc (revision 10885) |
+++ runtime/vm/intermediate_language_x64.cc (working copy) |
@@ -2143,6 +2143,47 @@ |
EmitBranchOnCondition(compiler, branch_condition); |
} |
+ |
+LocationSummary* CheckClassComp::MakeLocationSummary() const { |
+ const intptr_t kNumInputs = 1; |
+ const intptr_t kNumTemps = 1; |
+ LocationSummary* summary = |
+ new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
+ summary->set_in(0, Location::RequiresRegister()); |
+ summary->set_temp(0, Location::RequiresRegister()); |
+ return summary; |
+} |
+ |
+ |
+void CheckClassComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+ Register value = locs()->in(0).reg(); |
+ Register temp = locs()->temp(0).reg(); |
+ Label* deopt = compiler->AddDeoptStub(deopt_id(), |
+ try_index(), |
+ kDeoptCheckClass, |
+ value); |
+ ASSERT(ic_data()->GetReceiverClassIdAt(0) != kSmiCid); |
+ __ testq(value, Immediate(kSmiTagMask)); |
+ __ j(ZERO, deopt); |
+ __ LoadClassId(temp, value); |
+ Label is_ok; |
+ const intptr_t num_checks = ic_data()->NumberOfChecks(); |
+ const bool use_near_jump = num_checks < 5; |
+ for (intptr_t i = 0; i < num_checks; i++) { |
+ __ cmpl(temp, Immediate(ic_data()->GetReceiverClassIdAt(i))); |
+ if (i == (num_checks - 1)) { |
+ __ j(NOT_EQUAL, deopt); |
+ } else { |
+ if (use_near_jump) { |
+ __ j(EQUAL, &is_ok, Assembler::kNearJump); |
+ } else { |
+ __ j(EQUAL, &is_ok); |
+ } |
+ } |
+ } |
+ __ Bind(&is_ok); |
+} |
+ |
} // namespace dart |
#undef __ |