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

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

Issue 11341025: Propagate ICData from unoptimized code to instance calls in optimized code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 locs->set_temp(0, Location::RegisterLocation(ECX)); 328 locs->set_temp(0, Location::RegisterLocation(ECX));
329 locs->set_out(Location::RegisterLocation(EAX)); 329 locs->set_out(Location::RegisterLocation(EAX));
330 return locs; 330 return locs;
331 } 331 }
332 332
333 333
334 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, 334 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
335 intptr_t deopt_id, 335 intptr_t deopt_id,
336 intptr_t token_pos, 336 intptr_t token_pos,
337 Token::Kind kind, 337 Token::Kind kind,
338 LocationSummary* locs) { 338 LocationSummary* locs,
339 const ICData& original_ic_data) {
339 if (!compiler->is_optimizing()) { 340 if (!compiler->is_optimizing()) {
340 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore, 341 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore,
341 deopt_id, 342 deopt_id,
342 token_pos); 343 token_pos);
343 } 344 }
344 const String& operator_name = String::ZoneHandle(Symbols::EqualOperator()); 345 const String& operator_name = String::ZoneHandle(Symbols::EqualOperator());
345 const int kNumberOfArguments = 2; 346 const int kNumberOfArguments = 2;
346 const Array& kNoArgumentNames = Array::Handle(); 347 const Array& kNoArgumentNames = Array::Handle();
347 const int kNumArgumentsChecked = 2; 348 const int kNumArgumentsChecked = 2;
348 349
349 const Immediate raw_null = 350 const Immediate raw_null =
350 Immediate(reinterpret_cast<intptr_t>(Object::null())); 351 Immediate(reinterpret_cast<intptr_t>(Object::null()));
351 Label check_identity; 352 Label check_identity;
352 __ cmpl(Address(ESP, 0 * kWordSize), raw_null); 353 __ cmpl(Address(ESP, 0 * kWordSize), raw_null);
353 __ j(EQUAL, &check_identity, Assembler::kNearJump); 354 __ j(EQUAL, &check_identity, Assembler::kNearJump);
354 __ cmpl(Address(ESP, 1 * kWordSize), raw_null); 355 __ cmpl(Address(ESP, 1 * kWordSize), raw_null);
355 __ j(EQUAL, &check_identity, Assembler::kNearJump); 356 __ j(EQUAL, &check_identity, Assembler::kNearJump);
356 357
357 const ICData& ic_data = compiler->GenerateInstanceCall(deopt_id, 358 ICData& equality_ic_data = ICData::ZoneHandle(original_ic_data.raw());
358 token_pos, 359 if (equality_ic_data.IsNull()) {
359 operator_name, 360 equality_ic_data = ICData::New(compiler->parsed_function().function(),
360 kNumberOfArguments, 361 operator_name,
361 kNoArgumentNames, 362 deopt_id,
362 kNumArgumentsChecked, 363 kNumArgumentsChecked);
363 locs); 364 }
365 compiler->GenerateInstanceCall(deopt_id,
366 token_pos,
367 kNumberOfArguments,
368 kNoArgumentNames,
369 locs,
370 equality_ic_data);
364 Label check_ne; 371 Label check_ne;
365 __ jmp(&check_ne); 372 __ jmp(&check_ne);
366 373
367 __ Bind(&check_identity); 374 __ Bind(&check_identity);
368 // Call stub, load IC data in register. The stub will update ICData if 375 // Call stub, load IC data in register. The stub will update ICData if
369 // necessary. 376 // necessary.
370 Register ic_data_reg = locs->temp(0).reg(); 377 Register ic_data_reg = locs->temp(0).reg();
371 ASSERT(ic_data_reg == ECX); // Stub depends on it. 378 ASSERT(ic_data_reg == ECX); // Stub depends on it.
372 __ LoadObject(ic_data_reg, ic_data); 379 __ LoadObject(ic_data_reg, equality_ic_data);
373 compiler->GenerateCall(token_pos, 380 compiler->GenerateCall(token_pos,
374 &StubCode::EqualityWithNullArgLabel(), 381 &StubCode::EqualityWithNullArgLabel(),
375 PcDescriptors::kOther, 382 PcDescriptors::kOther,
376 locs); 383 locs);
377 __ Drop(2); 384 __ Drop(2);
378 __ Bind(&check_ne); 385 __ Bind(&check_ne);
379 if (kind == Token::kNE) { 386 if (kind == Token::kNE) {
380 Label false_label, true_label, done; 387 Label false_label, true_label, done;
381 // Negate the condition: true label returns false and vice versa. 388 // Negate the condition: true label returns false and vice versa.
382 __ CompareObject(EAX, compiler->bool_true()); 389 __ CompareObject(EAX, compiler->bool_true());
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 } 747 }
741 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { 748 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) {
742 EmitGenericEqualityCompare(compiler, locs(), kind(), kNoBranch, *ic_data(), 749 EmitGenericEqualityCompare(compiler, locs(), kind(), kNoBranch, *ic_data(),
743 deopt_id(), token_pos()); 750 deopt_id(), token_pos());
744 return; 751 return;
745 } 752 }
746 Register left = locs()->in(0).reg(); 753 Register left = locs()->in(0).reg();
747 Register right = locs()->in(1).reg(); 754 Register right = locs()->in(1).reg();
748 __ pushl(left); 755 __ pushl(left);
749 __ pushl(right); 756 __ pushl(right);
750 EmitEqualityAsInstanceCall(compiler, deopt_id(), token_pos(), kind(), locs()); 757 EmitEqualityAsInstanceCall(compiler,
758 deopt_id(),
759 token_pos(),
760 kind(),
761 locs(),
762 *ic_data());
751 ASSERT(locs()->out().reg() == EAX); 763 ASSERT(locs()->out().reg() == EAX);
752 } 764 }
753 765
754 766
755 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 767 void EqualityCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
756 BranchInstr* branch) { 768 BranchInstr* branch) {
757 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ)); 769 ASSERT((kind() == Token::kNE) || (kind() == Token::kEQ));
758 if (receiver_class_id() == kSmiCid) { 770 if (receiver_class_id() == kSmiCid) {
759 // Deoptimizes if both arguments not Smi. 771 // Deoptimizes if both arguments not Smi.
760 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 772 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
(...skipping 20 matching lines...) Expand all
781 return; 793 return;
782 } 794 }
783 Register left = locs()->in(0).reg(); 795 Register left = locs()->in(0).reg();
784 Register right = locs()->in(1).reg(); 796 Register right = locs()->in(1).reg();
785 __ pushl(left); 797 __ pushl(left);
786 __ pushl(right); 798 __ pushl(right);
787 EmitEqualityAsInstanceCall(compiler, 799 EmitEqualityAsInstanceCall(compiler,
788 deopt_id(), 800 deopt_id(),
789 token_pos(), 801 token_pos(),
790 Token::kEQ, // kNE reverse occurs at branch. 802 Token::kEQ, // kNE reverse occurs at branch.
791 locs()); 803 locs(),
804 *ic_data());
792 if (branch->is_checked()) { 805 if (branch->is_checked()) {
793 EmitAssertBoolean(EAX, token_pos(), locs(), compiler); 806 EmitAssertBoolean(EAX, token_pos(), locs(), compiler);
794 } 807 }
795 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 808 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
796 __ CompareObject(EAX, compiler->bool_true()); 809 __ CompareObject(EAX, compiler->bool_true());
797 branch->EmitBranchOnCondition(compiler, branch_condition); 810 branch->EmitBranchOnCondition(compiler, branch_condition);
798 } 811 }
799 812
800 813
801 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 814 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
867 } 880 }
868 const String& function_name = 881 const String& function_name =
869 String::ZoneHandle(Symbols::New(Token::Str(kind()))); 882 String::ZoneHandle(Symbols::New(Token::Str(kind())));
870 if (!compiler->is_optimizing()) { 883 if (!compiler->is_optimizing()) {
871 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore, 884 compiler->AddCurrentDescriptor(PcDescriptors::kDeoptBefore,
872 deopt_id(), 885 deopt_id(),
873 token_pos()); 886 token_pos());
874 } 887 }
875 const intptr_t kNumArguments = 2; 888 const intptr_t kNumArguments = 2;
876 const intptr_t kNumArgsChecked = 2; // Type-feedback. 889 const intptr_t kNumArgsChecked = 2; // Type-feedback.
890 ICData& relational_ic_data = ICData::ZoneHandle(ic_data()->raw());
891 if (relational_ic_data.IsNull()) {
892 relational_ic_data = ICData::New(compiler->parsed_function().function(),
893 function_name,
894 deopt_id(),
895 kNumArgsChecked);
896 }
877 compiler->GenerateInstanceCall(deopt_id(), 897 compiler->GenerateInstanceCall(deopt_id(),
878 token_pos(), 898 token_pos(),
879 function_name,
880 kNumArguments, 899 kNumArguments,
881 Array::ZoneHandle(), // No optional arguments. 900 Array::ZoneHandle(), // No optional arguments.
882 kNumArgsChecked, 901 locs(),
883 locs()); 902 relational_ic_data);
884 } 903 }
885 904
886 905
887 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 906 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
888 BranchInstr* branch) { 907 BranchInstr* branch) {
889 if (operands_class_id() == kSmiCid) { 908 if (operands_class_id() == kSmiCid) {
890 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 909 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
891 return; 910 return;
892 } 911 }
893 if (operands_class_id() == kDoubleCid) { 912 if (operands_class_id() == kDoubleCid) {
(...skipping 1664 matching lines...) Expand 10 before | Expand all | Expand 10 after
2558 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. 2577 __ pcmpeqq(XMM0, XMM0); // Generate all 1's.
2559 __ pxor(value, XMM0); 2578 __ pxor(value, XMM0);
2560 } 2579 }
2561 2580
2562 2581
2563 } // namespace dart 2582 } // namespace dart
2564 2583
2565 #undef __ 2584 #undef __
2566 2585
2567 #endif // defined TARGET_ARCH_X64 2586 #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