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

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

Issue 1192103004: VM: New calling convention for generated code. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: ia32 port, addressed comments Created 5 years, 3 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
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_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
7 7
8 #include "vm/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "vm/ast_printer.h" 10 #include "vm/ast_printer.h"
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 89
90 // Emit all kMaterializeObject instructions describing objects to be 90 // Emit all kMaterializeObject instructions describing objects to be
91 // materialized on the deoptimization as a prefix to the deoptimization info. 91 // materialized on the deoptimization as a prefix to the deoptimization info.
92 EmitMaterializations(deopt_env_, builder); 92 EmitMaterializations(deopt_env_, builder);
93 93
94 // The real frame starts here. 94 // The real frame starts here.
95 builder->MarkFrameStart(); 95 builder->MarkFrameStart();
96 96
97 Zone* zone = compiler->zone(); 97 Zone* zone = compiler->zone();
98 98
99 // Current PP, FP, and PC. 99 // Current PP, PC marker FP, and PC.
100 // Callee's PC marker is not used anymore. Pass Function::null() to set to 0.
100 builder->AddPp(current->function(), slot_ix++); 101 builder->AddPp(current->function(), slot_ix++);
102 builder->AddPcMarker(Function::Handle(zone), slot_ix++);
101 builder->AddCallerFp(slot_ix++); 103 builder->AddCallerFp(slot_ix++);
102 builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++); 104 builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
103 105
104 // Callee's PC marker is not used anymore. Pass Code::null() to set to 0.
105 builder->AddPcMarker(Function::Handle(zone), slot_ix++);
106 106
107 // Emit all values that are needed for materialization as a part of the 107 // Emit all values that are needed for materialization as a part of the
108 // expression stack for the bottom-most frame. This guarantees that GC 108 // expression stack for the bottom-most frame. This guarantees that GC
109 // will be able to find them during materialization. 109 // will be able to find them during materialization.
110 slot_ix = builder->EmitMaterializationArguments(slot_ix); 110 slot_ix = builder->EmitMaterializationArguments(slot_ix);
111 111
112 // For the innermost environment, set outgoing arguments and the locals. 112 // For the innermost environment, set outgoing arguments and the locals.
113 for (intptr_t i = current->Length() - 1; 113 for (intptr_t i = current->Length() - 1;
114 i >= current->fixed_parameter_count(); 114 i >= current->fixed_parameter_count();
115 i--) { 115 i--) {
116 builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++); 116 builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++);
117 } 117 }
118 118
119 Environment* previous = current; 119 Environment* previous = current;
120 current = current->outer(); 120 current = current->outer();
121 while (current != NULL) { 121 while (current != NULL) {
122 // PP, FP, and PC. 122 // PP, PC marker, FP, and PC.
123 builder->AddPp(current->function(), slot_ix++); 123 builder->AddPp(current->function(), slot_ix++);
124 builder->AddPcMarker(previous->function(), slot_ix++);
124 builder->AddCallerFp(slot_ix++); 125 builder->AddCallerFp(slot_ix++);
125 126
126 // For any outer environment the deopt id is that of the call instruction 127 // For any outer environment the deopt id is that of the call instruction
127 // which is recorded in the outer environment. 128 // which is recorded in the outer environment.
128 builder->AddReturnAddress( 129 builder->AddReturnAddress(
129 current->function(), 130 current->function(),
130 Isolate::ToDeoptAfter(current->deopt_id()), 131 Isolate::ToDeoptAfter(current->deopt_id()),
131 slot_ix++); 132 slot_ix++);
132 133
133 // PC marker.
134 builder->AddPcMarker(previous->function(), slot_ix++);
135
136 // The values of outgoing arguments can be changed from the inlined call so 134 // The values of outgoing arguments can be changed from the inlined call so
137 // we must read them from the previous environment. 135 // we must read them from the previous environment.
138 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { 136 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
139 builder->AddCopy(previous->ValueAt(i), 137 builder->AddCopy(previous->ValueAt(i),
140 previous->LocationAt(i), 138 previous->LocationAt(i),
141 slot_ix++); 139 slot_ix++);
142 } 140 }
143 141
144 // Set the locals, note that outgoing arguments are not in the environment. 142 // Set the locals, note that outgoing arguments are not in the environment.
145 for (intptr_t i = current->Length() - 1; 143 for (intptr_t i = current->Length() - 1;
146 i >= current->fixed_parameter_count(); 144 i >= current->fixed_parameter_count();
147 i--) { 145 i--) {
148 builder->AddCopy(current->ValueAt(i), 146 builder->AddCopy(current->ValueAt(i),
149 current->LocationAt(i), 147 current->LocationAt(i),
150 slot_ix++); 148 slot_ix++);
151 } 149 }
152 150
153 // Iterate on the outer environment. 151 // Iterate on the outer environment.
154 previous = current; 152 previous = current;
155 current = current->outer(); 153 current = current->outer();
156 } 154 }
157 // The previous pointer is now the outermost environment. 155 // The previous pointer is now the outermost environment.
158 ASSERT(previous != NULL); 156 ASSERT(previous != NULL);
159 157
160 // For the outermost environment, set caller PC, caller PP, and caller FP. 158 // For the outermost environment, set caller PC, PP, PC marker and caller FP.
161 builder->AddCallerPp(slot_ix++); 159 builder->AddCallerPp(slot_ix++);
160 builder->AddPcMarker(previous->function(), slot_ix++);
162 builder->AddCallerFp(slot_ix++); 161 builder->AddCallerFp(slot_ix++);
163 builder->AddCallerPc(slot_ix++); 162 builder->AddCallerPc(slot_ix++);
164 163
165 // PC marker.
166 builder->AddPcMarker(previous->function(), slot_ix++);
167
168 // For the outermost environment, set the incoming arguments. 164 // For the outermost environment, set the incoming arguments.
169 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { 165 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
170 builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++); 166 builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++);
171 } 167 }
172 168
173 return builder->CreateDeoptInfo(deopt_table); 169 return builder->CreateDeoptInfo(deopt_table);
174 } 170 }
175 171
176 172
177 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler, 173 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler,
178 intptr_t stub_ix) { 174 intptr_t stub_ix) {
179 // Calls do not need stubs, they share a deoptimization trampoline. 175 // Calls do not need stubs, they share a deoptimization trampoline.
180 ASSERT(reason() != ICData::kDeoptAtCall); 176 ASSERT(reason() != ICData::kDeoptAtCall);
181 Assembler* assem = compiler->assembler(); 177 Assembler* assem = compiler->assembler();
182 #define __ assem-> 178 #define __ assem->
183 __ Comment("%s", Name()); 179 __ Comment("%s", Name());
184 __ Bind(entry_label()); 180 __ Bind(entry_label());
185 if (FLAG_trap_on_deoptimization) { 181 if (FLAG_trap_on_deoptimization) {
186 __ break_(0); 182 __ break_(0);
187 } 183 }
188 184
189 ASSERT(deopt_env() != NULL); 185 ASSERT(deopt_env() != NULL);
190 186 __ Push(CODE_REG);
191 __ BranchLink(*StubCode::Deoptimize_entry()); 187 __ BranchLink(*StubCode::Deoptimize_entry());
192 set_pc_offset(assem->CodeSize()); 188 set_pc_offset(assem->CodeSize());
193 #undef __ 189 #undef __
194 } 190 }
195 191
196 192
197 #define __ assembler()-> 193 #define __ assembler()->
198 194
199 195
200 // Fall through if bool_register contains null. 196 // Fall through if bool_register contains null.
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 if (check_correct_named_args) { 917 if (check_correct_named_args) {
922 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); 918 __ lw(T1, FieldAddress(S4, ArgumentsDescriptor::count_offset()));
923 __ SmiUntag(T1); 919 __ SmiUntag(T1);
924 // Check that T2 equals T1, i.e. no named arguments passed. 920 // Check that T2 equals T1, i.e. no named arguments passed.
925 __ beq(T2, T1, &all_arguments_processed); 921 __ beq(T2, T1, &all_arguments_processed);
926 } 922 }
927 } 923 }
928 924
929 __ Bind(&wrong_num_arguments); 925 __ Bind(&wrong_num_arguments);
930 if (function.IsClosureFunction()) { 926 if (function.IsClosureFunction()) {
931 __ LeaveDartFrame(); // The arguments are still on the stack. 927 __ LeaveDartFrame(kKeepCalleePP); // Arguments are still on the stack.
932 __ Branch(*StubCode::CallClosureNoSuchMethod_entry()); 928 __ Branch(*StubCode::CallClosureNoSuchMethod_entry());
933 // The noSuchMethod call may return to the caller, but not here. 929 // The noSuchMethod call may return to the caller, but not here.
934 } else if (check_correct_named_args) { 930 } else if (check_correct_named_args) {
935 __ Stop("Wrong arguments"); 931 __ Stop("Wrong arguments");
936 } 932 }
937 933
938 __ Bind(&all_arguments_processed); 934 __ Bind(&all_arguments_processed);
939 // Nullify originally passed arguments only after they have been copied and 935 // Nullify originally passed arguments only after they have been copied and
940 // checked, otherwise noSuchMethod would not see their original values. 936 // checked, otherwise noSuchMethod would not see their original values.
941 // This step can be skipped in case we decide that formal parameters are 937 // This step can be skipped in case we decide that formal parameters are
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
979 // Sequence node has one store node and one return NULL node. 975 // Sequence node has one store node and one return NULL node.
980 __ Comment("Inlined Setter"); 976 __ Comment("Inlined Setter");
981 __ lw(T0, Address(SP, 1 * kWordSize)); // Receiver. 977 __ lw(T0, Address(SP, 1 * kWordSize)); // Receiver.
982 __ lw(T1, Address(SP, 0 * kWordSize)); // Value. 978 __ lw(T1, Address(SP, 0 * kWordSize)); // Value.
983 __ StoreIntoObjectOffset(T0, offset, T1); 979 __ StoreIntoObjectOffset(T0, offset, T1);
984 __ LoadImmediate(V0, reinterpret_cast<int32_t>(Object::null())); 980 __ LoadImmediate(V0, reinterpret_cast<int32_t>(Object::null()));
985 __ Ret(); 981 __ Ret();
986 } 982 }
987 983
988 984
985 static const Register new_pp = T7;
986
987
989 void FlowGraphCompiler::EmitFrameEntry() { 988 void FlowGraphCompiler::EmitFrameEntry() {
990 const Function& function = parsed_function().function(); 989 const Function& function = parsed_function().function();
991 if (CanOptimizeFunction() && 990 if (CanOptimizeFunction() &&
992 function.IsOptimizable() && 991 function.IsOptimizable() &&
993 (!is_optimizing() || may_reoptimize())) { 992 (!is_optimizing() || may_reoptimize())) {
994 const Register function_reg = T0; 993 const Register function_reg = T0;
995 994
996 __ GetNextPC(T2, TMP);
997
998 // Calculate offset of pool pointer from the PC.
999 const intptr_t object_pool_pc_dist =
1000 Instructions::HeaderSize() - Instructions::object_pool_offset() +
1001 assembler()->CodeSize() - 1 * Instr::kInstrSize;
1002
1003 // Preserve PP of caller.
1004 __ mov(T1, PP);
1005 // Temporarily setup pool pointer for this dart function. 995 // Temporarily setup pool pointer for this dart function.
1006 __ lw(PP, Address(T2, -object_pool_pc_dist)); 996 __ LoadPoolPointer(new_pp);
1007 // Load function object from object pool. 997 // Load function object from object pool.
1008 __ LoadObject(function_reg, function); // Uses PP. 998 __ LoadFunctionFromCalleePool(function_reg, function, new_pp);
1009 // Restore PP of caller.
1010 __ mov(PP, T1);
1011
1012 // Patch point is after the eventually inlined function object.
1013 entry_patch_pc_offset_ = assembler()->CodeSize();
1014 999
1015 __ lw(T1, FieldAddress(function_reg, Function::usage_counter_offset())); 1000 __ lw(T1, FieldAddress(function_reg, Function::usage_counter_offset()));
1016 // Reoptimization of an optimized function is triggered by counting in 1001 // Reoptimization of an optimized function is triggered by counting in
1017 // IC stubs, but not at the entry of the function. 1002 // IC stubs, but not at the entry of the function.
1018 if (!is_optimizing()) { 1003 if (!is_optimizing()) {
1019 __ addiu(T1, T1, Immediate(1)); 1004 __ addiu(T1, T1, Immediate(1));
1020 __ sw(T1, FieldAddress(function_reg, Function::usage_counter_offset())); 1005 __ sw(T1, FieldAddress(function_reg, Function::usage_counter_offset()));
1021 } 1006 }
1022 1007
1023 // Skip Branch if T1 is less than the threshold. 1008 // Skip Branch if T1 is less than the threshold.
1024 Label dont_branch; 1009 Label dont_branch;
1025 __ BranchSignedLess( 1010 __ BranchSignedLess(
1026 T1, Immediate(GetOptimizationThreshold()), &dont_branch); 1011 T1, Immediate(GetOptimizationThreshold()), &dont_branch);
1027 1012
1028 ASSERT(function_reg == T0); 1013 ASSERT(function_reg == T0);
1029 __ Branch(*StubCode::OptimizeFunction_entry()); 1014 __ Branch(*StubCode::OptimizeFunction_entry(), new_pp);
1030 1015
1031 __ Bind(&dont_branch); 1016 __ Bind(&dont_branch);
1032
1033 } else if (!flow_graph().IsCompiledForOsr()) {
1034 entry_patch_pc_offset_ = assembler()->CodeSize();
1035 } 1017 }
1036 __ Comment("Enter frame"); 1018 __ Comment("Enter frame");
1037 if (flow_graph().IsCompiledForOsr()) { 1019 if (flow_graph().IsCompiledForOsr()) {
1038 intptr_t extra_slots = StackSize() 1020 intptr_t extra_slots = StackSize()
1039 - flow_graph().num_stack_locals() 1021 - flow_graph().num_stack_locals()
1040 - flow_graph().num_copied_params(); 1022 - flow_graph().num_copied_params();
1041 ASSERT(extra_slots >= 0); 1023 ASSERT(extra_slots >= 0);
1042 __ EnterOsrFrame(extra_slots * kWordSize); 1024 __ EnterOsrFrame(extra_slots * kWordSize);
1043 } else { 1025 } else {
1044 ASSERT(StackSize() >= 0); 1026 ASSERT(StackSize() >= 0);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1085 Label correct_num_arguments, wrong_num_arguments; 1067 Label correct_num_arguments, wrong_num_arguments;
1086 __ lw(T0, FieldAddress(S4, ArgumentsDescriptor::count_offset())); 1068 __ lw(T0, FieldAddress(S4, ArgumentsDescriptor::count_offset()));
1087 __ BranchNotEqual(T0, Immediate(Smi::RawValue(num_fixed_params)), 1069 __ BranchNotEqual(T0, Immediate(Smi::RawValue(num_fixed_params)),
1088 &wrong_num_arguments); 1070 &wrong_num_arguments);
1089 1071
1090 __ lw(T1, FieldAddress(S4, 1072 __ lw(T1, FieldAddress(S4,
1091 ArgumentsDescriptor::positional_count_offset())); 1073 ArgumentsDescriptor::positional_count_offset()));
1092 __ beq(T0, T1, &correct_num_arguments); 1074 __ beq(T0, T1, &correct_num_arguments);
1093 __ Bind(&wrong_num_arguments); 1075 __ Bind(&wrong_num_arguments);
1094 if (function.IsClosureFunction()) { 1076 if (function.IsClosureFunction()) {
1095 __ LeaveDartFrame(); // The arguments are still on the stack. 1077 __ LeaveDartFrame(kKeepCalleePP); // Arguments are still on the stack.
1096 __ Branch(*StubCode::CallClosureNoSuchMethod_entry()); 1078 __ Branch(*StubCode::CallClosureNoSuchMethod_entry());
1097 // The noSuchMethod call may return to the caller, but not here. 1079 // The noSuchMethod call may return to the caller, but not here.
1098 } else { 1080 } else {
1099 __ Stop("Wrong number of arguments"); 1081 __ Stop("Wrong number of arguments");
1100 } 1082 }
1101 __ Bind(&correct_num_arguments); 1083 __ Bind(&correct_num_arguments);
1102 } 1084 }
1103 } else if (!flow_graph().IsCompiledForOsr()) { 1085 } else if (!flow_graph().IsCompiledForOsr()) {
1104 CopyParameters(); 1086 CopyParameters();
1105 } 1087 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1138 ASSERT(num_locals > 1); 1120 ASSERT(num_locals > 1);
1139 __ sw(V0, Address(FP, (slot_base - i) * kWordSize)); 1121 __ sw(V0, Address(FP, (slot_base - i) * kWordSize));
1140 } 1122 }
1141 } 1123 }
1142 } 1124 }
1143 1125
1144 VisitBlocks(); 1126 VisitBlocks();
1145 1127
1146 __ break_(0); 1128 __ break_(0);
1147 GenerateDeferredCode(); 1129 GenerateDeferredCode();
1148 // Emit function patching code. This will be swapped with the first 5 bytes
1149 // at entry point.
1150 patch_code_pc_offset_ = assembler()->CodeSize();
1151 __ BranchPatchable(*StubCode::FixCallersTarget_entry());
1152 1130
1153 if (is_optimizing()) { 1131 if (is_optimizing()) {
1154 lazy_deopt_pc_offset_ = assembler()->CodeSize(); 1132 lazy_deopt_pc_offset_ = assembler()->CodeSize();
1155 __ Branch(*StubCode::DeoptimizeLazy_entry()); 1133 __ Branch(*StubCode::DeoptimizeLazy_entry());
1156 } 1134 }
1157 } 1135 }
1158 1136
1159 1137
1160 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, 1138 void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
1161 const StubEntry& stub_entry, 1139 const StubEntry& stub_entry,
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after
1859 __ AddImmediate(SP, kDoubleSize); 1837 __ AddImmediate(SP, kDoubleSize);
1860 } 1838 }
1861 1839
1862 1840
1863 #undef __ 1841 #undef __
1864 1842
1865 1843
1866 } // namespace dart 1844 } // namespace dart
1867 1845
1868 #endif // defined TARGET_ARCH_MIPS 1846 #endif // defined TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698