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

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

Issue 10447133: FlowGraphCompiler is not a visitor any longer. Start consolidating shared code between the x64 and … (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
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/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 try_index_); 80 try_index_);
81 #undef __ 81 #undef __
82 } 82 }
83 83
84 84
85 FlowGraphCompiler::FlowGraphCompiler( 85 FlowGraphCompiler::FlowGraphCompiler(
86 Assembler* assembler, 86 Assembler* assembler,
87 const ParsedFunction& parsed_function, 87 const ParsedFunction& parsed_function,
88 const GrowableArray<BlockEntryInstr*>& block_order, 88 const GrowableArray<BlockEntryInstr*>& block_order,
89 bool is_optimizing) 89 bool is_optimizing)
90 : FlowGraphVisitor(block_order), 90 : FlowGraphCompilerShared(parsed_function, block_order.length()),
91 assembler_(assembler), 91 assembler_(assembler),
92 parsed_function_(parsed_function), 92 block_order_(block_order),
93 block_info_(block_order.length()),
94 current_block_(NULL), 93 current_block_(NULL),
95 pc_descriptors_list_(NULL),
96 stackmap_builder_(NULL),
97 exception_handlers_list_(NULL),
98 deopt_stubs_(), 94 deopt_stubs_(),
99 is_optimizing_(is_optimizing) { 95 is_optimizing_(is_optimizing) {
100 } 96 }
101 97
102 98
103 void FlowGraphCompiler::InitCompiler() {
104 pc_descriptors_list_ = new DescriptorList();
105 exception_handlers_list_ = new ExceptionHandlerList();
106 block_info_.Clear();
107 for (int i = 0; i < block_order_.length(); ++i) {
108 block_info_.Add(new BlockInfo());
109 }
110 }
111
112
113 FlowGraphCompiler::~FlowGraphCompiler() {
114 // BlockInfos are zone-allocated, so their destructors are not called.
115 // Verify the labels explicitly here.
116 for (int i = 0; i < block_info_.length(); ++i) {
117 ASSERT(!block_info_[i]->label.IsLinked());
118 ASSERT(!block_info_[i]->label.HasNear());
119 }
120 }
121
122
123 intptr_t FlowGraphCompiler::StackSize() const { 99 intptr_t FlowGraphCompiler::StackSize() const {
124 return parsed_function_.stack_local_count() + 100 return parsed_function().stack_local_count() +
125 parsed_function_.copied_parameter_count(); 101 parsed_function().copied_parameter_count();
126 } 102 }
127 103
128 104
129 void FlowGraphCompiler::Bailout(const char* reason) { 105 void FlowGraphCompiler::Bailout(const char* reason) {
130 const char* kFormat = "FlowGraphCompiler Bailout: %s %s."; 106 const char* kFormat = "FlowGraphCompiler Bailout: %s %s.";
131 const char* function_name = parsed_function_.function().ToCString(); 107 const char* function_name = parsed_function().function().ToCString();
132 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 108 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
133 char* chars = reinterpret_cast<char*>( 109 char* chars = reinterpret_cast<char*>(
134 Isolate::Current()->current_zone()->Allocate(len)); 110 Isolate::Current()->current_zone()->Allocate(len));
135 OS::SNPrint(chars, len, kFormat, function_name, reason); 111 OS::SNPrint(chars, len, kFormat, function_name, reason);
136 const Error& error = Error::Handle( 112 const Error& error = Error::Handle(
137 LanguageError::New(String::Handle(String::New(chars)))); 113 LanguageError::New(String::Handle(String::New(chars))));
138 Isolate::Current()->long_jump_base()->Jump(1, error); 114 Isolate::Current()->long_jump_base()->Jump(1, error);
139 } 115 }
140 116
141 117
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 } else { 591 } else {
616 __ LoadObject(dst, value->AsConstant()->value()); 592 __ LoadObject(dst, value->AsConstant()->value());
617 } 593 }
618 } else { 594 } else {
619 ASSERT(value->IsUse()); 595 ASSERT(value->IsUse());
620 __ popq(dst); 596 __ popq(dst);
621 } 597 }
622 } 598 }
623 599
624 600
625 void FlowGraphCompiler::VisitUse(UseVal* val) {
626 // UseVal is never visited during code generation.
627 UNREACHABLE();
628 }
629
630
631 void FlowGraphCompiler::VisitConstant(ConstantVal* val) {
632 // Moved to intermediate_language_x64.cc.
633 UNREACHABLE();
634 }
635
636
637 void FlowGraphCompiler::VisitAssertAssignable(AssertAssignableComp* comp) {
638 // Moved to intermediate_language_x64.cc.
639 UNREACHABLE();
640 }
641
642
643 void FlowGraphCompiler::VisitAssertBoolean(AssertBooleanComp* comp) {
644 // Moved to intermediate_language_x64.cc.
645 UNREACHABLE();
646 }
647
648
649 void FlowGraphCompiler::EmitInstanceCall(intptr_t cid, 601 void FlowGraphCompiler::EmitInstanceCall(intptr_t cid,
650 intptr_t token_index, 602 intptr_t token_index,
651 intptr_t try_index, 603 intptr_t try_index,
652 const String& function_name, 604 const String& function_name,
653 intptr_t argument_count, 605 intptr_t argument_count,
654 const Array& argument_names, 606 const Array& argument_names,
655 intptr_t checked_argument_count) { 607 intptr_t checked_argument_count) {
656 ICData& ic_data = 608 ICData& ic_data =
657 ICData::ZoneHandle(ICData::New(parsed_function_.function(), 609 ICData::ZoneHandle(ICData::New(parsed_function().function(),
658 function_name, 610 function_name,
659 cid, 611 cid,
660 checked_argument_count)); 612 checked_argument_count));
661 const Array& arguments_descriptor = 613 const Array& arguments_descriptor =
662 CodeGenerator::ArgumentsDescriptor(argument_count, argument_names); 614 CodeGenerator::ArgumentsDescriptor(argument_count, argument_names);
663 __ LoadObject(RBX, ic_data); 615 __ LoadObject(RBX, ic_data);
664 __ LoadObject(R10, arguments_descriptor); 616 __ LoadObject(R10, arguments_descriptor);
665 617
666 uword label_address = 0; 618 uword label_address = 0;
667 switch (checked_argument_count) { 619 switch (checked_argument_count) {
(...skipping 24 matching lines...) Expand all
692 __ LoadObject(R10, arguments_descriptor); 644 __ LoadObject(R10, arguments_descriptor);
693 645
694 GenerateCall(token_index, 646 GenerateCall(token_index,
695 try_index, 647 try_index,
696 &StubCode::CallStaticFunctionLabel(), 648 &StubCode::CallStaticFunctionLabel(),
697 PcDescriptors::kFuncCall); 649 PcDescriptors::kFuncCall);
698 __ Drop(argument_count); 650 __ Drop(argument_count);
699 } 651 }
700 652
701 653
702 void FlowGraphCompiler::VisitCurrentContext(CurrentContextComp* comp) {
703 // Moved to intermediate_language_x64.cc.
704 UNREACHABLE();
705 }
706
707
708 void FlowGraphCompiler::VisitStoreContext(StoreContextComp* comp) {
709 // Moved to intermediate_language_x64.cc.
710 UNREACHABLE();
711 }
712
713
714 void FlowGraphCompiler::VisitClosureCall(ClosureCallComp* comp) {
715 // Moved to intermediate_language_x64.cc.
716 UNREACHABLE();
717 }
718
719
720 void FlowGraphCompiler::VisitInstanceCall(InstanceCallComp* comp) {
721 // Moved to intermediate_language_x64.cc.
722 UNREACHABLE();
723 }
724
725
726 void FlowGraphCompiler::VisitStrictCompare(StrictCompareComp* comp) {
727 // Moved to intermediate_language_x64.cc.
728 UNREACHABLE();
729 }
730
731
732 void FlowGraphCompiler::VisitEqualityCompare(EqualityCompareComp* comp) {
733 // Moved to intermediate_language_x64.cc.
734 UNREACHABLE();
735 }
736
737
738 void FlowGraphCompiler::VisitStaticCall(StaticCallComp* comp) {
739 // Moved to intermediate_language_x64.cc.
740 UNREACHABLE();
741 }
742
743
744 void FlowGraphCompiler::VisitLoadLocal(LoadLocalComp* comp) {
745 // Moved to intermediate_language_x64.cc.
746 UNREACHABLE();
747 }
748
749
750 void FlowGraphCompiler::VisitStoreLocal(StoreLocalComp* comp) {
751 // Moved to intermediate_language_x64.cc.
752 UNREACHABLE();
753 }
754
755
756 void FlowGraphCompiler::VisitNativeCall(NativeCallComp* comp) {
757 // Moved to intermediate_language_x64.cc.
758 UNREACHABLE();
759 }
760
761
762 void FlowGraphCompiler::VisitLoadInstanceField(LoadInstanceFieldComp* comp) {
763 // Moved to intermediate_language_x64.cc.
764 UNREACHABLE();
765 }
766
767
768 void FlowGraphCompiler::VisitStoreInstanceField(StoreInstanceFieldComp* comp) {
769 // Moved to intermediate_language_x64.cc.
770 UNREACHABLE();
771 }
772
773
774
775 void FlowGraphCompiler::VisitLoadStaticField(LoadStaticFieldComp* comp) {
776 // Moved to intermediate_language_x64.cc.
777 UNREACHABLE();
778 }
779
780
781 void FlowGraphCompiler::VisitStoreStaticField(StoreStaticFieldComp* comp) {
782 // Moved to intermediate_language_x64.cc.
783 UNREACHABLE();
784 }
785
786
787 void FlowGraphCompiler::VisitStoreIndexed(StoreIndexedComp* comp) {
788 // Moved to intermediate_language_x64.cc.
789 UNREACHABLE();
790 }
791
792
793 void FlowGraphCompiler::VisitInstanceSetter(InstanceSetterComp* comp) {
794 // Moved to intermediate_language_x64.cc.
795 UNREACHABLE();
796 }
797
798
799 void FlowGraphCompiler::VisitStaticSetter(StaticSetterComp* comp) {
800 // Moved to intermediate_language_x64.cc.
801 UNREACHABLE();
802 }
803
804
805 void FlowGraphCompiler::VisitBooleanNegate(BooleanNegateComp* comp) {
806 // Moved to intermediate_language_x64.cc.
807 UNREACHABLE();
808 }
809
810
811 // Optimize instanceof type test by adding inlined tests for: 654 // Optimize instanceof type test by adding inlined tests for:
812 // - NULL -> return false. 655 // - NULL -> return false.
813 // - Smi -> compile time subtype check (only if dst class is not parameterized). 656 // - Smi -> compile time subtype check (only if dst class is not parameterized).
814 // - Class equality (only if class is not parameterized). 657 // - Class equality (only if class is not parameterized).
815 // Inputs: 658 // Inputs:
816 // - RAX: object. 659 // - RAX: object.
817 // - RDX: instantiator type arguments or raw_null. 660 // - RDX: instantiator type arguments or raw_null.
818 // - RCX: instantiator or raw_null. 661 // - RCX: instantiator or raw_null.
819 // Destroys RCX and RDX. 662 // Destroys RCX and RDX.
820 // Returns: 663 // Returns:
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 __ jmp(&done, Assembler::kNearJump); 728 __ jmp(&done, Assembler::kNearJump);
886 729
887 __ Bind(&is_instance); 730 __ Bind(&is_instance);
888 __ LoadObject(RAX, negate_result ? bool_false : bool_true); 731 __ LoadObject(RAX, negate_result ? bool_false : bool_true);
889 __ Bind(&done); 732 __ Bind(&done);
890 __ popq(RDX); // Remove pushed instantiator type arguments.. 733 __ popq(RDX); // Remove pushed instantiator type arguments..
891 __ popq(RCX); // Remove pushed instantiator. 734 __ popq(RCX); // Remove pushed instantiator.
892 } 735 }
893 736
894 737
895 void FlowGraphCompiler::VisitInstanceOf(InstanceOfComp* comp) {
896 // Moved to intermediate_language_x64.cc.
897 UNREACHABLE();
898 }
899
900
901 void FlowGraphCompiler::VisitAllocateObject(AllocateObjectComp* comp) {
902 // Moved to intermediate_language_x64.cc.
903 UNREACHABLE();
904 }
905
906
907 void FlowGraphCompiler::VisitAllocateObjectWithBoundsCheck(
908 AllocateObjectWithBoundsCheckComp* comp) {
909 // Moved to intermediate_language_x64.cc.
910 UNREACHABLE();
911 }
912
913
914 void FlowGraphCompiler::VisitCreateArray(CreateArrayComp* comp) {
915 // Moved to intermediate_language_x64.cc.
916 UNREACHABLE();
917 }
918
919
920 void FlowGraphCompiler::VisitCreateClosure(CreateClosureComp* comp) {
921 // Moved to intermediate_language_x64.cc.
922 UNREACHABLE();
923 }
924
925
926 void FlowGraphCompiler::VisitLoadVMField(LoadVMFieldComp* comp) {
927 // Moved to intermediate_language_x64.cc.
928 UNREACHABLE();
929 }
930
931
932 void FlowGraphCompiler::VisitStoreVMField(StoreVMFieldComp* comp) {
933 // Moved to intermediate_language_x64.cc.
934 UNREACHABLE();
935 }
936
937
938 void FlowGraphCompiler::VisitInstantiateTypeArguments(
939 InstantiateTypeArgumentsComp* comp) {
940 // Moved to intermediate_language_x64.cc.
941 UNREACHABLE();
942 }
943
944
945 void FlowGraphCompiler::VisitExtractConstructorTypeArguments(
946 ExtractConstructorTypeArgumentsComp* comp) {
947 // Moved to intermediate_language_x64.cc.
948 UNREACHABLE();
949 }
950
951
952 void FlowGraphCompiler::VisitExtractConstructorInstantiator(
953 ExtractConstructorInstantiatorComp* comp) {
954 // Moved to intermediate_language_x64.cc.
955 UNREACHABLE();
956 }
957
958
959 void FlowGraphCompiler::VisitAllocateContext(AllocateContextComp* comp) {
960 // Moved to intermediate_language_x64.cc.
961 UNREACHABLE();
962 }
963
964
965 void FlowGraphCompiler::VisitChainContext(ChainContextComp* comp) {
966 // Moved to intermediate_language_x64.cc.
967 UNREACHABLE();
968 }
969
970
971 void FlowGraphCompiler::VisitCloneContext(CloneContextComp* comp) {
972 // Moved to intermediate_language_x64.cc.
973 UNREACHABLE();
974 }
975
976
977 void FlowGraphCompiler::VisitCatchEntry(CatchEntryComp* comp) {
978 // Moved to intermediate_language_x64.cc.
979 UNREACHABLE();
980 }
981
982
983 void FlowGraphCompiler::VisitBinaryOp(BinaryOpComp* comp) {
984 UNIMPLEMENTED();
985 }
986
987
988 void FlowGraphCompiler::VisitUnarySmiOp(UnarySmiOpComp* comp) {
989 UNIMPLEMENTED();
990 }
991
992
993 void FlowGraphCompiler::VisitNumberNegate(NumberNegateComp* comp) {
994 UNIMPLEMENTED();
995 }
996
997
998 void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) { 738 void FlowGraphCompiler::EmitInstructionPrologue(Instruction* instr) {
999 LocationSummary* locs = instr->locs(); 739 LocationSummary* locs = instr->locs();
1000 ASSERT(locs != NULL); 740 ASSERT(locs != NULL);
1001 741
1002 locs->AllocateRegisters(); 742 locs->AllocateRegisters();
1003 743
1004 // Load instruction inputs into allocated registers. 744 // Load instruction inputs into allocated registers.
1005 for (intptr_t i = locs->input_count() - 1; i >= 0; i--) { 745 for (intptr_t i = locs->input_count() - 1; i >= 0; i--) {
1006 Location loc = locs->in(i); 746 Location loc = locs->in(i);
1007 ASSERT(loc.kind() == Location::kRegister); 747 ASSERT(loc.kind() == Location::kRegister);
1008 __ popq(loc.reg()); 748 __ popq(loc.reg());
1009 } 749 }
1010 } 750 }
1011 751
1012 752
1013 void FlowGraphCompiler::VisitBlocks() { 753 void FlowGraphCompiler::VisitBlocks() {
1014 for (intptr_t i = 0; i < block_order_.length(); ++i) { 754 for (intptr_t i = 0; i < block_order_.length(); ++i) {
1015 __ Comment("B%d", i); 755 __ Comment("B%d", i);
1016 // Compile the block entry. 756 // Compile the block entry.
1017 current_block_ = block_order_[i]; 757 current_block_ = block_order_[i];
1018 Instruction* instr = current_block()->Accept(this); 758 current_block_->EmitNativeCode(this);
Vyacheslav Egorov (Google) 2012/06/01 10:55:24 This is extremely confusing to read, if I did not
srdjan 2012/06/01 17:44:47 Agreed with readability problem, needs at least a
759 Instruction* instr = current_block_->StraightLineSuccessor();
1019 // Compile all successors until an exit, branch, or a block entry. 760 // Compile all successors until an exit, branch, or a block entry.
1020 while ((instr != NULL) && !instr->IsBlockEntry()) { 761 while ((instr != NULL) && !instr->IsBlockEntry()) {
1021 if (FLAG_code_comments) EmitComment(instr); 762 if (FLAG_code_comments) EmitComment(instr);
1022 if (instr->locs() != NULL) { 763 ASSERT(instr->locs() != NULL);
1023 EmitInstructionPrologue(instr); 764 EmitInstructionPrologue(instr);
1024 instr->EmitNativeCode(this); 765 instr->EmitNativeCode(this);
1025 instr = instr->StraightLineSuccessor(); 766 instr = instr->StraightLineSuccessor();
1026 } else {
1027 instr = instr->Accept(this);
1028 }
1029 } 767 }
1030 768
1031 BlockEntryInstr* successor = 769 BlockEntryInstr* successor =
1032 (instr == NULL) ? NULL : instr->AsBlockEntry(); 770 (instr == NULL) ? NULL : instr->AsBlockEntry();
1033 if (successor != NULL) { 771 if (successor != NULL) {
1034 // Block ended with a "goto". We can fall through if it is the 772 // Block ended with a "goto". We can fall through if it is the
1035 // next block in the list. Otherwise, we need a jump. 773 // next block in the list. Otherwise, we need a jump.
1036 if ((i == block_order_.length() - 1) || 774 if ((i == block_order_.length() - 1) ||
1037 (block_order_[i + 1] != successor)) { 775 (block_order_[i + 1] != successor)) {
1038 __ jmp(&block_info_[successor->postorder_number()]->label); 776 __ jmp(&block_info()[successor->postorder_number()]->label);
Vyacheslav Egorov (Google) 2012/06/01 10:55:24 use GetLabelFor?
srdjan 2012/06/01 17:44:47 Done.
1039 } 777 }
1040 } 778 }
1041 } 779 }
1042 } 780 }
1043 781
1044 782
1045 void FlowGraphCompiler::EmitComment(Instruction* instr) { 783 void FlowGraphCompiler::EmitComment(Instruction* instr) {
1046 char buffer[80]; 784 char buffer[80];
1047 BufferFormatter f(buffer, sizeof(buffer)); 785 BufferFormatter f(buffer, sizeof(buffer));
1048 instr->PrintTo(&f); 786 instr->PrintTo(&f);
1049 __ Comment("@%d: %s", instr->cid(), buffer); 787 __ Comment("@%d: %s", instr->cid(), buffer);
1050 } 788 }
1051 789
1052 790
1053 void FlowGraphCompiler::VisitGraphEntry(GraphEntryInstr* instr) {
1054 // Nothing to do.
1055 }
1056
1057
1058 void FlowGraphCompiler::VisitJoinEntry(JoinEntryInstr* instr) {
1059 __ Bind(&block_info_[instr->postorder_number()]->label);
1060 }
1061
1062
1063 void FlowGraphCompiler::VisitTargetEntry(TargetEntryInstr* instr) {
1064 __ Bind(&block_info_[instr->postorder_number()]->label);
1065 if (instr->HasTryIndex()) {
1066 exception_handlers_list_->AddHandler(instr->try_index(),
1067 assembler_->CodeSize());
1068 }
1069 }
1070
1071
1072 void FlowGraphCompiler::VisitDo(DoInstr* instr) {
1073 instr->computation()->Accept(this);
1074 }
1075
1076
1077 void FlowGraphCompiler::VisitBind(BindInstr* instr) {
1078 // Moved to intermediate_language_x64.cc.
1079 UNREACHABLE();
1080 }
1081
1082
1083 void FlowGraphCompiler::VisitReturn(ReturnInstr* instr) {
1084 // Moved to intermediate_language_x64.cc.
1085 UNREACHABLE();
1086 }
1087
1088
1089 void FlowGraphCompiler::VisitThrow(ThrowInstr* instr) {
1090 // Moved to intermediate_language_x64.cc.
1091 UNREACHABLE();
1092 }
1093
1094
1095 void FlowGraphCompiler::VisitReThrow(ReThrowInstr* instr) {
1096 // Moved to intermediate_language_x64.cc.
1097 UNREACHABLE();
1098 }
1099
1100
1101
1102 void FlowGraphCompiler::VisitBranch(BranchInstr* instr) {
1103 // Moved to intermediate_language_x64.cc.
1104 UNREACHABLE();
1105 }
1106
1107
1108 // Copied from CodeGenerator::CopyParameters (CodeGenerator will be deprecated). 791 // Copied from CodeGenerator::CopyParameters (CodeGenerator will be deprecated).
1109 void FlowGraphCompiler::CopyParameters() { 792 void FlowGraphCompiler::CopyParameters() {
1110 const Function& function = parsed_function_.function(); 793 const Function& function = parsed_function().function();
1111 LocalScope* scope = parsed_function_.node_sequence()->scope(); 794 LocalScope* scope = parsed_function().node_sequence()->scope();
1112 const int num_fixed_params = function.num_fixed_parameters(); 795 const int num_fixed_params = function.num_fixed_parameters();
1113 const int num_opt_params = function.num_optional_parameters(); 796 const int num_opt_params = function.num_optional_parameters();
1114 ASSERT(parsed_function_.first_parameter_index() == 797 ASSERT(parsed_function().first_parameter_index() ==
1115 ParsedFunction::kFirstLocalSlotIndex); 798 ParsedFunction::kFirstLocalSlotIndex);
1116 // Copy positional arguments. 799 // Copy positional arguments.
1117 // Check that no fewer than num_fixed_params positional arguments are passed 800 // Check that no fewer than num_fixed_params positional arguments are passed
1118 // in and that no more than num_params arguments are passed in. 801 // in and that no more than num_params arguments are passed in.
1119 // Passed argument i at fp[1 + argc - i] 802 // Passed argument i at fp[1 + argc - i]
1120 // copied to fp[ParsedFunction::kFirstLocalSlotIndex - i]. 803 // copied to fp[ParsedFunction::kFirstLocalSlotIndex - i].
1121 const int num_params = num_fixed_params + num_opt_params; 804 const int num_params = num_fixed_params + num_opt_params;
1122 805
1123 // Total number of args is the first Smi in args descriptor array (R10). 806 // Total number of args is the first Smi in args descriptor array (R10).
1124 __ movq(RBX, FieldAddress(R10, Array::data_offset())); 807 __ movq(RBX, FieldAddress(R10, Array::data_offset()));
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1205 // fp[1 + argc - arg_pos]. 888 // fp[1 + argc - arg_pos].
1206 __ movq(RAX, Address(RDI, kWordSize)); // RAX is arg_pos as Smi. 889 __ movq(RAX, Address(RDI, kWordSize)); // RAX is arg_pos as Smi.
1207 __ addq(RDI, Immediate(2 * kWordSize)); // Point to next name/pos pair. 890 __ addq(RDI, Immediate(2 * kWordSize)); // Point to next name/pos pair.
1208 __ negq(RAX); 891 __ negq(RAX);
1209 Address argument_addr(RBX, RAX, TIMES_4, 0); // RAX is a negative Smi. 892 Address argument_addr(RBX, RAX, TIMES_4, 0); // RAX is a negative Smi.
1210 __ movq(RAX, argument_addr); 893 __ movq(RAX, argument_addr);
1211 __ jmp(&assign_optional_parameter, Assembler::kNearJump); 894 __ jmp(&assign_optional_parameter, Assembler::kNearJump);
1212 __ Bind(&load_default_value); 895 __ Bind(&load_default_value);
1213 // Load RAX with default argument at pos. 896 // Load RAX with default argument at pos.
1214 const Object& value = Object::ZoneHandle( 897 const Object& value = Object::ZoneHandle(
1215 parsed_function_.default_parameter_values().At( 898 parsed_function().default_parameter_values().At(
1216 param_pos - num_fixed_params)); 899 param_pos - num_fixed_params));
1217 __ LoadObject(RAX, value); 900 __ LoadObject(RAX, value);
1218 __ Bind(&assign_optional_parameter); 901 __ Bind(&assign_optional_parameter);
1219 // Assign RAX to fp[ParsedFunction::kFirstLocalSlotIndex - param_pos]. 902 // Assign RAX to fp[ParsedFunction::kFirstLocalSlotIndex - param_pos].
1220 // We do not use the final allocation index of the variable here, i.e. 903 // We do not use the final allocation index of the variable here, i.e.
1221 // scope->VariableAt(i)->index(), because captured variables still need 904 // scope->VariableAt(i)->index(), because captured variables still need
1222 // to be copied to the context that is not yet allocated. 905 // to be copied to the context that is not yet allocated.
1223 const Address param_addr( 906 const Address param_addr(
1224 RBP, (ParsedFunction::kFirstLocalSlotIndex - param_pos) * kWordSize); 907 RBP, (ParsedFunction::kFirstLocalSlotIndex - param_pos) * kWordSize);
1225 __ movq(param_addr, RAX); 908 __ movq(param_addr, RAX);
(...skipping 17 matching lines...) Expand all
1243 } 926 }
1244 if (function.IsClosureFunction()) { 927 if (function.IsClosureFunction()) {
1245 GenerateCallRuntime(AstNode::kNoId, 928 GenerateCallRuntime(AstNode::kNoId,
1246 0, 929 0,
1247 CatchClauseNode::kInvalidTryIndex, 930 CatchClauseNode::kInvalidTryIndex,
1248 kClosureArgumentMismatchRuntimeEntry); 931 kClosureArgumentMismatchRuntimeEntry);
1249 } else { 932 } else {
1250 // Invoke noSuchMethod function. 933 // Invoke noSuchMethod function.
1251 const int kNumArgsChecked = 1; 934 const int kNumArgsChecked = 1;
1252 ICData& ic_data = ICData::ZoneHandle(); 935 ICData& ic_data = ICData::ZoneHandle();
1253 ic_data = ICData::New(parsed_function_.function(), 936 ic_data = ICData::New(parsed_function().function(),
1254 String::Handle(function.name()), 937 String::Handle(function.name()),
1255 AstNode::kNoId, 938 AstNode::kNoId,
1256 kNumArgsChecked); 939 kNumArgsChecked);
1257 __ LoadObject(RBX, ic_data); 940 __ LoadObject(RBX, ic_data);
1258 // RBP - 8 : PC marker, allows easy identification of RawInstruction obj. 941 // RBP - 8 : PC marker, allows easy identification of RawInstruction obj.
1259 // RBP : points to previous frame pointer. 942 // RBP : points to previous frame pointer.
1260 // RBP + 8 : points to return address. 943 // RBP + 8 : points to return address.
1261 // RBP + 16 : address of last argument (arg n-1). 944 // RBP + 16 : address of last argument (arg n-1).
1262 // RSP + 16 + 8*(n-1) : address of first argument (arg 0). 945 // RSP + 16 + 8*(n-1) : address of first argument (arg 0).
1263 // RBX : ic-data. 946 // RBX : ic-data.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1305 !FLAG_report_usage_count && 988 !FLAG_report_usage_count &&
1306 (FLAG_optimization_counter_threshold >= 0) && 989 (FLAG_optimization_counter_threshold >= 0) &&
1307 !Isolate::Current()->debugger()->IsActive(); 990 !Isolate::Current()->debugger()->IsActive();
1308 } 991 }
1309 992
1310 993
1311 void FlowGraphCompiler::IntrinsifyGetter() { 994 void FlowGraphCompiler::IntrinsifyGetter() {
1312 // TOS: return address. 995 // TOS: return address.
1313 // +1 : receiver. 996 // +1 : receiver.
1314 // Sequence node has one return node, its input is load field node. 997 // Sequence node has one return node, its input is load field node.
1315 const SequenceNode& sequence_node = *parsed_function_.node_sequence(); 998 const SequenceNode& sequence_node = *parsed_function().node_sequence();
1316 ASSERT(sequence_node.length() == 1); 999 ASSERT(sequence_node.length() == 1);
1317 ASSERT(sequence_node.NodeAt(0)->IsReturnNode()); 1000 ASSERT(sequence_node.NodeAt(0)->IsReturnNode());
1318 const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode(); 1001 const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode();
1319 ASSERT(return_node.value()->IsLoadInstanceFieldNode()); 1002 ASSERT(return_node.value()->IsLoadInstanceFieldNode());
1320 const LoadInstanceFieldNode& load_node = 1003 const LoadInstanceFieldNode& load_node =
1321 *return_node.value()->AsLoadInstanceFieldNode(); 1004 *return_node.value()->AsLoadInstanceFieldNode();
1322 __ movq(RAX, Address(RSP, 1 * kWordSize)); 1005 __ movq(RAX, Address(RSP, 1 * kWordSize));
1323 __ movq(RAX, FieldAddress(RAX, load_node.field().Offset())); 1006 __ movq(RAX, FieldAddress(RAX, load_node.field().Offset()));
1324 __ ret(); 1007 __ ret();
1325 } 1008 }
1326 1009
1327 1010
1328 void FlowGraphCompiler::IntrinsifySetter() { 1011 void FlowGraphCompiler::IntrinsifySetter() {
1329 // TOS: return address. 1012 // TOS: return address.
1330 // +1 : value 1013 // +1 : value
1331 // +2 : receiver. 1014 // +2 : receiver.
1332 // Sequence node has one store node and one return NULL node. 1015 // Sequence node has one store node and one return NULL node.
1333 const SequenceNode& sequence_node = *parsed_function_.node_sequence(); 1016 const SequenceNode& sequence_node = *parsed_function().node_sequence();
1334 ASSERT(sequence_node.length() == 2); 1017 ASSERT(sequence_node.length() == 2);
1335 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode()); 1018 ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode());
1336 ASSERT(sequence_node.NodeAt(1)->IsReturnNode()); 1019 ASSERT(sequence_node.NodeAt(1)->IsReturnNode());
1337 const StoreInstanceFieldNode& store_node = 1020 const StoreInstanceFieldNode& store_node =
1338 *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode(); 1021 *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode();
1339 __ movq(RAX, Address(RSP, 2 * kWordSize)); // Receiver. 1022 __ movq(RAX, Address(RSP, 2 * kWordSize)); // Receiver.
1340 __ movq(RBX, Address(RSP, 1 * kWordSize)); // Value. 1023 __ movq(RBX, Address(RSP, 1 * kWordSize)); // Value.
1341 __ StoreIntoObject(RAX, FieldAddress(RAX, store_node.field().Offset()), RBX); 1024 __ StoreIntoObject(RAX, FieldAddress(RAX, store_node.field().Offset()), RBX);
1342 const Immediate raw_null = 1025 const Immediate raw_null =
1343 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1026 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1344 __ movq(RAX, raw_null); 1027 __ movq(RAX, raw_null);
1345 __ ret(); 1028 __ ret();
1346 } 1029 }
1347 1030
1348 1031
1349 // Returns 'true' if code generation for this function is complete, i.e., 1032 // Returns 'true' if code generation for this function is complete, i.e.,
1350 // no fall-through to regular code is needed. 1033 // no fall-through to regular code is needed.
1351 bool FlowGraphCompiler::TryIntrinsify() { 1034 bool FlowGraphCompiler::TryIntrinsify() {
1352 if (!CanOptimize()) return false; 1035 if (!CanOptimize()) return false;
1353 // Intrinsification skips arguments checks, therefore disable if in checked 1036 // Intrinsification skips arguments checks, therefore disable if in checked
1354 // mode. 1037 // mode.
1355 if (FLAG_intrinsify && !FLAG_trace_functions && !FLAG_enable_type_checks) { 1038 if (FLAG_intrinsify && !FLAG_trace_functions && !FLAG_enable_type_checks) {
1356 if ((parsed_function_.function().kind() == RawFunction::kImplicitGetter)) { 1039 if ((parsed_function().function().kind() == RawFunction::kImplicitGetter)) {
1357 IntrinsifyGetter(); 1040 IntrinsifyGetter();
1358 return true; 1041 return true;
1359 } 1042 }
1360 if ((parsed_function_.function().kind() == RawFunction::kImplicitSetter)) { 1043 if ((parsed_function().function().kind() == RawFunction::kImplicitSetter)) {
1361 IntrinsifySetter(); 1044 IntrinsifySetter();
1362 return true; 1045 return true;
1363 } 1046 }
1364 } 1047 }
1365 // Even if an intrinsified version of the function was successfully 1048 // Even if an intrinsified version of the function was successfully
1366 // generated, it may fall through to the non-intrinsified method body. 1049 // generated, it may fall through to the non-intrinsified method body.
1367 if (!FLAG_trace_functions) { 1050 if (!FLAG_trace_functions) {
1368 return Intrinsifier::Intrinsify(parsed_function_.function(), assembler_); 1051 return Intrinsifier::Intrinsify(parsed_function().function(), assembler_);
1369 } 1052 }
1370 return false; 1053 return false;
1371 } 1054 }
1372 1055
1373 1056
1374 void FlowGraphCompiler::CompileGraph() { 1057 void FlowGraphCompiler::CompileGraph() {
1375 InitCompiler(); 1058 InitCompiler();
1376 if (TryIntrinsify()) { 1059 if (TryIntrinsify()) {
1377 // Make it patchable: code must have a minimum code size, nop(2) increases 1060 // Make it patchable: code must have a minimum code size, nop(2) increases
1378 // the minimum code size appropriately. 1061 // the minimum code size appropriately.
1379 __ nop(2); 1062 __ nop(2);
1380 __ int3(); 1063 __ int3();
1381 __ jmp(&StubCode::FixCallersTargetLabel()); 1064 __ jmp(&StubCode::FixCallersTargetLabel());
1382 return; 1065 return;
1383 } 1066 }
1384 // Specialized version of entry code from CodeGenerator::GenerateEntryCode. 1067 // Specialized version of entry code from CodeGenerator::GenerateEntryCode.
1385 const Function& function = parsed_function_.function(); 1068 const Function& function = parsed_function().function();
1386 1069
1387 const int parameter_count = function.num_fixed_parameters(); 1070 const int parameter_count = function.num_fixed_parameters();
1388 const int num_copied_params = parsed_function_.copied_parameter_count(); 1071 const int num_copied_params = parsed_function().copied_parameter_count();
1389 const int local_count = parsed_function_.stack_local_count(); 1072 const int local_count = parsed_function().stack_local_count();
1390 AssemblerMacros::EnterDartFrame(assembler_, (StackSize() * kWordSize)); 1073 AssemblerMacros::EnterDartFrame(assembler_, (StackSize() * kWordSize));
1391 1074
1392 // We check the number of passed arguments when we have to copy them due to 1075 // We check the number of passed arguments when we have to copy them due to
1393 // the presence of optional named parameters. 1076 // the presence of optional named parameters.
1394 // No such checking code is generated if only fixed parameters are declared, 1077 // No such checking code is generated if only fixed parameters are declared,
1395 // unless we are debug mode or unless we are compiling a closure. 1078 // unless we are debug mode or unless we are compiling a closure.
1396 if (num_copied_params == 0) { 1079 if (num_copied_params == 0) {
1397 #ifdef DEBUG 1080 #ifdef DEBUG
1398 const bool check_arguments = true; 1081 const bool check_arguments = true;
1399 #else 1082 #else
(...skipping 16 matching lines...) Expand all
1416 } 1099 }
1417 __ Bind(&argc_in_range); 1100 __ Bind(&argc_in_range);
1418 } 1101 }
1419 } else { 1102 } else {
1420 CopyParameters(); 1103 CopyParameters();
1421 } 1104 }
1422 1105
1423 // Initialize locals to null. 1106 // Initialize locals to null.
1424 if (local_count > 0) { 1107 if (local_count > 0) {
1425 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(Object::null()))); 1108 __ movq(RAX, Immediate(reinterpret_cast<intptr_t>(Object::null())));
1426 const int base = parsed_function_.first_stack_local_index(); 1109 const int base = parsed_function().first_stack_local_index();
1427 for (int i = 0; i < local_count; ++i) { 1110 for (int i = 0; i < local_count; ++i) {
1428 // Subtract index i (locals lie at lower addresses than RBP). 1111 // Subtract index i (locals lie at lower addresses than RBP).
1429 __ movq(Address(RBP, (base - i) * kWordSize), RAX); 1112 __ movq(Address(RBP, (base - i) * kWordSize), RAX);
1430 } 1113 }
1431 } 1114 }
1432 1115
1433 // Generate stack overflow check. 1116 // Generate stack overflow check.
1434 __ movq(TMP, Immediate(Isolate::Current()->stack_limit_address())); 1117 __ movq(TMP, Immediate(Isolate::Current()->stack_limit_address()));
1435 __ cmpq(RSP, Address(TMP, 0)); 1118 __ cmpq(RSP, Address(TMP, 0));
1436 Label no_stack_overflow; 1119 Label no_stack_overflow;
1437 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump); 1120 __ j(ABOVE, &no_stack_overflow, Assembler::kNearJump);
1438 GenerateCallRuntime(AstNode::kNoId, 1121 GenerateCallRuntime(AstNode::kNoId,
1439 function.token_index(), 1122 function.token_index(),
1440 CatchClauseNode::kInvalidTryIndex, 1123 CatchClauseNode::kInvalidTryIndex,
1441 kStackOverflowRuntimeEntry); 1124 kStackOverflowRuntimeEntry);
1442 __ Bind(&no_stack_overflow); 1125 __ Bind(&no_stack_overflow);
1443 1126
1444 if (FLAG_print_scopes) { 1127 if (FLAG_print_scopes) {
1445 // Print the function scope (again) after generating the prologue in order 1128 // Print the function scope (again) after generating the prologue in order
1446 // to see annotations such as allocation indices of locals. 1129 // to see annotations such as allocation indices of locals.
1447 if (FLAG_print_ast) { 1130 if (FLAG_print_ast) {
1448 // Second printing. 1131 // Second printing.
1449 OS::Print("Annotated "); 1132 OS::Print("Annotated ");
1450 } 1133 }
1451 AstPrinter::PrintFunctionScope(parsed_function_); 1134 AstPrinter::PrintFunctionScope(parsed_function());
1452 } 1135 }
1453 1136
1454 VisitBlocks(); 1137 VisitBlocks();
1455 1138
1456 __ int3(); 1139 __ int3();
1457 GenerateDeferredCode(); 1140 GenerateDeferredCode();
1458 // Emit function patching code. This will be swapped with the first 13 bytes 1141 // Emit function patching code. This will be swapped with the first 13 bytes
1459 // at entry point. 1142 // at entry point.
1460 pc_descriptors_list_->AddDescriptor(PcDescriptors::kPatchCode, 1143 pc_descriptors_list()->AddDescriptor(PcDescriptors::kPatchCode,
1461 assembler_->CodeSize(), 1144 assembler_->CodeSize(),
1462 AstNode::kNoId, 1145 AstNode::kNoId,
1463 0, 1146 0,
1464 -1); 1147 -1);
1465 __ jmp(&StubCode::FixCallersTargetLabel()); 1148 __ jmp(&StubCode::FixCallersTargetLabel());
1466 } 1149 }
1467 1150
1468 1151
1469 void FlowGraphCompiler::GenerateDeferredCode() { 1152 void FlowGraphCompiler::GenerateDeferredCode() {
1470 for (intptr_t i = 0; i < deopt_stubs_.length(); i++) { 1153 for (intptr_t i = 0; i < deopt_stubs_.length(); i++) {
1471 deopt_stubs_[i]->GenerateCode(this); 1154 deopt_stubs_[i]->GenerateCode(this);
1472 } 1155 }
1473 } 1156 }
1474 1157
(...skipping 15 matching lines...) Expand all
1490 __ CallRuntime(entry); 1173 __ CallRuntime(entry);
1491 AddCurrentDescriptor(PcDescriptors::kOther, cid, token_index, try_index); 1174 AddCurrentDescriptor(PcDescriptors::kOther, cid, token_index, try_index);
1492 } 1175 }
1493 1176
1494 1177
1495 // Uses current pc position and try-index. 1178 // Uses current pc position and try-index.
1496 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind, 1179 void FlowGraphCompiler::AddCurrentDescriptor(PcDescriptors::Kind kind,
1497 intptr_t cid, 1180 intptr_t cid,
1498 intptr_t token_index, 1181 intptr_t token_index,
1499 intptr_t try_index) { 1182 intptr_t try_index) {
1500 pc_descriptors_list_->AddDescriptor(kind, 1183 pc_descriptors_list()->AddDescriptor(kind,
1501 assembler_->CodeSize(), 1184 assembler_->CodeSize(),
1502 cid, 1185 cid,
1503 token_index, 1186 token_index,
1504 try_index); 1187 try_index);
1505 } 1188 }
1506 1189
1507 1190
1508 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id, 1191 Label* FlowGraphCompiler::AddDeoptStub(intptr_t deopt_id,
1509 intptr_t deopt_token_index, 1192 intptr_t deopt_token_index,
1510 intptr_t try_index, 1193 intptr_t try_index,
1511 DeoptReasonId reason, 1194 DeoptReasonId reason,
1512 Register reg1, 1195 Register reg1,
1513 Register reg2) { 1196 Register reg2) {
1514 DeoptimizationStub* stub = 1197 DeoptimizationStub* stub =
1515 new DeoptimizationStub(deopt_id, deopt_token_index, try_index, reason); 1198 new DeoptimizationStub(deopt_id, deopt_token_index, try_index, reason);
1516 stub->Push(reg1); 1199 stub->Push(reg1);
1517 stub->Push(reg2); 1200 stub->Push(reg2);
1518 deopt_stubs_.Add(stub); 1201 deopt_stubs_.Add(stub);
1519 return stub->entry_label(); 1202 return stub->entry_label();
1520 } 1203 }
1521 1204
1522 1205
1523 void FlowGraphCompiler::FinalizePcDescriptors(const Code& code) {
1524 ASSERT(pc_descriptors_list_ != NULL);
1525 const PcDescriptors& descriptors = PcDescriptors::Handle(
1526 pc_descriptors_list_->FinalizePcDescriptors(code.EntryPoint()));
1527 descriptors.Verify(parsed_function_.function().is_optimizable());
1528 code.set_pc_descriptors(descriptors);
1529 }
1530
1531
1532 void FlowGraphCompiler::FinalizeStackmaps(const Code& code) {
1533 if (stackmap_builder_ == NULL) {
1534 // The unoptimizing compiler has no stack maps.
1535 code.set_stackmaps(Array::Handle());
1536 } else {
1537 // Finalize the stack map array and add it to the code object.
1538 code.set_stackmaps(
1539 Array::Handle(stackmap_builder_->FinalizeStackmaps(code)));
1540 }
1541 }
1542
1543
1544 void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) {
1545 const LocalVarDescriptors& var_descs = LocalVarDescriptors::Handle(
1546 parsed_function_.node_sequence()->scope()->GetVarDescriptors());
1547 code.set_var_descriptors(var_descs);
1548 }
1549
1550
1551 void FlowGraphCompiler::FinalizeExceptionHandlers(const Code& code) {
1552 ASSERT(exception_handlers_list_ != NULL);
1553 const ExceptionHandlers& handlers = ExceptionHandlers::Handle(
1554 exception_handlers_list_->FinalizeExceptionHandlers(code.EntryPoint()));
1555 code.set_exception_handlers(handlers);
1556 }
1557
1558
1559 void FlowGraphCompiler::FinalizeComments(const Code& code) { 1206 void FlowGraphCompiler::FinalizeComments(const Code& code) {
1560 code.set_comments(assembler_->GetCodeComments()); 1207 code.set_comments(assembler_->GetCodeComments());
1561 } 1208 }
1562 1209
1563 #undef __ 1210 #undef __
1564 1211
1565 } // namespace dart 1212 } // namespace dart
1566 1213
1567 #endif // defined TARGET_ARCH_X64 1214 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698