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

Side by Side Diff: runtime/vm/intermediate_language_arm64.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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
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 5463 matching lines...) Expand 10 before | Expand all | Expand 10 after
5474 5474
5475 5475
5476 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5476 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5477 comparison()->EmitBranchCode(compiler, this); 5477 comparison()->EmitBranchCode(compiler, this);
5478 } 5478 }
5479 5479
5480 5480
5481 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone, 5481 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone,
5482 bool opt) const { 5482 bool opt) const {
5483 const intptr_t kNumInputs = 1; 5483 const intptr_t kNumInputs = 1;
5484 const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); 5484 const bool need_mask_temp = IsBitTest();
5485 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; 5485 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0;
5486 LocationSummary* summary = new (zone) 5486 LocationSummary* summary = new (zone)
5487 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5487 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5488 summary->set_in(0, Location::RequiresRegister()); 5488 summary->set_in(0, Location::RequiresRegister());
5489 if (!IsNullCheck()) { 5489 if (!IsNullCheck()) {
5490 summary->set_temp(0, Location::RequiresRegister()); 5490 summary->set_temp(0, Location::RequiresRegister());
5491 if (need_mask_temp) { 5491 if (need_mask_temp) {
5492 summary->set_temp(1, Location::RequiresRegister()); 5492 summary->set_temp(1, Location::RequiresRegister());
5493 } 5493 }
5494 } 5494 }
5495 return summary; 5495 return summary;
5496 } 5496 }
5497 5497
5498 5498
5499 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5499 void CheckClassInstr::EmitNullCheck(FlowGraphCompiler* compiler, Label* deopt) {
5500 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass, 5500 __ CompareObject(locs()->in(0).reg(), Object::null_object());
5501 licm_hoisted_ ? ICData::kHoisted : 0); 5501 ASSERT(IsDeoptIfNull() || IsDeoptIfNotNull());
5502 if (IsNullCheck()) { 5502 Condition cond = IsDeoptIfNull() ? EQ : NE;
5503 __ CompareObject(locs()->in(0).reg(), Object::null_object()); 5503 __ b(deopt, cond);
5504 ASSERT(DeoptIfNull() || DeoptIfNotNull()); 5504 return;
Vyacheslav Egorov (Google) 2017/05/09 21:07:27 any reason for implicit return?
erikcorry 2017/05/10 08:47:43 Gone
5505 Condition cond = DeoptIfNull() ? EQ : NE;
5506 __ b(deopt, cond);
5507 return;
5508 }
5509
5510 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) ||
5511 (unary_checks().NumberOfChecks() > 1));
5512 const Register value = locs()->in(0).reg();
5513 const Register temp = locs()->temp(0).reg();
5514 Label is_ok;
5515 if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) {
5516 __ tsti(value, Immediate(kSmiTagMask));
5517 __ b(&is_ok, EQ);
5518 } else {
5519 __ tsti(value, Immediate(kSmiTagMask));
5520 __ b(deopt, EQ);
5521 }
5522 Register biased_cid = temp;
5523 __ LoadClassId(biased_cid, value);
5524
5525 GrowableArray<CidRangeTarget> sorted_ic_data;
5526 FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data,
5527 /* drop_smi = */ true);
5528
5529 if (IsDenseSwitch()) {
5530 ASSERT(cids_[0] < cids_[cids_.length() - 1]);
5531 __ AddImmediate(biased_cid, biased_cid, -cids_[0]);
5532 __ CompareImmediate(biased_cid, cids_[cids_.length() - 1] - cids_[0]);
5533 __ b(deopt, HI);
5534
5535 intptr_t mask = ComputeCidMask();
5536 if (!IsDenseMask(mask)) {
5537 // Only need mask if there are missing numbers in the range.
5538 ASSERT(cids_.length() > 2);
5539 Register mask_reg = locs()->temp(1).reg();
5540 __ LoadImmediate(mask_reg, 1);
5541 __ lslv(mask_reg, mask_reg, biased_cid);
5542 __ TestImmediate(mask_reg, mask);
5543 __ b(deopt, EQ);
5544 }
5545
5546 } else {
5547 const intptr_t num_checks = sorted_ic_data.length();
5548 int bias = 0;
5549 for (intptr_t i = 0; i < num_checks; i++) {
5550 const intptr_t cid_start = sorted_ic_data[i].cid_start;
5551 const intptr_t cid_end = sorted_ic_data[i].cid_end;
5552 ASSERT(cid_start > kSmiCid || cid_end < kSmiCid);
5553 Condition no_match, match;
5554 if (cid_start == cid_end) {
5555 __ CompareImmediate(biased_cid, cid_start - bias);
5556 no_match = NE;
5557 match = EQ;
5558 } else {
5559 // For class ID ranges use a subtract followed by an unsigned
5560 // comparison to check both ends of the ranges with one comparison.
5561 __ AddImmediate(biased_cid, biased_cid, bias - cid_start);
5562 bias = cid_start;
5563 __ CompareImmediate(biased_cid, cid_end - cid_start);
5564 no_match = HI; // Unsigned higher.
5565 match = LS; // Unsigned lower or same.
5566 }
5567 if (i == (num_checks - 1)) {
5568 __ b(deopt, no_match);
5569 } else {
5570 __ b(&is_ok, match);
5571 }
5572 }
5573 }
5574 __ Bind(&is_ok);
5575 } 5505 }
5576 5506
5577 5507
5508 void CheckClassInstr::EmitBitTest(FlowGraphCompiler* compiler,
5509 intptr_t min,
5510 intptr_t max,
5511 intptr_t mask,
5512 Label* deopt) {
5513 Register biased_cid = locs()->temp(0).reg();
5514 __ AddImmediate(biased_cid, biased_cid, -min);
5515 __ CompareImmediate(biased_cid, max - min);
5516 __ b(deopt, HI);
5517
5518 Register bit_reg = locs()->temp(1).reg();
5519 __ LoadImmediate(bit_reg, 1);
5520 __ lslv(bit_reg, bit_reg, biased_cid);
5521 __ TestImmediate(bit_reg, mask);
5522 __ b(deopt, EQ);
5523 }
5524
5525
5526 int CheckClassInstr::EmitCheckCid(FlowGraphCompiler* compiler,
5527 int bias,
5528 intptr_t cid_start,
5529 intptr_t cid_end,
5530 bool is_last,
5531 Label* is_ok,
5532 Label* deopt,
5533 bool use_near_jump) {
5534 Register biased_cid = locs()->temp(0).reg();
5535 Condition no_match, match;
5536 if (cid_start == cid_end) {
5537 __ CompareImmediate(biased_cid, cid_start - bias);
5538 no_match = NE;
5539 match = EQ;
5540 } else {
5541 // For class ID ranges use a subtract followed by an unsigned
5542 // comparison to check both ends of the ranges with one comparison.
5543 __ AddImmediate(biased_cid, biased_cid, bias - cid_start);
5544 bias = cid_start;
5545 __ CompareImmediate(biased_cid, cid_end - cid_start);
5546 no_match = HI; // Unsigned higher.
5547 match = LS; // Unsigned lower or same.
5548 }
5549 if (is_last) {
5550 __ b(deopt, no_match);
5551 } else {
5552 __ b(is_ok, match);
5553 }
5554 return bias;
5555 }
5556
5557
5578 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Zone* zone, 5558 LocationSummary* CheckClassIdInstr::MakeLocationSummary(Zone* zone,
5579 bool opt) const { 5559 bool opt) const {
5580 const intptr_t kNumInputs = 1; 5560 const intptr_t kNumInputs = 1;
5581 const intptr_t kNumTemps = 0; 5561 const intptr_t kNumTemps = 0;
5582 LocationSummary* summary = new (zone) 5562 LocationSummary* summary = new (zone)
5583 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5563 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5584 summary->set_in(0, Location::RequiresRegister()); 5564 summary->set_in(0, Location::RequiresRegister());
5585 return summary; 5565 return summary;
5586 } 5566 }
5587 5567
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
6112 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(), 6092 compiler->GenerateRuntimeCall(TokenPosition::kNoSource, deopt_id(),
6113 kGrowRegExpStackRuntimeEntry, 1, locs()); 6093 kGrowRegExpStackRuntimeEntry, 1, locs());
6114 __ Drop(1); 6094 __ Drop(1);
6115 __ Pop(result); 6095 __ Pop(result);
6116 } 6096 }
6117 6097
6118 6098
6119 } // namespace dart 6099 } // namespace dart
6120 6100
6121 #endif // defined TARGET_ARCH_ARM64 6101 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698