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

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

Issue 24203004: Dart VM: Simplify code generation for equality operators. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: rebased Created 7 years, 2 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_mips.cc ('k') | runtime/vm/parser.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 const ICData& original_ic_data) { 446 const ICData& original_ic_data) {
447 if (!compiler->is_optimizing()) { 447 if (!compiler->is_optimizing()) {
448 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 448 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
449 deopt_id, 449 deopt_id,
450 token_pos); 450 token_pos);
451 } 451 }
452 const int kNumberOfArguments = 2; 452 const int kNumberOfArguments = 2;
453 const Array& kNoArgumentNames = Object::null_array(); 453 const Array& kNoArgumentNames = Object::null_array();
454 const int kNumArgumentsChecked = 2; 454 const int kNumArgumentsChecked = 2;
455 455
456 Label check_identity;
457 __ LoadObject(TMP, Object::null_object(), PP);
458 __ cmpq(Address(RSP, 0 * kWordSize), TMP);
459 __ j(EQUAL, &check_identity);
460 __ cmpq(Address(RSP, 1 * kWordSize), TMP);
461 __ j(EQUAL, &check_identity);
462
463 ICData& equality_ic_data = ICData::ZoneHandle(original_ic_data.raw()); 456 ICData& equality_ic_data = ICData::ZoneHandle(original_ic_data.raw());
464 if (compiler->is_optimizing() && FLAG_propagate_ic_data) { 457 if (compiler->is_optimizing() && FLAG_propagate_ic_data) {
465 ASSERT(!original_ic_data.IsNull()); 458 ASSERT(!original_ic_data.IsNull());
466 if (original_ic_data.NumberOfChecks() == 0) { 459 if (original_ic_data.NumberOfChecks() == 0) {
467 // IC call for reoptimization populates original ICData. 460 // IC call for reoptimization populates original ICData.
468 equality_ic_data = original_ic_data.raw(); 461 equality_ic_data = original_ic_data.raw();
469 } else { 462 } else {
470 // Megamorphic call. 463 // Megamorphic call.
471 equality_ic_data = original_ic_data.AsUnaryClassChecks(); 464 equality_ic_data = original_ic_data.AsUnaryClassChecks();
472 } 465 }
473 } else { 466 } else {
474 const Array& arguments_descriptor = 467 const Array& arguments_descriptor =
475 Array::Handle(ArgumentsDescriptor::New(kNumberOfArguments, 468 Array::Handle(ArgumentsDescriptor::New(kNumberOfArguments,
476 kNoArgumentNames)); 469 kNoArgumentNames));
477 equality_ic_data = ICData::New(compiler->parsed_function().function(), 470 equality_ic_data = ICData::New(compiler->parsed_function().function(),
478 Symbols::EqualOperator(), 471 Symbols::EqualOperator(),
479 arguments_descriptor, 472 arguments_descriptor,
480 deopt_id, 473 deopt_id,
481 kNumArgumentsChecked); 474 kNumArgumentsChecked);
482 } 475 }
483 compiler->GenerateInstanceCall(deopt_id, 476 compiler->GenerateInstanceCall(deopt_id,
484 token_pos, 477 token_pos,
485 kNumberOfArguments, 478 kNumberOfArguments,
486 kNoArgumentNames, 479 kNoArgumentNames,
487 locs, 480 locs,
488 equality_ic_data); 481 equality_ic_data);
489 Label check_ne;
490 __ jmp(&check_ne);
491
492 __ Bind(&check_identity);
493 Label equality_done;
494 if (compiler->is_optimizing()) {
495 // No need to update IC data.
496 Label is_true;
497 __ popq(RAX);
498 __ popq(RDX);
499 __ cmpq(RAX, RDX);
500 __ j(EQUAL, &is_true);
501 __ LoadObject(RAX, Bool::Get(kind != Token::kEQ), PP);
502 __ jmp(&equality_done);
503 __ Bind(&is_true);
504 __ LoadObject(RAX, Bool::Get(kind == Token::kEQ), PP);
505 if (kind == Token::kNE) {
506 // Skip not-equal result conversion.
507 __ jmp(&equality_done);
508 }
509 } else {
510 // Call stub, load IC data in register. The stub will update ICData if
511 // necessary.
512 Register ic_data_reg = locs->temp(0).reg();
513 ASSERT(ic_data_reg == RBX); // Stub depends on it.
514 __ LoadObject(ic_data_reg, equality_ic_data, PP);
515 compiler->GenerateCall(token_pos,
516 &StubCode::EqualityWithNullArgLabel(),
517 PcDescriptors::kRuntimeCall,
518 locs);
519 __ Drop(2);
520 }
521 __ Bind(&check_ne);
522 if (kind == Token::kNE) { 482 if (kind == Token::kNE) {
523 Label true_label, done; 483 Label true_label, done;
524 // Negate the condition: true label returns false and vice versa. 484 // Negate the condition: true label returns false and vice versa.
525 __ CompareObject(RAX, Bool::True(), PP); 485 __ CompareObject(RAX, Bool::True(), PP);
526 __ j(EQUAL, &true_label, Assembler::kNearJump); 486 __ j(EQUAL, &true_label, Assembler::kNearJump);
527 __ LoadObject(RAX, Bool::True(), PP); 487 __ LoadObject(RAX, Bool::True(), PP);
528 __ jmp(&done, Assembler::kNearJump); 488 __ jmp(&done, Assembler::kNearJump);
529 __ Bind(&true_label); 489 __ Bind(&true_label);
530 __ LoadObject(RAX, Bool::False(), PP); 490 __ LoadObject(RAX, Bool::False(), PP);
531 __ Bind(&done); 491 __ Bind(&done);
532 } 492 }
533 __ Bind(&equality_done);
534 } 493 }
535 494
536 495
537 static void LoadValueCid(FlowGraphCompiler* compiler, 496 static void LoadValueCid(FlowGraphCompiler* compiler,
538 Register value_cid_reg, 497 Register value_cid_reg,
539 Register value_reg, 498 Register value_reg,
540 Label* value_is_smi = NULL) { 499 Label* value_is_smi = NULL) {
541 Label done; 500 Label done;
542 if (value_is_smi == NULL) { 501 if (value_is_smi == NULL) {
543 __ LoadImmediate(value_cid_reg, Immediate(kSmiCid), PP); 502 __ LoadImmediate(value_cid_reg, Immediate(kSmiCid), PP);
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 LocationSummary* locs, 656 LocationSummary* locs,
698 Token::Kind kind, 657 Token::Kind kind,
699 BranchInstr* branch, 658 BranchInstr* branch,
700 const ICData& ic_data, 659 const ICData& ic_data,
701 intptr_t deopt_id, 660 intptr_t deopt_id,
702 intptr_t token_pos) { 661 intptr_t token_pos) {
703 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); 662 ASSERT((kind == Token::kEQ) || (kind == Token::kNE));
704 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); 663 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0));
705 Register left = locs->in(0).reg(); 664 Register left = locs->in(0).reg();
706 Register right = locs->in(1).reg(); 665 Register right = locs->in(1).reg();
707
708 Label done, identity_compare, non_null_compare;
709 __ CompareObject(right, Object::null_object(), PP);
710 __ j(EQUAL, &identity_compare, Assembler::kNearJump);
711 __ CompareObject(left, Object::null_object(), PP);
712 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump);
713 // Comparison with NULL is "===".
714 __ Bind(&identity_compare);
715 __ cmpq(left, right);
716 Condition cond = TokenKindToSmiCondition(kind);
717 if (branch != NULL) {
718 branch->EmitBranchOnCondition(compiler, cond);
719 } else {
720 Register result = locs->out().reg();
721 Label load_true;
722 __ j(cond, &load_true, Assembler::kNearJump);
723 __ LoadObject(result, Bool::False(), PP);
724 __ jmp(&done);
725 __ Bind(&load_true);
726 __ LoadObject(result, Bool::True(), PP);
727 }
728 __ jmp(&done);
729 __ Bind(&non_null_compare); // Receiver is not null.
730 __ pushq(left); 666 __ pushq(left);
731 __ pushq(right); 667 __ pushq(right);
732 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind, 668 EmitEqualityAsPolymorphicCall(compiler, ic_data, locs, branch, kind,
733 deopt_id, token_pos); 669 deopt_id, token_pos);
734 __ Bind(&done);
735 } 670 }
736 671
737 672
738 static Condition FlipCondition(Condition condition) { 673 static Condition FlipCondition(Condition condition) {
739 switch (condition) { 674 switch (condition) {
740 case EQUAL: return EQUAL; 675 case EQUAL: return EQUAL;
741 case NOT_EQUAL: return NOT_EQUAL; 676 case NOT_EQUAL: return NOT_EQUAL;
742 case LESS: return GREATER; 677 case LESS: return GREATER;
743 case LESS_EQUAL: return GREATER_EQUAL; 678 case LESS_EQUAL: return GREATER_EQUAL;
744 case GREATER: return LESS; 679 case GREATER: return LESS;
(...skipping 4115 matching lines...) Expand 10 before | Expand all | Expand 10 after
4860 PcDescriptors::kOther, 4795 PcDescriptors::kOther,
4861 locs()); 4796 locs());
4862 __ Drop(2); // Discard type arguments and receiver. 4797 __ Drop(2); // Discard type arguments and receiver.
4863 } 4798 }
4864 4799
4865 } // namespace dart 4800 } // namespace dart
4866 4801
4867 #undef __ 4802 #undef __
4868 4803
4869 #endif // defined TARGET_ARCH_X64 4804 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | runtime/vm/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698