OLD | NEW |
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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 return Error::null(); | 102 return Error::null(); |
103 } | 103 } |
104 | 104 |
105 | 105 |
106 static void InstallUnoptimizedCode(const Function& function) { | 106 static void InstallUnoptimizedCode(const Function& function) { |
107 // Disable optimized code. | 107 // Disable optimized code. |
108 ASSERT(function.HasOptimizedCode()); | 108 ASSERT(function.HasOptimizedCode()); |
109 // Patch entry of optimized code. | 109 // Patch entry of optimized code. |
110 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); | 110 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); |
111 if (FLAG_trace_compiler) { | 111 if (FLAG_trace_compiler) { |
112 OS::Print("--> patching entry 0x%x\n", | 112 OS::Print("--> patching entry %#"Px"\n", |
113 Code::Handle(function.CurrentCode()).EntryPoint()); | 113 Code::Handle(function.CurrentCode()).EntryPoint()); |
114 } | 114 } |
115 // Use previously compiled code. | 115 // Use previously compiled code. |
116 function.SetCode(Code::Handle(function.unoptimized_code())); | 116 function.SetCode(Code::Handle(function.unoptimized_code())); |
117 CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code())); | 117 CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code())); |
118 if (FLAG_trace_compiler) { | 118 if (FLAG_trace_compiler) { |
119 OS::Print("--> restoring entry at 0x%x\n", | 119 OS::Print("--> restoring entry at %#"Px"\n", |
120 Code::Handle(function.unoptimized_code()).EntryPoint()); | 120 Code::Handle(function.unoptimized_code()).EntryPoint()); |
121 } | 121 } |
122 } | 122 } |
123 | 123 |
124 | 124 |
125 // Return false if bailed out. | 125 // Return false if bailed out. |
126 static bool CompileParsedFunctionHelper(const ParsedFunction& parsed_function, | 126 static bool CompileParsedFunctionHelper(const ParsedFunction& parsed_function, |
127 bool optimized) { | 127 bool optimized) { |
128 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); | 128 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); |
129 bool is_compiled = false; | 129 bool is_compiled = false; |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 graph_compiler.FinalizePcDescriptors(code); | 253 graph_compiler.FinalizePcDescriptors(code); |
254 graph_compiler.FinalizeDeoptInfo(code); | 254 graph_compiler.FinalizeDeoptInfo(code); |
255 graph_compiler.FinalizeStackmaps(code); | 255 graph_compiler.FinalizeStackmaps(code); |
256 graph_compiler.FinalizeVarDescriptors(code); | 256 graph_compiler.FinalizeVarDescriptors(code); |
257 graph_compiler.FinalizeExceptionHandlers(code); | 257 graph_compiler.FinalizeExceptionHandlers(code); |
258 graph_compiler.FinalizeComments(code); | 258 graph_compiler.FinalizeComments(code); |
259 if (optimized) { | 259 if (optimized) { |
260 function.SetCode(code); | 260 function.SetCode(code); |
261 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code())); | 261 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code())); |
262 if (FLAG_trace_compiler) { | 262 if (FLAG_trace_compiler) { |
263 OS::Print("--> patching entry 0x%x\n", | 263 OS::Print("--> patching entry %#"Px"\n", |
264 Code::Handle(function.unoptimized_code()).EntryPoint()); | 264 Code::Handle(function.unoptimized_code()).EntryPoint()); |
265 } | 265 } |
266 } else { | 266 } else { |
267 function.set_unoptimized_code(code); | 267 function.set_unoptimized_code(code); |
268 function.SetCode(code); | 268 function.SetCode(code); |
269 ASSERT(CodePatcher::CodeIsPatchable(code)); | 269 ASSERT(CodePatcher::CodeIsPatchable(code)); |
270 } | 270 } |
271 } | 271 } |
272 is_compiled = true; | 272 is_compiled = true; |
273 } else { | 273 } else { |
(...skipping 29 matching lines...) Expand all Loading... |
303 start + instructions.size(), | 303 start + instructions.size(), |
304 code.comments()); | 304 code.comments()); |
305 OS::Print("}\n"); | 305 OS::Print("}\n"); |
306 | 306 |
307 OS::Print("Pointer offsets for function: {\n"); | 307 OS::Print("Pointer offsets for function: {\n"); |
308 // Pointer offsets are stored in descending order. | 308 // Pointer offsets are stored in descending order. |
309 for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) { | 309 for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) { |
310 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); | 310 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); |
311 Object& obj = Object::Handle(); | 311 Object& obj = Object::Handle(); |
312 obj = *reinterpret_cast<RawObject**>(addr); | 312 obj = *reinterpret_cast<RawObject**>(addr); |
313 OS::Print(" %" PRIdPTR " : 0x%" PRIxPTR " '%s'\n", | 313 OS::Print(" %d : %#"Px" '%s'\n", |
314 code.GetPointerOffsetAt(i), addr, obj.ToCString()); | 314 code.GetPointerOffsetAt(i), addr, obj.ToCString()); |
315 } | 315 } |
316 OS::Print("}\n"); | 316 OS::Print("}\n"); |
317 | 317 |
318 OS::Print("PC Descriptors for function '%s' {\n", function_fullname); | 318 OS::Print("PC Descriptors for function '%s' {\n", function_fullname); |
319 PcDescriptors::PrintHeaderString(); | 319 PcDescriptors::PrintHeaderString(); |
320 const PcDescriptors& descriptors = | 320 const PcDescriptors& descriptors = |
321 PcDescriptors::Handle(code.pc_descriptors()); | 321 PcDescriptors::Handle(code.pc_descriptors()); |
322 OS::Print("%s}\n", descriptors.ToCString()); | 322 OS::Print("%s}\n", descriptors.ToCString()); |
323 | 323 |
324 const Array& deopt_info_array = Array::Handle(code.deopt_info_array()); | 324 const Array& deopt_info_array = Array::Handle(code.deopt_info_array()); |
325 if (deopt_info_array.Length() > 0) { | 325 if (deopt_info_array.Length() > 0) { |
326 OS::Print("DeoptInfo: {\n"); | 326 OS::Print("DeoptInfo: {\n"); |
327 for (intptr_t i = 0; i < deopt_info_array.Length(); i++) { | 327 for (intptr_t i = 0; i < deopt_info_array.Length(); i++) { |
328 OS::Print(" %d: %s\n", | 328 OS::Print(" %"Pd": %s\n", |
329 i, Object::Handle(deopt_info_array.At(i)).ToCString()); | 329 i, Object::Handle(deopt_info_array.At(i)).ToCString()); |
330 } | 330 } |
331 OS::Print("}\n"); | 331 OS::Print("}\n"); |
332 } | 332 } |
333 | 333 |
334 const Array& object_table = Array::Handle(code.object_table()); | 334 const Array& object_table = Array::Handle(code.object_table()); |
335 if (object_table.Length() > 0) { | 335 if (object_table.Length() > 0) { |
336 OS::Print("Object Table: {\n"); | 336 OS::Print("Object Table: {\n"); |
337 for (intptr_t i = 0; i < object_table.Length(); i++) { | 337 for (intptr_t i = 0; i < object_table.Length(); i++) { |
338 OS::Print(" %d: %s\n", i, | 338 OS::Print(" %"Pd": %s\n", i, |
339 Object::Handle(object_table.At(i)).ToCString()); | 339 Object::Handle(object_table.At(i)).ToCString()); |
340 } | 340 } |
341 OS::Print("}\n"); | 341 OS::Print("}\n"); |
342 } | 342 } |
343 | 343 |
344 OS::Print("Stackmaps for function '%s' {\n", function_fullname); | 344 OS::Print("Stackmaps for function '%s' {\n", function_fullname); |
345 if (code.stackmaps() != Array::null()) { | 345 if (code.stackmaps() != Array::null()) { |
346 const Array& stackmap_table = Array::Handle(code.stackmaps()); | 346 const Array& stackmap_table = Array::Handle(code.stackmaps()); |
347 Stackmap& map = Stackmap::Handle(); | 347 Stackmap& map = Stackmap::Handle(); |
348 for (intptr_t i = 0; i < stackmap_table.Length(); ++i) { | 348 for (intptr_t i = 0; i < stackmap_table.Length(); ++i) { |
349 map ^= stackmap_table.At(i); | 349 map ^= stackmap_table.At(i); |
350 OS::Print("%s\n", map.ToCString()); | 350 OS::Print("%s\n", map.ToCString()); |
351 } | 351 } |
352 } | 352 } |
353 OS::Print("}\n"); | 353 OS::Print("}\n"); |
354 | 354 |
355 OS::Print("Variable Descriptors for function '%s' {\n", | 355 OS::Print("Variable Descriptors for function '%s' {\n", |
356 function_fullname); | 356 function_fullname); |
357 const LocalVarDescriptors& var_descriptors = | 357 const LocalVarDescriptors& var_descriptors = |
358 LocalVarDescriptors::Handle(code.var_descriptors()); | 358 LocalVarDescriptors::Handle(code.var_descriptors()); |
359 intptr_t var_desc_length = | 359 intptr_t var_desc_length = |
360 var_descriptors.IsNull() ? 0 : var_descriptors.Length(); | 360 var_descriptors.IsNull() ? 0 : var_descriptors.Length(); |
361 String& var_name = String::Handle(); | 361 String& var_name = String::Handle(); |
362 for (intptr_t i = 0; i < var_desc_length; i++) { | 362 for (intptr_t i = 0; i < var_desc_length; i++) { |
363 var_name = var_descriptors.GetName(i); | 363 var_name = var_descriptors.GetName(i); |
364 RawLocalVarDescriptors::VarInfo var_info; | 364 RawLocalVarDescriptors::VarInfo var_info; |
365 var_descriptors.GetInfo(i, &var_info); | 365 var_descriptors.GetInfo(i, &var_info); |
366 if (var_info.kind == RawLocalVarDescriptors::kContextChain) { | 366 if (var_info.kind == RawLocalVarDescriptors::kContextChain) { |
367 OS::Print(" saved CTX reg offset %" PRIdPTR "\n", var_info.index); | 367 OS::Print(" saved CTX reg offset %"Pd"\n", var_info.index); |
368 } else { | 368 } else { |
369 if (var_info.kind == RawLocalVarDescriptors::kContextLevel) { | 369 if (var_info.kind == RawLocalVarDescriptors::kContextLevel) { |
370 OS::Print(" context level %" PRIdPTR " scope %d", | 370 OS::Print(" context level %"Pd" scope %d", |
371 var_info.index, var_info.scope_id); | 371 var_info.index, var_info.scope_id); |
372 } else if (var_info.kind == RawLocalVarDescriptors::kStackVar) { | 372 } else if (var_info.kind == RawLocalVarDescriptors::kStackVar) { |
373 OS::Print(" stack var '%s' offset %" PRIdPTR, | 373 OS::Print(" stack var '%s' offset %"Pd"", |
374 var_name.ToCString(), var_info.index); | 374 var_name.ToCString(), var_info.index); |
375 } else { | 375 } else { |
376 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); | 376 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); |
377 OS::Print(" context var '%s' level %d offset %" PRIdPTR, | 377 OS::Print(" context var '%s' level %d offset %"Pd"", |
378 var_name.ToCString(), var_info.scope_id, var_info.index); | 378 var_name.ToCString(), var_info.scope_id, var_info.index); |
379 } | 379 } |
380 OS::Print(" (valid %" PRIdPTR "-%" PRIdPTR ")\n", | 380 OS::Print(" (valid %"Pd"-%"Pd")\n", |
381 var_info.begin_pos, var_info.end_pos); | 381 var_info.begin_pos, var_info.end_pos); |
382 } | 382 } |
383 } | 383 } |
384 OS::Print("}\n"); | 384 OS::Print("}\n"); |
385 | 385 |
386 OS::Print("Exception Handlers for function '%s' {\n", function_fullname); | 386 OS::Print("Exception Handlers for function '%s' {\n", function_fullname); |
387 const ExceptionHandlers& handlers = | 387 const ExceptionHandlers& handlers = |
388 ExceptionHandlers::Handle(code.exception_handlers()); | 388 ExceptionHandlers::Handle(code.exception_handlers()); |
389 OS::Print("%s}\n", handlers.ToCString()); | 389 OS::Print("%s}\n", handlers.ToCString()); |
390 } | 390 } |
391 | 391 |
392 | 392 |
393 static RawError* CompileFunctionHelper(const Function& function, | 393 static RawError* CompileFunctionHelper(const Function& function, |
394 bool optimized) { | 394 bool optimized) { |
395 Isolate* isolate = Isolate::Current(); | 395 Isolate* isolate = Isolate::Current(); |
396 LongJump* base = isolate->long_jump_base(); | 396 LongJump* base = isolate->long_jump_base(); |
397 LongJump jump; | 397 LongJump jump; |
398 isolate->set_long_jump_base(&jump); | 398 isolate->set_long_jump_base(&jump); |
399 // Skips parsing if we need to only install unoptimized code. | 399 // Skips parsing if we need to only install unoptimized code. |
400 if (!optimized && !Code::Handle(function.unoptimized_code()).IsNull()) { | 400 if (!optimized && !Code::Handle(function.unoptimized_code()).IsNull()) { |
401 InstallUnoptimizedCode(function); | 401 InstallUnoptimizedCode(function); |
402 isolate->set_long_jump_base(base); | 402 isolate->set_long_jump_base(base); |
403 return Error::null(); | 403 return Error::null(); |
404 } | 404 } |
405 if (setjmp(*jump.Set()) == 0) { | 405 if (setjmp(*jump.Set()) == 0) { |
406 TIMERSCOPE(time_compilation); | 406 TIMERSCOPE(time_compilation); |
407 ParsedFunction parsed_function(function); | 407 ParsedFunction parsed_function(function); |
408 if (FLAG_trace_compiler) { | 408 if (FLAG_trace_compiler) { |
409 OS::Print("Compiling %sfunction: '%s' @ token %d\n", | 409 OS::Print("Compiling %sfunction: '%s' @ token %"Pd"\n", |
410 (optimized ? "optimized " : ""), | 410 (optimized ? "optimized " : ""), |
411 function.ToFullyQualifiedCString(), | 411 function.ToFullyQualifiedCString(), |
412 function.token_pos()); | 412 function.token_pos()); |
413 } | 413 } |
414 Parser::ParseFunction(&parsed_function); | 414 Parser::ParseFunction(&parsed_function); |
415 parsed_function.AllocateVariables(); | 415 parsed_function.AllocateVariables(); |
416 | 416 |
417 const bool success = | 417 const bool success = |
418 CompileParsedFunctionHelper(parsed_function, optimized); | 418 CompileParsedFunctionHelper(parsed_function, optimized); |
419 if (optimized && !success) { | 419 if (optimized && !success) { |
420 // Optimizer bailed out. Disable optimizations and to never try again. | 420 // Optimizer bailed out. Disable optimizations and to never try again. |
421 if (FLAG_trace_compiler) { | 421 if (FLAG_trace_compiler) { |
422 OS::Print("--> disabling optimizations for '%s'\n", | 422 OS::Print("--> disabling optimizations for '%s'\n", |
423 function.ToFullyQualifiedCString()); | 423 function.ToFullyQualifiedCString()); |
424 } | 424 } |
425 function.set_is_optimizable(false); | 425 function.set_is_optimizable(false); |
426 isolate->set_long_jump_base(base); | 426 isolate->set_long_jump_base(base); |
427 return Error::null(); | 427 return Error::null(); |
428 } | 428 } |
429 | 429 |
430 ASSERT(success); | 430 ASSERT(success); |
431 | 431 |
432 if (FLAG_trace_compiler) { | 432 if (FLAG_trace_compiler) { |
433 OS::Print("--> '%s' entry: 0x%x\n", | 433 OS::Print("--> '%s' entry: %#"Px"\n", |
434 function.ToFullyQualifiedCString(), | 434 function.ToFullyQualifiedCString(), |
435 Code::Handle(function.CurrentCode()).EntryPoint()); | 435 Code::Handle(function.CurrentCode()).EntryPoint()); |
436 } | 436 } |
437 | 437 |
438 if (Isolate::Current()->debugger()->IsActive()) { | 438 if (Isolate::Current()->debugger()->IsActive()) { |
439 Isolate::Current()->debugger()->NotifyCompilation(function); | 439 Isolate::Current()->debugger()->NotifyCompilation(function); |
440 } | 440 } |
441 | 441 |
442 if (FLAG_disassemble) { | 442 if (FLAG_disassemble) { |
443 DisassembleCode(function, optimized); | 443 DisassembleCode(function, optimized); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 result = isolate->object_store()->sticky_error(); | 571 result = isolate->object_store()->sticky_error(); |
572 isolate->object_store()->clear_sticky_error(); | 572 isolate->object_store()->clear_sticky_error(); |
573 isolate->set_long_jump_base(base); | 573 isolate->set_long_jump_base(base); |
574 return result.raw(); | 574 return result.raw(); |
575 } | 575 } |
576 UNREACHABLE(); | 576 UNREACHABLE(); |
577 return Object::null(); | 577 return Object::null(); |
578 } | 578 } |
579 | 579 |
580 } // namespace dart | 580 } // namespace dart |
OLD | NEW |