| 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 | 8 |
| 9 #include "vm/ast_printer.h" | 9 #include "vm/ast_printer.h" |
| 10 #include "vm/code_generator.h" | 10 #include "vm/code_generator.h" |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 } | 222 } |
| 223 UNREACHABLE(); | 223 UNREACHABLE(); |
| 224 return Error::null(); | 224 return Error::null(); |
| 225 } | 225 } |
| 226 | 226 |
| 227 | 227 |
| 228 static void InstallUnoptimizedCode(const Function& function) { | 228 static void InstallUnoptimizedCode(const Function& function) { |
| 229 // Disable optimized code. | 229 // Disable optimized code. |
| 230 ASSERT(function.HasOptimizedCode()); | 230 ASSERT(function.HasOptimizedCode()); |
| 231 if (FLAG_trace_compiler) { | 231 if (FLAG_trace_compiler) { |
| 232 OS::Print("--> patching entry %#"Px"\n", | 232 OS::Print("--> patching entry %#" Px "\n", |
| 233 Code::Handle(function.CurrentCode()).EntryPoint()); | 233 Code::Handle(function.CurrentCode()).EntryPoint()); |
| 234 } | 234 } |
| 235 function.SwitchToUnoptimizedCode(); | 235 function.SwitchToUnoptimizedCode(); |
| 236 if (FLAG_trace_compiler) { | 236 if (FLAG_trace_compiler) { |
| 237 OS::Print("--> restoring entry at %#"Px"\n", | 237 OS::Print("--> restoring entry at %#" Px "\n", |
| 238 Code::Handle(function.unoptimized_code()).EntryPoint()); | 238 Code::Handle(function.unoptimized_code()).EntryPoint()); |
| 239 } | 239 } |
| 240 } | 240 } |
| 241 | 241 |
| 242 | 242 |
| 243 // Return false if bailed out. | 243 // Return false if bailed out. |
| 244 static bool CompileParsedFunctionHelper(ParsedFunction* parsed_function, | 244 static bool CompileParsedFunctionHelper(ParsedFunction* parsed_function, |
| 245 bool optimized, | 245 bool optimized, |
| 246 intptr_t osr_id) { | 246 intptr_t osr_id) { |
| 247 const Function& function = parsed_function->function(); | 247 const Function& function = parsed_function->function(); |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 graph_compiler.FinalizeStackmaps(code); | 521 graph_compiler.FinalizeStackmaps(code); |
| 522 graph_compiler.FinalizeVarDescriptors(code); | 522 graph_compiler.FinalizeVarDescriptors(code); |
| 523 graph_compiler.FinalizeExceptionHandlers(code); | 523 graph_compiler.FinalizeExceptionHandlers(code); |
| 524 graph_compiler.FinalizeComments(code); | 524 graph_compiler.FinalizeComments(code); |
| 525 graph_compiler.FinalizeStaticCallTargetsTable(code); | 525 graph_compiler.FinalizeStaticCallTargetsTable(code); |
| 526 | 526 |
| 527 if (optimized) { | 527 if (optimized) { |
| 528 if (osr_id == Isolate::kNoDeoptId) { | 528 if (osr_id == Isolate::kNoDeoptId) { |
| 529 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); | 529 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); |
| 530 if (FLAG_trace_compiler) { | 530 if (FLAG_trace_compiler) { |
| 531 OS::Print("--> patching entry %#"Px"\n", | 531 OS::Print("--> patching entry %#" Px "\n", |
| 532 Code::Handle(function.unoptimized_code()).EntryPoint()); | 532 Code::Handle(function.unoptimized_code()).EntryPoint()); |
| 533 } | 533 } |
| 534 } | 534 } |
| 535 function.SetCode(code); | 535 function.SetCode(code); |
| 536 | 536 |
| 537 for (intptr_t i = 0; i < guarded_fields.length(); i++) { | 537 for (intptr_t i = 0; i < guarded_fields.length(); i++) { |
| 538 const Field& field = *guarded_fields[i]; | 538 const Field& field = *guarded_fields[i]; |
| 539 field.RegisterDependentCode(code); | 539 field.RegisterDependentCode(code); |
| 540 } | 540 } |
| 541 } else { | 541 } else { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 const Code& code = Code::Handle(function.CurrentCode()); | 588 const Code& code = Code::Handle(function.CurrentCode()); |
| 589 code.Disassemble(); | 589 code.Disassemble(); |
| 590 OS::Print("}\n"); | 590 OS::Print("}\n"); |
| 591 | 591 |
| 592 OS::Print("Pointer offsets for function: {\n"); | 592 OS::Print("Pointer offsets for function: {\n"); |
| 593 // Pointer offsets are stored in descending order. | 593 // Pointer offsets are stored in descending order. |
| 594 for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) { | 594 for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) { |
| 595 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); | 595 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); |
| 596 Object& obj = Object::Handle(); | 596 Object& obj = Object::Handle(); |
| 597 obj = *reinterpret_cast<RawObject**>(addr); | 597 obj = *reinterpret_cast<RawObject**>(addr); |
| 598 OS::Print(" %d : %#"Px" '%s'\n", | 598 OS::Print(" %d : %#" Px " '%s'\n", |
| 599 code.GetPointerOffsetAt(i), addr, obj.ToCString()); | 599 code.GetPointerOffsetAt(i), addr, obj.ToCString()); |
| 600 } | 600 } |
| 601 OS::Print("}\n"); | 601 OS::Print("}\n"); |
| 602 | 602 |
| 603 OS::Print("PC Descriptors for function '%s' {\n", function_fullname); | 603 OS::Print("PC Descriptors for function '%s' {\n", function_fullname); |
| 604 PcDescriptors::PrintHeaderString(); | 604 PcDescriptors::PrintHeaderString(); |
| 605 const PcDescriptors& descriptors = | 605 const PcDescriptors& descriptors = |
| 606 PcDescriptors::Handle(code.pc_descriptors()); | 606 PcDescriptors::Handle(code.pc_descriptors()); |
| 607 OS::Print("%s}\n", descriptors.ToCString()); | 607 OS::Print("%s}\n", descriptors.ToCString()); |
| 608 | 608 |
| 609 uword start = Instructions::Handle(code.instructions()).EntryPoint(); | 609 uword start = Instructions::Handle(code.instructions()).EntryPoint(); |
| 610 const Array& deopt_table = Array::Handle(code.deopt_info_array()); | 610 const Array& deopt_table = Array::Handle(code.deopt_info_array()); |
| 611 intptr_t deopt_table_length = DeoptTable::GetLength(deopt_table); | 611 intptr_t deopt_table_length = DeoptTable::GetLength(deopt_table); |
| 612 if (deopt_table_length > 0) { | 612 if (deopt_table_length > 0) { |
| 613 OS::Print("DeoptInfo: {\n"); | 613 OS::Print("DeoptInfo: {\n"); |
| 614 Smi& offset = Smi::Handle(); | 614 Smi& offset = Smi::Handle(); |
| 615 DeoptInfo& info = DeoptInfo::Handle(); | 615 DeoptInfo& info = DeoptInfo::Handle(); |
| 616 Smi& reason = Smi::Handle(); | 616 Smi& reason = Smi::Handle(); |
| 617 for (intptr_t i = 0; i < deopt_table_length; ++i) { | 617 for (intptr_t i = 0; i < deopt_table_length; ++i) { |
| 618 DeoptTable::GetEntry(deopt_table, i, &offset, &info, &reason); | 618 DeoptTable::GetEntry(deopt_table, i, &offset, &info, &reason); |
| 619 OS::Print("%4"Pd": 0x%"Px" %s (%s)\n", | 619 OS::Print("%4" Pd ": 0x%" Px " %s (%s)\n", |
| 620 i, | 620 i, |
| 621 start + offset.Value(), | 621 start + offset.Value(), |
| 622 info.ToCString(), | 622 info.ToCString(), |
| 623 DeoptReasonToText(reason.Value())); | 623 DeoptReasonToText(reason.Value())); |
| 624 } | 624 } |
| 625 OS::Print("}\n"); | 625 OS::Print("}\n"); |
| 626 } | 626 } |
| 627 | 627 |
| 628 const Array& object_table = Array::Handle(code.object_table()); | 628 const Array& object_table = Array::Handle(code.object_table()); |
| 629 if (object_table.Length() > 0) { | 629 if (object_table.Length() > 0) { |
| 630 OS::Print("Object Table: {\n"); | 630 OS::Print("Object Table: {\n"); |
| 631 for (intptr_t i = 0; i < object_table.Length(); i++) { | 631 for (intptr_t i = 0; i < object_table.Length(); i++) { |
| 632 OS::Print(" %"Pd": %s\n", i, | 632 OS::Print(" %" Pd ": %s\n", i, |
| 633 Object::Handle(object_table.At(i)).ToCString()); | 633 Object::Handle(object_table.At(i)).ToCString()); |
| 634 } | 634 } |
| 635 OS::Print("}\n"); | 635 OS::Print("}\n"); |
| 636 } | 636 } |
| 637 | 637 |
| 638 OS::Print("Stackmaps for function '%s' {\n", function_fullname); | 638 OS::Print("Stackmaps for function '%s' {\n", function_fullname); |
| 639 if (code.stackmaps() != Array::null()) { | 639 if (code.stackmaps() != Array::null()) { |
| 640 const Array& stackmap_table = Array::Handle(code.stackmaps()); | 640 const Array& stackmap_table = Array::Handle(code.stackmaps()); |
| 641 Stackmap& map = Stackmap::Handle(); | 641 Stackmap& map = Stackmap::Handle(); |
| 642 for (intptr_t i = 0; i < stackmap_table.Length(); ++i) { | 642 for (intptr_t i = 0; i < stackmap_table.Length(); ++i) { |
| 643 map ^= stackmap_table.At(i); | 643 map ^= stackmap_table.At(i); |
| 644 OS::Print("%s\n", map.ToCString()); | 644 OS::Print("%s\n", map.ToCString()); |
| 645 } | 645 } |
| 646 } | 646 } |
| 647 OS::Print("}\n"); | 647 OS::Print("}\n"); |
| 648 | 648 |
| 649 OS::Print("Variable Descriptors for function '%s' {\n", | 649 OS::Print("Variable Descriptors for function '%s' {\n", |
| 650 function_fullname); | 650 function_fullname); |
| 651 const LocalVarDescriptors& var_descriptors = | 651 const LocalVarDescriptors& var_descriptors = |
| 652 LocalVarDescriptors::Handle(code.var_descriptors()); | 652 LocalVarDescriptors::Handle(code.var_descriptors()); |
| 653 intptr_t var_desc_length = | 653 intptr_t var_desc_length = |
| 654 var_descriptors.IsNull() ? 0 : var_descriptors.Length(); | 654 var_descriptors.IsNull() ? 0 : var_descriptors.Length(); |
| 655 String& var_name = String::Handle(); | 655 String& var_name = String::Handle(); |
| 656 for (intptr_t i = 0; i < var_desc_length; i++) { | 656 for (intptr_t i = 0; i < var_desc_length; i++) { |
| 657 var_name = var_descriptors.GetName(i); | 657 var_name = var_descriptors.GetName(i); |
| 658 RawLocalVarDescriptors::VarInfo var_info; | 658 RawLocalVarDescriptors::VarInfo var_info; |
| 659 var_descriptors.GetInfo(i, &var_info); | 659 var_descriptors.GetInfo(i, &var_info); |
| 660 if (var_info.kind == RawLocalVarDescriptors::kSavedEntryContext) { | 660 if (var_info.kind == RawLocalVarDescriptors::kSavedEntryContext) { |
| 661 OS::Print(" saved caller's CTX reg offset %"Pd"\n", var_info.index); | 661 OS::Print(" saved caller's CTX reg offset %" Pd "\n", var_info.index); |
| 662 } else if (var_info.kind == RawLocalVarDescriptors::kSavedCurrentContext) { | 662 } else if (var_info.kind == RawLocalVarDescriptors::kSavedCurrentContext) { |
| 663 OS::Print(" saved current CTX reg offset %"Pd"\n", var_info.index); | 663 OS::Print(" saved current CTX reg offset %" Pd "\n", var_info.index); |
| 664 } else { | 664 } else { |
| 665 if (var_info.kind == RawLocalVarDescriptors::kContextLevel) { | 665 if (var_info.kind == RawLocalVarDescriptors::kContextLevel) { |
| 666 OS::Print(" context level %"Pd" scope %d", | 666 OS::Print(" context level %" Pd " scope %d", |
| 667 var_info.index, var_info.scope_id); | 667 var_info.index, var_info.scope_id); |
| 668 } else if (var_info.kind == RawLocalVarDescriptors::kStackVar) { | 668 } else if (var_info.kind == RawLocalVarDescriptors::kStackVar) { |
| 669 OS::Print(" stack var '%s' offset %"Pd"", | 669 OS::Print(" stack var '%s' offset %" Pd "", |
| 670 var_name.ToCString(), var_info.index); | 670 var_name.ToCString(), var_info.index); |
| 671 } else { | 671 } else { |
| 672 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); | 672 ASSERT(var_info.kind == RawLocalVarDescriptors::kContextVar); |
| 673 OS::Print(" context var '%s' level %d offset %"Pd"", | 673 OS::Print(" context var '%s' level %d offset %" Pd "", |
| 674 var_name.ToCString(), var_info.scope_id, var_info.index); | 674 var_name.ToCString(), var_info.scope_id, var_info.index); |
| 675 } | 675 } |
| 676 OS::Print(" (valid %"Pd"-%"Pd")\n", | 676 OS::Print(" (valid %" Pd "-%" Pd ")\n", |
| 677 var_info.begin_pos, var_info.end_pos); | 677 var_info.begin_pos, var_info.end_pos); |
| 678 } | 678 } |
| 679 } | 679 } |
| 680 OS::Print("}\n"); | 680 OS::Print("}\n"); |
| 681 | 681 |
| 682 OS::Print("Exception Handlers for function '%s' {\n", function_fullname); | 682 OS::Print("Exception Handlers for function '%s' {\n", function_fullname); |
| 683 const ExceptionHandlers& handlers = | 683 const ExceptionHandlers& handlers = |
| 684 ExceptionHandlers::Handle(code.exception_handlers()); | 684 ExceptionHandlers::Handle(code.exception_handlers()); |
| 685 OS::Print("%s}\n", handlers.ToCString()); | 685 OS::Print("%s}\n", handlers.ToCString()); |
| 686 | 686 |
| 687 { | 687 { |
| 688 OS::Print("Static call target functions {\n"); | 688 OS::Print("Static call target functions {\n"); |
| 689 const Array& table = Array::Handle(code.static_calls_target_table()); | 689 const Array& table = Array::Handle(code.static_calls_target_table()); |
| 690 Smi& offset = Smi::Handle(); | 690 Smi& offset = Smi::Handle(); |
| 691 Function& function = Function::Handle(); | 691 Function& function = Function::Handle(); |
| 692 Code& code = Code::Handle(); | 692 Code& code = Code::Handle(); |
| 693 for (intptr_t i = 0; i < table.Length(); | 693 for (intptr_t i = 0; i < table.Length(); |
| 694 i += Code::kSCallTableEntryLength) { | 694 i += Code::kSCallTableEntryLength) { |
| 695 offset ^= table.At(i + Code::kSCallTableOffsetEntry); | 695 offset ^= table.At(i + Code::kSCallTableOffsetEntry); |
| 696 function ^= table.At(i + Code::kSCallTableFunctionEntry); | 696 function ^= table.At(i + Code::kSCallTableFunctionEntry); |
| 697 code ^= table.At(i + Code::kSCallTableCodeEntry); | 697 code ^= table.At(i + Code::kSCallTableCodeEntry); |
| 698 OS::Print(" 0x%"Px": %s, %p\n", | 698 OS::Print(" 0x%" Px ": %s, %p\n", |
| 699 start + offset.Value(), | 699 start + offset.Value(), |
| 700 function.ToFullyQualifiedCString(), | 700 function.ToFullyQualifiedCString(), |
| 701 code.raw()); | 701 code.raw()); |
| 702 } | 702 } |
| 703 OS::Print("}\n"); | 703 OS::Print("}\n"); |
| 704 } | 704 } |
| 705 } | 705 } |
| 706 | 706 |
| 707 | 707 |
| 708 static RawError* CompileFunctionHelper(const Function& function, | 708 static RawError* CompileFunctionHelper(const Function& function, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 719 isolate->set_long_jump_base(base); | 719 isolate->set_long_jump_base(base); |
| 720 return Error::null(); | 720 return Error::null(); |
| 721 } | 721 } |
| 722 if (setjmp(*jump.Set()) == 0) { | 722 if (setjmp(*jump.Set()) == 0) { |
| 723 TIMERSCOPE(time_compilation); | 723 TIMERSCOPE(time_compilation); |
| 724 Timer per_compile_timer(FLAG_trace_compiler, "Compilation time"); | 724 Timer per_compile_timer(FLAG_trace_compiler, "Compilation time"); |
| 725 per_compile_timer.Start(); | 725 per_compile_timer.Start(); |
| 726 ParsedFunction* parsed_function = new ParsedFunction( | 726 ParsedFunction* parsed_function = new ParsedFunction( |
| 727 Function::ZoneHandle(function.raw())); | 727 Function::ZoneHandle(function.raw())); |
| 728 if (FLAG_trace_compiler) { | 728 if (FLAG_trace_compiler) { |
| 729 OS::Print("Compiling %s%sfunction: '%s' @ token %"Pd", size %"Pd"\n", | 729 OS::Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", |
| 730 (osr_id == Isolate::kNoDeoptId ? "" : "osr "), | 730 (osr_id == Isolate::kNoDeoptId ? "" : "osr "), |
| 731 (optimized ? "optimized " : ""), | 731 (optimized ? "optimized " : ""), |
| 732 function.ToFullyQualifiedCString(), | 732 function.ToFullyQualifiedCString(), |
| 733 function.token_pos(), | 733 function.token_pos(), |
| 734 (function.end_token_pos() - function.token_pos())); | 734 (function.end_token_pos() - function.token_pos())); |
| 735 } | 735 } |
| 736 { | 736 { |
| 737 HANDLESCOPE(isolate); | 737 HANDLESCOPE(isolate); |
| 738 Parser::ParseFunction(parsed_function); | 738 Parser::ParseFunction(parsed_function); |
| 739 parsed_function->AllocateVariables(); | 739 parsed_function->AllocateVariables(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 751 } | 751 } |
| 752 function.set_is_optimizable(false); | 752 function.set_is_optimizable(false); |
| 753 isolate->set_long_jump_base(base); | 753 isolate->set_long_jump_base(base); |
| 754 return Error::null(); | 754 return Error::null(); |
| 755 } | 755 } |
| 756 | 756 |
| 757 ASSERT(success); | 757 ASSERT(success); |
| 758 per_compile_timer.Stop(); | 758 per_compile_timer.Stop(); |
| 759 | 759 |
| 760 if (FLAG_trace_compiler) { | 760 if (FLAG_trace_compiler) { |
| 761 OS::Print("--> '%s' entry: %#"Px" size: %"Pd" time: %"Pd64" us\n", | 761 OS::Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n", |
| 762 function.ToFullyQualifiedCString(), | 762 function.ToFullyQualifiedCString(), |
| 763 Code::Handle(function.CurrentCode()).EntryPoint(), | 763 Code::Handle(function.CurrentCode()).EntryPoint(), |
| 764 Code::Handle(function.CurrentCode()).Size(), | 764 Code::Handle(function.CurrentCode()).Size(), |
| 765 per_compile_timer.TotalElapsedTime()); | 765 per_compile_timer.TotalElapsedTime()); |
| 766 } | 766 } |
| 767 | 767 |
| 768 isolate->debugger()->NotifyCompilation(function); | 768 isolate->debugger()->NotifyCompilation(function); |
| 769 | 769 |
| 770 if (FLAG_disassemble) { | 770 if (FLAG_disassemble) { |
| 771 DisassembleCode(function, optimized); | 771 DisassembleCode(function, optimized); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 Object::Handle(isolate->object_store()->sticky_error()); | 908 Object::Handle(isolate->object_store()->sticky_error()); |
| 909 isolate->object_store()->clear_sticky_error(); | 909 isolate->object_store()->clear_sticky_error(); |
| 910 isolate->set_long_jump_base(base); | 910 isolate->set_long_jump_base(base); |
| 911 return result.raw(); | 911 return result.raw(); |
| 912 } | 912 } |
| 913 UNREACHABLE(); | 913 UNREACHABLE(); |
| 914 return Object::null(); | 914 return Object::null(); |
| 915 } | 915 } |
| 916 | 916 |
| 917 } // namespace dart | 917 } // namespace dart |
| OLD | NEW |