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

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

Issue 10543013: More code for ia32, more shared code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 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.h ('k') | runtime/vm/intermediate_language_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/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"
10 #include "vm/locations.h"
9 #include "vm/object.h" 11 #include "vm/object.h"
10 #include "vm/os.h" 12 #include "vm/os.h"
11 #include "vm/scopes.h" 13 #include "vm/scopes.h"
14 #include "vm/stub_code.h"
12 15
13 namespace dart { 16 namespace dart {
14 17
15 // ==== Support for visiting flow graphs. 18 // ==== Support for visiting flow graphs.
16 #define DEFINE_ACCEPT(ShortName, ClassName) \ 19 #define DEFINE_ACCEPT(ShortName, ClassName) \
17 void ClassName::Accept(FlowGraphVisitor* visitor) { \ 20 void ClassName::Accept(FlowGraphVisitor* visitor) { \
18 visitor->Visit##ShortName(this); \ 21 visitor->Visit##ShortName(this); \
19 } 22 }
20 23
21 FOR_EACH_COMPUTATION(DEFINE_ACCEPT) 24 FOR_EACH_COMPUTATION(DEFINE_ACCEPT)
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after
579 RawAbstractType* UnarySmiOpComp::StaticType() const { 582 RawAbstractType* UnarySmiOpComp::StaticType() const {
580 return Type::IntInterface(); 583 return Type::IntInterface();
581 } 584 }
582 585
583 586
584 RawAbstractType* NumberNegateComp::StaticType() const { 587 RawAbstractType* NumberNegateComp::StaticType() const {
585 return Type::NumberInterface(); 588 return Type::NumberInterface();
586 } 589 }
587 590
588 591
592 // Shared code generation methods (EmitNativeCode, MakeLocationSummary, and
593 // PrepareEntry). Only assembly code that can be shared across all architectures
594 // can be used. Machine specific register allocation and code generation
595 // is located in intermediate_language_<arch>.cc
596
597
598 // True iff. the arguments to a call will be properly pushed and can
599 // be popped after the call.
600 template <typename T> static bool VerifyCallComputation(T* comp) {
601 // Argument values should be consecutive temps.
602 //
603 // TODO(kmillikin): implement stack height tracking so we can also assert
604 // they are on top of the stack.
605 intptr_t previous = -1;
606 for (int i = 0; i < comp->ArgumentCount(); ++i) {
607 Value* val = comp->ArgumentAt(i);
608 if (!val->IsUse()) return false;
609 intptr_t current = val->AsUse()->definition()->temp_index();
610 if (i != 0) {
611 if (current != (previous + 1)) return false;
612 }
613 previous = current;
614 }
615 return true;
616 }
617
618
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()->
628
629 void GraphEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) {
630 // Nothing to do.
631 }
632
633
634 void JoinEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) {
635 __ Bind(compiler->GetBlockLabel(this));
636 }
637
638
639 void TargetEntryInstr::PrepareEntry(FlowGraphCompiler* compiler) {
640 __ Bind(compiler->GetBlockLabel(this));
641 if (HasTryIndex()) {
642 compiler->AddExceptionHandler(try_index(),
643 compiler->assembler()->CodeSize());
644 }
645 }
646
647
648 LocationSummary* ThrowInstr::MakeLocationSummary() const {
649 const int kNumInputs = 0;
650 const int kNumTemps = 0;
651 return new LocationSummary(kNumInputs, kNumTemps);
652 }
653
654
655
656 void ThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
657 ASSERT(exception()->IsUse());
658 compiler->GenerateCallRuntime(cid(),
659 token_index(),
660 try_index(),
661 kThrowRuntimeEntry);
662 __ int3();
Ivan Posva 2012/06/07 06:54:27 How can this be shared code?
663 }
664
665
666 LocationSummary* ReThrowInstr::MakeLocationSummary() const {
667 const int kNumInputs = 0;
668 const int kNumTemps = 0;
669 return new LocationSummary(kNumInputs, kNumTemps);
670 }
671
672
673 void ReThrowInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
674 ASSERT(exception()->IsUse());
675 ASSERT(stack_trace()->IsUse());
676 compiler->GenerateCallRuntime(cid(),
677 token_index(),
678 try_index(),
679 kReThrowRuntimeEntry);
680 __ int3();
Ivan Posva 2012/06/07 06:54:27 ditto!
681 }
682
683
684 LocationSummary* BranchInstr::MakeLocationSummary() const {
685 const int kNumInputs = 1;
686 const int kNumTemps = 0;
687 LocationSummary* locs = new LocationSummary(kNumInputs, kNumTemps);
688 locs->set_in(0, Location::RequiresRegister());
689 return locs;
690 }
691
692
693 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
694 Register value = locs()->in(0).reg();
695 __ CompareObject(value, Bool::ZoneHandle(Bool::True()));
696 if (compiler->IsNextBlock(false_successor())) {
697 // If the next block is the false successor we will fall through to it if
698 // comparison with true fails.
699 __ j(EQUAL, compiler->GetBlockLabel(true_successor()));
Ivan Posva 2012/06/07 06:54:27 This is definitely not a portable assembler instru
700 } else {
701 ASSERT(compiler->IsNextBlock(true_successor()));
702 // If the next block is the true successor we negate comparison and fall
703 // through to it.
704 __ j(NOT_EQUAL, compiler->GetBlockLabel(false_successor()));
705 }
706 }
707
708
709 LocationSummary* CurrentContextComp::MakeLocationSummary() const {
710 return LocationSummary::Make(0, Location::RequiresRegister());
711 }
712
713
714 void CurrentContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
715 __ MoveRegister(locs()->out().reg(), CTX);
Ivan Posva 2012/06/07 06:54:27 CTX sounds like a very CPU-specific register to me
716 }
717
718
719 LocationSummary* StoreContextComp::MakeLocationSummary() const {
720 const intptr_t kNumInputs = 1;
721 const intptr_t kNumTemps = 0;
722 LocationSummary* summary = new LocationSummary(kNumInputs, kNumTemps);
723 summary->set_in(0, Location::RegisterLocation(CTX));
724 return summary;
725 }
726
727
728 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
729 // Nothing to do. Context register were loaded by register allocator.
730 ASSERT(locs()->in(0).reg() == CTX);
731 }
732
733
734 LocationSummary* StrictCompareComp::MakeLocationSummary() const {
735 return LocationSummary::Make(2, Location::SameAsFirstInput());
736 }
737
738
739 void StrictCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) {
740 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
741 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
742
743 Register left = locs()->in(0).reg();
744 Register right = locs()->in(1).reg();
745 Register result = locs()->out().reg();
746
747 __ CompareRegisters(left, right);
748 Label load_true, done;
749 if (kind() == Token::kEQ_STRICT) {
750 __ j(EQUAL, &load_true, Assembler::kNearJump);
751 } else {
752 ASSERT(kind() == Token::kNE_STRICT);
753 __ j(NOT_EQUAL, &load_true, Assembler::kNearJump);
754 }
755 __ LoadObject(result, bool_false);
756 __ jmp(&done, Assembler::kNearJump);
757 __ Bind(&load_true);
758 __ LoadObject(result, bool_true);
759 __ Bind(&done);
760 }
761
762
763 void ClosureCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
764 ASSERT(VerifyCallComputation(this));
765 // The arguments to the stub include the closure. The arguments
766 // descriptor describes the closure's arguments (and so does not include
767 // the closure).
768 Register temp_reg = locs()->temp(0).reg();
769 int argument_count = ArgumentCount();
770 const Array& arguments_descriptor =
771 CodeGenerator::ArgumentsDescriptor(argument_count - 1,
772 argument_names());
773 __ LoadObject(temp_reg, arguments_descriptor);
774
775 compiler->GenerateCall(token_index(),
776 try_index(),
777 &StubCode::CallClosureFunctionLabel(),
778 PcDescriptors::kOther);
779 __ Drop(argument_count);
780 }
781
782
783 LocationSummary* InstanceCallComp::MakeLocationSummary() const {
784 return MakeCallSummary();
785 }
786
787
788 void InstanceCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
789 ASSERT(VerifyCallComputation(this));
790 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
791 cid(),
792 token_index(),
793 try_index());
794 compiler->GenerateInstanceCall(cid(),
795 token_index(),
796 try_index(),
797 function_name(),
798 ArgumentCount(),
799 argument_names(),
800 checked_argument_count());
801 }
802
803
804 LocationSummary* StaticCallComp::MakeLocationSummary() const {
805 return MakeCallSummary();
806 }
807
808
809 void StaticCallComp::EmitNativeCode(FlowGraphCompiler* compiler) {
810 ASSERT(VerifyCallComputation(this));
811 compiler->GenerateStaticCall(cid(),
812 token_index(),
813 try_index(),
814 function(),
815 ArgumentCount(),
816 argument_names());
817 }
818
819
820 LocationSummary* UseVal::MakeLocationSummary() const {
821 return NULL;
822 }
823
824
825 void UseVal::EmitNativeCode(FlowGraphCompiler* compiler) {
826 UNIMPLEMENTED();
827 }
828
829
830 void AssertAssignableComp::EmitNativeCode(FlowGraphCompiler* compiler) {
831 compiler->GenerateAssertAssignable(cid(),
832 token_index(),
833 try_index(),
834 dst_type(),
835 dst_name());
836 ASSERT(locs()->in(0).reg() == locs()->out().reg());
837 }
838
839
840 LocationSummary* AssertBooleanComp::MakeLocationSummary() const {
841 return LocationSummary::Make(1, Location::SameAsFirstInput());
842 }
843
844
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 {
865 LocationSummary* locs = new LocationSummary(1, 1);
866 locs->set_in(0, Location::RequiresRegister());
867 locs->set_temp(0, Location::RequiresRegister());
868 locs->set_out(Location::SameAsFirstInput());
869 return locs;
870 }
871
872
873 void StoreStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
874 Register value = locs()->in(0).reg();
875 Register temp = locs()->temp(0).reg();
876 ASSERT(locs()->out().reg() == value);
877
878 __ LoadObject(temp, field());
879 __ StoreIntoObject(temp, FieldAddress(temp, Field::value_offset()), value);
880 }
881
882
883 LocationSummary* BooleanNegateComp::MakeLocationSummary() const {
884 return LocationSummary::Make(1, Location::RequiresRegister());
885 }
886
887
888 void BooleanNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) {
889 Register value = locs()->in(0).reg();
890 Register result = locs()->out().reg();
891
892 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
893 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
894 Label done;
895 __ LoadObject(result, bool_true);
896 __ CompareRegisters(result, value);
897 __ j(NOT_EQUAL, &done, Assembler::kNearJump);
898 __ LoadObject(result, bool_false);
899 __ Bind(&done);
900 }
901
902
903 LocationSummary* ChainContextComp::MakeLocationSummary() const {
904 return LocationSummary::Make(1, Location::NoLocation());
905 }
906
907
908 void ChainContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
909 Register context_value = locs()->in(0).reg();
910
911 // Chain the new context in context_value to its parent in CTX.
912 __ StoreIntoObject(context_value,
913 FieldAddress(context_value, Context::parent_offset()),
914 CTX);
915 // Set new context as current context.
916 __ MoveRegister(CTX, context_value);
917 }
918
919
920 LocationSummary* StoreVMFieldComp::MakeLocationSummary() const {
921 return LocationSummary::Make(2, Location::SameAsFirstInput());
922 }
923
924
925 void StoreVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) {
926 Register value_reg = locs()->in(0).reg();
927 Register dest_reg = locs()->in(1).reg();
928 ASSERT(value_reg == locs()->out().reg());
929
930 __ StoreIntoObject(dest_reg, FieldAddress(dest_reg, offset_in_bytes()),
931 value_reg);
932 }
933
934
935 LocationSummary* AllocateObjectComp::MakeLocationSummary() const {
936 return MakeCallSummary();
937 }
938
939
940 void AllocateObjectComp::EmitNativeCode(FlowGraphCompiler* compiler) {
941 const Class& cls = Class::ZoneHandle(constructor().owner());
942 const Code& stub = Code::Handle(StubCode::GetAllocationStubForClass(cls));
943 const ExternalLabel label(cls.ToCString(), stub.EntryPoint());
944 compiler->GenerateCall(token_index(),
945 try_index(),
946 &label,
947 PcDescriptors::kOther);
948 __ Drop(arguments().length()); // Discard arguments.
949 }
950
951
952 LocationSummary* CreateClosureComp::MakeLocationSummary() const {
953 return MakeCallSummary();
954 }
955
956
957 void CreateClosureComp::EmitNativeCode(FlowGraphCompiler* compiler) {
958 const Function& closure_function = function();
959 const Code& stub = Code::Handle(
960 StubCode::GetAllocationStubForClosure(closure_function));
961 const ExternalLabel label(closure_function.ToCString(), stub.EntryPoint());
962 compiler->GenerateCall(token_index(), try_index(), &label,
963 PcDescriptors::kOther);
964 __ Drop(2); // Discard type arguments and receiver.
965 }
966
967 #undef __
589 968
590 } // namespace dart 969 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/intermediate_language_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698