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

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

Issue 10594002: More ICData cleanups: try to use ICData instead of converting it to another intermediate representa… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 "lib/error.h" 10 #include "lib/error.h"
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 ASSERT(obj == result); 189 ASSERT(obj == result);
190 } 190 }
191 191
192 192
193 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { 193 LocationSummary* EqualityCompareComp::MakeLocationSummary() const {
194 const LocationSummary::ContainsBranch contains_branch = 194 const LocationSummary::ContainsBranch contains_branch =
195 is_fused_with_branch() ? LocationSummary::kBranch 195 is_fused_with_branch() ? LocationSummary::kBranch
196 : LocationSummary::kNoBranch; 196 : LocationSummary::kNoBranch;
197 197
198 const intptr_t kNumInputs = 2; 198 const intptr_t kNumInputs = 2;
199 if ((NumTargets() == 1) && (ClassIdAt(0) == kSmi)) { 199 if (HasICData() &&
200 (ic_data()->NumberOfChecks() == 1) &&
201 (ic_data()->GetReceiverClassIdAt(0) == kSmi)) {
200 const intptr_t kNumTemps = 1; 202 const intptr_t kNumTemps = 1;
201 LocationSummary* locs = new LocationSummary(kNumInputs, 203 LocationSummary* locs = new LocationSummary(kNumInputs,
202 kNumTemps, 204 kNumTemps,
203 LocationSummary::kNoCall, 205 LocationSummary::kNoCall,
204 contains_branch); 206 contains_branch);
205 locs->set_in(0, Location::RequiresRegister()); 207 locs->set_in(0, Location::RequiresRegister());
206 locs->set_in(1, Location::RequiresRegister()); 208 locs->set_in(1, Location::RequiresRegister());
207 locs->set_temp(0, Location::RequiresRegister()); 209 locs->set_temp(0, Location::RequiresRegister());
208 if (!is_fused_with_branch()) { 210 if (!is_fused_with_branch()) {
209 locs->set_out(Location::RequiresRegister()); 211 locs->set_out(Location::RequiresRegister());
210 } 212 }
211 return locs; 213 return locs;
212 } 214 }
213 if (NumTargets() > 0) { 215 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
214 const intptr_t kNumTemps = 1; 216 const intptr_t kNumTemps = 1;
215 LocationSummary* locs = new LocationSummary(kNumInputs, 217 LocationSummary* locs = new LocationSummary(kNumInputs,
216 kNumTemps, 218 kNumTemps,
217 LocationSummary::kCall, 219 LocationSummary::kCall,
218 contains_branch); 220 contains_branch);
219 locs->set_in(0, Location::RequiresRegister()); 221 locs->set_in(0, Location::RequiresRegister());
220 locs->set_in(1, Location::RequiresRegister()); 222 locs->set_in(1, Location::RequiresRegister());
221 locs->set_temp(0, Location::RequiresRegister()); 223 locs->set_temp(0, Location::RequiresRegister());
222 if (!is_fused_with_branch()) { 224 if (!is_fused_with_branch()) {
223 locs->set_out(Location::RegisterLocation(EAX)); 225 locs->set_out(Location::RegisterLocation(EAX));
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 __ CompareObject(EAX, compiler->bool_true()); 296 __ CompareObject(EAX, compiler->bool_true());
295 comp->fused_with_branch()->EmitBranchOnCondition(compiler, EQUAL); 297 comp->fused_with_branch()->EmitBranchOnCondition(compiler, EQUAL);
296 } 298 }
297 } 299 }
298 300
299 301
300 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, 302 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler,
301 EqualityCompareComp* comp, 303 EqualityCompareComp* comp,
302 Register left, 304 Register left,
303 Register right) { 305 Register right) {
304 ASSERT(comp->NumTargets() > 0); 306 ASSERT(comp->HasICData());
307 const ICData& ic_data = *comp->ic_data();
308 ASSERT(ic_data.NumberOfChecks() > 0);
305 Label* deopt = compiler->AddDeoptStub(comp->cid(), 309 Label* deopt = compiler->AddDeoptStub(comp->cid(),
306 comp->token_index(), 310 comp->token_index(),
307 comp->try_index(), 311 comp->try_index(),
308 kDeoptEquality); 312 kDeoptEquality);
309 __ testl(left, Immediate(kSmiTagMask)); 313 __ testl(left, Immediate(kSmiTagMask));
310 Register temp = comp->locs()->temp(0).reg(); 314 Register temp = comp->locs()->temp(0).reg();
311 if (comp->ClassIdAt(0) == kSmi) { 315 if (ic_data.GetReceiverClassIdAt(0) == kSmi) {
312 Label done, load_class_id; 316 Label done, load_class_id;
313 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump); 317 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump);
314 __ movl(temp, Immediate(kSmi)); 318 __ movl(temp, Immediate(kSmi));
315 __ jmp(&done, Assembler::kNearJump); 319 __ jmp(&done, Assembler::kNearJump);
316 __ Bind(&load_class_id); 320 __ Bind(&load_class_id);
317 __ LoadClassId(temp, left); 321 __ LoadClassId(temp, left);
318 __ Bind(&done); 322 __ Bind(&done);
319 } else { 323 } else {
320 __ j(ZERO, deopt); // Smi deopts. 324 __ j(ZERO, deopt); // Smi deopts.
321 __ LoadClassId(temp, left); 325 __ LoadClassId(temp, left);
322 } 326 }
323 Label done; 327 Label done;
324 for (intptr_t i = 0; i < comp->NumTargets(); i++) { 328 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
325 ASSERT((comp->ClassIdAt(i) != kSmi) || (i == 0)); 329 ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmi) || (i == 0));
326 Label next_test; 330 Label next_test;
327 __ cmpl(temp, Immediate(comp->ClassIdAt(i))); 331 __ cmpl(temp, Immediate(ic_data.GetReceiverClassIdAt(i)));
328 __ j(NOT_EQUAL, &next_test, Assembler::kNearJump); 332 __ j(NOT_EQUAL, &next_test, Assembler::kNearJump);
329 const Function& target = *comp->TargetAt(i); 333 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i));
330 ObjectStore* object_store = Isolate::Current()->object_store(); 334 ObjectStore* object_store = Isolate::Current()->object_store();
331 if (target.owner() == object_store->object_class()) { 335 if (target.owner() == object_store->object_class()) {
332 // Object.== is same as ===. 336 // Object.== is same as ===.
333 __ Drop(2); 337 __ Drop(2);
334 __ cmpl(left, right); 338 __ cmpl(left, right);
335 if (comp->is_fused_with_branch()) { 339 if (comp->is_fused_with_branch()) {
336 comp->fused_with_branch()->EmitBranchOnCondition(compiler, EQUAL); 340 comp->fused_with_branch()->EmitBranchOnCondition(compiler, EQUAL);
337 } else { 341 } else {
338 // This case should be rare. 342 // This case should be rare.
339 Register result = comp->locs()->out().reg(); 343 Register result = comp->locs()->out().reg();
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 __ LoadObject(result, compiler->bool_false()); 396 __ LoadObject(result, compiler->bool_false());
393 __ jmp(&done); 397 __ jmp(&done);
394 __ Bind(&load_true); 398 __ Bind(&load_true);
395 __ LoadObject(result, compiler->bool_true()); 399 __ LoadObject(result, compiler->bool_true());
396 } 400 }
397 __ jmp(&done); 401 __ jmp(&done);
398 402
399 __ Bind(&non_null_compare); // Receiver is not null. 403 __ Bind(&non_null_compare); // Receiver is not null.
400 __ pushl(left); 404 __ pushl(left);
401 __ pushl(right); 405 __ pushl(right);
402 if (comp->NumTargets() > 0) { 406 if (comp->HasICData() && (comp->ic_data()->NumberOfChecks() > 0)) {
403 EmitEqualityAsPolymorphicCall(compiler, comp, left, right); 407 EmitEqualityAsPolymorphicCall(compiler, comp, left, right);
404 } else { 408 } else {
405 EmitEqualityAsInstanceCall(compiler, comp); 409 EmitEqualityAsInstanceCall(compiler, comp);
406 } 410 }
407 __ Bind(&done); 411 __ Bind(&done);
408 } 412 }
409 413
410 414
411 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { 415 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
412 if ((NumTargets() == 1) && (ClassIdAt(0) == kSmi)) { 416 if (HasICData() &&
417 (ic_data()->NumberOfChecks() == 1) &&
418 (ic_data()->GetReceiverClassIdAt(0) == kSmi)) {
413 EmitSmiEqualityCompare(compiler, this); 419 EmitSmiEqualityCompare(compiler, this);
414 return; 420 return;
415 } 421 }
416 EmitGenericEqualityCompare(compiler, this); 422 EmitGenericEqualityCompare(compiler, this);
417 } 423 }
418 424
419 425
420 LocationSummary* RelationalOpComp::MakeLocationSummary() const { 426 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
421 const LocationSummary::ContainsBranch contains_branch = 427 const LocationSummary::ContainsBranch contains_branch =
422 is_fused_with_branch() ? LocationSummary::kBranch 428 is_fused_with_branch() ? LocationSummary::kBranch
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { 854 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const {
849 // TODO(fschneider): For this instruction the input register may be 855 // TODO(fschneider): For this instruction the input register may be
850 // reused for the result (but is not required to) because the input 856 // reused for the result (but is not required to) because the input
851 // is not used after the result is defined. We should consider adding 857 // is not used after the result is defined. We should consider adding
852 // this information to the input policy. 858 // this information to the input policy.
853 return LocationSummary::Make(1, Location::RequiresRegister()); 859 return LocationSummary::Make(1, Location::RequiresRegister());
854 } 860 }
855 861
856 862
857 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 863 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
858 Register instance = locs()->in(0).reg(); 864 Register instance_reg = locs()->in(0).reg();
859 Register result = locs()->out().reg(); 865 Register result_reg = locs()->out().reg();
860 866
861 if (class_ids() != NULL) { 867 if (HasICData()) {
862 ASSERT(original() != NULL); 868 ASSERT(original() != NULL);
863 Label* deopt = compiler->AddDeoptStub(original()->cid(), 869 Label* deopt = compiler->AddDeoptStub(original()->cid(),
864 original()->token_index(), 870 original()->token_index(),
865 original()->try_index(), 871 original()->try_index(),
866 kDeoptInstanceGetterSameTarget, 872 kDeoptInstanceGetterSameTarget,
867 instance); 873 instance_reg);
868 // Smis do not have instance fields (Smi class is always first). 874 // Smis do not have instance fields (Smi class is always first).
869 // Use 'result' as temporary register. 875 // Use 'result' as temporary register.
870 ASSERT(result != instance); 876 ASSERT(result_reg != instance_reg);
871 compiler->EmitClassChecksNoSmi(*class_ids(), instance, result, deopt); 877 ASSERT(ic_data() != NULL);
878 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt);
872 } 879 }
873 __ movl(result, FieldAddress(instance, field().Offset())); 880 __ movl(result_reg, FieldAddress(instance_reg, field().Offset()));
874 } 881 }
875 882
876 883
877 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { 884 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const {
878 return LocationSummary::Make(0, Location::RequiresRegister()); 885 return LocationSummary::Make(0, Location::RequiresRegister());
879 } 886 }
880 887
881 888
882 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 889 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
883 Register result = locs()->out().reg(); 890 Register result = locs()->out().reg();
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 __ popl(result); // Pop new instance. 985 __ popl(result); // Pop new instance.
979 } 986 }
980 987
981 988
982 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { 989 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const {
983 return LocationSummary::Make(1, Location::RequiresRegister()); 990 return LocationSummary::Make(1, Location::RequiresRegister());
984 } 991 }
985 992
986 993
987 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 994 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
988 Register instance = locs()->in(0).reg(); 995 Register instance_reg = locs()->in(0).reg();
989 Register result = locs()->out().reg(); 996 Register result_reg = locs()->out().reg();
990 if (class_ids() != NULL) { 997 if (HasICData()) {
991 ASSERT(original() != NULL); 998 ASSERT(original() != NULL);
992 Label* deopt = compiler->AddDeoptStub(original()->cid(), 999 Label* deopt = compiler->AddDeoptStub(original()->cid(),
993 original()->token_index(), 1000 original()->token_index(),
994 original()->try_index(), 1001 original()->try_index(),
995 kDeoptInstanceGetterSameTarget, 1002 kDeoptInstanceGetterSameTarget,
996 instance); 1003 instance_reg);
997 // Smis do not have instance fields (Smi class is always first). 1004 // Smis do not have instance fields (Smi class is always first).
998 // Use 'result' as temporary register. 1005 // Use 'result' as temporary register.
999 ASSERT(result != instance); 1006 ASSERT(result_reg != instance_reg);
1000 compiler->EmitClassChecksNoSmi(*class_ids(), instance, result, deopt); 1007 ASSERT(ic_data() != NULL);
1008 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt);
1001 } 1009 }
1002 1010
1003 __ movl(result, FieldAddress(instance, offset_in_bytes())); 1011 __ movl(result_reg, FieldAddress(instance_reg, offset_in_bytes()));
1004 } 1012 }
1005 1013
1006 1014
1007 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { 1015 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const {
1008 const intptr_t kNumInputs = 1; 1016 const intptr_t kNumInputs = 1;
1009 const intptr_t kNumTemps = 1; 1017 const intptr_t kNumTemps = 1;
1010 LocationSummary* locs = new LocationSummary(kNumInputs, 1018 LocationSummary* locs = new LocationSummary(kNumInputs,
1011 kNumTemps, 1019 kNumTemps,
1012 LocationSummary::kCall); 1020 LocationSummary::kCall);
1013 locs->set_in(0, Location::RequiresRegister()); 1021 locs->set_in(0, Location::RequiresRegister());
(...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after
1743 } 1751 }
1744 1752
1745 1753
1746 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const { 1754 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const {
1747 return MakeCallSummary(); 1755 return MakeCallSummary();
1748 } 1756 }
1749 1757
1750 1758
1751 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1759 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1752 ASSERT(instance_call()->VerifyComputation()); 1760 ASSERT(instance_call()->VerifyComputation());
1753 ASSERT(class_ids().length() == targets().length()); 1761 ASSERT(HasICData());
1754 ASSERT(class_ids().length() > 0); 1762 ASSERT(ic_data()->num_args_tested() == 1);
1755 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1763 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
1756 instance_call()->token_index(), 1764 instance_call()->token_index(),
1757 instance_call()->try_index(), 1765 instance_call()->try_index(),
1758 kDeoptPolymorphicInstanceCallTestFail); 1766 kDeoptPolymorphicInstanceCallTestFail);
1759 Label handle_smi; 1767 Label handle_smi;
1760 Label* is_smi_label = class_ids()[0] == kSmi ? &handle_smi : deopt; 1768 Label* is_smi_label =
1769 ic_data()->GetReceiverClassIdAt(0) == kSmi ? &handle_smi : deopt;
1770
1761 // Load receiver into EAX. 1771 // Load receiver into EAX.
1762 __ movl(EAX, 1772 __ movl(EAX,
1763 Address(ESP, (instance_call()->ArgumentCount() - 1) * kWordSize)); 1773 Address(ESP, (instance_call()->ArgumentCount() - 1) * kWordSize));
1764 __ testl(EAX, Immediate(kSmiTagMask)); 1774 __ testl(EAX, Immediate(kSmiTagMask));
1765 __ j(ZERO, is_smi_label); 1775 __ j(ZERO, is_smi_label);
1766 Label done; 1776 Label done;
1767 __ LoadClassId(EDI, EAX); 1777 __ LoadClassId(EDI, EAX);
1768 for (intptr_t i = 0; i < class_ids().length(); i++) { 1778 for (intptr_t i = 0; i < ic_data()->NumberOfChecks(); i++) {
1769 Label next_test; 1779 Label next_test;
1770 __ cmpl(EDI, Immediate(class_ids()[i])); 1780 __ cmpl(EDI, Immediate(ic_data()->GetReceiverClassIdAt(i)));
1771 __ j(NOT_EQUAL, &next_test); 1781 __ j(NOT_EQUAL, &next_test);
1782 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(i));
1772 compiler->GenerateStaticCall(instance_call()->cid(), 1783 compiler->GenerateStaticCall(instance_call()->cid(),
1773 instance_call()->token_index(), 1784 instance_call()->token_index(),
1774 instance_call()->try_index(), 1785 instance_call()->try_index(),
1775 *targets()[i], 1786 target,
1776 instance_call()->ArgumentCount(), 1787 instance_call()->ArgumentCount(),
1777 instance_call()->argument_names()); 1788 instance_call()->argument_names());
1778 __ jmp(&done); 1789 __ jmp(&done);
1779 __ Bind(&next_test); 1790 __ Bind(&next_test);
1780 } 1791 }
1781 __ jmp(deopt); 1792 __ jmp(deopt);
1782 if (is_smi_label == &handle_smi) { 1793 if (is_smi_label == &handle_smi) {
1783 __ Bind(&handle_smi); 1794 __ Bind(&handle_smi);
1795 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmi);
1796 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0));
1784 compiler->GenerateStaticCall(instance_call()->cid(), 1797 compiler->GenerateStaticCall(instance_call()->cid(),
1785 instance_call()->token_index(), 1798 instance_call()->token_index(),
1786 instance_call()->try_index(), 1799 instance_call()->try_index(),
1787 *targets()[0], 1800 target,
1788 instance_call()->ArgumentCount(), 1801 instance_call()->ArgumentCount(),
1789 instance_call()->argument_names()); 1802 instance_call()->argument_names());
1790 } 1803 }
1791 __ Bind(&done); 1804 __ Bind(&done);
1792 } 1805 }
1793 1806
1794 1807
1795 } // namespace dart 1808 } // namespace dart
1796 1809
1797 #undef __ 1810 #undef __
1798 1811
1799 #endif // defined TARGET_ARCH_X64 1812 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.cc ('k') | runtime/vm/intermediate_language_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698