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

Side by Side Diff: vm/intermediate_language_ia32.cc

Issue 11745022: - Make Boolean 'true' and 'false' singleton VM isolate objects. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 7 years, 11 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 | « vm/intermediate_language.cc ('k') | vm/intermediate_language_test.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 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 199
200 200
201 static void EmitAssertBoolean(Register reg, 201 static void EmitAssertBoolean(Register reg,
202 intptr_t token_pos, 202 intptr_t token_pos,
203 LocationSummary* locs, 203 LocationSummary* locs,
204 FlowGraphCompiler* compiler) { 204 FlowGraphCompiler* compiler) {
205 // Check that the type of the value is allowed in conditional context. 205 // Check that the type of the value is allowed in conditional context.
206 // Call the runtime if the object is not bool::true or bool::false. 206 // Call the runtime if the object is not bool::true or bool::false.
207 ASSERT(locs->always_calls()); 207 ASSERT(locs->always_calls());
208 Label done; 208 Label done;
209 __ CompareObject(reg, compiler->bool_true()); 209 __ CompareObject(reg, Bool::True());
210 __ j(EQUAL, &done, Assembler::kNearJump); 210 __ j(EQUAL, &done, Assembler::kNearJump);
211 __ CompareObject(reg, compiler->bool_false()); 211 __ CompareObject(reg, Bool::False());
212 __ j(EQUAL, &done, Assembler::kNearJump); 212 __ j(EQUAL, &done, Assembler::kNearJump);
213 213
214 __ pushl(reg); // Push the source object. 214 __ pushl(reg); // Push the source object.
215 compiler->GenerateCallRuntime(token_pos, 215 compiler->GenerateCallRuntime(token_pos,
216 kConditionTypeErrorRuntimeEntry, 216 kConditionTypeErrorRuntimeEntry,
217 locs); 217 locs);
218 // We should never return here. 218 // We should never return here.
219 __ int3(); 219 __ int3();
220 __ Bind(&done); 220 __ Bind(&done);
221 } 221 }
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 392
393 __ Bind(&check_identity); 393 __ Bind(&check_identity);
394 Label equality_done; 394 Label equality_done;
395 if (compiler->is_optimizing()) { 395 if (compiler->is_optimizing()) {
396 // No need to update IC data. 396 // No need to update IC data.
397 Label is_true; 397 Label is_true;
398 __ popl(EAX); 398 __ popl(EAX);
399 __ popl(EDX); 399 __ popl(EDX);
400 __ cmpl(EAX, EDX); 400 __ cmpl(EAX, EDX);
401 __ j(EQUAL, &is_true); 401 __ j(EQUAL, &is_true);
402 __ LoadObject(EAX, (kind == Token::kEQ) ? compiler->bool_false() 402 __ LoadObject(EAX, (kind == Token::kEQ) ? Bool::False() : Bool::True());
403 : compiler->bool_true());
404 __ jmp(&equality_done); 403 __ jmp(&equality_done);
405 __ Bind(&is_true); 404 __ Bind(&is_true);
406 __ LoadObject(EAX, (kind == Token::kEQ) ? compiler->bool_true() 405 __ LoadObject(EAX, (kind == Token::kEQ) ? Bool::True() : Bool::False());
407 : compiler->bool_false());
408 if (kind == Token::kNE) { 406 if (kind == Token::kNE) {
409 // Skip not-equal result conversion. 407 // Skip not-equal result conversion.
410 __ jmp(&equality_done); 408 __ jmp(&equality_done);
411 } 409 }
412 } else { 410 } else {
413 // Call stub, load IC data in register. The stub will update ICData if 411 // Call stub, load IC data in register. The stub will update ICData if
414 // necessary. 412 // necessary.
415 Register ic_data_reg = locs->temp(0).reg(); 413 Register ic_data_reg = locs->temp(0).reg();
416 ASSERT(ic_data_reg == ECX); // Stub depends on it. 414 ASSERT(ic_data_reg == ECX); // Stub depends on it.
417 __ LoadObject(ic_data_reg, equality_ic_data); 415 __ LoadObject(ic_data_reg, equality_ic_data);
418 compiler->GenerateCall(token_pos, 416 compiler->GenerateCall(token_pos,
419 &StubCode::EqualityWithNullArgLabel(), 417 &StubCode::EqualityWithNullArgLabel(),
420 PcDescriptors::kOther, 418 PcDescriptors::kOther,
421 locs); 419 locs);
422 __ Drop(2); 420 __ Drop(2);
423 } 421 }
424 __ Bind(&check_ne); 422 __ Bind(&check_ne);
425 if (kind == Token::kNE) { 423 if (kind == Token::kNE) {
426 Label false_label, true_label, done; 424 Label false_label, true_label, done;
427 // Negate the condition: true label returns false and vice versa. 425 // Negate the condition: true label returns false and vice versa.
428 __ CompareObject(EAX, compiler->bool_true()); 426 __ CompareObject(EAX, Bool::True());
429 __ j(EQUAL, &true_label, Assembler::kNearJump); 427 __ j(EQUAL, &true_label, Assembler::kNearJump);
430 __ Bind(&false_label); 428 __ Bind(&false_label);
431 __ LoadObject(EAX, compiler->bool_true()); 429 __ LoadObject(EAX, Bool::True());
432 __ jmp(&done, Assembler::kNearJump); 430 __ jmp(&done, Assembler::kNearJump);
433 __ Bind(&true_label); 431 __ Bind(&true_label);
434 __ LoadObject(EAX, compiler->bool_false()); 432 __ LoadObject(EAX, Bool::False());
435 __ Bind(&done); 433 __ Bind(&done);
436 } 434 }
437 __ Bind(&equality_done); 435 __ Bind(&equality_done);
438 } 436 }
439 437
440 438
441 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, 439 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler,
442 const ICData& orig_ic_data, 440 const ICData& orig_ic_data,
443 LocationSummary* locs, 441 LocationSummary* locs,
444 BranchInstr* branch, 442 BranchInstr* branch,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 if (target.Owner() == object_store->object_class()) { 479 if (target.Owner() == object_store->object_class()) {
482 // Object.== is same as ===. 480 // Object.== is same as ===.
483 __ Drop(2); 481 __ Drop(2);
484 __ cmpl(left, right); 482 __ cmpl(left, right);
485 if (branch != NULL) { 483 if (branch != NULL) {
486 branch->EmitBranchOnCondition(compiler, cond); 484 branch->EmitBranchOnCondition(compiler, cond);
487 } else { 485 } else {
488 Register result = locs->out().reg(); 486 Register result = locs->out().reg();
489 Label load_true; 487 Label load_true;
490 __ j(cond, &load_true, Assembler::kNearJump); 488 __ j(cond, &load_true, Assembler::kNearJump);
491 __ LoadObject(result, compiler->bool_false()); 489 __ LoadObject(result, Bool::False());
492 __ jmp(&done); 490 __ jmp(&done);
493 __ Bind(&load_true); 491 __ Bind(&load_true);
494 __ LoadObject(result, compiler->bool_true()); 492 __ LoadObject(result, Bool::True());
495 } 493 }
496 } else { 494 } else {
497 const int kNumberOfArguments = 2; 495 const int kNumberOfArguments = 2;
498 const Array& kNoArgumentNames = Array::Handle(); 496 const Array& kNoArgumentNames = Array::Handle();
499 compiler->GenerateStaticCall(deopt_id, 497 compiler->GenerateStaticCall(deopt_id,
500 token_pos, 498 token_pos,
501 target, 499 target,
502 kNumberOfArguments, 500 kNumberOfArguments,
503 kNoArgumentNames, 501 kNoArgumentNames,
504 locs); 502 locs);
505 if (branch == NULL) { 503 if (branch == NULL) {
506 if (kind == Token::kNE) { 504 if (kind == Token::kNE) {
507 Label false_label; 505 Label false_label;
508 __ CompareObject(EAX, compiler->bool_true()); 506 __ CompareObject(EAX, Bool::True());
509 __ j(EQUAL, &false_label, Assembler::kNearJump); 507 __ j(EQUAL, &false_label, Assembler::kNearJump);
510 __ LoadObject(EAX, compiler->bool_true()); 508 __ LoadObject(EAX, Bool::True());
511 __ jmp(&done); 509 __ jmp(&done);
512 __ Bind(&false_label); 510 __ Bind(&false_label);
513 __ LoadObject(EAX, compiler->bool_false()); 511 __ LoadObject(EAX, Bool::False());
514 __ jmp(&done); 512 __ jmp(&done);
515 } 513 }
516 } else { 514 } else {
517 if (branch->is_checked()) { 515 if (branch->is_checked()) {
518 EmitAssertBoolean(EAX, token_pos, locs, compiler); 516 EmitAssertBoolean(EAX, token_pos, locs, compiler);
519 } 517 }
520 __ CompareObject(EAX, compiler->bool_true()); 518 __ CompareObject(EAX, Bool::True());
521 branch->EmitBranchOnCondition(compiler, cond); 519 branch->EmitBranchOnCondition(compiler, cond);
522 } 520 }
523 } 521 }
524 __ jmp(&done); 522 __ jmp(&done);
525 __ Bind(&next_test); 523 __ Bind(&next_test);
526 } 524 }
527 // Fall through leads to deoptimization 525 // Fall through leads to deoptimization
528 __ jmp(deopt); 526 __ jmp(deopt);
529 __ Bind(&done); 527 __ Bind(&done);
530 } 528 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 __ j(EQUAL, &identity_compare); 561 __ j(EQUAL, &identity_compare);
564 } 562 }
565 } 563 }
566 __ Bind(&identity_compare); 564 __ Bind(&identity_compare);
567 __ cmpl(left, right); 565 __ cmpl(left, right);
568 if (branch == NULL) { 566 if (branch == NULL) {
569 Label done, is_equal; 567 Label done, is_equal;
570 Register result = locs.out().reg(); 568 Register result = locs.out().reg();
571 __ j(EQUAL, &is_equal, Assembler::kNearJump); 569 __ j(EQUAL, &is_equal, Assembler::kNearJump);
572 // Not equal. 570 // Not equal.
573 __ LoadObject(result, (kind == Token::kEQ) ? compiler->bool_false() 571 __ LoadObject(result, (kind == Token::kEQ) ? Bool::False() : Bool::True());
574 : compiler->bool_true());
575 __ jmp(&done, Assembler::kNearJump); 572 __ jmp(&done, Assembler::kNearJump);
576 __ Bind(&is_equal); 573 __ Bind(&is_equal);
577 __ LoadObject(result, (kind == Token::kEQ) ? compiler->bool_true() 574 __ LoadObject(result, (kind == Token::kEQ) ? Bool::True() : Bool::False());
578 : compiler->bool_false());
579 __ Bind(&done); 575 __ Bind(&done);
580 } else { 576 } else {
581 Condition cond = TokenKindToSmiCondition(kind); 577 Condition cond = TokenKindToSmiCondition(kind);
582 branch->EmitBranchOnCondition(compiler, cond); 578 branch->EmitBranchOnCondition(compiler, cond);
583 } 579 }
584 } 580 }
585 581
586 582
587 // First test if receiver is NULL, in which case === is applied. 583 // First test if receiver is NULL, in which case === is applied.
588 // If type feedback was provided (lists of <class-id, target>), do a 584 // If type feedback was provided (lists of <class-id, target>), do a
(...skipping 19 matching lines...) Expand all
608 // Comparison with NULL is "===". 604 // Comparison with NULL is "===".
609 __ Bind(&identity_compare); 605 __ Bind(&identity_compare);
610 __ cmpl(left, right); 606 __ cmpl(left, right);
611 Condition cond = TokenKindToSmiCondition(kind); 607 Condition cond = TokenKindToSmiCondition(kind);
612 if (branch != NULL) { 608 if (branch != NULL) {
613 branch->EmitBranchOnCondition(compiler, cond); 609 branch->EmitBranchOnCondition(compiler, cond);
614 } else { 610 } else {
615 Register result = locs->out().reg(); 611 Register result = locs->out().reg();
616 Label load_true; 612 Label load_true;
617 __ j(cond, &load_true, Assembler::kNearJump); 613 __ j(cond, &load_true, Assembler::kNearJump);
618 __ LoadObject(result, compiler->bool_false()); 614 __ LoadObject(result, Bool::False());
619 __ jmp(&done); 615 __ jmp(&done);
620 __ Bind(&load_true); 616 __ Bind(&load_true);
621 __ LoadObject(result, compiler->bool_true()); 617 __ LoadObject(result, Bool::True());
622 } 618 }
623 __ jmp(&done); 619 __ jmp(&done);
624 __ Bind(&non_null_compare); // Receiver is not null. 620 __ Bind(&non_null_compare); // Receiver is not null.
625 __ pushl(left); 621 __ pushl(left);
626 __ pushl(right); 622 __ pushl(right);
627 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 623 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
628 deopt_id, token_pos); 624 deopt_id, token_pos);
629 __ Bind(&done); 625 __ Bind(&done);
630 } 626 }
631 627
(...skipping 16 matching lines...) Expand all
648 } else { 644 } else {
649 __ cmpl(left.reg(), right.reg()); 645 __ cmpl(left.reg(), right.reg());
650 } 646 }
651 647
652 if (branch != NULL) { 648 if (branch != NULL) {
653 branch->EmitBranchOnCondition(compiler, true_condition); 649 branch->EmitBranchOnCondition(compiler, true_condition);
654 } else { 650 } else {
655 Register result = locs.out().reg(); 651 Register result = locs.out().reg();
656 Label done, is_true; 652 Label done, is_true;
657 __ j(true_condition, &is_true); 653 __ j(true_condition, &is_true);
658 __ LoadObject(result, compiler->bool_false()); 654 __ LoadObject(result, Bool::False());
659 __ jmp(&done); 655 __ jmp(&done);
660 __ Bind(&is_true); 656 __ Bind(&is_true);
661 __ LoadObject(result, compiler->bool_true()); 657 __ LoadObject(result, Bool::True());
662 __ Bind(&done); 658 __ Bind(&done);
663 } 659 }
664 } 660 }
665 661
666 662
667 static Condition TokenKindToMintCondition(Token::Kind kind) { 663 static Condition TokenKindToMintCondition(Token::Kind kind) {
668 switch (kind) { 664 switch (kind) {
669 case Token::kEQ: return EQUAL; 665 case Token::kEQ: return EQUAL;
670 case Token::kNE: return NOT_EQUAL; 666 case Token::kNE: return NOT_EQUAL;
671 case Token::kLT: return LESS; 667 case Token::kLT: return LESS;
(...skipping 21 matching lines...) Expand all
693 689
694 Condition true_condition = TokenKindToMintCondition(kind); 690 Condition true_condition = TokenKindToMintCondition(kind);
695 __ cmpl(temp, Immediate(-1)); 691 __ cmpl(temp, Immediate(-1));
696 692
697 if (branch != NULL) { 693 if (branch != NULL) {
698 branch->EmitBranchOnCondition(compiler, true_condition); 694 branch->EmitBranchOnCondition(compiler, true_condition);
699 } else { 695 } else {
700 Register result = locs.out().reg(); 696 Register result = locs.out().reg();
701 Label done, is_true; 697 Label done, is_true;
702 __ j(true_condition, &is_true); 698 __ j(true_condition, &is_true);
703 __ LoadObject(result, compiler->bool_false()); 699 __ LoadObject(result, Bool::False());
704 __ jmp(&done); 700 __ jmp(&done);
705 __ Bind(&is_true); 701 __ Bind(&is_true);
706 __ LoadObject(result, compiler->bool_true()); 702 __ LoadObject(result, Bool::True());
707 __ Bind(&done); 703 __ Bind(&done);
708 } 704 }
709 } 705 }
710 706
711 707
712 static void EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler, 708 static void EmitUnboxedMintComparisonOp(FlowGraphCompiler* compiler,
713 const LocationSummary& locs, 709 const LocationSummary& locs,
714 Token::Kind kind, 710 Token::Kind kind,
715 BranchInstr* branch) { 711 BranchInstr* branch) {
716 XmmRegister left = locs.in(0).xmm_reg(); 712 XmmRegister left = locs.in(0).xmm_reg();
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 // If upper is equal, compare lower half. 754 // If upper is equal, compare lower half.
759 __ pextrd(left_tmp, left, Immediate(0)); 755 __ pextrd(left_tmp, left, Immediate(0));
760 __ pextrd(right_tmp, right, Immediate(0)); 756 __ pextrd(right_tmp, right, Immediate(0));
761 __ cmpl(left_tmp, right_tmp); 757 __ cmpl(left_tmp, right_tmp);
762 if (branch != NULL) { 758 if (branch != NULL) {
763 branch->EmitBranchOnCondition(compiler, lo_cond); 759 branch->EmitBranchOnCondition(compiler, lo_cond);
764 } else { 760 } else {
765 Label done; 761 Label done;
766 __ j(lo_cond, &is_true); 762 __ j(lo_cond, &is_true);
767 __ Bind(&is_false); 763 __ Bind(&is_false);
768 __ LoadObject(result, compiler->bool_false()); 764 __ LoadObject(result, Bool::False());
769 __ jmp(&done); 765 __ jmp(&done);
770 __ Bind(&is_true); 766 __ Bind(&is_true);
771 __ LoadObject(result, compiler->bool_true()); 767 __ LoadObject(result, Bool::True());
772 __ Bind(&done); 768 __ Bind(&done);
773 } 769 }
774 } 770 }
775 771
776 772
777 static Condition TokenKindToDoubleCondition(Token::Kind kind) { 773 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
778 switch (kind) { 774 switch (kind) {
779 case Token::kEQ: return EQUAL; 775 case Token::kEQ: return EQUAL;
780 case Token::kNE: return NOT_EQUAL; 776 case Token::kNE: return NOT_EQUAL;
781 case Token::kLT: return BELOW; 777 case Token::kLT: return BELOW;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 EmitEqualityAsInstanceCall(compiler, 880 EmitEqualityAsInstanceCall(compiler,
885 deopt_id(), 881 deopt_id(),
886 token_pos(), 882 token_pos(),
887 Token::kEQ, // kNE reverse occurs at branch. 883 Token::kEQ, // kNE reverse occurs at branch.
888 locs(), 884 locs(),
889 *ic_data()); 885 *ic_data());
890 if (branch->is_checked()) { 886 if (branch->is_checked()) {
891 EmitAssertBoolean(EAX, token_pos(), locs(), compiler); 887 EmitAssertBoolean(EAX, token_pos(), locs(), compiler);
892 } 888 }
893 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 889 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
894 __ CompareObject(EAX, compiler->bool_true()); 890 __ CompareObject(EAX, Bool::True());
895 branch->EmitBranchOnCondition(compiler, branch_condition); 891 branch->EmitBranchOnCondition(compiler, branch_condition);
896 } 892 }
897 893
898 894
899 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 895 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
900 const intptr_t kNumInputs = 2; 896 const intptr_t kNumInputs = 2;
901 const intptr_t kNumTemps = 0; 897 const intptr_t kNumTemps = 0;
902 if (operands_class_id() == kMintCid) { 898 if (operands_class_id() == kMintCid) {
903 const intptr_t kNumTemps = 2; 899 const intptr_t kNumTemps = 2;
904 LocationSummary* locs = 900 LocationSummary* locs =
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 } 1020 }
1025 if (operands_class_id() == kMintCid) { 1021 if (operands_class_id() == kMintCid) {
1026 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch); 1022 EmitUnboxedMintComparisonOp(compiler, *locs(), kind(), branch);
1027 return; 1023 return;
1028 } 1024 }
1029 if (operands_class_id() == kDoubleCid) { 1025 if (operands_class_id() == kDoubleCid) {
1030 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); 1026 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
1031 return; 1027 return;
1032 } 1028 }
1033 EmitNativeCode(compiler); 1029 EmitNativeCode(compiler);
1034 __ CompareObject(EAX, compiler->bool_true()); 1030 __ CompareObject(EAX, Bool::True());
1035 branch->EmitBranchOnCondition(compiler, EQUAL); 1031 branch->EmitBranchOnCondition(compiler, EQUAL);
1036 } 1032 }
1037 1033
1038 1034
1039 LocationSummary* NativeCallInstr::MakeLocationSummary() const { 1035 LocationSummary* NativeCallInstr::MakeLocationSummary() const {
1040 const intptr_t kNumInputs = 0; 1036 const intptr_t kNumInputs = 0;
1041 const intptr_t kNumTemps = 3; 1037 const intptr_t kNumTemps = 3;
1042 LocationSummary* locs = 1038 LocationSummary* locs =
1043 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 1039 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1044 locs->set_temp(0, Location::RegisterLocation(EAX)); 1040 locs->set_temp(0, Location::RegisterLocation(EAX));
(...skipping 1772 matching lines...) Expand 10 before | Expand all | Expand 10 after
2817 __ pcmpeqq(XMM0, XMM0); // Generate all 1's. 2813 __ pcmpeqq(XMM0, XMM0); // Generate all 1's.
2818 __ pxor(value, XMM0); 2814 __ pxor(value, XMM0);
2819 } 2815 }
2820 2816
2821 2817
2822 } // namespace dart 2818 } // namespace dart
2823 2819
2824 #undef __ 2820 #undef __
2825 2821
2826 #endif // defined TARGET_ARCH_X64 2822 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « vm/intermediate_language.cc ('k') | vm/intermediate_language_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698