| 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 |