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

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

Issue 10375017: Remove old x64 code generator. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/compiler.h ('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) 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/compiler.h" 5 #include "vm/compiler.h"
6 6
7 #include "vm/assembler.h" 7 #include "vm/assembler.h"
8 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/code_patcher.h" 10 #include "vm/code_patcher.h"
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 // Use previously compiled code. 124 // Use previously compiled code.
125 function.SetCode(Code::Handle(function.unoptimized_code())); 125 function.SetCode(Code::Handle(function.unoptimized_code()));
126 CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code())); 126 CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code()));
127 if (FLAG_trace_compiler) { 127 if (FLAG_trace_compiler) {
128 OS::Print("--> restoring entry at 0x%x\n", 128 OS::Print("--> restoring entry at 0x%x\n",
129 Code::Handle(function.unoptimized_code()).EntryPoint()); 129 Code::Handle(function.unoptimized_code()).EntryPoint());
130 } 130 }
131 } 131 }
132 132
133 133
134 static void CompileParsedFunctionHelper(
135 const ParsedFunction& parsed_function, bool optimized) {
136 Isolate* isolate = Isolate::Current();
137 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer);
138 const Function& function = parsed_function.function();
139 const char* function_fullname = function.ToFullyQualifiedCString();
140 bool is_compiled = false;
141 if (FLAG_use_new_compiler) {
142 ASSERT(!optimized);
143 LongJump* old_base = isolate->long_jump_base();
144 LongJump bailout_jump;
145 isolate->set_long_jump_base(&bailout_jump);
146 if (setjmp(*bailout_jump.Set()) == 0) {
147 FlowGraphBuilder graph_builder(parsed_function);
148 graph_builder.BuildGraph();
149
150 // The non-optimizing compiler compiles blocks in reverse postorder,
151 // because it is a 'natural' order for the human reader of the
152 // generated code.
153 intptr_t length = graph_builder.postorder_block_entries().length();
154 GrowableArray<BlockEntryInstr*> block_order(length);
155 for (intptr_t i = length - 1; i >= 0; --i) {
156 block_order.Add(graph_builder.postorder_block_entries()[i]);
157 }
158
159 Assembler assembler;
160 FlowGraphCompiler graph_compiler(&assembler, parsed_function,
161 block_order);
162 graph_compiler.CompileGraph();
163
164 TimerScope timer(FLAG_compiler_stats,
165 &CompilerStats::codefinalizer_timer);
166 const Code& code =
167 Code::Handle(Code::FinalizeCode(function_fullname, &assembler));
168 code.set_is_optimized(false);
169 graph_compiler.FinalizePcDescriptors(code);
170 graph_compiler.FinalizeStackmaps(code);
171 graph_compiler.FinalizeVarDescriptors(code);
172 graph_compiler.FinalizeExceptionHandlers(code);
173 function.set_unoptimized_code(code);
174 function.SetCode(code);
175 ASSERT(CodePatcher::CodeIsPatchable(code));
176 is_compiled = true;
177 } else {
178 // We bailed out.
179 Error& bailout_error = Error::Handle(
180 isolate->object_store()->sticky_error());
181 isolate->object_store()->clear_sticky_error();
182 if (FLAG_trace_bailout) {
183 OS::Print("%s\n", bailout_error.ToErrorCString());
184 }
185 }
186 isolate->set_long_jump_base(old_base);
187 }
188
189 if (!is_compiled) {
190 Assembler assembler;
191 if (optimized) {
192 // Transition to optimized code only from unoptimized code ...
193 // for now.
194 ASSERT(function.HasCode());
195 ASSERT(!function.HasOptimizedCode());
196 // Do not use type feedback to optimize a function that was
197 // deoptimized too often.
198 if (parsed_function.function().deoptimization_counter() <
199 FLAG_deoptimization_counter_threshold) {
200 ExtractTypeFeedback(
201 Code::Handle(parsed_function.function().unoptimized_code()),
202 parsed_function.node_sequence());
203 }
204 OptimizingCodeGenerator code_gen(&assembler, parsed_function);
205 code_gen.GenerateCode();
206 TimerScope timer(FLAG_compiler_stats,
207 &CompilerStats::codefinalizer_timer);
208 Code& code = Code::Handle(
209 Code::FinalizeCode(function_fullname, &assembler));
210 code.set_is_optimized(true);
211 code_gen.FinalizePcDescriptors(code);
212 code_gen.FinalizeStackmaps(code);
213 code_gen.FinalizeExceptionHandlers(code);
214 function.SetCode(code);
215 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code()));
216 if (FLAG_trace_compiler) {
217 OS::Print("--> patching entry 0x%x\n",
218 Code::Handle(function.unoptimized_code()).EntryPoint());
219 }
220 } else {
221 // Compile unoptimized code.
222 ASSERT(!function.HasCode());
223 // Compiling first time.
224 CodeGenerator code_gen(&assembler, parsed_function);
225 code_gen.GenerateCode();
226 TimerScope timer(FLAG_compiler_stats,
227 &CompilerStats::codefinalizer_timer);
228 const Code& code =
229 Code::Handle(Code::FinalizeCode(function_fullname, &assembler));
230 code.set_is_optimized(false);
231 code_gen.FinalizePcDescriptors(code);
232 code_gen.FinalizeStackmaps(code);
233 code_gen.FinalizeVarDescriptors(code);
234 code_gen.FinalizeExceptionHandlers(code);
235 function.set_unoptimized_code(code);
236 function.SetCode(code);
237 ASSERT(CodePatcher::CodeIsPatchable(code));
238 }
239 }
240 }
241
242
134 static RawError* CompileFunctionHelper(const Function& function, 243 static RawError* CompileFunctionHelper(const Function& function,
135 bool optimized) { 244 bool optimized) {
136 Isolate* isolate = Isolate::Current(); 245 Isolate* isolate = Isolate::Current();
137 Error& error = Error::Handle(); 246 Error& error = Error::Handle();
138 LongJump* base = isolate->long_jump_base(); 247 LongJump* base = isolate->long_jump_base();
139 LongJump jump; 248 LongJump jump;
140 isolate->set_long_jump_base(&jump); 249 isolate->set_long_jump_base(&jump);
141 // Skips parsing if we need to only install unoptimized code. 250 // Skips parsing if we need to only install unoptimized code.
142 if (!optimized && !Code::Handle(function.unoptimized_code()).IsNull()) { 251 if (!optimized && !Code::Handle(function.unoptimized_code()).IsNull()) {
143 InstallUnoptimizedCode(function); 252 InstallUnoptimizedCode(function);
144 isolate->set_long_jump_base(base); 253 isolate->set_long_jump_base(base);
145 return Error::null(); 254 return Error::null();
146 } 255 }
147 if (setjmp(*jump.Set()) == 0) { 256 if (setjmp(*jump.Set()) == 0) {
148 TIMERSCOPE(time_compilation); 257 TIMERSCOPE(time_compilation);
149 ParsedFunction parsed_function(function); 258 ParsedFunction parsed_function(function);
150 const char* function_fullname = function.ToFullyQualifiedCString();
151 if (FLAG_trace_compiler) { 259 if (FLAG_trace_compiler) {
152 OS::Print("Compiling %sfunction: '%s' @ token %d\n", 260 OS::Print("Compiling %sfunction: '%s' @ token %d\n",
153 (optimized ? "optimized " : ""), 261 (optimized ? "optimized " : ""),
154 function_fullname, 262 function.ToFullyQualifiedCString(),
155 function.token_index()); 263 function.token_index());
156 } 264 }
157 Parser::ParseFunction(&parsed_function); 265 Parser::ParseFunction(&parsed_function);
158 parsed_function.AllocateVariables(); 266 parsed_function.AllocateVariables();
159 267
160 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); 268 CompileParsedFunctionHelper(parsed_function, optimized);
161 bool is_compiled = false;
162 if (FLAG_use_new_compiler) {
163 ASSERT(!optimized);
164 LongJump* old_base = isolate->long_jump_base();
165 LongJump bailout_jump;
166 isolate->set_long_jump_base(&bailout_jump);
167 if (setjmp(*bailout_jump.Set()) == 0) {
168 FlowGraphBuilder graph_builder(parsed_function);
169 graph_builder.BuildGraph();
170 269
171 // The non-optimizing compiler compiles blocks in reverse postorder,
172 // because it is a 'natural' order for the human reader of the
173 // generated code.
174 intptr_t length = graph_builder.postorder_block_entries().length();
175 GrowableArray<BlockEntryInstr*> block_order(length);
176 for (intptr_t i = length - 1; i >= 0; --i) {
177 block_order.Add(graph_builder.postorder_block_entries()[i]);
178 }
179
180 Assembler assembler;
181 FlowGraphCompiler graph_compiler(&assembler, parsed_function,
182 block_order);
183 graph_compiler.CompileGraph();
184
185 TimerScope timer(FLAG_compiler_stats,
186 &CompilerStats::codefinalizer_timer);
187 const Code& code =
188 Code::Handle(Code::FinalizeCode(function_fullname, &assembler));
189 code.set_is_optimized(false);
190 graph_compiler.FinalizePcDescriptors(code);
191 graph_compiler.FinalizeStackmaps(code);
192 graph_compiler.FinalizeVarDescriptors(code);
193 graph_compiler.FinalizeExceptionHandlers(code);
194 function.set_unoptimized_code(code);
195 function.SetCode(code);
196 ASSERT(CodePatcher::CodeIsPatchable(code));
197 is_compiled = true;
198 } else {
199 // We bailed out.
200 Error& bailout_error = Error::Handle(
201 isolate->object_store()->sticky_error());
202 isolate->object_store()->clear_sticky_error();
203 if (FLAG_trace_bailout) {
204 OS::Print("%s\n", bailout_error.ToErrorCString());
205 }
206 }
207 isolate->set_long_jump_base(old_base);
208 }
209
210 if (!is_compiled) {
211 Assembler assembler;
212 if (optimized) {
213 // Transition to optimized code only from unoptimized code ...
214 // for now.
215 ASSERT(function.HasCode());
216 ASSERT(!function.HasOptimizedCode());
217 // Do not use type feedback to optimize a function that was
218 // deoptimized too often.
219 if (parsed_function.function().deoptimization_counter() <
220 FLAG_deoptimization_counter_threshold) {
221 ExtractTypeFeedback(
222 Code::Handle(parsed_function.function().unoptimized_code()),
223 parsed_function.node_sequence());
224 }
225 OptimizingCodeGenerator code_gen(&assembler, parsed_function);
226 code_gen.GenerateCode();
227 TimerScope timer(FLAG_compiler_stats,
228 &CompilerStats::codefinalizer_timer);
229 Code& code = Code::Handle(
230 Code::FinalizeCode(function_fullname, &assembler));
231 code.set_is_optimized(true);
232 code_gen.FinalizePcDescriptors(code);
233 code_gen.FinalizeStackmaps(code);
234 code_gen.FinalizeExceptionHandlers(code);
235 function.SetCode(code);
236 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code()));
237 if (FLAG_trace_compiler) {
238 OS::Print("--> patching entry 0x%x\n",
239 Code::Handle(function.unoptimized_code()).EntryPoint());
240 }
241 } else {
242 // Compile unnoptimized code.
243 ASSERT(!function.HasCode());
244 // Compiling first time.
245 CodeGenerator code_gen(&assembler, parsed_function);
246 code_gen.GenerateCode();
247 TimerScope timer(FLAG_compiler_stats,
248 &CompilerStats::codefinalizer_timer);
249 const Code& code =
250 Code::Handle(Code::FinalizeCode(function_fullname, &assembler));
251 code.set_is_optimized(false);
252 code_gen.FinalizePcDescriptors(code);
253 code_gen.FinalizeStackmaps(code);
254 code_gen.FinalizeVarDescriptors(code);
255 code_gen.FinalizeExceptionHandlers(code);
256 function.set_unoptimized_code(code);
257 function.SetCode(code);
258 ASSERT(CodePatcher::CodeIsPatchable(code));
259 }
260 }
261 if (FLAG_trace_compiler) { 270 if (FLAG_trace_compiler) {
262 OS::Print("--> '%s' entry: 0x%x\n", 271 OS::Print("--> '%s' entry: 0x%x\n",
263 function_fullname, 272 function.ToFullyQualifiedCString(),
264 Code::Handle(function.CurrentCode()).EntryPoint()); 273 Code::Handle(function.CurrentCode()).EntryPoint());
265 } 274 }
266 if (Isolate::Current()->debugger()->IsActive()) { 275 if (Isolate::Current()->debugger()->IsActive()) {
267 Isolate::Current()->debugger()->NotifyCompilation(function); 276 Isolate::Current()->debugger()->NotifyCompilation(function);
268 } 277 }
269 if (FLAG_disassemble) { 278 if (FLAG_disassemble) {
279 const char* function_fullname = function.ToFullyQualifiedCString();
270 OS::Print("Code for %sfunction '%s' {\n", 280 OS::Print("Code for %sfunction '%s' {\n",
271 optimized ? "optimized " : "", function_fullname); 281 optimized ? "optimized " : "",
282 function_fullname);
272 const Code& code = Code::Handle(function.CurrentCode()); 283 const Code& code = Code::Handle(function.CurrentCode());
273 const Instructions& instructions = 284 const Instructions& instructions =
274 Instructions::Handle(code.instructions()); 285 Instructions::Handle(code.instructions());
275 uword start = instructions.EntryPoint(); 286 uword start = instructions.EntryPoint();
276 Disassembler::Disassemble(start, start + instructions.size()); 287 Disassembler::Disassemble(start, start + instructions.size());
277 OS::Print("}\n"); 288 OS::Print("}\n");
278 OS::Print("Pointer offsets for function: {\n"); 289 OS::Print("Pointer offsets for function: {\n");
279 for (intptr_t i = 0; i < code.pointer_offsets_length(); i++) { 290 for (intptr_t i = 0; i < code.pointer_offsets_length(); i++) {
280 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); 291 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint();
281 Object& obj = Object::Handle(); 292 Object& obj = Object::Handle();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 RawError* Compiler::CompileFunction(const Function& function) { 336 RawError* Compiler::CompileFunction(const Function& function) {
326 return CompileFunctionHelper(function, false); // Non-optimized. 337 return CompileFunctionHelper(function, false); // Non-optimized.
327 } 338 }
328 339
329 340
330 RawError* Compiler::CompileOptimizedFunction(const Function& function) { 341 RawError* Compiler::CompileOptimizedFunction(const Function& function) {
331 return CompileFunctionHelper(function, true); // Optimized. 342 return CompileFunctionHelper(function, true); // Optimized.
332 } 343 }
333 344
334 345
346 RawError* Compiler::CompileParsedFunction(
347 const ParsedFunction& parsed_function) {
348 Isolate* isolate = Isolate::Current();
349 Error& error = Error::Handle();
350 LongJump* base = isolate->long_jump_base();
351 LongJump jump;
352 isolate->set_long_jump_base(&jump);
353 if (setjmp(*jump.Set()) == 0) {
354 CompileParsedFunctionHelper(parsed_function, false); // Non-optimized.
355 } else {
356 // We got an error during compilation.
357 error = isolate->object_store()->sticky_error();
358 isolate->object_store()->clear_sticky_error();
359 }
360 isolate->set_long_jump_base(base);
361 return error.raw();
362 }
363
364
335 RawError* Compiler::CompileAllFunctions(const Class& cls) { 365 RawError* Compiler::CompileAllFunctions(const Class& cls) {
336 Error& error = Error::Handle(); 366 Error& error = Error::Handle();
337 Array& functions = Array::Handle(cls.functions()); 367 Array& functions = Array::Handle(cls.functions());
338 Function& func = Function::Handle(); 368 Function& func = Function::Handle();
339 for (int i = 0; i < functions.Length(); i++) { 369 for (int i = 0; i < functions.Length(); i++) {
340 func ^= functions.At(i); 370 func ^= functions.At(i);
341 ASSERT(!func.IsNull()); 371 ASSERT(!func.IsNull());
342 if (!func.HasCode() && !func.IsAbstract()) { 372 if (!func.HasCode() && !func.IsAbstract()) {
343 error = CompileFunction(func); 373 error = CompileFunction(func);
344 if (!error.IsNull()) { 374 if (!error.IsNull()) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 func.set_owner(Class::Handle( 410 func.set_owner(Class::Handle(
381 Type::Handle(Type::FunctionInterface()).type_class())); 411 Type::Handle(Type::FunctionInterface()).type_class()));
382 412
383 // We compile the function here, even though InvokeStatic() below 413 // We compile the function here, even though InvokeStatic() below
384 // would compile func automatically. We are checking fewer invariants 414 // would compile func automatically. We are checking fewer invariants
385 // here. 415 // here.
386 ParsedFunction parsed_function(func); 416 ParsedFunction parsed_function(func);
387 parsed_function.SetNodeSequence(fragment); 417 parsed_function.SetNodeSequence(fragment);
388 parsed_function.set_default_parameter_values(Array::Handle()); 418 parsed_function.set_default_parameter_values(Array::Handle());
389 419
390 Assembler assembler; 420 CompileParsedFunctionHelper(parsed_function, false); // Non-optimized.
391 CodeGenerator code_gen(&assembler, parsed_function);
392 code_gen.GenerateCode();
393 const Code& code = Code::Handle(Code::FinalizeCode(kEvalConst, &assembler));
394
395 func.SetCode(code);
396 code_gen.FinalizePcDescriptors(code);
397 code_gen.FinalizeStackmaps(code);
398 code_gen.FinalizeExceptionHandlers(code);
399 421
400 GrowableArray<const Object*> arguments; // no arguments. 422 GrowableArray<const Object*> arguments; // no arguments.
401 const Array& kNoArgumentNames = Array::Handle(); 423 const Array& kNoArgumentNames = Array::Handle();
402 result = DartEntry::InvokeStatic(func, 424 result = DartEntry::InvokeStatic(func,
403 arguments, 425 arguments,
404 kNoArgumentNames); 426 kNoArgumentNames);
405 } else { 427 } else {
406 result = isolate->object_store()->sticky_error(); 428 result = isolate->object_store()->sticky_error();
407 isolate->object_store()->clear_sticky_error(); 429 isolate->object_store()->clear_sticky_error();
408 } 430 }
409 isolate->set_long_jump_base(base); 431 isolate->set_long_jump_base(base);
410 return result.raw(); 432 return result.raw();
411 } 433 }
412 434
413 435
414 } // namespace dart 436 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/flow_graph_compiler_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698