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

Side by Side Diff: runtime/vm/intermediate_language_ia32.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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 5805 matching lines...) Expand 10 before | Expand all | Expand 10 after
5816 5816
5817 5817
5818 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5818 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5819 comparison()->EmitBranchCode(compiler, this); 5819 comparison()->EmitBranchCode(compiler, this);
5820 } 5820 }
5821 5821
5822 5822
5823 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone, 5823 LocationSummary* CheckClassInstr::MakeLocationSummary(Zone* zone,
5824 bool opt) const { 5824 bool opt) const {
5825 const intptr_t kNumInputs = 1; 5825 const intptr_t kNumInputs = 1;
5826 const bool need_mask_temp = IsDenseSwitch() && !IsDenseMask(ComputeCidMask()); 5826 const bool need_mask_temp = IsBitTest();
5827 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0; 5827 const intptr_t kNumTemps = !IsNullCheck() ? (need_mask_temp ? 2 : 1) : 0;
5828 LocationSummary* summary = new (zone) 5828 LocationSummary* summary = new (zone)
5829 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5829 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5830 summary->set_in(0, Location::RequiresRegister()); 5830 summary->set_in(0, Location::RequiresRegister());
5831 if (!IsNullCheck()) { 5831 if (!IsNullCheck()) {
5832 summary->set_temp(0, Location::RequiresRegister()); 5832 summary->set_temp(0, Location::RequiresRegister());
5833 if (need_mask_temp) { 5833 if (need_mask_temp) {
5834 summary->set_temp(1, Location::RequiresRegister()); 5834 summary->set_temp(1, Location::RequiresRegister());
5835 } 5835 }
5836 } 5836 }
5837 return summary; 5837 return summary;
5838 } 5838 }
5839 5839
5840 5840
5841 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5841 void CheckClassInstr::EmitNullCheck(FlowGraphCompiler* compiler, Label* deopt) {
5842 Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass, 5842 const Immediate& raw_null =
5843 licm_hoisted_ ? ICData::kHoisted : 0); 5843 Immediate(reinterpret_cast<intptr_t>(Object::null()));
5844 if (IsNullCheck()) { 5844 __ cmpl(locs()->in(0).reg(), raw_null);
5845 const Immediate& raw_null = 5845 ASSERT(IsDeoptIfNull() || IsDeoptIfNotNull());
5846 Immediate(reinterpret_cast<intptr_t>(Object::null())); 5846 Condition cond = IsDeoptIfNull() ? EQUAL : NOT_EQUAL;
5847 __ cmpl(locs()->in(0).reg(), raw_null); 5847 __ j(cond, deopt);
5848 ASSERT(DeoptIfNull() || DeoptIfNotNull()); 5848 return;
Vyacheslav Egorov (Google) 2017/05/09 21:07:28 delete return;
erikcorry 2017/05/10 08:47:43 Done.
5849 Condition cond = DeoptIfNull() ? EQUAL : NOT_EQUAL;
5850 __ j(cond, deopt);
5851 return;
5852 }
5853
5854 ASSERT((unary_checks().GetReceiverClassIdAt(0) != kSmiCid) ||
5855 (unary_checks().NumberOfChecks() > 1));
5856 Register value = locs()->in(0).reg();
5857 Register temp = locs()->temp(0).reg();
5858 Label is_ok;
5859 if (unary_checks().GetReceiverClassIdAt(0) == kSmiCid) {
5860 __ testl(value, Immediate(kSmiTagMask));
5861 __ j(ZERO, &is_ok);
5862 } else {
5863 __ testl(value, Immediate(kSmiTagMask));
5864 __ j(ZERO, deopt);
5865 }
5866 Register biased_cid = temp;
5867 __ LoadClassId(biased_cid, value);
5868
5869 GrowableArray<CidRangeTarget> sorted_ic_data;
5870 FlowGraphCompiler::SortICDataByCount(unary_checks(), &sorted_ic_data,
5871 /* drop_smi = */ true);
5872
5873 if (IsDenseSwitch()) {
5874 ASSERT(cids_[0] < cids_[cids_.length() - 1]);
5875 __ subl(biased_cid, Immediate(cids_[0]));
5876 __ cmpl(biased_cid, Immediate(cids_[cids_.length() - 1] - cids_[0]));
5877 __ j(ABOVE, deopt);
5878
5879 intptr_t mask = ComputeCidMask();
5880 if (!IsDenseMask(mask)) {
5881 // Only need mask if there are missing numbers in the range.
5882 ASSERT(cids_.length() > 2);
5883 Register mask_reg = locs()->temp(1).reg();
5884 __ movl(mask_reg, Immediate(mask));
5885 __ bt(mask_reg, biased_cid);
5886 __ j(NOT_CARRY, deopt);
5887 }
5888 } else {
5889 const intptr_t num_checks = sorted_ic_data.length();
5890 const bool use_near_jump = num_checks < 5;
5891 int bias = 0;
5892 for (intptr_t i = 0; i < num_checks; i++) {
5893 const intptr_t cid_start = sorted_ic_data[i].cid_start;
5894 const intptr_t cid_end = sorted_ic_data[i].cid_end;
5895 ASSERT(cid_start > kSmiCid || cid_end < kSmiCid);
5896 Condition no_match, match;
5897 if (cid_start == cid_end) {
5898 __ cmpl(biased_cid, Immediate(cid_start - bias));
5899 no_match = NOT_EQUAL;
5900 match = EQUAL;
5901 } else {
5902 // For class ID ranges use a subtract followed by an unsigned
5903 // comparison to check both ends of the ranges with one comparison.
5904 __ addl(biased_cid, Immediate(bias - cid_start));
5905 bias = cid_start;
5906 __ cmpl(biased_cid, Immediate(cid_end - cid_start));
5907 no_match = ABOVE;
5908 match = BELOW_EQUAL;
5909 }
5910
5911 if (i == num_checks - 1) {
5912 __ j(no_match, deopt);
5913 } else {
5914 if (use_near_jump) {
5915 __ j(match, &is_ok, Assembler::kNearJump);
5916 } else {
5917 __ j(match, &is_ok);
5918 }
5919 }
5920 }
5921 }
5922 __ Bind(&is_ok);
5923 } 5849 }
5924 5850
5925 5851
5852 void CheckClassInstr::EmitBitTest(FlowGraphCompiler* compiler,
5853 intptr_t min,
5854 intptr_t max,
5855 intptr_t mask,
5856 Label* deopt) {
5857 Register biased_cid = locs()->temp(0).reg();
5858 __ subl(biased_cid, Immediate(min));
5859 __ cmpl(biased_cid, Immediate(max - min));
5860 __ j(ABOVE, deopt);
5861
5862 Register mask_reg = locs()->temp(1).reg();
5863 __ movl(mask_reg, Immediate(mask));
5864 __ bt(mask_reg, biased_cid);
5865 __ j(NOT_CARRY, deopt);
5866 }
5867
5868
5869 int CheckClassInstr::EmitCheckCid(FlowGraphCompiler* compiler,
5870 int bias,
5871 intptr_t cid_start,
5872 intptr_t cid_end,
5873 bool is_last,
5874 Label* is_ok,
5875 Label* deopt,
5876 bool use_near_jump) {
5877 Register biased_cid = locs()->temp(0).reg();
5878 Condition no_match, match;
5879 if (cid_start == cid_end) {
5880 __ cmpl(biased_cid, Immediate(cid_start - bias));
5881 no_match = NOT_EQUAL;
5882 match = EQUAL;
5883 } else {
5884 // For class ID ranges use a subtract followed by an unsigned
5885 // comparison to check both ends of the ranges with one comparison.
5886 __ addl(biased_cid, Immediate(bias - cid_start));
5887 bias = cid_start;
5888 __ cmpl(biased_cid, Immediate(cid_end - cid_start));
5889 no_match = ABOVE;
5890 match = BELOW_EQUAL;
5891 }
5892
5893 if (is_last) {
5894 __ j(no_match, deopt);
5895 } else {
5896 if (use_near_jump) {
5897 __ j(match, is_ok, Assembler::kNearJump);
5898 } else {
5899 __ j(match, is_ok);
5900 }
5901 }
5902 return bias;
5903 }
5904
5905
5926 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone, 5906 LocationSummary* CheckSmiInstr::MakeLocationSummary(Zone* zone,
5927 bool opt) const { 5907 bool opt) const {
5928 const intptr_t kNumInputs = 1; 5908 const intptr_t kNumInputs = 1;
5929 const intptr_t kNumTemps = 0; 5909 const intptr_t kNumTemps = 0;
5930 LocationSummary* summary = new (zone) 5910 LocationSummary* summary = new (zone)
5931 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5911 LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5932 summary->set_in(0, Location::RequiresRegister()); 5912 summary->set_in(0, Location::RequiresRegister());
5933 return summary; 5913 return summary;
5934 } 5914 }
5935 5915
(...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after
6953 __ Drop(1); 6933 __ Drop(1);
6954 __ popl(result); 6934 __ popl(result);
6955 } 6935 }
6956 6936
6957 6937
6958 } // namespace dart 6938 } // namespace dart
6959 6939
6960 #undef __ 6940 #undef __
6961 6941
6962 #endif // defined TARGET_ARCH_IA32 6942 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698