| 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/block_scheduler.h" | 10 #include "vm/block_scheduler.h" |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 | 177 |
| 178 | 178 |
| 179 RawError* Compiler::Compile(const Library& library, const Script& script) { | 179 RawError* Compiler::Compile(const Library& library, const Script& script) { |
| 180 Isolate* isolate = Isolate::Current(); | 180 Isolate* isolate = Isolate::Current(); |
| 181 StackZone zone(isolate); | 181 StackZone zone(isolate); |
| 182 LongJumpScope jump; | 182 LongJumpScope jump; |
| 183 if (setjmp(*jump.Set()) == 0) { | 183 if (setjmp(*jump.Set()) == 0) { |
| 184 if (FLAG_trace_compiler) { | 184 if (FLAG_trace_compiler) { |
| 185 const String& script_url = String::Handle(script.url()); | 185 const String& script_url = String::Handle(script.url()); |
| 186 // TODO(iposva): Extract script kind. | 186 // TODO(iposva): Extract script kind. |
| 187 OS::Print("Compiling %s '%s'\n", "", script_url.ToCString()); | 187 ISL_Print("Compiling %s '%s'\n", "", script_url.ToCString()); |
| 188 } | 188 } |
| 189 const String& library_key = String::Handle(library.private_key()); | 189 const String& library_key = String::Handle(library.private_key()); |
| 190 script.Tokenize(library_key); | 190 script.Tokenize(library_key); |
| 191 Parser::ParseCompilationUnit(library, script); | 191 Parser::ParseCompilationUnit(library, script); |
| 192 return Error::null(); | 192 return Error::null(); |
| 193 } else { | 193 } else { |
| 194 Error& error = Error::Handle(); | 194 Error& error = Error::Handle(); |
| 195 error = isolate->object_store()->sticky_error(); | 195 error = isolate->object_store()->sticky_error(); |
| 196 isolate->object_store()->clear_sticky_error(); | 196 isolate->object_store()->clear_sticky_error(); |
| 197 return error.raw(); | 197 return error.raw(); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 const GrowableObjectArray& parse_list = | 287 const GrowableObjectArray& parse_list = |
| 288 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New(4)); | 288 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New(4)); |
| 289 const GrowableObjectArray& patch_list = | 289 const GrowableObjectArray& patch_list = |
| 290 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New(4)); | 290 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New(4)); |
| 291 | 291 |
| 292 // Parse the class and all the interfaces it implements and super classes. | 292 // Parse the class and all the interfaces it implements and super classes. |
| 293 StackZone zone(isolate); | 293 StackZone zone(isolate); |
| 294 LongJumpScope jump; | 294 LongJumpScope jump; |
| 295 if (setjmp(*jump.Set()) == 0) { | 295 if (setjmp(*jump.Set()) == 0) { |
| 296 if (FLAG_trace_compiler) { | 296 if (FLAG_trace_compiler) { |
| 297 OS::Print("Compiling Class %s '%s'\n", "", cls.ToCString()); | 297 ISL_Print("Compiling Class %s '%s'\n", "", cls.ToCString()); |
| 298 } | 298 } |
| 299 | 299 |
| 300 // Add the primary class which needs to be parsed to the parse list. | 300 // Add the primary class which needs to be parsed to the parse list. |
| 301 // Mark the class as parsed so that we don't recursively add the same | 301 // Mark the class as parsed so that we don't recursively add the same |
| 302 // class back into the list. | 302 // class back into the list. |
| 303 parse_list.Add(cls); | 303 parse_list.Add(cls); |
| 304 cls.set_is_marked_for_parsing(); | 304 cls.set_is_marked_for_parsing(); |
| 305 | 305 |
| 306 // Add all super classes, interface classes and patch class if one | 306 // Add all super classes, interface classes and patch class if one |
| 307 // exists to the corresponding lists. | 307 // exists to the corresponding lists. |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 if (optimized) { | 407 if (optimized) { |
| 408 ASSERT(function.HasCode()); | 408 ASSERT(function.HasCode()); |
| 409 // Extract type feedback before the graph is built, as the graph | 409 // Extract type feedback before the graph is built, as the graph |
| 410 // builder uses it to attach it to nodes. | 410 // builder uses it to attach it to nodes. |
| 411 ASSERT(function.deoptimization_counter() < | 411 ASSERT(function.deoptimization_counter() < |
| 412 FLAG_deoptimization_counter_threshold); | 412 FLAG_deoptimization_counter_threshold); |
| 413 function.RestoreICDataMap(ic_data_array); | 413 function.RestoreICDataMap(ic_data_array); |
| 414 if (FLAG_print_ic_data_map) { | 414 if (FLAG_print_ic_data_map) { |
| 415 for (intptr_t i = 0; i < ic_data_array->length(); i++) { | 415 for (intptr_t i = 0; i < ic_data_array->length(); i++) { |
| 416 if ((*ic_data_array)[i] != NULL) { | 416 if ((*ic_data_array)[i] != NULL) { |
| 417 OS::Print("%" Pd " ", i); | 417 ISL_Print("%" Pd " ", i); |
| 418 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]); | 418 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]); |
| 419 } | 419 } |
| 420 } | 420 } |
| 421 } | 421 } |
| 422 } | 422 } |
| 423 | 423 |
| 424 flow_graph = pipeline->BuildFlowGraph(parsed_function, | 424 flow_graph = pipeline->BuildFlowGraph(parsed_function, |
| 425 *ic_data_array, | 425 *ic_data_array, |
| 426 osr_id); | 426 osr_id); |
| 427 } | 427 } |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 graph_compiler.FinalizeStackmaps(code); | 710 graph_compiler.FinalizeStackmaps(code); |
| 711 graph_compiler.FinalizeVarDescriptors(code); | 711 graph_compiler.FinalizeVarDescriptors(code); |
| 712 graph_compiler.FinalizeExceptionHandlers(code); | 712 graph_compiler.FinalizeExceptionHandlers(code); |
| 713 graph_compiler.FinalizeStaticCallTargetsTable(code); | 713 graph_compiler.FinalizeStaticCallTargetsTable(code); |
| 714 | 714 |
| 715 if (optimized) { | 715 if (optimized) { |
| 716 if (osr_id == Isolate::kNoDeoptId) { | 716 if (osr_id == Isolate::kNoDeoptId) { |
| 717 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); | 717 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); |
| 718 if (FLAG_trace_compiler || FLAG_trace_patching) { | 718 if (FLAG_trace_compiler || FLAG_trace_patching) { |
| 719 if (FLAG_trace_compiler) { | 719 if (FLAG_trace_compiler) { |
| 720 OS::Print(" "); | 720 ISL_Print(" "); |
| 721 } | 721 } |
| 722 OS::Print("Patch unoptimized '%s' entry point %#" Px "\n", | 722 ISL_Print("Patch unoptimized '%s' entry point %#" Px "\n", |
| 723 function.ToFullyQualifiedCString(), | 723 function.ToFullyQualifiedCString(), |
| 724 Code::Handle(function.unoptimized_code()).EntryPoint()); | 724 Code::Handle(function.unoptimized_code()).EntryPoint()); |
| 725 } | 725 } |
| 726 } | 726 } |
| 727 function.AttachCode(code); | 727 function.AttachCode(code); |
| 728 | 728 |
| 729 // Register code with the classes it depends on because of CHA. | 729 // Register code with the classes it depends on because of CHA. |
| 730 for (intptr_t i = 0; | 730 for (intptr_t i = 0; |
| 731 i < isolate->cha()->leaf_classes().length(); | 731 i < isolate->cha()->leaf_classes().length(); |
| 732 ++i) { | 732 ++i) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 // Compilation failed due to an out of range branch offset in the | 766 // Compilation failed due to an out of range branch offset in the |
| 767 // assembler. We try again (done = false) with far branches enabled. | 767 // assembler. We try again (done = false) with far branches enabled. |
| 768 done = false; | 768 done = false; |
| 769 ASSERT(!use_far_branches); | 769 ASSERT(!use_far_branches); |
| 770 use_far_branches = true; | 770 use_far_branches = true; |
| 771 } else { | 771 } else { |
| 772 // If the error isn't due to an out of range branch offset, we don't | 772 // If the error isn't due to an out of range branch offset, we don't |
| 773 // try again (done = true), and indicate that we did not finish | 773 // try again (done = true), and indicate that we did not finish |
| 774 // compiling (is_compiled = false). | 774 // compiling (is_compiled = false). |
| 775 if (FLAG_trace_bailout) { | 775 if (FLAG_trace_bailout) { |
| 776 OS::Print("%s\n", error.ToErrorCString()); | 776 ISL_Print("%s\n", error.ToErrorCString()); |
| 777 } | 777 } |
| 778 done = true; | 778 done = true; |
| 779 ASSERT(optimized); | 779 ASSERT(optimized); |
| 780 } | 780 } |
| 781 | 781 |
| 782 // Clear the error if it was not a real error, but just a bailout. | 782 // Clear the error if it was not a real error, but just a bailout. |
| 783 if (error.IsLanguageError() && | 783 if (error.IsLanguageError() && |
| 784 (LanguageError::Cast(error).kind() == Report::kBailout)) { | 784 (LanguageError::Cast(error).kind() == Report::kBailout)) { |
| 785 isolate->object_store()->clear_sticky_error(); | 785 isolate->object_store()->clear_sticky_error(); |
| 786 } | 786 } |
| 787 is_compiled = false; | 787 is_compiled = false; |
| 788 } | 788 } |
| 789 // Reset global isolate state. | 789 // Reset global isolate state. |
| 790 isolate->set_deopt_id(prev_deopt_id); | 790 isolate->set_deopt_id(prev_deopt_id); |
| 791 } | 791 } |
| 792 return is_compiled; | 792 return is_compiled; |
| 793 } | 793 } |
| 794 | 794 |
| 795 | 795 |
| 796 static void DisassembleCode(const Function& function, bool optimized) { | 796 static void DisassembleCode(const Function& function, bool optimized) { |
| 797 const char* function_fullname = function.ToFullyQualifiedCString(); | 797 const char* function_fullname = function.ToFullyQualifiedCString(); |
| 798 OS::Print("Code for %sfunction '%s' {\n", | 798 ISL_Print("Code for %sfunction '%s' {\n", |
| 799 optimized ? "optimized " : "", | 799 optimized ? "optimized " : "", |
| 800 function_fullname); | 800 function_fullname); |
| 801 const Code& code = Code::Handle(function.CurrentCode()); | 801 const Code& code = Code::Handle(function.CurrentCode()); |
| 802 code.Disassemble(); | 802 code.Disassemble(); |
| 803 OS::Print("}\n"); | 803 ISL_Print("}\n"); |
| 804 | 804 |
| 805 OS::Print("Pointer offsets for function: {\n"); | 805 ISL_Print("Pointer offsets for function: {\n"); |
| 806 // Pointer offsets are stored in descending order. | 806 // Pointer offsets are stored in descending order. |
| 807 Object& obj = Object::Handle(); | 807 Object& obj = Object::Handle(); |
| 808 for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) { | 808 for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) { |
| 809 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); | 809 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); |
| 810 obj = *reinterpret_cast<RawObject**>(addr); | 810 obj = *reinterpret_cast<RawObject**>(addr); |
| 811 OS::Print(" %d : %#" Px " '%s'\n", | 811 ISL_Print(" %d : %#" Px " '%s'\n", |
| 812 code.GetPointerOffsetAt(i), addr, obj.ToCString()); | 812 code.GetPointerOffsetAt(i), addr, obj.ToCString()); |
| 813 } | 813 } |
| 814 OS::Print("}\n"); | 814 ISL_Print("}\n"); |
| 815 | 815 |
| 816 OS::Print("PC Descriptors for function '%s' {\n", function_fullname); | 816 ISL_Print("PC Descriptors for function '%s' {\n", function_fullname); |
| 817 PcDescriptors::PrintHeaderString(); | 817 PcDescriptors::PrintHeaderString(); |
| 818 const PcDescriptors& descriptors = | 818 const PcDescriptors& descriptors = |
| 819 PcDescriptors::Handle(code.pc_descriptors()); | 819 PcDescriptors::Handle(code.pc_descriptors()); |
| 820 OS::Print("%s}\n", descriptors.ToCString()); | 820 ISL_Print("%s}\n", descriptors.ToCString()); |
| 821 | 821 |
| 822 uword start = Instructions::Handle(code.instructions()).EntryPoint(); | 822 uword start = Instructions::Handle(code.instructions()).EntryPoint(); |
| 823 const Array& deopt_table = Array::Handle(code.deopt_info_array()); | 823 const Array& deopt_table = Array::Handle(code.deopt_info_array()); |
| 824 intptr_t deopt_table_length = DeoptTable::GetLength(deopt_table); | 824 intptr_t deopt_table_length = DeoptTable::GetLength(deopt_table); |
| 825 if (deopt_table_length > 0) { | 825 if (deopt_table_length > 0) { |
| 826 OS::Print("DeoptInfo: {\n"); | 826 ISL_Print("DeoptInfo: {\n"); |
| 827 Smi& offset = Smi::Handle(); | 827 Smi& offset = Smi::Handle(); |
| 828 DeoptInfo& info = DeoptInfo::Handle(); | 828 DeoptInfo& info = DeoptInfo::Handle(); |
| 829 Smi& reason_and_flags = Smi::Handle(); | 829 Smi& reason_and_flags = Smi::Handle(); |
| 830 for (intptr_t i = 0; i < deopt_table_length; ++i) { | 830 for (intptr_t i = 0; i < deopt_table_length; ++i) { |
| 831 DeoptTable::GetEntry(deopt_table, i, &offset, &info, &reason_and_flags); | 831 DeoptTable::GetEntry(deopt_table, i, &offset, &info, &reason_and_flags); |
| 832 const intptr_t reason = | 832 const intptr_t reason = |
| 833 DeoptTable::ReasonField::decode(reason_and_flags.Value()); | 833 DeoptTable::ReasonField::decode(reason_and_flags.Value()); |
| 834 ASSERT((0 <= reason) && (reason < ICData::kDeoptNumReasons)); | 834 ASSERT((0 <= reason) && (reason < ICData::kDeoptNumReasons)); |
| 835 OS::Print("%4" Pd ": 0x%" Px " %s (%s)\n", | 835 ISL_Print("%4" Pd ": 0x%" Px " %s (%s)\n", |
| 836 i, | 836 i, |
| 837 start + offset.Value(), | 837 start + offset.Value(), |
| 838 info.ToCString(), | 838 info.ToCString(), |
| 839 DeoptReasonToCString( | 839 DeoptReasonToCString( |
| 840 static_cast<ICData::DeoptReasonId>(reason))); | 840 static_cast<ICData::DeoptReasonId>(reason))); |
| 841 } | 841 } |
| 842 OS::Print("}\n"); | 842 ISL_Print("}\n"); |
| 843 } | 843 } |
| 844 | 844 |
| 845 const Array& object_table = Array::Handle(code.object_table()); | 845 const Array& object_table = Array::Handle(code.object_table()); |
| 846 if (object_table.Length() > 0) { | 846 if (object_table.Length() > 0) { |
| 847 OS::Print("Object Table: {\n"); | 847 ISL_Print("Object Table: {\n"); |
| 848 for (intptr_t i = 0; i < object_table.Length(); i++) { | 848 for (intptr_t i = 0; i < object_table.Length(); i++) { |
| 849 OS::Print(" %" Pd ": %s\n", i, | 849 ISL_Print(" %" Pd ": %s\n", i, |
| 850 Object::Handle(object_table.At(i)).ToCString()); | 850 Object::Handle(object_table.At(i)).ToCString()); |
| 851 } | 851 } |
| 852 OS::Print("}\n"); | 852 ISL_Print("}\n"); |
| 853 } | 853 } |
| 854 | 854 |
| 855 const Array& object_pool = Array::Handle( | 855 const Array& object_pool = Array::Handle( |
| 856 Instructions::Handle(code.instructions()).object_pool()); | 856 Instructions::Handle(code.instructions()).object_pool()); |
| 857 if (object_pool.Length() > 0) { | 857 if (object_pool.Length() > 0) { |
| 858 OS::Print("Object Pool: {\n"); | 858 ISL_Print("Object Pool: {\n"); |
| 859 for (intptr_t i = 0; i < object_pool.Length(); i++) { | 859 for (intptr_t i = 0; i < object_pool.Length(); i++) { |
| 860 OS::Print(" %" Pd ": %s\n", i, | 860 ISL_Print(" %" Pd ": %s\n", i, |
| 861 Object::Handle(object_pool.At(i)).ToCString()); | 861 Object::Handle(object_pool.At(i)).ToCString()); |
| 862 } | 862 } |
| 863 OS::Print("}\n"); | 863 ISL_Print("}\n"); |
| 864 } | 864 } |
| 865 | 865 |
| 866 OS::Print("Stackmaps for function '%s' {\n", function_fullname); | 866 ISL_Print("Stackmaps for function '%s' {\n", function_fullname); |
| 867 if (code.stackmaps() != Array::null()) { | 867 if (code.stackmaps() != Array::null()) { |
| 868 const Array& stackmap_table = Array::Handle(code.stackmaps()); | 868 const Array& stackmap_table = Array::Handle(code.stackmaps()); |
| 869 Stackmap& map = Stackmap::Handle(); | 869 Stackmap& map = Stackmap::Handle(); |
| 870 for (intptr_t i = 0; i < stackmap_table.Length(); ++i) { | 870 for (intptr_t i = 0; i < stackmap_table.Length(); ++i) { |
| 871 map ^= stackmap_table.At(i); | 871 map ^= stackmap_table.At(i); |
| 872 OS::Print("%s\n", map.ToCString()); | 872 ISL_Print("%s\n", map.ToCString()); |
| 873 } | 873 } |
| 874 } | 874 } |
| 875 OS::Print("}\n"); | 875 ISL_Print("}\n"); |
| 876 | 876 |
| 877 OS::Print("Variable Descriptors for function '%s' {\n", | 877 ISL_Print("Variable Descriptors for function '%s' {\n", |
| 878 function_fullname); | 878 function_fullname); |
| 879 const LocalVarDescriptors& var_descriptors = | 879 const LocalVarDescriptors& var_descriptors = |
| 880 LocalVarDescriptors::Handle(code.var_descriptors()); | 880 LocalVarDescriptors::Handle(code.var_descriptors()); |
| 881 intptr_t var_desc_length = | 881 intptr_t var_desc_length = |
| 882 var_descriptors.IsNull() ? 0 : var_descriptors.Length(); | 882 var_descriptors.IsNull() ? 0 : var_descriptors.Length(); |
| 883 String& var_name = String::Handle(); | 883 String& var_name = String::Handle(); |
| 884 for (intptr_t i = 0; i < var_desc_length; i++) { | 884 for (intptr_t i = 0; i < var_desc_length; i++) { |
| 885 var_name = var_descriptors.GetName(i); | 885 var_name = var_descriptors.GetName(i); |
| 886 RawLocalVarDescriptors::VarInfo var_info; | 886 RawLocalVarDescriptors::VarInfo var_info; |
| 887 var_descriptors.GetInfo(i, &var_info); | 887 var_descriptors.GetInfo(i, &var_info); |
| 888 const int8_t kind = var_info.kind(); | 888 const int8_t kind = var_info.kind(); |
| 889 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { | 889 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { |
| 890 OS::Print(" saved current CTX reg offset %d\n", var_info.index()); | 890 ISL_Print(" saved current CTX reg offset %d\n", var_info.index()); |
| 891 } else { | 891 } else { |
| 892 if (kind == RawLocalVarDescriptors::kContextLevel) { | 892 if (kind == RawLocalVarDescriptors::kContextLevel) { |
| 893 OS::Print(" context level %d scope %d", var_info.index(), | 893 ISL_Print(" context level %d scope %d", var_info.index(), |
| 894 var_info.scope_id); | 894 var_info.scope_id); |
| 895 } else if (kind == RawLocalVarDescriptors::kStackVar) { | 895 } else if (kind == RawLocalVarDescriptors::kStackVar) { |
| 896 OS::Print(" stack var '%s' offset %d", | 896 ISL_Print(" stack var '%s' offset %d", |
| 897 var_name.ToCString(), var_info.index()); | 897 var_name.ToCString(), var_info.index()); |
| 898 } else { | 898 } else { |
| 899 ASSERT(kind == RawLocalVarDescriptors::kContextVar); | 899 ASSERT(kind == RawLocalVarDescriptors::kContextVar); |
| 900 OS::Print(" context var '%s' level %d offset %d", | 900 ISL_Print(" context var '%s' level %d offset %d", |
| 901 var_name.ToCString(), var_info.scope_id, var_info.index()); | 901 var_name.ToCString(), var_info.scope_id, var_info.index()); |
| 902 } | 902 } |
| 903 OS::Print(" (valid %d-%d)\n", var_info.begin_pos, var_info.end_pos); | 903 ISL_Print(" (valid %d-%d)\n", var_info.begin_pos, var_info.end_pos); |
| 904 } | 904 } |
| 905 } | 905 } |
| 906 OS::Print("}\n"); | 906 ISL_Print("}\n"); |
| 907 | 907 |
| 908 OS::Print("Exception Handlers for function '%s' {\n", function_fullname); | 908 ISL_Print("Exception Handlers for function '%s' {\n", function_fullname); |
| 909 const ExceptionHandlers& handlers = | 909 const ExceptionHandlers& handlers = |
| 910 ExceptionHandlers::Handle(code.exception_handlers()); | 910 ExceptionHandlers::Handle(code.exception_handlers()); |
| 911 OS::Print("%s}\n", handlers.ToCString()); | 911 ISL_Print("%s}\n", handlers.ToCString()); |
| 912 | 912 |
| 913 { | 913 { |
| 914 OS::Print("Static call target functions {\n"); | 914 ISL_Print("Static call target functions {\n"); |
| 915 const Array& table = Array::Handle(code.static_calls_target_table()); | 915 const Array& table = Array::Handle(code.static_calls_target_table()); |
| 916 Smi& offset = Smi::Handle(); | 916 Smi& offset = Smi::Handle(); |
| 917 Function& function = Function::Handle(); | 917 Function& function = Function::Handle(); |
| 918 Code& code = Code::Handle(); | 918 Code& code = Code::Handle(); |
| 919 for (intptr_t i = 0; i < table.Length(); | 919 for (intptr_t i = 0; i < table.Length(); |
| 920 i += Code::kSCallTableEntryLength) { | 920 i += Code::kSCallTableEntryLength) { |
| 921 offset ^= table.At(i + Code::kSCallTableOffsetEntry); | 921 offset ^= table.At(i + Code::kSCallTableOffsetEntry); |
| 922 function ^= table.At(i + Code::kSCallTableFunctionEntry); | 922 function ^= table.At(i + Code::kSCallTableFunctionEntry); |
| 923 code ^= table.At(i + Code::kSCallTableCodeEntry); | 923 code ^= table.At(i + Code::kSCallTableCodeEntry); |
| 924 if (function.IsNull()) { | 924 if (function.IsNull()) { |
| 925 Class& cls = Class::Handle(); | 925 Class& cls = Class::Handle(); |
| 926 cls ^= code.owner(); | 926 cls ^= code.owner(); |
| 927 OS::Print(" 0x%" Px ": allocation stub for %s, %p\n", | 927 ISL_Print(" 0x%" Px ": allocation stub for %s, %p\n", |
| 928 start + offset.Value(), | 928 start + offset.Value(), |
| 929 cls.ToCString(), | 929 cls.ToCString(), |
| 930 code.raw()); | 930 code.raw()); |
| 931 } else { | 931 } else { |
| 932 OS::Print(" 0x%" Px ": %s, %p\n", | 932 ISL_Print(" 0x%" Px ": %s, %p\n", |
| 933 start + offset.Value(), | 933 start + offset.Value(), |
| 934 function.ToFullyQualifiedCString(), | 934 function.ToFullyQualifiedCString(), |
| 935 code.raw()); | 935 code.raw()); |
| 936 } | 936 } |
| 937 } | 937 } |
| 938 OS::Print("}\n"); | 938 ISL_Print("}\n"); |
| 939 } | 939 } |
| 940 } | 940 } |
| 941 | 941 |
| 942 | 942 |
| 943 static RawError* CompileFunctionHelper(CompilationPipeline* pipeline, | 943 static RawError* CompileFunctionHelper(CompilationPipeline* pipeline, |
| 944 const Function& function, | 944 const Function& function, |
| 945 bool optimized, | 945 bool optimized, |
| 946 intptr_t osr_id) { | 946 intptr_t osr_id) { |
| 947 Thread* thread = Thread::Current(); | 947 Thread* thread = Thread::Current(); |
| 948 Isolate* isolate = thread->isolate(); | 948 Isolate* isolate = thread->isolate(); |
| 949 StackZone stack_zone(isolate); | 949 StackZone stack_zone(isolate); |
| 950 Zone* zone = stack_zone.GetZone(); | 950 Zone* zone = stack_zone.GetZone(); |
| 951 LongJumpScope jump; | 951 LongJumpScope jump; |
| 952 if (setjmp(*jump.Set()) == 0) { | 952 if (setjmp(*jump.Set()) == 0) { |
| 953 TIMERSCOPE(isolate, time_compilation); | 953 TIMERSCOPE(isolate, time_compilation); |
| 954 Timer per_compile_timer(FLAG_trace_compiler, "Compilation time"); | 954 Timer per_compile_timer(FLAG_trace_compiler, "Compilation time"); |
| 955 per_compile_timer.Start(); | 955 per_compile_timer.Start(); |
| 956 ParsedFunction* parsed_function = new(zone) ParsedFunction( | 956 ParsedFunction* parsed_function = new(zone) ParsedFunction( |
| 957 thread, Function::ZoneHandle(zone, function.raw())); | 957 thread, Function::ZoneHandle(zone, function.raw())); |
| 958 if (FLAG_trace_compiler) { | 958 if (FLAG_trace_compiler) { |
| 959 OS::Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", | 959 ISL_Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", |
| 960 (osr_id == Isolate::kNoDeoptId ? "" : "osr "), | 960 (osr_id == Isolate::kNoDeoptId ? "" : "osr "), |
| 961 (optimized ? "optimized " : ""), | 961 (optimized ? "optimized " : ""), |
| 962 function.ToFullyQualifiedCString(), | 962 function.ToFullyQualifiedCString(), |
| 963 function.token_pos(), | 963 function.token_pos(), |
| 964 (function.end_token_pos() - function.token_pos())); | 964 (function.end_token_pos() - function.token_pos())); |
| 965 } | 965 } |
| 966 { | 966 { |
| 967 HANDLESCOPE(isolate); | 967 HANDLESCOPE(isolate); |
| 968 pipeline->ParseFunction(parsed_function); | 968 pipeline->ParseFunction(parsed_function); |
| 969 } | 969 } |
| 970 | 970 |
| 971 const bool success = CompileParsedFunctionHelper(pipeline, | 971 const bool success = CompileParsedFunctionHelper(pipeline, |
| 972 parsed_function, | 972 parsed_function, |
| 973 optimized, | 973 optimized, |
| 974 osr_id); | 974 osr_id); |
| 975 if (!success) { | 975 if (!success) { |
| 976 if (optimized) { | 976 if (optimized) { |
| 977 // Optimizer bailed out. Disable optimizations and to never try again. | 977 // Optimizer bailed out. Disable optimizations and to never try again. |
| 978 if (FLAG_trace_compiler) { | 978 if (FLAG_trace_compiler) { |
| 979 OS::Print("--> disabling optimizations for '%s'\n", | 979 ISL_Print("--> disabling optimizations for '%s'\n", |
| 980 function.ToFullyQualifiedCString()); | 980 function.ToFullyQualifiedCString()); |
| 981 } else if (FLAG_trace_failed_optimization_attempts) { | 981 } else if (FLAG_trace_failed_optimization_attempts) { |
| 982 OS::Print("Cannot optimize: %s\n", | 982 ISL_Print("Cannot optimize: %s\n", |
| 983 function.ToFullyQualifiedCString()); | 983 function.ToFullyQualifiedCString()); |
| 984 } | 984 } |
| 985 function.SetIsOptimizable(false); | 985 function.SetIsOptimizable(false); |
| 986 return Error::null(); | 986 return Error::null(); |
| 987 } | 987 } |
| 988 UNREACHABLE(); | 988 UNREACHABLE(); |
| 989 } | 989 } |
| 990 | 990 |
| 991 per_compile_timer.Stop(); | 991 per_compile_timer.Stop(); |
| 992 | 992 |
| 993 if (FLAG_trace_compiler) { | 993 if (FLAG_trace_compiler) { |
| 994 OS::Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n", | 994 ISL_Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n", |
| 995 function.ToFullyQualifiedCString(), | 995 function.ToFullyQualifiedCString(), |
| 996 Code::Handle(function.CurrentCode()).EntryPoint(), | 996 Code::Handle(function.CurrentCode()).EntryPoint(), |
| 997 Code::Handle(function.CurrentCode()).Size(), | 997 Code::Handle(function.CurrentCode()).Size(), |
| 998 per_compile_timer.TotalElapsedTime()); | 998 per_compile_timer.TotalElapsedTime()); |
| 999 } | 999 } |
| 1000 | 1000 |
| 1001 isolate->debugger()->NotifyCompilation(function); | 1001 isolate->debugger()->NotifyCompilation(function); |
| 1002 | 1002 |
| 1003 if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) { | 1003 if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) { |
| 1004 DisassembleCode(function, optimized); | 1004 DisassembleCode(function, optimized); |
| 1005 } else if (FLAG_disassemble_optimized && | 1005 } else if (FLAG_disassemble_optimized && |
| 1006 optimized && | 1006 optimized && |
| 1007 FlowGraphPrinter::ShouldPrint(function)) { | 1007 FlowGraphPrinter::ShouldPrint(function)) { |
| 1008 // TODO(fschneider): Print unoptimized code along with the optimized code. | 1008 // TODO(fschneider): Print unoptimized code along with the optimized code. |
| 1009 OS::Print("*** BEGIN CODE\n"); | 1009 ISL_Print("*** BEGIN CODE\n"); |
| 1010 DisassembleCode(function, true); | 1010 DisassembleCode(function, true); |
| 1011 OS::Print("*** END CODE\n"); | 1011 ISL_Print("*** END CODE\n"); |
| 1012 } | 1012 } |
| 1013 | 1013 |
| 1014 return Error::null(); | 1014 return Error::null(); |
| 1015 } else { | 1015 } else { |
| 1016 Error& error = Error::Handle(); | 1016 Error& error = Error::Handle(); |
| 1017 // We got an error during compilation. | 1017 // We got an error during compilation. |
| 1018 error = isolate->object_store()->sticky_error(); | 1018 error = isolate->object_store()->sticky_error(); |
| 1019 isolate->object_store()->clear_sticky_error(); | 1019 isolate->object_store()->clear_sticky_error(); |
| 1020 return error.raw(); | 1020 return error.raw(); |
| 1021 } | 1021 } |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1151 } | 1151 } |
| 1152 | 1152 |
| 1153 | 1153 |
| 1154 | 1154 |
| 1155 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { | 1155 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { |
| 1156 Thread* thread = Thread::Current(); | 1156 Thread* thread = Thread::Current(); |
| 1157 Isolate* isolate = thread->isolate(); | 1157 Isolate* isolate = thread->isolate(); |
| 1158 LongJumpScope jump; | 1158 LongJumpScope jump; |
| 1159 if (setjmp(*jump.Set()) == 0) { | 1159 if (setjmp(*jump.Set()) == 0) { |
| 1160 if (FLAG_trace_compiler) { | 1160 if (FLAG_trace_compiler) { |
| 1161 OS::Print("compiling expression: "); | 1161 ISL_Print("compiling expression: "); |
| 1162 AstPrinter::PrintNode(fragment); | 1162 AstPrinter::PrintNode(fragment); |
| 1163 } | 1163 } |
| 1164 | 1164 |
| 1165 // Create a dummy function object for the code generator. | 1165 // Create a dummy function object for the code generator. |
| 1166 // The function needs to be associated with a named Class: the interface | 1166 // The function needs to be associated with a named Class: the interface |
| 1167 // Function fits the bill. | 1167 // Function fits the bill. |
| 1168 const char* kEvalConst = "eval_const"; | 1168 const char* kEvalConst = "eval_const"; |
| 1169 const Function& func = Function::ZoneHandle(Function::New( | 1169 const Function& func = Function::ZoneHandle(Function::New( |
| 1170 String::Handle(Symbols::New(kEvalConst)), | 1170 String::Handle(Symbols::New(kEvalConst)), |
| 1171 RawFunction::kRegularFunction, | 1171 RawFunction::kRegularFunction, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1209 const Object& result = | 1209 const Object& result = |
| 1210 PassiveObject::Handle(isolate->object_store()->sticky_error()); | 1210 PassiveObject::Handle(isolate->object_store()->sticky_error()); |
| 1211 isolate->object_store()->clear_sticky_error(); | 1211 isolate->object_store()->clear_sticky_error(); |
| 1212 return result.raw(); | 1212 return result.raw(); |
| 1213 } | 1213 } |
| 1214 UNREACHABLE(); | 1214 UNREACHABLE(); |
| 1215 return Object::null(); | 1215 return Object::null(); |
| 1216 } | 1216 } |
| 1217 | 1217 |
| 1218 } // namespace dart | 1218 } // namespace dart |
| OLD | NEW |