Chromium Code Reviews| 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 12 matching lines...) Expand all Loading... | |
| 23 #include "vm/object_store.h" | 23 #include "vm/object_store.h" |
| 24 #include "vm/os.h" | 24 #include "vm/os.h" |
| 25 #include "vm/parser.h" | 25 #include "vm/parser.h" |
| 26 #include "vm/scanner.h" | 26 #include "vm/scanner.h" |
| 27 #include "vm/symbols.h" | 27 #include "vm/symbols.h" |
| 28 #include "vm/timer.h" | 28 #include "vm/timer.h" |
| 29 | 29 |
| 30 namespace dart { | 30 namespace dart { |
| 31 | 31 |
| 32 DEFINE_FLAG(bool, disassemble, false, "Disassemble dart code."); | 32 DEFINE_FLAG(bool, disassemble, false, "Disassemble dart code."); |
| 33 DEFINE_FLAG(bool, disassemble_optimized, false, "Disassemble optimized code."); | |
| 33 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler."); | 34 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler."); |
| 34 DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations."); | 35 DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations."); |
| 35 #if defined(TARGET_ARCH_X64) | 36 #if defined(TARGET_ARCH_X64) |
| 36 DEFINE_FLAG(bool, use_ssa, true, "Use SSA form"); | 37 DEFINE_FLAG(bool, use_ssa, true, "Use SSA form"); |
| 37 #else | 38 #else |
| 38 DEFINE_FLAG(bool, use_ssa, false, "Use SSA form"); | 39 DEFINE_FLAG(bool, use_ssa, false, "Use SSA form"); |
| 39 #endif | 40 #endif |
| 40 DEFINE_FLAG(int, deoptimization_counter_threshold, 5, | 41 DEFINE_FLAG(int, deoptimization_counter_threshold, 5, |
| 41 "How many times we allow deoptimization before we disallow" | 42 "How many times we allow deoptimization before we disallow" |
| 42 " certain optimizations"); | 43 " certain optimizations"); |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 249 is_compiled = false; | 250 is_compiled = false; |
| 250 } | 251 } |
| 251 // Reset global isolate state. | 252 // Reset global isolate state. |
| 252 isolate->set_ic_data_array(Array::null()); | 253 isolate->set_ic_data_array(Array::null()); |
| 253 isolate->set_long_jump_base(old_base); | 254 isolate->set_long_jump_base(old_base); |
| 254 isolate->set_deopt_id(prev_deopt_id); | 255 isolate->set_deopt_id(prev_deopt_id); |
| 255 return is_compiled; | 256 return is_compiled; |
| 256 } | 257 } |
| 257 | 258 |
| 258 | 259 |
| 260 static void DisassembleCode(const Function& function, bool optimized) { | |
| 261 const char* function_fullname = function.ToFullyQualifiedCString(); | |
| 262 OS::Print("Code for %sfunction '%s' {\n", | |
| 263 optimized ? "optimized " : "", | |
| 264 function_fullname); | |
| 265 const Code& code = Code::Handle(function.CurrentCode()); | |
| 266 const Instructions& instructions = | |
| 267 Instructions::Handle(code.instructions()); | |
| 268 uword start = instructions.EntryPoint(); | |
| 269 Disassembler::Disassemble(start, | |
| 270 start + instructions.size(), | |
| 271 code.comments()); | |
| 272 OS::Print("}\n"); | |
| 273 OS::Print("Pointer offsets for function: {\n"); | |
| 274 // Pointer offsets are stored in descending order. | |
| 275 for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) { | |
| 276 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); | |
| 277 Object& obj = Object::Handle(); | |
| 278 obj = *reinterpret_cast<RawObject**>(addr); | |
| 279 OS::Print(" %" PRIdPTR " : 0x%" PRIxPTR " '%s'\n", | |
| 280 code.GetPointerOffsetAt(i), addr, obj.ToCString()); | |
| 281 } | |
| 282 OS::Print("}\n"); | |
| 283 OS::Print("PC Descriptors for function '%s' {\n", function_fullname); | |
| 284 OS::Print("(pc\t\tkind\t\tid\ttok-ix\ttry/deopt-ix)\n"); | |
| 285 const PcDescriptors& descriptors = | |
| 286 PcDescriptors::Handle(code.pc_descriptors()); | |
| 287 OS::Print("%s\n", descriptors.ToCString()); | |
| 288 OS::Print("}\n"); | |
| 289 const Array& deopt_info_array = Array::Handle(code.deopt_info_array()); | |
| 290 if (deopt_info_array.Length() > 0) { | |
| 291 OS::Print("DeoptInfo: {\n"); | |
| 292 for (intptr_t i = 0; i < deopt_info_array.Length(); i++) { | |
| 293 OS::Print(" %d: %s\n", | |
| 294 i, Object::Handle(deopt_info_array.At(i)).ToCString()); | |
| 295 } | |
| 296 OS::Print("}\n"); | |
| 297 } | |
| 298 const Array& object_table = Array::Handle(code.object_table()); | |
| 299 if (object_table.Length() > 0) { | |
| 300 OS::Print("Object Table: {\n"); | |
| 301 for (intptr_t i = 0; i < object_table.Length(); i++) { | |
| 302 OS::Print(" %d: %s\n", i, | |
| 303 Object::Handle(object_table.At(i)).ToCString()); | |
| 304 } | |
| 305 OS::Print("}\n"); | |
| 306 } | |
| 307 OS::Print("Variable Descriptors for function '%s' {\n", | |
| 308 function_fullname); | |
| 309 const LocalVarDescriptors& var_descriptors = | |
| 310 LocalVarDescriptors::Handle(code.var_descriptors()); | |
| 311 intptr_t var_desc_length = | |
| 312 var_descriptors.IsNull() ? 0 : var_descriptors.Length(); | |
| 313 String& var_name = String::Handle(); | |
| 314 for (intptr_t i = 0; i < var_desc_length; i++) { | |
| 315 var_name = var_descriptors.GetName(i); | |
| 316 RawLocalVarDescriptors::VarInfo var_info; | |
| 317 var_descriptors.GetInfo(i, &var_info); | |
| 318 if (var_info.kind == RawLocalVarDescriptors::kContextChain) { | |
| 319 OS::Print(" saved CTX reg offset %" PRIdPTR "\n", var_info.index); | |
| 320 } else { | |
| 321 if (var_info.kind == RawLocalVarDescriptors::kContextLevel) { | |
| 322 OS::Print(" context level %" PRIdPTR " scope %d", | |
| 323 var_info.index, var_info.scope_id); | |
| 324 } else if (var_info.kind == RawLocalVarDescriptors::kStackVar) { | |
| 325 OS::Print(" stack var '%s' offset %" PRIdPTR, | |
| 326 var_name.ToCString(), var_info.index); | |
| 327 } else { | |
| 328 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); | |
| 329 OS::Print(" context var '%s' level %d offset %" PRIdPTR, | |
| 330 var_name.ToCString(), var_info.scope_id, var_info.index); | |
| 331 } | |
| 332 OS::Print(" (valid %" PRIdPTR "-%" PRIdPTR ")\n", | |
| 333 var_info.begin_pos, var_info.end_pos); | |
| 334 } | |
| 335 } | |
| 336 OS::Print("}\n"); | |
| 337 OS::Print("Exception Handlers for function '%s' {\n", function_fullname); | |
| 338 const ExceptionHandlers& handlers = | |
| 339 ExceptionHandlers::Handle(code.exception_handlers()); | |
| 340 OS::Print("%s\n", handlers.ToCString()); | |
| 341 OS::Print("}\n"); | |
| 342 } | |
| 343 | |
|
Vyacheslav Egorov (Google)
2012/08/10 10:41:36
add empty line here
Florian Schneider
2012/08/13 08:26:01
Done.
| |
| 259 static RawError* CompileFunctionHelper(const Function& function, | 344 static RawError* CompileFunctionHelper(const Function& function, |
| 260 bool optimized) { | 345 bool optimized) { |
| 261 Isolate* isolate = Isolate::Current(); | 346 Isolate* isolate = Isolate::Current(); |
| 262 LongJump* base = isolate->long_jump_base(); | 347 LongJump* base = isolate->long_jump_base(); |
| 263 LongJump jump; | 348 LongJump jump; |
| 264 isolate->set_long_jump_base(&jump); | 349 isolate->set_long_jump_base(&jump); |
| 265 // Skips parsing if we need to only install unoptimized code. | 350 // Skips parsing if we need to only install unoptimized code. |
| 266 if (!optimized && !Code::Handle(function.unoptimized_code()).IsNull()) { | 351 if (!optimized && !Code::Handle(function.unoptimized_code()).IsNull()) { |
| 267 InstallUnoptimizedCode(function); | 352 InstallUnoptimizedCode(function); |
| 268 isolate->set_long_jump_base(base); | 353 isolate->set_long_jump_base(base); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 293 | 378 |
| 294 if (FLAG_trace_compiler) { | 379 if (FLAG_trace_compiler) { |
| 295 OS::Print("--> '%s' entry: 0x%x\n", | 380 OS::Print("--> '%s' entry: 0x%x\n", |
| 296 function.ToFullyQualifiedCString(), | 381 function.ToFullyQualifiedCString(), |
| 297 Code::Handle(function.CurrentCode()).EntryPoint()); | 382 Code::Handle(function.CurrentCode()).EntryPoint()); |
| 298 } | 383 } |
| 299 if (Isolate::Current()->debugger()->IsActive()) { | 384 if (Isolate::Current()->debugger()->IsActive()) { |
| 300 Isolate::Current()->debugger()->NotifyCompilation(function); | 385 Isolate::Current()->debugger()->NotifyCompilation(function); |
| 301 } | 386 } |
| 302 if (FLAG_disassemble) { | 387 if (FLAG_disassemble) { |
| 303 const char* function_fullname = function.ToFullyQualifiedCString(); | 388 DisassembleCode(function, optimized); |
| 304 OS::Print("Code for %sfunction '%s' {\n", | 389 } |
| 305 optimized ? "optimized " : "", | 390 if (FLAG_disassemble_optimized && optimized) { |
| 306 function_fullname); | 391 // Print unoptimized code along with the optimized code. |
| 307 const Code& code = Code::Handle(function.CurrentCode()); | 392 DisassembleCode(function, false); |
| 308 const Instructions& instructions = | 393 DisassembleCode(function, true); |
|
srdjan
2012/08/10 14:00:10
I do not understand why you call DisassembleCode t
Florian Schneider
2012/08/13 08:26:01
This is just to see the non-optimized code togethe
| |
| 309 Instructions::Handle(code.instructions()); | |
| 310 uword start = instructions.EntryPoint(); | |
| 311 Disassembler::Disassemble(start, | |
| 312 start + instructions.size(), | |
| 313 code.comments()); | |
| 314 OS::Print("}\n"); | |
| 315 OS::Print("Pointer offsets for function: {\n"); | |
| 316 // Pointer offsets are stored in descending order. | |
| 317 for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) { | |
| 318 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); | |
| 319 Object& obj = Object::Handle(); | |
| 320 obj = *reinterpret_cast<RawObject**>(addr); | |
| 321 OS::Print(" %" PRIdPTR " : 0x%" PRIxPTR " '%s'\n", | |
| 322 code.GetPointerOffsetAt(i), addr, obj.ToCString()); | |
| 323 } | |
| 324 OS::Print("}\n"); | |
| 325 OS::Print("PC Descriptors for function '%s' {\n", function_fullname); | |
| 326 OS::Print("(pc\t\tkind\t\tid\ttok-ix\ttry/deopt-ix)\n"); | |
| 327 const PcDescriptors& descriptors = | |
| 328 PcDescriptors::Handle(code.pc_descriptors()); | |
| 329 OS::Print("%s\n", descriptors.ToCString()); | |
| 330 OS::Print("}\n"); | |
| 331 const Array& deopt_info_array = Array::Handle(code.deopt_info_array()); | |
| 332 if (deopt_info_array.Length() > 0) { | |
| 333 OS::Print("DeoptInfo: {\n"); | |
| 334 for (intptr_t i = 0; i < deopt_info_array.Length(); i++) { | |
| 335 OS::Print(" %d: %s\n", | |
| 336 i, Object::Handle(deopt_info_array.At(i)).ToCString()); | |
| 337 } | |
| 338 OS::Print("}\n"); | |
| 339 } | |
| 340 const Array& object_table = Array::Handle(code.object_table()); | |
| 341 if (object_table.Length() > 0) { | |
| 342 OS::Print("Object Table: {\n"); | |
| 343 for (intptr_t i = 0; i < object_table.Length(); i++) { | |
| 344 OS::Print(" %d: %s\n", i, | |
| 345 Object::Handle(object_table.At(i)).ToCString()); | |
| 346 } | |
| 347 OS::Print("}\n"); | |
| 348 } | |
| 349 OS::Print("Variable Descriptors for function '%s' {\n", | |
| 350 function_fullname); | |
| 351 const LocalVarDescriptors& var_descriptors = | |
| 352 LocalVarDescriptors::Handle(code.var_descriptors()); | |
| 353 intptr_t var_desc_length = | |
| 354 var_descriptors.IsNull() ? 0 : var_descriptors.Length(); | |
| 355 String& var_name = String::Handle(); | |
| 356 for (intptr_t i = 0; i < var_desc_length; i++) { | |
| 357 var_name = var_descriptors.GetName(i); | |
| 358 RawLocalVarDescriptors::VarInfo var_info; | |
| 359 var_descriptors.GetInfo(i, &var_info); | |
| 360 if (var_info.kind == RawLocalVarDescriptors::kContextChain) { | |
| 361 OS::Print(" saved CTX reg offset %" PRIdPTR "\n", var_info.index); | |
| 362 } else { | |
| 363 if (var_info.kind == RawLocalVarDescriptors::kContextLevel) { | |
| 364 OS::Print(" context level %" PRIdPTR " scope %d", | |
| 365 var_info.index, var_info.scope_id); | |
| 366 } else if (var_info.kind == RawLocalVarDescriptors::kStackVar) { | |
| 367 OS::Print(" stack var '%s' offset %" PRIdPTR, | |
| 368 var_name.ToCString(), var_info.index); | |
| 369 } else { | |
| 370 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); | |
| 371 OS::Print(" context var '%s' level %d offset %" PRIdPTR, | |
| 372 var_name.ToCString(), var_info.scope_id, var_info.index); | |
| 373 } | |
| 374 OS::Print(" (valid %" PRIdPTR "-%" PRIdPTR ")\n", | |
| 375 var_info.begin_pos, var_info.end_pos); | |
| 376 } | |
| 377 } | |
| 378 OS::Print("}\n"); | |
| 379 OS::Print("Exception Handlers for function '%s' {\n", function_fullname); | |
| 380 const ExceptionHandlers& handlers = | |
| 381 ExceptionHandlers::Handle(code.exception_handlers()); | |
| 382 OS::Print("%s\n", handlers.ToCString()); | |
| 383 OS::Print("}\n"); | |
| 384 } | 394 } |
| 385 isolate->set_long_jump_base(base); | 395 isolate->set_long_jump_base(base); |
| 386 return Error::null(); | 396 return Error::null(); |
| 387 } else { | 397 } else { |
| 388 Error& error = Error::Handle(); | 398 Error& error = Error::Handle(); |
| 389 // We got an error during compilation. | 399 // We got an error during compilation. |
| 390 error = isolate->object_store()->sticky_error(); | 400 error = isolate->object_store()->sticky_error(); |
| 391 isolate->object_store()->clear_sticky_error(); | 401 isolate->object_store()->clear_sticky_error(); |
| 392 isolate->set_long_jump_base(base); | 402 isolate->set_long_jump_base(base); |
| 393 return error.raw(); | 403 return error.raw(); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 505 result = isolate->object_store()->sticky_error(); | 515 result = isolate->object_store()->sticky_error(); |
| 506 isolate->object_store()->clear_sticky_error(); | 516 isolate->object_store()->clear_sticky_error(); |
| 507 isolate->set_long_jump_base(base); | 517 isolate->set_long_jump_base(base); |
| 508 return result.raw(); | 518 return result.raw(); |
| 509 } | 519 } |
| 510 UNREACHABLE(); | 520 UNREACHABLE(); |
| 511 return Object::null(); | 521 return Object::null(); |
| 512 } | 522 } |
| 513 | 523 |
| 514 } // namespace dart | 524 } // namespace dart |
| OLD | NEW |