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

Side by Side Diff: runtime/vm/intermediate_language_arm.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 1
2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 2 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
3 // for details. All rights reserved. Use of this source code is governed by a 3 // for details. All rights reserved. Use of this source code is governed by a
4 // BSD-style license that can be found in the LICENSE file. 4 // BSD-style license that can be found in the LICENSE file.
5 5
6 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. 6 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
7 #if defined(TARGET_ARCH_ARM) 7 #if defined(TARGET_ARCH_ARM)
8 8
9 #include "vm/intermediate_language.h" 9 #include "vm/intermediate_language.h"
10 10
(...skipping 6287 matching lines...) Expand 10 before | Expand all | Expand 10 after
6298 6298
6299 6299
6300 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6300 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
6301 comparison()->EmitBranchCode(compiler, this); 6301 comparison()->EmitBranchCode(compiler, this);
6302 } 6302 }
6303 6303
6304 6304
6305 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone, 6305 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone,
6306 bool opt) const { 6306 bool opt) const {
6307 const intptr_t kNumInputs = 1; 6307 const intptr_t kNumInputs = 1;
6308 const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); 6308 const bool need_mask_temp = IsBitTest();
6309 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; 6309 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0;
6310 LocationSummary* summary = new (zone) 6310 LocationSummary* summary = new (zone)
6311 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 6311 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6312 summary->set_in(0, Location::RequiresRegister()); 6312 summary->set_in(0, Location::RequiresRegister());
6313 if (!IsNullCheck()) { 6313 if (!IsNullCheck()) {
6314 summary->set_temp(0, Location::RequiresRegister()); 6314 summary->set_temp(0, Location::RequiresRegister());
6315 if (need_mask_temp) { 6315 if (need_mask_temp) {
6316 summary->set_temp(1, Location::RequiresRegister()); 6316 summary->set_temp(1, Location::RequiresRegister());
6317 } 6317 }
6318 } 6318 }
6319 return summary; 6319 return summary;
6320 } 6320 }
6321 6321
6322 6322
6323 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 6323 void CheckClassInstr::EmitNullCheck(FlowGraphCompiler* compiler, Label* deopt) {
6324 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass, 6324 __ CompareObject(locs()->in(0).reg(), Object::null_object());
6325 licm_hoisted_ ? ICData::kHoisted : 0); 6325 ASSERT(IsDeoptIfNull() || IsDeoptIfNotNull());
6326 if (IsNullCheck()) { 6326 Condition cond = IsDeoptIfNull() ? EQ : NE;
6327 __ CompareObject(locs()->in(0).reg(), Object::null_object()); 6327 __ b(deopt, cond);
6328 ASSERT(DeoptIfNull() || DeoptIfNotNull()); 6328 return;
6329 Condition cond = DeoptIfNull() ? EQ : NE;
6330 __ b(deopt, cond);
6331 return;
6332 }
6333
6334 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) ||
6335 (unary_checks().NumberOfChecks() > 1));
6336 const Register value = locs()->in(0).reg();
6337 const Register temp = locs()->temp(0).reg();
6338 Label is_ok;
6339 if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) {
6340 __ tst(value, Operand(kSmiTagMask));
6341 __ b(&is_ok, EQ);
6342 } else {
6343 __ tst(value, Operand(kSmiTagMask));
6344 __ b(deopt, EQ);
6345 }
6346 Register biased_cid = temp;
6347 __ LoadClassId(biased_cid, value);
6348
6349 GrowableArray<CidRangeTarget> sorted_ic_data;
6350 FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data,
6351 /* drop_smi = */ true);
6352
6353 if (IsDenseSwitch()) {
6354 ASSERT(cids_[0] < cids_[cids_.length() - 1]);
6355 __ AddImmediate(biased_cid, -cids_[0]);
6356 __ CompareImmediate(biased_cid, cids_[cids_.length() - 1] - cids_[0]);
6357 __ b(deopt, HI);
6358
6359 intptr_t mask = ComputeCidMask();
6360 if (!IsDenseMask(mask)) {
6361 // Only need mask if there are missing numbers in the range.
6362 ASSERT(cids_.length() > 2);
6363 Register mask_reg = locs()->temp(1).reg();
6364 __ LoadImmediate(mask_reg, 1);
6365 __ Lsl(mask_reg, mask_reg, biased_cid);
6366 __ TestImmediate(mask_reg, mask);
6367 __ b(deopt, EQ);
6368 }
6369 } else {
6370 const intptr_t num_checks = sorted_ic_data.length();
6371 int bias = 0;
6372 for (intptr_t i = 0; i < num_checks; i++) {
6373 const intptr_t cid_start = sorted_ic_data[i].cid_start;
6374 const intptr_t cid_end = sorted_ic_data[i].cid_end;
6375 ASSERT(cid_start > kSmiCid || cid_end < kSmiCid);
6376 Condition no_match, match;
6377 if (cid_start == cid_end) {
6378 __ CompareImmediate(biased_cid, cid_start - bias);
6379 no_match = NE;
6380 match = EQ;
6381 } else {
6382 // For class ID ranges use a subtract followed by an unsigned
6383 // comparison to check both ends of the ranges with one comparison.
6384 __ AddImmediate(biased_cid, biased_cid, bias - cid_start);
6385 bias = cid_start;
6386 __ CompareImmediate(biased_cid, cid_end - cid_start);
6387 no_match = HI; // Unsigned higher.
6388 match = LS; // Unsigned lower or same.
6389 }
6390 if (i == (num_checks - 1)) {
6391 __ b(deopt, no_match);
6392 } else {
6393 __ b(&is_ok, match);
6394 }
6395 }
6396 }
6397 __ Bind(&is_ok);
6398 } 6329 }
6399 6330
6400 6331
6332 void CheckClassInstr::EmitBitTest(FlowGraphCompiler* compiler,
6333 intptr_t min,
6334 intptr_t max,
6335 intptr_t mask,
6336 Label* deopt) {
6337 Register biased_cid = locs()->temp(0).reg();
6338 __ AddImmediate(biased_cid, -min);
6339 __ CompareImmediate(biased_cid, max - min);
6340 __ b(deopt, HI);
6341
6342 Register bit_reg = locs()->temp(1).reg();
6343 __ LoadImmediate(bit_reg, 1);
6344 __ Lsl(bit_reg, bit_reg, biased_cid);
6345 __ TestImmediate(bit_reg, mask);
6346 __ b(deopt, EQ);
6347 }
6348
6349
6350 int CheckClassInstr::EmitCheckCid(FlowGraphCompiler* compiler,
6351 int bias,
6352 intptr_t cid_start,
6353 intptr_t cid_end,
6354 bool is_last,
6355 Label* is_ok,
6356 Label* deopt,
6357 bool use_near_jump) {
6358 Register biased_cid = locs()->temp(0).reg();
6359 Condition no_match, match;
6360 if (cid_start == cid_end) {
6361 __ CompareImmediate(biased_cid, cid_start - bias);
6362 no_match = NE;
6363 match = EQ;
6364 } else {
6365 // For class ID ranges use a subtract followed by an unsigned
6366 // comparison to check both ends of the ranges with one comparison.
6367 __ AddImmediate(biased_cid, biased_cid, bias - cid_start);
6368 bias = cid_start;
6369 __ CompareImmediate(biased_cid, cid_end - cid_start);
6370 no_match = HI; // Unsigned higher.
6371 match = LS; // Unsigned lower or same.
6372 }
6373 if (is_last) {
6374 __ b(deopt, no_match);
6375 } else {
6376 __ b(is_ok, match);
6377 }
6378 return bias;
6379 }
6380
6381
6401 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone, 6382 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone,
6402 bool opt) const { 6383 bool opt) const {
6403 const intptr_t kNumInputs = 1; 6384 const intptr_t kNumInputs = 1;
6404 const intptr_t kNumTemps = 0; 6385 const intptr_t kNumTemps = 0;
6405 LocationSummary* summary = new (zone) 6386 LocationSummary* summary = new (zone)
6406 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 6387 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
6407 summary->set_in(0, Location::RequiresRegister()); 6388 summary->set_in(0, Location::RequiresRegister());
6408 return summary; 6389 return summary;
6409 } 6390 }
6410 6391
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after
7289 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), 7270 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(),
7290 kGrowRegExpStackRuntimeEntry, 1, locs()); 7271 kGrowRegExpStackRuntimeEntry, 1, locs());
7291 __ Drop(1); 7272 __ Drop(1);
7292 __ Pop(result); 7273 __ Pop(result);
7293 } 7274 }
7294 7275
7295 7276
7296 } // namespace dart 7277 } // namespace dart
7297 7278
7298 #endif // defined TARGET_ARCH_ARM 7279 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698