| OLD | NEW |
| 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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
| 9 #include "vm/flow_graph_compiler.h" | 9 #include "vm/flow_graph_compiler.h" |
| 10 #include "vm/locations.h" | 10 #include "vm/locations.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 Instruction* ShortName##Instr::Accept(FlowGraphVisitor* visitor) { \ | 30 Instruction* ShortName##Instr::Accept(FlowGraphVisitor* visitor) { \ |
| 31 visitor->Visit##ShortName(this); \ | 31 visitor->Visit##ShortName(this); \ |
| 32 return StraightLineSuccessor(); \ | 32 return StraightLineSuccessor(); \ |
| 33 } | 33 } |
| 34 | 34 |
| 35 FOR_EACH_INSTRUCTION(DEFINE_ACCEPT) | 35 FOR_EACH_INSTRUCTION(DEFINE_ACCEPT) |
| 36 | 36 |
| 37 #undef DEFINE_ACCEPT | 37 #undef DEFINE_ACCEPT |
| 38 | 38 |
| 39 | 39 |
| 40 // Truee iff. the v2 is above v1 on stack, or one of them is constant. |
| 41 static bool VerifyValues(Value* v1, Value* v2) { |
| 42 ASSERT(v1->IsUse() && v2->IsUse()); |
| 43 return (v1->AsUse()->definition()->temp_index() + 1) == |
| 44 v2->AsUse()->definition()->temp_index(); |
| 45 } |
| 46 |
| 47 |
| 40 // Default implementation of visiting basic blocks. Can be overridden. | 48 // Default implementation of visiting basic blocks. Can be overridden. |
| 41 void FlowGraphVisitor::VisitBlocks() { | 49 void FlowGraphVisitor::VisitBlocks() { |
| 42 for (intptr_t i = 0; i < block_order_.length(); ++i) { | 50 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| 43 Instruction* current = block_order_[i]->Accept(this); | 51 Instruction* current = block_order_[i]->Accept(this); |
| 44 while ((current != NULL) && !current->IsBlockEntry()) { | 52 while ((current != NULL) && !current->IsBlockEntry()) { |
| 45 current = current->Accept(this); | 53 current = current->Accept(this); |
| 46 } | 54 } |
| 47 } | 55 } |
| 48 } | 56 } |
| 49 | 57 |
| (...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 intptr_t current = val->AsUse()->definition()->temp_index(); | 617 intptr_t current = val->AsUse()->definition()->temp_index(); |
| 610 if (i != 0) { | 618 if (i != 0) { |
| 611 if (current != (previous + 1)) return false; | 619 if (current != (previous + 1)) return false; |
| 612 } | 620 } |
| 613 previous = current; | 621 previous = current; |
| 614 } | 622 } |
| 615 return true; | 623 return true; |
| 616 } | 624 } |
| 617 | 625 |
| 618 | 626 |
| 619 // Truee iff. the v2 is above v1 on stack, or one of them is constant. | |
| 620 static bool VerifyValues(Value* v1, Value* v2) { | |
| 621 ASSERT(v1->IsUse() && v2->IsUse()); | |
| 622 return (v1->AsUse()->definition()->temp_index() + 1) == | |
| 623 v2->AsUse()->definition()->temp_index(); | |
| 624 } | |
| 625 | |
| 626 | |
| 627 #define __ compiler->assembler()-> | 627 #define __ compiler->assembler()-> |
| 628 | 628 |
| 629 void GraphEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { | 629 void GraphEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { |
| 630 // Nothing to do. | 630 // Nothing to do. |
| 631 } | 631 } |
| 632 | 632 |
| 633 | 633 |
| 634 void JoinEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { | 634 void JoinEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { |
| 635 __ Bind(compiler->GetBlockLabel(this)); | 635 __ Bind(compiler->GetBlockLabel(this)); |
| 636 } | 636 } |
| 637 | 637 |
| 638 | 638 |
| 639 void TargetEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { | 639 void TargetEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) { |
| 640 __ Bind(compiler->GetBlockLabel(this)); | 640 __ Bind(compiler->GetBlockLabel(this)); |
| 641 if (HasTryIndex()) { | 641 if (HasTryIndex()) { |
| 642 compiler->AddExceptionHandler(try_index(), | 642 compiler->AddExceptionHandler(try_index(), |
| 643 compiler->assembler()->CodeSize()); | 643 compiler->assembler()->CodeSize()); |
| 644 } | 644 } |
| 645 } | 645 } |
| 646 | 646 |
| 647 | 647 |
| 648 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { |
| 649 const intptr_t kNumInputs = 2; |
| 650 intptr_t num_temps = (class_ids() == NULL) ? 0 : 1; |
| 651 LocationSummary* summary = new LocationSummary(kNumInputs, num_temps); |
| 652 summary->set_in(0, Location::RequiresRegister()); |
| 653 summary->set_in(1, Location::RequiresRegister()); |
| 654 if (class_ids() != NULL) { |
| 655 summary->set_temp(0, Location::RequiresRegister()); |
| 656 } |
| 657 return summary; |
| 658 } |
| 659 |
| 660 |
| 661 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 662 ASSERT(VerifyValues(instance(), value())); |
| 663 Register instance = locs()->in(0).reg(); |
| 664 Register value = locs()->in(1).reg(); |
| 665 |
| 666 if (class_ids() != NULL) { |
| 667 ASSERT(original() != NULL); |
| 668 Label* deopt = compiler->AddDeoptStub(original()->cid(), |
| 669 original()->token_index(), |
| 670 original()->try_index(), |
| 671 kDeoptInstanceGetterSameTarget, |
| 672 instance, |
| 673 value); |
| 674 // Smis do not have instance fields (Smi class is always first). |
| 675 Register temp = locs()->temp(0).reg(); |
| 676 ASSERT(temp != instance); |
| 677 ASSERT(temp != value); |
| 678 compiler->EmitClassChecksNoSmi(*class_ids(), instance, temp, deopt); |
| 679 } |
| 680 __ StoreIntoObject(instance, FieldAddress(instance, field().Offset()), |
| 681 value); |
| 682 } |
| 683 |
| 684 |
| 648 LocationSummary* ThrowInstr::MakeLocationSummary() const { | 685 LocationSummary* ThrowInstr::MakeLocationSummary() const { |
| 649 const int kNumInputs = 0; | 686 const int kNumInputs = 0; |
| 650 const int kNumTemps = 0; | 687 const int kNumTemps = 0; |
| 651 return new LocationSummary(kNumInputs, kNumTemps); | 688 return new LocationSummary(kNumInputs, kNumTemps); |
| 652 } | 689 } |
| 653 | 690 |
| 654 | 691 |
| 655 | 692 |
| 656 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 693 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 657 ASSERT(exception()->IsUse()); | 694 ASSERT(exception()->IsUse()); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 835 dst_name()); | 872 dst_name()); |
| 836 ASSERT(locs()->in(0).reg() == locs()->out().reg()); | 873 ASSERT(locs()->in(0).reg() == locs()->out().reg()); |
| 837 } | 874 } |
| 838 | 875 |
| 839 | 876 |
| 840 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { | 877 LocationSummary* AssertBooleanComp::MakeLocationSummary() const { |
| 841 return LocationSummary::Make(1, Location::SameAsFirstInput()); | 878 return LocationSummary::Make(1, Location::SameAsFirstInput()); |
| 842 } | 879 } |
| 843 | 880 |
| 844 | 881 |
| 845 LocationSummary* StoreInstanceFieldComp::MakeLocationSummary() const { | |
| 846 return LocationSummary::Make(2, Location::RequiresRegister()); | |
| 847 } | |
| 848 | |
| 849 | |
| 850 void StoreInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 851 ASSERT(VerifyValues(instance(), value())); | |
| 852 Register instance = locs()->in(0).reg(); | |
| 853 Register value = locs()->in(1).reg(); | |
| 854 Register result = locs()->out().reg(); | |
| 855 | |
| 856 __ StoreIntoObject(instance, FieldAddress(instance, field().Offset()), | |
| 857 value); | |
| 858 // TODO(fschneider): Consider eliminating this move by specifying a | |
| 859 // SameAsSecondInput for the result. | |
| 860 __ MoveRegister(result, value); | |
| 861 } | |
| 862 | |
| 863 | |
| 864 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const { | 882 LocationSummary* StoreStaticFieldComp::MakeLocationSummary() const { |
| 865 LocationSummary* locs = new LocationSummary(1, 1); | 883 LocationSummary* locs = new LocationSummary(1, 1); |
| 866 locs->set_in(0, Location::RequiresRegister()); | 884 locs->set_in(0, Location::RequiresRegister()); |
| 867 locs->set_temp(0, Location::RequiresRegister()); | 885 locs->set_temp(0, Location::RequiresRegister()); |
| 868 locs->set_out(Location::SameAsFirstInput()); | 886 locs->set_out(Location::SameAsFirstInput()); |
| 869 return locs; | 887 return locs; |
| 870 } | 888 } |
| 871 | 889 |
| 872 | 890 |
| 873 void StoreStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 891 void StoreStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 960 StubCode::GetAllocationStubForClosure(closure_function)); | 978 StubCode::GetAllocationStubForClosure(closure_function)); |
| 961 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); | 979 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint()); |
| 962 compiler->GenerateCall(token_index(), try_index(), &label, | 980 compiler->GenerateCall(token_index(), try_index(), &label, |
| 963 PcDescriptors::kOther); | 981 PcDescriptors::kOther); |
| 964 __ Drop(2); // Discard type arguments and receiver. | 982 __ Drop(2); // Discard type arguments and receiver. |
| 965 } | 983 } |
| 966 | 984 |
| 967 #undef __ | 985 #undef __ |
| 968 | 986 |
| 969 } // namespace dart | 987 } // namespace dart |
| OLD | NEW |