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

Side by Side Diff: runtime/vm/intermediate_language_mips.cc

Issue 2856543002: Use off-heap data for class check instructions (Closed)
Patch Set: Feedback from Slava: rejig inheritance of CallTargets Created 3 years, 7 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 5045 matching lines...) Expand 10 before | Expand all | Expand 10 after
5056 5056
5057 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5057 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5058 __ Comment("BranchInstr"); 5058 __ Comment("BranchInstr");
5059 comparison()->EmitBranchCode(compiler, this); 5059 comparison()->EmitBranchCode(compiler, this);
5060 } 5060 }
5061 5061
5062 5062
5063 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone, 5063 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone,
5064 bool opt) const { 5064 bool opt) const {
5065 const intptr_t kNumInputs = 1; 5065 const intptr_t kNumInputs = 1;
5066 const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); 5066 const bool need_mask_temp = IsBitTest();
5067 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; 5067 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0;
5068 LocationSummary* summary = new (zone) 5068 LocationSummary* summary = new (zone)
5069 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5069 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5070 summary->set_in(0, Location::RequiresRegister()); 5070 summary->set_in(0, Location::RequiresRegister());
5071 if (!IsNullCheck()) { 5071 if (!IsNullCheck()) {
5072 summary->set_temp(0, Location::RequiresRegister()); 5072 summary->set_temp(0, Location::RequiresRegister());
5073 if (need_mask_temp) { 5073 if (need_mask_temp) {
5074 summary->set_temp(1, Location::RequiresRegister()); 5074 summary->set_temp(1, Location::RequiresRegister());
5075 } 5075 }
5076 } 5076 }
5077 return summary; 5077 return summary;
5078 } 5078 }
5079 5079
5080 5080
5081 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5081 void CheckClassInstr::EmitNullCheck(FlowGraphCompiler* compiler, Label* deopt) {
5082 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass, 5082 if (IsDeoptIfNull()) {
5083 licm_hoisted_ ? ICData::kHoisted : 0); 5083 __ BranchEqual(locs()->in(0).reg(), Object::null_object(), deopt);
5084 if (IsNullCheck()) { 5084 } else {
5085 if (DeoptIfNull()) { 5085 ASSERT(IsDeoptIfNotNull());
5086 __ BranchEqual(locs()->in(0).reg(), Object::null_object(), deopt); 5086 __ BranchNotEqual(locs()->in(0).reg(), Object::null_object(), deopt);
5087 } else {
5088 ASSERT(DeoptIfNotNull());
5089 __ BranchNotEqual(locs()->in(0).reg(), Object::null_object(), deopt);
5090 }
5091 return;
5092 } 5087 }
5093 5088 return;
Vyacheslav Egorov (Google) 2017/05/09 21:07:28 remove return (I guess all EmitNullCheck have this
erikcorry 2017/05/10 08:47:43 Done.
5094 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) ||
5095 (unary_checks().NumberOfChecks() > 1));
5096 Register value = locs()->in(0).reg();
5097 Register temp = locs()->temp(0).reg();
5098 Label is_ok;
5099 if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) {
5100 __ andi(CMPRES1, value, Immediate(kSmiTagMask));
5101 __ beq(CMPRES1, ZR, &is_ok);
5102 } else {
5103 __ andi(CMPRES1, value, Immediate(kSmiTagMask));
5104 __ beq(CMPRES1, ZR, deopt);
5105 }
5106 Register biased_cid = temp;
5107 __ LoadClassId(biased_cid, value);
5108
5109 GrowableArray<CidRangeTarget> sorted_ic_data;
5110 FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data,
5111 /* drop_smi = */ true);
5112
5113 if (IsDenseSwitch()) {
5114 ASSERT(cids_[0] < cids_[cids_.length() - 1]);
5115 __ LoadImmediate(TMP, cids_[0]);
5116 __ subu(biased_cid, biased_cid, TMP);
5117 __ LoadImmediate(TMP, cids_[cids_.length() - 1] - cids_[0]);
5118 __ BranchUnsignedGreater(biased_cid, TMP, deopt);
5119
5120 intptr_t mask = ComputeCidMask();
5121 if (!IsDenseMask(mask)) {
5122 // Only need mask if there are missing numbers in the range.
5123 ASSERT(cids_.length() > 2);
5124 Register mask_reg = locs()->temp(1).reg();
5125 __ LoadImmediate(mask_reg, 1);
5126 __ sllv(mask_reg, mask_reg, biased_cid);
5127 __ AndImmediate(mask_reg, mask_reg, mask);
5128 __ beq(mask_reg, ZR, deopt);
5129 }
5130 } else {
5131 const intptr_t num_checks = sorted_ic_data.length();
5132 int bias = 0;
5133 for (intptr_t i = 0; i < num_checks; i++) {
5134 const intptr_t cid_start = sorted_ic_data[i].cid_start;
5135 const intptr_t cid_end = sorted_ic_data[i].cid_end;
5136 ASSERT(cid_start > kSmiCid || cid_end < kSmiCid);
5137 if (cid_start == cid_end) {
5138 __ LoadImmediate(TMP, cid_start - bias);
5139 if (i == (num_checks - 1)) {
5140 __ bne(biased_cid, TMP, deopt);
5141 } else {
5142 __ beq(biased_cid, TMP, &is_ok);
5143 }
5144 } else {
5145 // For class ID ranges use a subtract followed by an unsigned
5146 // comparison to check both ends of the ranges with one comparison.
5147 __ AddImmediate(biased_cid, biased_cid, bias - cid_start);
5148 bias = cid_start;
5149 // TODO(erikcorry): We should use sltiu instead of the temporary TMP if
5150 // the range is small enough.
5151 __ LoadImmediate(TMP, cid_end - cid_start);
5152 // Reverse comparison so we get 1 if biased_cid > tmp ie cid is out of
5153 // range.
5154 __ sltu(TMP, TMP, biased_cid);
5155 if (i == (num_checks - 1)) {
5156 __ bne(TMP, ZR, deopt);
5157 } else {
5158 __ beq(TMP, ZR, &is_ok);
5159 }
5160 }
5161 }
5162 }
5163 __ Bind(&is_ok);
5164 } 5089 }
5165 5090
5166 5091
5092 void CheckClassInstr::EmitBitTest(FlowGraphCompiler* compiler,
5093 intptr_t min,
5094 intptr_t max,
5095 intptr_t mask,
5096 Label* deopt) {
5097 Register biased_cid = locs()->temp(0).reg();
5098 __ LoadImmediate(TMP, min);
5099 __ subu(biased_cid, biased_cid, TMP);
5100 __ LoadImmediate(TMP, max - min);
5101 __ BranchUnsignedGreater(biased_cid, TMP, deopt);
5102
5103 Register bit_reg = locs()->temp(1).reg();
5104 __ LoadImmediate(bit_reg, 1);
5105 __ sllv(bit_reg, bit_reg, biased_cid);
5106 __ AndImmediate(bit_reg, bit_reg, mask);
5107 __ beq(bit_reg, ZR, deopt);
5108 }
5109
5110
5111 int CheckClassInstr::EmitCheckCid(FlowGraphCompiler* compiler,
5112 int bias,
5113 intptr_t cid_start,
5114 intptr_t cid_end,
5115 bool is_last,
5116 Label* is_ok,
5117 Label* deopt,
5118 bool use_near_jump) {
5119 Register biased_cid = locs()->temp(0).reg();
5120 if (cid_start == cid_end) {
5121 __ LoadImmediate(TMP, cid_start - bias);
5122 if (is_last) {
5123 __ bne(biased_cid, TMP, deopt);
5124 } else {
5125 __ beq(biased_cid, TMP, is_ok);
5126 }
5127 } else {
5128 // For class ID ranges use a subtract followed by an unsigned
5129 // comparison to check both ends of the ranges with one comparison.
5130 __ AddImmediate(biased_cid, biased_cid, bias - cid_start);
5131 bias = cid_start;
5132 // TODO(erikcorry): We should use sltiu instead of the temporary TMP if
5133 // the range is small enough.
5134 __ LoadImmediate(TMP, cid_end - cid_start);
5135 // Reverse comparison so we get 1 if biased_cid > tmp ie cid is out of
5136 // range.
5137 __ sltu(TMP, TMP, biased_cid);
5138 if (is_last) {
5139 __ bne(TMP, ZR, deopt);
5140 } else {
5141 __ beq(TMP, ZR, is_ok);
5142 }
5143 }
5144 return bias;
5145 }
5146
5147
5167 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone, 5148 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone,
5168 bool opt) const { 5149 bool opt) const {
5169 const intptr_t kNumInputs = 1; 5150 const intptr_t kNumInputs = 1;
5170 const intptr_t kNumTemps = 0; 5151 const intptr_t kNumTemps = 0;
5171 LocationSummary* summary = new (zone) 5152 LocationSummary* summary = new (zone)
5172 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5153 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5173 summary->set_in(0, Location::RequiresRegister()); 5154 summary->set_in(0, Location::RequiresRegister());
5174 return summary; 5155 return summary;
5175 } 5156 }
5176 5157
(...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after
6108 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), 6089 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(),
6109 kGrowRegExpStackRuntimeEntry, 1, locs()); 6090 kGrowRegExpStackRuntimeEntry, 1, locs());
6110 __ lw(result, Address(SP, 1 * kWordSize)); 6091 __ lw(result, Address(SP, 1 * kWordSize));
6111 __ addiu(SP, SP, Immediate(2 * kWordSize)); 6092 __ addiu(SP, SP, Immediate(2 * kWordSize));
6112 } 6093 }
6113 6094
6114 6095
6115 } // namespace dart 6096 } // namespace dart
6116 6097
6117 #endif // defined TARGET_ARCH_MIPS 6098 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698