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

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

Issue 1192103004: VM: New calling convention for generated code. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fixed 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
« no previous file with comments | « runtime/vm/flow_graph_compiler_arm64.cc ('k') | runtime/vm/flow_graph_compiler_mips.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_IA32. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32.
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 95
96 // Emit all kMaterializeObject instructions describing objects to be 96 // Emit all kMaterializeObject instructions describing objects to be
97 // materialized on the deoptimization as a prefix to the deoptimization info. 97 // materialized on the deoptimization as a prefix to the deoptimization info.
98 EmitMaterializations(deopt_env_, builder); 98 EmitMaterializations(deopt_env_, builder);
99 99
100 // The real frame starts here. 100 // The real frame starts here.
101 builder->MarkFrameStart(); 101 builder->MarkFrameStart();
102 102
103 Zone* zone = compiler->zone(); 103 Zone* zone = compiler->zone();
104 104
105 // Callee's PC marker is not used anymore. Pass Code::null() to set to 0.
106 builder->AddPcMarker(Function::Handle(zone), slot_ix++); 105 builder->AddPcMarker(Function::Handle(zone), slot_ix++);
107
108 // Current FP and PC.
109 builder->AddCallerFp(slot_ix++); 106 builder->AddCallerFp(slot_ix++);
110 builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++); 107 builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
111 108
112 // Emit all values that are needed for materialization as a part of the 109 // Emit all values that are needed for materialization as a part of the
113 // expression stack for the bottom-most frame. This guarantees that GC 110 // expression stack for the bottom-most frame. This guarantees that GC
114 // will be able to find them during materialization. 111 // will be able to find them during materialization.
115 slot_ix = builder->EmitMaterializationArguments(slot_ix); 112 slot_ix = builder->EmitMaterializationArguments(slot_ix);
116 113
117 // For the innermost environment, set outgoing arguments and the locals. 114 // For the innermost environment, set outgoing arguments and the locals.
118 for (intptr_t i = current->Length() - 1; 115 for (intptr_t i = current->Length() - 1;
119 i >= current->fixed_parameter_count(); 116 i >= current->fixed_parameter_count();
120 i--) { 117 i--) {
121 builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++); 118 builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++);
122 } 119 }
123 120
124 // Current PC marker and caller FP.
125 builder->AddPcMarker(current->function(), slot_ix++); 121 builder->AddPcMarker(current->function(), slot_ix++);
126 builder->AddCallerFp(slot_ix++); 122 builder->AddCallerFp(slot_ix++);
127 123
128 Environment* previous = current; 124 Environment* previous = current;
129 current = current->outer(); 125 current = current->outer();
130 while (current != NULL) { 126 while (current != NULL) {
131 // 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
132 // which is recorded in the outer environment. 128 // which is recorded in the outer environment.
133 builder->AddReturnAddress( 129 builder->AddReturnAddress(
134 current->function(), 130 current->function(),
(...skipping 10 matching lines...) Expand all
145 141
146 // 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.
147 for (intptr_t i = current->Length() - 1; 143 for (intptr_t i = current->Length() - 1;
148 i >= current->fixed_parameter_count(); 144 i >= current->fixed_parameter_count();
149 i--) { 145 i--) {
150 builder->AddCopy(current->ValueAt(i), 146 builder->AddCopy(current->ValueAt(i),
151 current->LocationAt(i), 147 current->LocationAt(i),
152 slot_ix++); 148 slot_ix++);
153 } 149 }
154 150
155 // PC marker and caller FP.
156 builder->AddPcMarker(current->function(), slot_ix++); 151 builder->AddPcMarker(current->function(), slot_ix++);
157 builder->AddCallerFp(slot_ix++); 152 builder->AddCallerFp(slot_ix++);
158 153
159 // Iterate on the outer environment. 154 // Iterate on the outer environment.
160 previous = current; 155 previous = current;
161 current = current->outer(); 156 current = current->outer();
162 } 157 }
163 // The previous pointer is now the outermost environment. 158 // The previous pointer is now the outermost environment.
164 ASSERT(previous != NULL); 159 ASSERT(previous != NULL);
165 160
(...skipping 15 matching lines...) Expand all
181 ASSERT(reason() != ICData::kDeoptAtCall); 176 ASSERT(reason() != ICData::kDeoptAtCall);
182 Assembler* assem = compiler->assembler(); 177 Assembler* assem = compiler->assembler();
183 #define __ assem-> 178 #define __ assem->
184 __ Comment("%s", Name()); 179 __ Comment("%s", Name());
185 __ Bind(entry_label()); 180 __ Bind(entry_label());
186 if (FLAG_trap_on_deoptimization) { 181 if (FLAG_trap_on_deoptimization) {
187 __ int3(); 182 __ int3();
188 } 183 }
189 184
190 ASSERT(deopt_env() != NULL); 185 ASSERT(deopt_env() != NULL);
191 186 __ pushl(CODE_REG);
192 __ Call(*StubCode::Deoptimize_entry()); 187 __ Call(*StubCode::Deoptimize_entry());
193 set_pc_offset(assem->CodeSize()); 188 set_pc_offset(assem->CodeSize());
194 __ int3(); 189 __ int3();
195 #undef __ 190 #undef __
196 } 191 }
197 192
198 193
199 #define __ assembler()-> 194 #define __ assembler()->
200 195
201 196
(...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 } 987 }
993 988
994 989
995 // NOTE: If the entry code shape changes, ReturnAddressLocator in profiler.cc 990 // NOTE: If the entry code shape changes, ReturnAddressLocator in profiler.cc
996 // needs to be updated to match. 991 // needs to be updated to match.
997 void FlowGraphCompiler::EmitFrameEntry() { 992 void FlowGraphCompiler::EmitFrameEntry() {
998 const Function& function = parsed_function().function(); 993 const Function& function = parsed_function().function();
999 if (CanOptimizeFunction() && 994 if (CanOptimizeFunction() &&
1000 function.IsOptimizable() && 995 function.IsOptimizable() &&
1001 (!is_optimizing() || may_reoptimize())) { 996 (!is_optimizing() || may_reoptimize())) {
1002 const Register function_reg = EDI; 997 const Register function_reg = EBX;
1003 __ LoadObject(function_reg, function); 998 __ LoadObject(function_reg, function);
1004 999
1005 // Patch point is after the eventually inlined function object.
1006 entry_patch_pc_offset_ = assembler()->CodeSize();
1007
1008 // Reoptimization of an optimized function is triggered by counting in 1000 // Reoptimization of an optimized function is triggered by counting in
1009 // IC stubs, but not at the entry of the function. 1001 // IC stubs, but not at the entry of the function.
1010 if (!is_optimizing()) { 1002 if (!is_optimizing()) {
1011 __ incl(FieldAddress(function_reg, Function::usage_counter_offset())); 1003 __ incl(FieldAddress(function_reg, Function::usage_counter_offset()));
1012 } 1004 }
1013 __ cmpl(FieldAddress(function_reg, Function::usage_counter_offset()), 1005 __ cmpl(FieldAddress(function_reg, Function::usage_counter_offset()),
1014 Immediate(GetOptimizationThreshold())); 1006 Immediate(GetOptimizationThreshold()));
1015 ASSERT(function_reg == EDI); 1007 ASSERT(function_reg == EBX);
1016 __ J(GREATER_EQUAL, *StubCode::OptimizeFunction_entry()); 1008 __ J(GREATER_EQUAL, *StubCode::OptimizeFunction_entry());
1017 } else if (!flow_graph().IsCompiledForOsr()) {
1018 entry_patch_pc_offset_ = assembler()->CodeSize();
1019 } 1009 }
1020 __ Comment("Enter frame"); 1010 __ Comment("Enter frame");
1021 if (flow_graph().IsCompiledForOsr()) { 1011 if (flow_graph().IsCompiledForOsr()) {
1022 intptr_t extra_slots = StackSize() 1012 intptr_t extra_slots = StackSize()
1023 - flow_graph().num_stack_locals() 1013 - flow_graph().num_stack_locals()
1024 - flow_graph().num_copied_params(); 1014 - flow_graph().num_copied_params();
1025 ASSERT(extra_slots >= 0); 1015 ASSERT(extra_slots >= 0);
1026 __ EnterOsrFrame(extra_slots * kWordSize); 1016 __ EnterOsrFrame(extra_slots * kWordSize);
1027 } else { 1017 } else {
1028 ASSERT(StackSize() >= 0); 1018 ASSERT(StackSize() >= 0);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 __ movl(Address(EBP, (slot_base - i) * kWordSize), EAX); 1119 __ movl(Address(EBP, (slot_base - i) * kWordSize), EAX);
1130 } 1120 }
1131 } 1121 }
1132 } 1122 }
1133 1123
1134 ASSERT(!block_order().is_empty()); 1124 ASSERT(!block_order().is_empty());
1135 VisitBlocks(); 1125 VisitBlocks();
1136 1126
1137 __ int3(); 1127 __ int3();
1138 GenerateDeferredCode(); 1128 GenerateDeferredCode();
1139 // Emit function patching code. This will be swapped with the first 5 bytes
1140 // at entry point.
1141 patch_code_pc_offset_ = assembler()->CodeSize();
1142 __ Jmp(*StubCode::FixCallersTarget_entry());
1143 1129
1144 if (is_optimizing()) { 1130 if (is_optimizing()) {
1145 lazy_deopt_pc_offset_ = assembler()->CodeSize(); 1131 lazy_deopt_pc_offset_ = assembler()->CodeSize();
1146 __ Jmp(*StubCode::DeoptimizeLazy_entry()); 1132 __ Jmp(*StubCode::DeoptimizeLazy_entry());
1147 } 1133 }
1148 } 1134 }
1149 1135
1150 1136
1151 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, 1137 void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
1152 const StubEntry& stub_entry, 1138 const StubEntry& stub_entry,
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1255 intptr_t deopt_id, 1241 intptr_t deopt_id,
1256 intptr_t token_pos, 1242 intptr_t token_pos,
1257 LocationSummary* locs) { 1243 LocationSummary* locs) {
1258 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0); 1244 ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
1259 // Each ICData propagated from unoptimized to optimized code contains the 1245 // Each ICData propagated from unoptimized to optimized code contains the
1260 // function that corresponds to the Dart function of that IC call. Due 1246 // function that corresponds to the Dart function of that IC call. Due
1261 // to inlining in optimized code, that function may not correspond to the 1247 // to inlining in optimized code, that function may not correspond to the
1262 // top-level function (parsed_function().function()) which could be 1248 // top-level function (parsed_function().function()) which could be
1263 // reoptimized and which counter needs to be incremented. 1249 // reoptimized and which counter needs to be incremented.
1264 // Pass the function explicitly, it is used in IC stub. 1250 // Pass the function explicitly, it is used in IC stub.
1265 __ LoadObject(EDI, parsed_function().function()); 1251 __ LoadObject(EBX, parsed_function().function());
1266 __ LoadObject(ECX, ic_data); 1252 __ LoadObject(ECX, ic_data);
1267 GenerateDartCall(deopt_id, 1253 GenerateDartCall(deopt_id,
1268 token_pos, 1254 token_pos,
1269 stub_entry, 1255 stub_entry,
1270 RawPcDescriptors::kIcCall, 1256 RawPcDescriptors::kIcCall,
1271 locs); 1257 locs);
1272 __ Drop(argument_count); 1258 __ Drop(argument_count);
1273 } 1259 }
1274 1260
1275 1261
(...skipping 19 matching lines...) Expand all
1295 intptr_t argument_count, 1281 intptr_t argument_count,
1296 intptr_t deopt_id, 1282 intptr_t deopt_id,
1297 intptr_t token_pos, 1283 intptr_t token_pos,
1298 LocationSummary* locs) { 1284 LocationSummary* locs) {
1299 const String& name = String::Handle(zone(), ic_data.target_name()); 1285 const String& name = String::Handle(zone(), ic_data.target_name());
1300 const Array& arguments_descriptor = 1286 const Array& arguments_descriptor =
1301 Array::ZoneHandle(zone(), ic_data.arguments_descriptor()); 1287 Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
1302 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0)); 1288 ASSERT(!arguments_descriptor.IsNull() && (arguments_descriptor.Length() > 0));
1303 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(), 1289 const MegamorphicCache& cache = MegamorphicCache::ZoneHandle(zone(),
1304 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor)); 1290 MegamorphicCacheTable::Lookup(isolate(), name, arguments_descriptor));
1305 const Register receiverR = EDI; 1291 const Register receiverR = ECX;
1306 const Register cacheR = EBX; 1292 const Register cacheR = EBX;
1307 const Register targetR = EBX; 1293 const Register targetR = EBX;
1308 __ movl(receiverR, Address(ESP, (argument_count - 1) * kWordSize)); 1294 __ movl(receiverR, Address(ESP, (argument_count - 1) * kWordSize));
1309 __ LoadObject(cacheR, cache); 1295 __ LoadObject(cacheR, cache);
1310 1296
1311 if (FLAG_use_megamorphic_stub) { 1297 if (FLAG_use_megamorphic_stub) {
1312 __ Call(*StubCode::MegamorphicLookup_entry()); 1298 __ Call(*StubCode::MegamorphicLookup_entry());
1313 } else { 1299 } else {
1314 StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR); 1300 StubCode::EmitMegamorphicLookup(assembler(), receiverR, cacheR, targetR);
1315 } 1301 }
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
1847 __ movups(reg, Address(ESP, 0)); 1833 __ movups(reg, Address(ESP, 0));
1848 __ addl(ESP, Immediate(kFpuRegisterSize)); 1834 __ addl(ESP, Immediate(kFpuRegisterSize));
1849 } 1835 }
1850 1836
1851 1837
1852 #undef __ 1838 #undef __
1853 1839
1854 } // namespace dart 1840 } // namespace dart
1855 1841
1856 #endif // defined TARGET_ARCH_IA32 1842 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_arm64.cc ('k') | runtime/vm/flow_graph_compiler_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698