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

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

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

Powered by Google App Engine
This is Rietveld 408576698