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

Side by Side Diff: vm/intermediate_language_x64.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_test.cc ('k') | vm/intrinsifier_ia32.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_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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 210
211 211
212 static void EmitAssertBoolean(Register reg, 212 static void EmitAssertBoolean(Register reg,
213 intptr_t token_pos, 213 intptr_t token_pos,
214 LocationSummary* locs, 214 LocationSummary* locs,
215 FlowGraphCompiler* compiler) { 215 FlowGraphCompiler* compiler) {
216 // Check that the type of the value is allowed in conditional context. 216 // Check that the type of the value is allowed in conditional context.
217 // Call the runtime if the object is not bool::true or bool::false. 217 // Call the runtime if the object is not bool::true or bool::false.
218 ASSERT(locs->always_calls()); 218 ASSERT(locs->always_calls());
219 Label done; 219 Label done;
220 __ CompareObject(reg, compiler->bool_true()); 220 __ CompareObject(reg, Bool::True());
221 __ j(EQUAL, &done, Assembler::kNearJump); 221 __ j(EQUAL, &done, Assembler::kNearJump);
222 __ CompareObject(reg, compiler->bool_false()); 222 __ CompareObject(reg, Bool::False());
223 __ j(EQUAL, &done, Assembler::kNearJump); 223 __ j(EQUAL, &done, Assembler::kNearJump);
224 224
225 __ pushq(reg); // Push the source object. 225 __ pushq(reg); // Push the source object.
226 compiler->GenerateCallRuntime(token_pos, 226 compiler->GenerateCallRuntime(token_pos,
227 kConditionTypeErrorRuntimeEntry, 227 kConditionTypeErrorRuntimeEntry,
228 locs); 228 locs);
229 // We should never return here. 229 // We should never return here.
230 __ int3(); 230 __ int3();
231 __ Bind(&done); 231 __ Bind(&done);
232 } 232 }
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 393
394 __ Bind(&check_identity); 394 __ Bind(&check_identity);
395 Label equality_done; 395 Label equality_done;
396 if (compiler->is_optimizing()) { 396 if (compiler->is_optimizing()) {
397 // No need to update IC data. 397 // No need to update IC data.
398 Label is_true; 398 Label is_true;
399 __ popq(RAX); 399 __ popq(RAX);
400 __ popq(RDX); 400 __ popq(RDX);
401 __ cmpq(RAX, RDX); 401 __ cmpq(RAX, RDX);
402 __ j(EQUAL, &is_true); 402 __ j(EQUAL, &is_true);
403 __ LoadObject(RAX, (kind == Token::kEQ) ? compiler->bool_false() 403 __ LoadObject(RAX, (kind == Token::kEQ) ? Bool::False() : Bool::True());
404 : compiler->bool_true());
405 __ jmp(&equality_done); 404 __ jmp(&equality_done);
406 __ Bind(&is_true); 405 __ Bind(&is_true);
407 __ LoadObject(RAX, (kind == Token::kEQ) ? compiler->bool_true() 406 __ LoadObject(RAX, (kind == Token::kEQ) ? Bool::True() : Bool::False());
408 : compiler->bool_false());
409 if (kind == Token::kNE) { 407 if (kind == Token::kNE) {
410 // Skip not-equal result conversion. 408 // Skip not-equal result conversion.
411 __ jmp(&equality_done); 409 __ jmp(&equality_done);
412 } 410 }
413 } else { 411 } else {
414 // Call stub, load IC data in register. The stub will update ICData if 412 // Call stub, load IC data in register. The stub will update ICData if
415 // necessary. 413 // necessary.
416 Register ic_data_reg = locs->temp(0).reg(); 414 Register ic_data_reg = locs->temp(0).reg();
417 ASSERT(ic_data_reg == RBX); // Stub depends on it. 415 ASSERT(ic_data_reg == RBX); // Stub depends on it.
418 __ LoadObject(ic_data_reg, equality_ic_data); 416 __ LoadObject(ic_data_reg, equality_ic_data);
419 compiler->GenerateCall(token_pos, 417 compiler->GenerateCall(token_pos,
420 &StubCode::EqualityWithNullArgLabel(), 418 &StubCode::EqualityWithNullArgLabel(),
421 PcDescriptors::kOther, 419 PcDescriptors::kOther,
422 locs); 420 locs);
423 __ Drop(2); 421 __ Drop(2);
424 } 422 }
425 __ Bind(&check_ne); 423 __ Bind(&check_ne);
426 if (kind == Token::kNE) { 424 if (kind == Token::kNE) {
427 Label false_label, true_label, done; 425 Label false_label, true_label, done;
428 // Negate the condition: true label returns false and vice versa. 426 // Negate the condition: true label returns false and vice versa.
429 __ CompareObject(RAX, compiler->bool_true()); 427 __ CompareObject(RAX, Bool::True());
430 __ j(EQUAL, &true_label, Assembler::kNearJump); 428 __ j(EQUAL, &true_label, Assembler::kNearJump);
431 __ Bind(&false_label); 429 __ Bind(&false_label);
432 __ LoadObject(RAX, compiler->bool_true()); 430 __ LoadObject(RAX, Bool::True());
433 __ jmp(&done, Assembler::kNearJump); 431 __ jmp(&done, Assembler::kNearJump);
434 __ Bind(&true_label); 432 __ Bind(&true_label);
435 __ LoadObject(RAX, compiler->bool_false()); 433 __ LoadObject(RAX, Bool::False());
436 __ Bind(&done); 434 __ Bind(&done);
437 } 435 }
438 __ Bind(&equality_done); 436 __ Bind(&equality_done);
439 } 437 }
440 438
441 439
442 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, 440 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler,
443 const ICData& orig_ic_data, 441 const ICData& orig_ic_data,
444 LocationSummary* locs, 442 LocationSummary* locs,
445 BranchInstr* branch, 443 BranchInstr* branch,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 // Object.== is same as ===. 481 // Object.== is same as ===.
484 __ Drop(2); 482 __ Drop(2);
485 __ cmpq(left, right); 483 __ cmpq(left, right);
486 if (branch != NULL) { 484 if (branch != NULL) {
487 branch->EmitBranchOnCondition(compiler, cond); 485 branch->EmitBranchOnCondition(compiler, cond);
488 } else { 486 } else {
489 // This case should be rare. 487 // This case should be rare.
490 Register result = locs->out().reg(); 488 Register result = locs->out().reg();
491 Label load_true; 489 Label load_true;
492 __ j(cond, &load_true, Assembler::kNearJump); 490 __ j(cond, &load_true, Assembler::kNearJump);
493 __ LoadObject(result, compiler->bool_false()); 491 __ LoadObject(result, Bool::False());
494 __ jmp(&done); 492 __ jmp(&done);
495 __ Bind(&load_true); 493 __ Bind(&load_true);
496 __ LoadObject(result, compiler->bool_true()); 494 __ LoadObject(result, Bool::True());
497 } 495 }
498 } else { 496 } else {
499 const int kNumberOfArguments = 2; 497 const int kNumberOfArguments = 2;
500 const Array& kNoArgumentNames = Array::Handle(); 498 const Array& kNoArgumentNames = Array::Handle();
501 compiler->GenerateStaticCall(deopt_id, 499 compiler->GenerateStaticCall(deopt_id,
502 token_pos, 500 token_pos,
503 target, 501 target,
504 kNumberOfArguments, 502 kNumberOfArguments,
505 kNoArgumentNames, 503 kNoArgumentNames,
506 locs); 504 locs);
507 if (branch == NULL) { 505 if (branch == NULL) {
508 if (kind == Token::kNE) { 506 if (kind == Token::kNE) {
509 Label false_label; 507 Label false_label;
510 __ CompareObject(RAX, compiler->bool_true()); 508 __ CompareObject(RAX, Bool::True());
511 __ j(EQUAL, &false_label, Assembler::kNearJump); 509 __ j(EQUAL, &false_label, Assembler::kNearJump);
512 __ LoadObject(RAX, compiler->bool_true()); 510 __ LoadObject(RAX, Bool::True());
513 __ jmp(&done); 511 __ jmp(&done);
514 __ Bind(&false_label); 512 __ Bind(&false_label);
515 __ LoadObject(RAX, compiler->bool_false()); 513 __ LoadObject(RAX, Bool::False());
516 __ jmp(&done); 514 __ jmp(&done);
517 } 515 }
518 } else { 516 } else {
519 if (branch->is_checked()) { 517 if (branch->is_checked()) {
520 EmitAssertBoolean(RAX, token_pos, locs, compiler); 518 EmitAssertBoolean(RAX, token_pos, locs, compiler);
521 } 519 }
522 __ CompareObject(RAX, compiler->bool_true()); 520 __ CompareObject(RAX, Bool::True());
523 branch->EmitBranchOnCondition(compiler, cond); 521 branch->EmitBranchOnCondition(compiler, cond);
524 } 522 }
525 } 523 }
526 __ jmp(&done); 524 __ jmp(&done);
527 __ Bind(&next_test); 525 __ Bind(&next_test);
528 } 526 }
529 // Fall through leads to deoptimization 527 // Fall through leads to deoptimization
530 __ jmp(deopt); 528 __ jmp(deopt);
531 __ Bind(&done); 529 __ Bind(&done);
532 } 530 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 __ j(EQUAL, &identity_compare); 563 __ j(EQUAL, &identity_compare);
566 } 564 }
567 } 565 }
568 __ Bind(&identity_compare); 566 __ Bind(&identity_compare);
569 __ cmpq(left, right); 567 __ cmpq(left, right);
570 if (branch == NULL) { 568 if (branch == NULL) {
571 Label done, is_equal; 569 Label done, is_equal;
572 Register result = locs.out().reg(); 570 Register result = locs.out().reg();
573 __ j(EQUAL, &is_equal, Assembler::kNearJump); 571 __ j(EQUAL, &is_equal, Assembler::kNearJump);
574 // Not equal. 572 // Not equal.
575 __ LoadObject(result, (kind == Token::kEQ) ? compiler->bool_false() 573 __ LoadObject(result, (kind == Token::kEQ) ? Bool::False() : Bool::True());
576 : compiler->bool_true());
577 __ jmp(&done, Assembler::kNearJump); 574 __ jmp(&done, Assembler::kNearJump);
578 __ Bind(&is_equal); 575 __ Bind(&is_equal);
579 __ LoadObject(result, (kind == Token::kEQ) ? compiler->bool_true() 576 __ LoadObject(result, (kind == Token::kEQ) ? Bool::True() : Bool::False());
580 : compiler->bool_false());
581 __ Bind(&done); 577 __ Bind(&done);
582 } else { 578 } else {
583 Condition cond = TokenKindToSmiCondition(kind); 579 Condition cond = TokenKindToSmiCondition(kind);
584 branch->EmitBranchOnCondition(compiler, cond); 580 branch->EmitBranchOnCondition(compiler, cond);
585 } 581 }
586 } 582 }
587 583
588 584
589 // First test if receiver is NULL, in which case === is applied. 585 // First test if receiver is NULL, in which case === is applied.
590 // If type feedback was provided (lists of <class-id, target>), do a 586 // If type feedback was provided (lists of <class-id, target>), do a
(...skipping 19 matching lines...) Expand all
610 // Comparison with NULL is "===". 606 // Comparison with NULL is "===".
611 __ Bind(&identity_compare); 607 __ Bind(&identity_compare);
612 __ cmpq(left, right); 608 __ cmpq(left, right);
613 Condition cond = TokenKindToSmiCondition(kind); 609 Condition cond = TokenKindToSmiCondition(kind);
614 if (branch != NULL) { 610 if (branch != NULL) {
615 branch->EmitBranchOnCondition(compiler, cond); 611 branch->EmitBranchOnCondition(compiler, cond);
616 } else { 612 } else {
617 Register result = locs->out().reg(); 613 Register result = locs->out().reg();
618 Label load_true; 614 Label load_true;
619 __ j(cond, &load_true, Assembler::kNearJump); 615 __ j(cond, &load_true, Assembler::kNearJump);
620 __ LoadObject(result, compiler->bool_false()); 616 __ LoadObject(result, Bool::False());
621 __ jmp(&done); 617 __ jmp(&done);
622 __ Bind(&load_true); 618 __ Bind(&load_true);
623 __ LoadObject(result, compiler->bool_true()); 619 __ LoadObject(result, Bool::True());
624 } 620 }
625 __ jmp(&done); 621 __ jmp(&done);
626 __ Bind(&non_null_compare); // Receiver is not null. 622 __ Bind(&non_null_compare); // Receiver is not null.
627 __ pushq(left); 623 __ pushq(left);
628 __ pushq(right); 624 __ pushq(right);
629 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 625 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
630 deopt_id, token_pos); 626 deopt_id, token_pos);
631 __ Bind(&done); 627 __ Bind(&done);
632 } 628 }
633 629
(...skipping 16 matching lines...) Expand all
650 } else { 646 } else {
651 __ cmpq(left.reg(), right.reg()); 647 __ cmpq(left.reg(), right.reg());
652 } 648 }
653 649
654 if (branch != NULL) { 650 if (branch != NULL) {
655 branch->EmitBranchOnCondition(compiler, true_condition); 651 branch->EmitBranchOnCondition(compiler, true_condition);
656 } else { 652 } else {
657 Register result = locs.out().reg(); 653 Register result = locs.out().reg();
658 Label done, is_true; 654 Label done, is_true;
659 __ j(true_condition, &is_true); 655 __ j(true_condition, &is_true);
660 __ LoadObject(result, compiler->bool_false()); 656 __ LoadObject(result, Bool::False());
661 __ jmp(&done); 657 __ jmp(&done);
662 __ Bind(&is_true); 658 __ Bind(&is_true);
663 __ LoadObject(result, compiler->bool_true()); 659 __ LoadObject(result, Bool::True());
664 __ Bind(&done); 660 __ Bind(&done);
665 } 661 }
666 } 662 }
667 663
668 664
669 static Condition TokenKindToDoubleCondition(Token::Kind kind) { 665 static Condition TokenKindToDoubleCondition(Token::Kind kind) {
670 switch (kind) { 666 switch (kind) {
671 case Token::kEQ: return EQUAL; 667 case Token::kEQ: return EQUAL;
672 case Token::kNE: return NOT_EQUAL; 668 case Token::kNE: return NOT_EQUAL;
673 case Token::kLT: return BELOW; 669 case Token::kLT: return BELOW;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 EmitEqualityAsInstanceCall(compiler, 766 EmitEqualityAsInstanceCall(compiler,
771 deopt_id(), 767 deopt_id(),
772 token_pos(), 768 token_pos(),
773 Token::kEQ, // kNE reverse occurs at branch. 769 Token::kEQ, // kNE reverse occurs at branch.
774 locs(), 770 locs(),
775 *ic_data()); 771 *ic_data());
776 if (branch->is_checked()) { 772 if (branch->is_checked()) {
777 EmitAssertBoolean(RAX, token_pos(), locs(), compiler); 773 EmitAssertBoolean(RAX, token_pos(), locs(), compiler);
778 } 774 }
779 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; 775 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL;
780 __ CompareObject(RAX, compiler->bool_true()); 776 __ CompareObject(RAX, Bool::True());
781 branch->EmitBranchOnCondition(compiler, branch_condition); 777 branch->EmitBranchOnCondition(compiler, branch_condition);
782 } 778 }
783 779
784 780
785 LocationSummary* RelationalOpInstr::MakeLocationSummary() const { 781 LocationSummary* RelationalOpInstr::MakeLocationSummary() const {
786 const intptr_t kNumInputs = 2; 782 const intptr_t kNumInputs = 2;
787 const intptr_t kNumTemps = 0; 783 const intptr_t kNumTemps = 0;
788 if (operands_class_id() == kDoubleCid) { 784 if (operands_class_id() == kDoubleCid) {
789 LocationSummary* summary = 785 LocationSummary* summary =
790 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 786 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 BranchInstr* branch) { 888 BranchInstr* branch) {
893 if (operands_class_id() == kSmiCid) { 889 if (operands_class_id() == kSmiCid) {
894 EmitSmiComparisonOp(compiler, *locs(), kind(), branch); 890 EmitSmiComparisonOp(compiler, *locs(), kind(), branch);
895 return; 891 return;
896 } 892 }
897 if (operands_class_id() == kDoubleCid) { 893 if (operands_class_id() == kDoubleCid) {
898 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch); 894 EmitDoubleComparisonOp(compiler, *locs(), kind(), branch);
899 return; 895 return;
900 } 896 }
901 EmitNativeCode(compiler); 897 EmitNativeCode(compiler);
902 __ CompareObject(RAX, compiler->bool_true()); 898 __ CompareObject(RAX, Bool::True());
903 branch->EmitBranchOnCondition(compiler, EQUAL); 899 branch->EmitBranchOnCondition(compiler, EQUAL);
904 } 900 }
905 901
906 902
907 LocationSummary* NativeCallInstr::MakeLocationSummary() const { 903 LocationSummary* NativeCallInstr::MakeLocationSummary() const {
908 const intptr_t kNumInputs = 0; 904 const intptr_t kNumInputs = 0;
909 const intptr_t kNumTemps = 3; 905 const intptr_t kNumTemps = 3;
910 LocationSummary* locs = 906 LocationSummary* locs =
911 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 907 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
912 locs->set_temp(0, Location::RegisterLocation(RAX)); 908 locs->set_temp(0, Location::RegisterLocation(RAX));
(...skipping 1551 matching lines...) Expand 10 before | Expand all | Expand 10 after
2464 2460
2465 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2461 void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2466 UNIMPLEMENTED(); 2462 UNIMPLEMENTED();
2467 } 2463 }
2468 2464
2469 } // namespace dart 2465 } // namespace dart
2470 2466
2471 #undef __ 2467 #undef __
2472 2468
2473 #endif // defined TARGET_ARCH_X64 2469 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « vm/intermediate_language_test.cc ('k') | vm/intrinsifier_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698