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

Side by Side Diff: runtime/vm/intermediate_language_x64.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_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
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 5789 matching lines...) Expand 10 before | Expand all | Expand 10 after
5800 5800
5801 5801
5802 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5802 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5803 comparison()->EmitBranchCode(compiler, this); 5803 comparison()->EmitBranchCode(compiler, this);
5804 } 5804 }
5805 5805
5806 5806
5807 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone, 5807 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone,
5808 bool opt) const { 5808 bool opt) const {
5809 const intptr_t kNumInputs = 1; 5809 const intptr_t kNumInputs = 1;
5810 const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); 5810 const bool need_mask_temp = IsBitTest();
5811 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; 5811 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0;
5812 LocationSummary* summary = new (zone) 5812 LocationSummary* summary = new (zone)
5813 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5813 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5814 summary->set_in(0, Location::RequiresRegister()); 5814 summary->set_in(0, Location::RequiresRegister());
5815 if (!IsNullCheck()) { 5815 if (!IsNullCheck()) {
5816 summary->set_temp(0, Location::RequiresRegister()); 5816 summary->set_temp(0, Location::RequiresRegister());
5817 if (need_mask_temp) { 5817 if (need_mask_temp) {
5818 summary->set_temp(1, Location::RequiresRegister()); 5818 summary->set_temp(1, Location::RequiresRegister());
5819 } 5819 }
5820 } 5820 }
5821 return summary; 5821 return summary;
5822 } 5822 }
5823 5823
5824 5824
5825 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5825 void CheckClassInstr::EmitNullCheck(FlowGraphCompiler* compiler, Label* deopt) {
5826 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass, 5826 __ CompareObject(locs()->in(0).reg(), Object::null_object());
5827 licm_hoisted_ ? ICData::kHoisted : 0); 5827 Condition cond = IsDeoptIfNull() ? EQUAL : NOT_EQUAL;
5828 if (IsNullCheck()) { 5828 __ j(cond, deopt);
5829 __ CompareObject(locs()->in(0).reg(), Object::null_object()); 5829 return;
Vyacheslav Egorov (Google) 2017/05/09 21:07:28 ditto
erikcorry 2017/05/10 08:47:43 Done.
5830 Condition cond = DeoptIfNull() ? EQUAL : NOT_EQUAL;
5831 __ j(cond, deopt);
5832 return;
5833 }
5834
5835 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) ||
5836 (unary_checks().NumberOfChecks() > 1));
5837 Register value = locs()->in(0).reg();
5838 Register temp = locs()->temp(0).reg();
5839 Label is_ok;
5840 if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) {
5841 __ testq(value, Immediate(kSmiTagMask));
5842 __ j(ZERO, &is_ok);
5843 } else {
5844 __ testq(value, Immediate(kSmiTagMask));
5845 __ j(ZERO, deopt);
5846 }
5847 __ LoadClassId(temp, value);
5848
5849 GrowableArray<CidRangeTarget> sorted_ic_data;
5850 FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data,
5851 /* drop_smi = */ true);
5852
5853 if (IsDenseSwitch()) {
5854 ASSERT(cids_[0] < cids_[cids_.length() - 1]);
5855 __ subq(temp, Immediate(cids_[0]));
5856 __ cmpq(temp, Immediate(cids_[cids_.length() - 1] - cids_[0]));
5857 __ j(ABOVE, deopt);
5858
5859 intptr_t mask = ComputeCidMask();
5860 if (!IsDenseMask(mask)) {
5861 // Only need mask if there are missing numbers in the range.
5862 ASSERT(cids_.length() > 2);
5863 Register mask_reg = locs()->temp(1).reg();
5864 __ movq(mask_reg, Immediate(mask));
5865 __ btq(mask_reg, temp);
5866 __ j(NOT_CARRY, deopt);
5867 }
5868 } else {
5869 const intptr_t num_checks = sorted_ic_data.length();
5870 const bool use_near_jump = num_checks < 5;
5871 int bias = 0;
5872 for (intptr_t i = 0; i < num_checks; i++) {
5873 const intptr_t cid_start = sorted_ic_data[i].cid_start;
5874 const intptr_t cid_end = sorted_ic_data[i].cid_end;
5875 ASSERT(cid_start > kSmiCid || cid_end < kSmiCid);
5876 Condition no_match, match;
5877 if (cid_start == cid_end) {
5878 __ cmpl(temp, Immediate(cid_start - bias));
5879 no_match = NOT_EQUAL;
5880 match = EQUAL;
5881 } else {
5882 // For class ID ranges use a subtract followed by an unsigned
5883 // comparison to check both ends of the ranges with one comparison.
5884 __ addl(temp, Immediate(bias - cid_start));
5885 bias = cid_start;
5886 __ cmpl(temp, Immediate(cid_end - cid_start));
5887 no_match = ABOVE;
5888 match = BELOW_EQUAL;
5889 }
5890
5891 if (i == num_checks - 1) {
5892 __ j(no_match, deopt);
5893 } else {
5894 if (use_near_jump) {
5895 __ j(match, &is_ok, Assembler::kNearJump);
5896 } else {
5897 __ j(match, &is_ok);
5898 }
5899 }
5900 }
5901 }
5902 __ Bind(&is_ok);
5903 } 5830 }
5904 5831
5905 5832
5833 void CheckClassInstr::EmitBitTest(FlowGraphCompiler* compiler,
5834 intptr_t min,
5835 intptr_t max,
5836 intptr_t mask,
5837 Label* deopt) {
5838 Register biased_cid = locs()->temp(0).reg();
5839 __ subq(biased_cid, Immediate(min));
5840 __ cmpq(biased_cid, Immediate(max - min));
5841 __ j(ABOVE, deopt);
5842
5843 Register mask_reg = locs()->temp(1).reg();
5844 __ movq(mask_reg, Immediate(mask));
5845 __ btq(mask_reg, biased_cid);
5846 __ j(NOT_CARRY, deopt);
5847 }
5848
5849
5850 int CheckClassInstr::EmitCheckCid(FlowGraphCompiler* compiler,
5851 int bias,
5852 intptr_t cid_start,
5853 intptr_t cid_end,
5854 bool is_last,
5855 Label* is_ok,
5856 Label* deopt,
5857 bool use_near_jump) {
5858 Register biased_cid = locs()->temp(0).reg();
5859 Condition no_match, match;
5860 if (cid_start == cid_end) {
5861 __ cmpl(biased_cid, Immediate(cid_start - bias));
5862 no_match = NOT_EQUAL;
5863 match = EQUAL;
5864 } else {
5865 // For class ID ranges use a subtract followed by an unsigned
5866 // comparison to check both ends of the ranges with one comparison.
5867 __ addl(biased_cid, Immediate(bias - cid_start));
5868 bias = cid_start;
5869 __ cmpl(biased_cid, Immediate(cid_end - cid_start));
5870 no_match = ABOVE;
5871 match = BELOW_EQUAL;
5872 }
5873
5874 if (is_last) {
5875 __ j(no_match, deopt);
5876 } else {
5877 if (use_near_jump) {
5878 __ j(match, is_ok, Assembler::kNearJump);
5879 } else {
5880 __ j(match, is_ok);
5881 }
5882 }
5883 return bias;
5884 }
5885
5886
5906 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone, 5887 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone,
5907 bool opt) const { 5888 bool opt) const {
5908 const intptr_t kNumInputs = 1; 5889 const intptr_t kNumInputs = 1;
5909 const intptr_t kNumTemps = 0; 5890 const intptr_t kNumTemps = 0;
5910 LocationSummary* summary = new (zone) 5891 LocationSummary* summary = new (zone)
5911 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5892 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5912 summary->set_in(0, Location::RequiresRegister()); 5893 summary->set_in(0, Location::RequiresRegister());
5913 return summary; 5894 return summary;
5914 } 5895 }
5915 5896
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after
6810 __ Drop(1); 6791 __ Drop(1);
6811 __ popq(result); 6792 __ popq(result);
6812 } 6793 }
6813 6794
6814 6795
6815 } // namespace dart 6796 } // namespace dart
6816 6797
6817 #undef __ 6798 #undef __
6818 6799
6819 #endif // defined TARGET_ARCH_X64 6800 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698