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

Side by Side Diff: runtime/vm/intermediate_language_x64.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_ia32.cc ('k') | runtime/vm/object.h » ('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_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 "lib/error.h" 10 #include "lib/error.h"
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 ASSERT(obj == result); 198 ASSERT(obj == result);
199 } 199 }
200 200
201 201
202 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { 202 LocationSummary* EqualityCompareComp::MakeLocationSummary() const {
203 const LocationSummary::ContainsBranch contains_branch = 203 const LocationSummary::ContainsBranch contains_branch =
204 is_fused_with_branch() ? LocationSummary::kBranch 204 is_fused_with_branch() ? LocationSummary::kBranch
205 : LocationSummary::kNoBranch; 205 : LocationSummary::kNoBranch;
206 206
207 const intptr_t kNumInputs = 2; 207 const intptr_t kNumInputs = 2;
208 if ((NumTargets() == 1) && (ClassIdAt(0) == kSmi)) { 208 if (HasICData() &&
209 (ic_data()->NumberOfChecks() == 1) &&
210 (ic_data()->GetReceiverClassIdAt(0) == kSmi)) {
209 const intptr_t kNumTemps = 1; 211 const intptr_t kNumTemps = 1;
210 LocationSummary* locs = new LocationSummary(kNumInputs, 212 LocationSummary* locs = new LocationSummary(kNumInputs,
211 kNumTemps, 213 kNumTemps,
212 LocationSummary::kNoCall, 214 LocationSummary::kNoCall,
213 contains_branch); 215 contains_branch);
214 locs->set_in(0, Location::RequiresRegister()); 216 locs->set_in(0, Location::RequiresRegister());
215 locs->set_in(1, Location::RequiresRegister()); 217 locs->set_in(1, Location::RequiresRegister());
216 locs->set_temp(0, Location::RequiresRegister()); 218 locs->set_temp(0, Location::RequiresRegister());
217 if (!is_fused_with_branch()) { 219 if (!is_fused_with_branch()) {
218 locs->set_out(Location::RequiresRegister()); 220 locs->set_out(Location::RequiresRegister());
219 } 221 }
220 return locs; 222 return locs;
221 } 223 }
222 if (NumTargets() > 0) { 224 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
223 const intptr_t kNumTemps = 1; 225 const intptr_t kNumTemps = 1;
224 LocationSummary* locs = new LocationSummary(kNumInputs, 226 LocationSummary* locs = new LocationSummary(kNumInputs,
225 kNumTemps, 227 kNumTemps,
226 LocationSummary::kCall, 228 LocationSummary::kCall,
227 contains_branch); 229 contains_branch);
228 locs->set_in(0, Location::RequiresRegister()); 230 locs->set_in(0, Location::RequiresRegister());
229 locs->set_in(1, Location::RequiresRegister()); 231 locs->set_in(1, Location::RequiresRegister());
230 locs->set_temp(0, Location::RequiresRegister()); 232 locs->set_temp(0, Location::RequiresRegister());
231 if (!is_fused_with_branch()) { 233 if (!is_fused_with_branch()) {
232 locs->set_out(Location::RegisterLocation(RAX)); 234 locs->set_out(Location::RegisterLocation(RAX));
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
303 __ CompareObject(RAX, compiler->bool_true()); 305 __ CompareObject(RAX, compiler->bool_true());
304 comp->fused_with_branch()->EmitBranchOnCondition(compiler, EQUAL); 306 comp->fused_with_branch()->EmitBranchOnCondition(compiler, EQUAL);
305 } 307 }
306 } 308 }
307 309
308 310
309 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, 311 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler,
310 EqualityCompareComp* comp, 312 EqualityCompareComp* comp,
311 Register left, 313 Register left,
312 Register right) { 314 Register right) {
313 ASSERT(comp->NumTargets() > 0); 315 ASSERT(comp->HasICData());
316 const ICData& ic_data = *comp->ic_data();
317 ASSERT(ic_data.NumberOfChecks() > 0);
314 Label* deopt = compiler->AddDeoptStub(comp->cid(), 318 Label* deopt = compiler->AddDeoptStub(comp->cid(),
315 comp->token_index(), 319 comp->token_index(),
316 comp->try_index(), 320 comp->try_index(),
317 kDeoptEquality); 321 kDeoptEquality);
318 __ testq(left, Immediate(kSmiTagMask)); 322 __ testq(left, Immediate(kSmiTagMask));
319 Register temp = comp->locs()->temp(0).reg(); 323 Register temp = comp->locs()->temp(0).reg();
320 if (comp->ClassIdAt(0) == kSmi) { 324 if (ic_data.GetReceiverClassIdAt(0) == kSmi) {
321 Label done, load_class_id; 325 Label done, load_class_id;
322 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump); 326 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump);
323 __ movq(temp, Immediate(kSmi)); 327 __ movq(temp, Immediate(kSmi));
324 __ jmp(&done, Assembler::kNearJump); 328 __ jmp(&done, Assembler::kNearJump);
325 __ Bind(&load_class_id); 329 __ Bind(&load_class_id);
326 __ LoadClassId(temp, left); 330 __ LoadClassId(temp, left);
327 __ Bind(&done); 331 __ Bind(&done);
328 } else { 332 } else {
329 __ j(ZERO, deopt); // Smi deopts. 333 __ j(ZERO, deopt); // Smi deopts.
330 __ LoadClassId(temp, left); 334 __ LoadClassId(temp, left);
331 } 335 }
332 Label done; 336 Label done;
333 for (intptr_t i = 0; i < comp->NumTargets(); i++) { 337 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
334 ASSERT((comp->ClassIdAt(i) != kSmi) || (i == 0)); 338 ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmi) || (i == 0));
335 Label next_test; 339 Label next_test;
336 __ cmpq(temp, Immediate(comp->ClassIdAt(i))); 340 __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i)));
337 __ j(NOT_EQUAL, &next_test, Assembler::kNearJump); 341 __ j(NOT_EQUAL, &next_test, Assembler::kNearJump);
338 const Function& target = *comp->TargetAt(i); 342 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i));
339 ObjectStore* object_store = Isolate::Current()->object_store(); 343 ObjectStore* object_store = Isolate::Current()->object_store();
340 if (target.owner() == object_store->object_class()) { 344 if (target.owner() == object_store->object_class()) {
341 // Object.== is same as ===. 345 // Object.== is same as ===.
342 __ Drop(2); 346 __ Drop(2);
343 __ cmpq(left, right); 347 __ cmpq(left, right);
344 if (comp->is_fused_with_branch()) { 348 if (comp->is_fused_with_branch()) {
345 comp->fused_with_branch()->EmitBranchOnCondition(compiler, EQUAL); 349 comp->fused_with_branch()->EmitBranchOnCondition(compiler, EQUAL);
346 } else { 350 } else {
347 // This case should be rare. 351 // This case should be rare.
348 Register result = comp->locs()->out().reg(); 352 Register result = comp->locs()->out().reg();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 __ LoadObject(result, compiler->bool_false()); 406 __ LoadObject(result, compiler->bool_false());
403 __ jmp(&done); 407 __ jmp(&done);
404 __ Bind(&load_true); 408 __ Bind(&load_true);
405 __ LoadObject(result, compiler->bool_true()); 409 __ LoadObject(result, compiler->bool_true());
406 } 410 }
407 __ jmp(&done); 411 __ jmp(&done);
408 412
409 __ Bind(&non_null_compare); // Receiver is not null. 413 __ Bind(&non_null_compare); // Receiver is not null.
410 __ pushq(left); 414 __ pushq(left);
411 __ pushq(right); 415 __ pushq(right);
412 if (comp->NumTargets() > 0) { 416 if (comp->HasICData() && (comp->ic_data()->NumberOfChecks() > 0)) {
413 EmitEqualityAsPolymorphicCall(compiler, comp, left, right); 417 EmitEqualityAsPolymorphicCall(compiler, comp, left, right);
414 } else { 418 } else {
415 EmitEqualityAsInstanceCall(compiler, comp); 419 EmitEqualityAsInstanceCall(compiler, comp);
416 } 420 }
417 __ Bind(&done); 421 __ Bind(&done);
418 } 422 }
419 423
420 424
421 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { 425 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
422 if ((NumTargets() == 1) && (ClassIdAt(0) == kSmi)) { 426 if (HasICData() &&
427 (ic_data()->NumberOfChecks() == 1) &&
428 (ic_data()->GetReceiverClassIdAt(0) == kSmi)) {
423 EmitSmiEqualityCompare(compiler, this); 429 EmitSmiEqualityCompare(compiler, this);
424 return; 430 return;
425 } 431 }
426 EmitGenericEqualityCompare(compiler, this); 432 EmitGenericEqualityCompare(compiler, this);
427 } 433 }
428 434
429 435
430 LocationSummary* RelationalOpComp::MakeLocationSummary() const { 436 LocationSummary* RelationalOpComp::MakeLocationSummary() const {
431 const LocationSummary::ContainsBranch contains_branch = 437 const LocationSummary::ContainsBranch contains_branch =
432 is_fused_with_branch() ? LocationSummary::kBranch 438 is_fused_with_branch() ? LocationSummary::kBranch
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { 869 LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const {
864 // TODO(fschneider): For this instruction the input register may be 870 // TODO(fschneider): For this instruction the input register may be
865 // reused for the result (but is not required to) because the input 871 // reused for the result (but is not required to) because the input
866 // is not used after the result is defined. We should consider adding 872 // is not used after the result is defined. We should consider adding
867 // this information to the input policy. 873 // this information to the input policy.
868 return LocationSummary::Make(1, Location::RequiresRegister()); 874 return LocationSummary::Make(1, Location::RequiresRegister());
869 } 875 }
870 876
871 877
872 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 878 void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
873 Register instance = locs()->in(0).reg(); 879 Register instance_reg = locs()->in(0).reg();
874 Register result = locs()->out().reg(); 880 Register result_reg = locs()->out().reg();
875 881
876 if (class_ids() != NULL) { 882 if (HasICData()) {
877 ASSERT(original() != NULL); 883 ASSERT(original() != NULL);
878 Label* deopt = compiler->AddDeoptStub(original()->cid(), 884 Label* deopt = compiler->AddDeoptStub(original()->cid(),
879 original()->token_index(), 885 original()->token_index(),
880 original()->try_index(), 886 original()->try_index(),
881 kDeoptInstanceGetterSameTarget, 887 kDeoptInstanceGetterSameTarget,
882 instance); 888 instance_reg);
883 // Smis do not have instance fields (Smi class is always first). 889 // Smis do not have instance fields (Smi class is always first).
884 // Use 'result' as temporary register. 890 // Use 'result' as temporary register.
885 ASSERT(result != instance); 891 ASSERT(result_reg != instance_reg);
886 compiler->EmitClassChecksNoSmi(*class_ids(), instance, result, deopt); 892 ASSERT(ic_data() != NULL);
893 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt);
887 } 894 }
888 __ movq(result, FieldAddress(instance, field().Offset())); 895 __ movq(result_reg, FieldAddress(instance_reg, field().Offset()));
889 } 896 }
890 897
891 898
892 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const { 899 LocationSummary* LoadStaticFieldComp::MakeLocationSummary() const {
893 return LocationSummary::Make(0, Location::RequiresRegister()); 900 return LocationSummary::Make(0, Location::RequiresRegister());
894 } 901 }
895 902
896 903
897 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 904 void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
898 Register result = locs()->out().reg(); 905 Register result = locs()->out().reg();
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 __ popq(result); // Pop new instance. 1002 __ popq(result); // Pop new instance.
996 } 1003 }
997 1004
998 1005
999 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const { 1006 LocationSummary* LoadVMFieldComp::MakeLocationSummary() const {
1000 return LocationSummary::Make(1, Location::RequiresRegister()); 1007 return LocationSummary::Make(1, Location::RequiresRegister());
1001 } 1008 }
1002 1009
1003 1010
1004 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1011 void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1005 Register instance = locs()->in(0).reg(); 1012 Register instance_reg = locs()->in(0).reg();
1006 Register result = locs()->out().reg(); 1013 Register result_reg = locs()->out().reg();
1007 if (class_ids() != NULL) { 1014 if (HasICData()) {
1008 ASSERT(original() != NULL); 1015 ASSERT(original() != NULL);
1009 Label* deopt = compiler->AddDeoptStub(original()->cid(), 1016 Label* deopt = compiler->AddDeoptStub(original()->cid(),
1010 original()->token_index(), 1017 original()->token_index(),
1011 original()->try_index(), 1018 original()->try_index(),
1012 kDeoptInstanceGetterSameTarget, 1019 kDeoptInstanceGetterSameTarget,
1013 instance); 1020 instance_reg);
1014 // Smis do not have instance fields (Smi class is always first). 1021 // Smis do not have instance fields (Smi class is always first).
1015 // Use 'result' as temporary register. 1022 // Use 'result' as temporary register.
1016 ASSERT(result != instance); 1023 ASSERT(result_reg != instance_reg);
1017 compiler->EmitClassChecksNoSmi(*class_ids(), instance, result, deopt); 1024 ASSERT(ic_data() != NULL);
1025 compiler->EmitClassChecksNoSmi(*ic_data(), instance_reg, result_reg, deopt);
1018 } 1026 }
1019 1027
1020 __ movq(result, FieldAddress(instance, offset_in_bytes())); 1028 __ movq(result_reg, FieldAddress(instance_reg, offset_in_bytes()));
1021 } 1029 }
1022 1030
1023 1031
1024 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const { 1032 LocationSummary* InstantiateTypeArgumentsComp::MakeLocationSummary() const {
1025 const intptr_t kNumInputs = 1; 1033 const intptr_t kNumInputs = 1;
1026 const intptr_t kNumTemps = 0; 1034 const intptr_t kNumTemps = 0;
1027 LocationSummary* locs = new LocationSummary(kNumInputs, 1035 LocationSummary* locs = new LocationSummary(kNumInputs,
1028 kNumTemps, 1036 kNumTemps,
1029 LocationSummary::kCall); 1037 LocationSummary::kCall);
1030 locs->set_in(0, Location::RequiresRegister()); 1038 locs->set_in(0, Location::RequiresRegister());
(...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after
1757 } 1765 }
1758 1766
1759 1767
1760 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const { 1768 LocationSummary* PolymorphicInstanceCallComp::MakeLocationSummary() const {
1761 return MakeCallSummary(); 1769 return MakeCallSummary();
1762 } 1770 }
1763 1771
1764 1772
1765 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1773 void PolymorphicInstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1766 ASSERT(instance_call()->VerifyComputation()); 1774 ASSERT(instance_call()->VerifyComputation());
1767 ASSERT(class_ids().length() == targets().length()); 1775 ASSERT(HasICData());
1768 ASSERT(class_ids().length() > 0); 1776 ASSERT(ic_data()->num_args_tested() == 1);
1769 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(), 1777 Label* deopt = compiler->AddDeoptStub(instance_call()->cid(),
1770 instance_call()->token_index(), 1778 instance_call()->token_index(),
1771 instance_call()->try_index(), 1779 instance_call()->try_index(),
1772 kDeoptPolymorphicInstanceCallTestFail); 1780 kDeoptPolymorphicInstanceCallTestFail);
1773 Label handle_smi; 1781 Label handle_smi;
1774 Label* is_smi_label = class_ids()[0] == kSmi ? &handle_smi : deopt; 1782 Label* is_smi_label =
1783 ic_data()->GetReceiverClassIdAt(0) == kSmi ? &handle_smi : deopt;
1775 // Load receiver into RAX. 1784 // Load receiver into RAX.
1776 __ movq(RAX, 1785 __ movq(RAX,
1777 Address(RSP, (instance_call()->ArgumentCount() - 1) * kWordSize)); 1786 Address(RSP, (instance_call()->ArgumentCount() - 1) * kWordSize));
1778 __ testq(RAX, Immediate(kSmiTagMask)); 1787 __ testq(RAX, Immediate(kSmiTagMask));
1779 __ j(ZERO, is_smi_label); 1788 __ j(ZERO, is_smi_label);
1780 Label done; 1789 Label done;
1781 __ LoadClassId(RDI, RAX); 1790 __ LoadClassId(RDI, RAX);
1782 for (intptr_t i = 0; i < class_ids().length(); i++) { 1791 for (intptr_t i = 0; i < ic_data()->NumberOfChecks(); i++) {
1783 Label next_test; 1792 Label next_test;
1784 __ cmpq(RDI, Immediate(class_ids()[i])); 1793 __ cmpq(RDI, Immediate(ic_data()->GetReceiverClassIdAt(i)));
1785 __ j(NOT_EQUAL, &next_test); 1794 __ j(NOT_EQUAL, &next_test);
1795 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(i));
1786 compiler->GenerateStaticCall(instance_call()->cid(), 1796 compiler->GenerateStaticCall(instance_call()->cid(),
1787 instance_call()->token_index(), 1797 instance_call()->token_index(),
1788 instance_call()->try_index(), 1798 instance_call()->try_index(),
1789 *targets()[i], 1799 target,
1790 instance_call()->ArgumentCount(), 1800 instance_call()->ArgumentCount(),
1791 instance_call()->argument_names()); 1801 instance_call()->argument_names());
1792 __ jmp(&done); 1802 __ jmp(&done);
1793 __ Bind(&next_test); 1803 __ Bind(&next_test);
1794 } 1804 }
1795 __ jmp(deopt); 1805 __ jmp(deopt);
1796 if (is_smi_label == &handle_smi) { 1806 if (is_smi_label == &handle_smi) {
1797 __ Bind(&handle_smi); 1807 __ Bind(&handle_smi);
1808 ASSERT(ic_data()->GetReceiverClassIdAt(0) == kSmi);
1809 const Function& target = Function::ZoneHandle(ic_data()->GetTargetAt(0));
1798 compiler->GenerateStaticCall(instance_call()->cid(), 1810 compiler->GenerateStaticCall(instance_call()->cid(),
1799 instance_call()->token_index(), 1811 instance_call()->token_index(),
1800 instance_call()->try_index(), 1812 instance_call()->try_index(),
1801 *targets()[0], 1813 target,
1802 instance_call()->ArgumentCount(), 1814 instance_call()->ArgumentCount(),
1803 instance_call()->argument_names()); 1815 instance_call()->argument_names());
1804 } 1816 }
1805 __ Bind(&done); 1817 __ Bind(&done);
1806 } 1818 }
1807 1819
1808 } // namespace dart 1820 } // namespace dart
1809 1821
1810 #undef __ 1822 #undef __
1811 1823
1812 #endif // defined TARGET_ARCH_X64 1824 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_ia32.cc ('k') | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698