| 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 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 | 185 |
| 186 | 186 |
| 187 RawError* Compiler::Compile(const Library& library, const Script& script) { | 187 RawError* Compiler::Compile(const Library& library, const Script& script) { |
| 188 LongJumpScope jump; | 188 LongJumpScope jump; |
| 189 if (setjmp(*jump.Set()) == 0) { | 189 if (setjmp(*jump.Set()) == 0) { |
| 190 Thread* const thread = Thread::Current(); | 190 Thread* const thread = Thread::Current(); |
| 191 StackZone zone(thread); | 191 StackZone zone(thread); |
| 192 if (FLAG_trace_compiler) { | 192 if (FLAG_trace_compiler) { |
| 193 const String& script_url = String::Handle(script.url()); | 193 const String& script_url = String::Handle(script.url()); |
| 194 // TODO(iposva): Extract script kind. | 194 // TODO(iposva): Extract script kind. |
| 195 ISL_Print("Compiling %s '%s'\n", "", script_url.ToCString()); | 195 THR_Print("Compiling %s '%s'\n", "", script_url.ToCString()); |
| 196 } | 196 } |
| 197 const String& library_key = String::Handle(library.private_key()); | 197 const String& library_key = String::Handle(library.private_key()); |
| 198 script.Tokenize(library_key); | 198 script.Tokenize(library_key); |
| 199 Parser::ParseCompilationUnit(library, script); | 199 Parser::ParseCompilationUnit(library, script); |
| 200 return Error::null(); | 200 return Error::null(); |
| 201 } else { | 201 } else { |
| 202 Thread* const thread = Thread::Current(); | 202 Thread* const thread = Thread::Current(); |
| 203 Isolate* const isolate = thread->isolate(); | 203 Isolate* const isolate = thread->isolate(); |
| 204 StackZone zone(thread); | 204 StackZone zone(thread); |
| 205 Error& error = Error::Handle(); | 205 Error& error = Error::Handle(); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 // also allows us to reset the marked_for_parsing state in case we see an | 297 // also allows us to reset the marked_for_parsing state in case we see an |
| 298 // error. | 298 // error. |
| 299 VMTagScope tagScope(thread, VMTag::kCompileClassTagId); | 299 VMTagScope tagScope(thread, VMTag::kCompileClassTagId); |
| 300 GrowableHandlePtrArray<const Class> parse_list(thread->zone(), 4); | 300 GrowableHandlePtrArray<const Class> parse_list(thread->zone(), 4); |
| 301 GrowableHandlePtrArray<const Class> patch_list(thread->zone(), 4); | 301 GrowableHandlePtrArray<const Class> patch_list(thread->zone(), 4); |
| 302 | 302 |
| 303 // Parse the class and all the interfaces it implements and super classes. | 303 // Parse the class and all the interfaces it implements and super classes. |
| 304 LongJumpScope jump; | 304 LongJumpScope jump; |
| 305 if (setjmp(*jump.Set()) == 0) { | 305 if (setjmp(*jump.Set()) == 0) { |
| 306 if (FLAG_trace_compiler) { | 306 if (FLAG_trace_compiler) { |
| 307 ISL_Print("Compiling Class %s '%s'\n", "", cls.ToCString()); | 307 THR_Print("Compiling Class %s '%s'\n", "", cls.ToCString()); |
| 308 } | 308 } |
| 309 | 309 |
| 310 // Add the primary class which needs to be parsed to the parse list. | 310 // Add the primary class which needs to be parsed to the parse list. |
| 311 // Mark the class as parsed so that we don't recursively add the same | 311 // Mark the class as parsed so that we don't recursively add the same |
| 312 // class back into the list. | 312 // class back into the list. |
| 313 parse_list.Add(cls); | 313 parse_list.Add(cls); |
| 314 cls.set_is_marked_for_parsing(); | 314 cls.set_is_marked_for_parsing(); |
| 315 | 315 |
| 316 // Add all super classes, interface classes and patch class if one | 316 // Add all super classes, interface classes and patch class if one |
| 317 // exists to the corresponding lists. | 317 // exists to the corresponding lists. |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 new(zone) ZoneGrowableArray<const ICData*>(); | 420 new(zone) ZoneGrowableArray<const ICData*>(); |
| 421 if (optimized) { | 421 if (optimized) { |
| 422 // Extract type feedback before the graph is built, as the graph | 422 // Extract type feedback before the graph is built, as the graph |
| 423 // builder uses it to attach it to nodes. | 423 // builder uses it to attach it to nodes. |
| 424 ASSERT(function.deoptimization_counter() < | 424 ASSERT(function.deoptimization_counter() < |
| 425 FLAG_deoptimization_counter_threshold); | 425 FLAG_deoptimization_counter_threshold); |
| 426 function.RestoreICDataMap(ic_data_array); | 426 function.RestoreICDataMap(ic_data_array); |
| 427 if (FLAG_print_ic_data_map) { | 427 if (FLAG_print_ic_data_map) { |
| 428 for (intptr_t i = 0; i < ic_data_array->length(); i++) { | 428 for (intptr_t i = 0; i < ic_data_array->length(); i++) { |
| 429 if ((*ic_data_array)[i] != NULL) { | 429 if ((*ic_data_array)[i] != NULL) { |
| 430 ISL_Print("%" Pd " ", i); | 430 THR_Print("%" Pd " ", i); |
| 431 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]); | 431 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]); |
| 432 } | 432 } |
| 433 } | 433 } |
| 434 } | 434 } |
| 435 } | 435 } |
| 436 | 436 |
| 437 flow_graph = pipeline->BuildFlowGraph(zone, | 437 flow_graph = pipeline->BuildFlowGraph(zone, |
| 438 parsed_function, | 438 parsed_function, |
| 439 *ic_data_array, | 439 *ic_data_array, |
| 440 osr_id); | 440 osr_id); |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 graph_compiler.FinalizeVarDescriptors(code); | 754 graph_compiler.FinalizeVarDescriptors(code); |
| 755 graph_compiler.FinalizeExceptionHandlers(code); | 755 graph_compiler.FinalizeExceptionHandlers(code); |
| 756 graph_compiler.FinalizeStaticCallTargetsTable(code); | 756 graph_compiler.FinalizeStaticCallTargetsTable(code); |
| 757 | 757 |
| 758 if (optimized) { | 758 if (optimized) { |
| 759 // We may not have previous code if 'always_optimize' is set. | 759 // We may not have previous code if 'always_optimize' is set. |
| 760 if ((osr_id == Isolate::kNoDeoptId) && function.HasCode()) { | 760 if ((osr_id == Isolate::kNoDeoptId) && function.HasCode()) { |
| 761 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); | 761 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); |
| 762 if (FLAG_trace_compiler || FLAG_trace_patching) { | 762 if (FLAG_trace_compiler || FLAG_trace_patching) { |
| 763 if (FLAG_trace_compiler) { | 763 if (FLAG_trace_compiler) { |
| 764 ISL_Print(" "); | 764 THR_Print(" "); |
| 765 } | 765 } |
| 766 ISL_Print("Patch unoptimized '%s' entry point %#" Px "\n", | 766 THR_Print("Patch unoptimized '%s' entry point %#" Px "\n", |
| 767 function.ToFullyQualifiedCString(), | 767 function.ToFullyQualifiedCString(), |
| 768 Code::Handle(function.unoptimized_code()).EntryPoint()); | 768 Code::Handle(function.unoptimized_code()).EntryPoint()); |
| 769 } | 769 } |
| 770 } | 770 } |
| 771 function.AttachCode(code); | 771 function.AttachCode(code); |
| 772 | 772 |
| 773 // Register code with the classes it depends on because of CHA. | 773 // Register code with the classes it depends on because of CHA. |
| 774 for (intptr_t i = 0; | 774 for (intptr_t i = 0; |
| 775 i < thread->cha()->leaf_classes().length(); | 775 i < thread->cha()->leaf_classes().length(); |
| 776 ++i) { | 776 ++i) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 // Compilation failed due to an out of range branch offset in the | 815 // Compilation failed due to an out of range branch offset in the |
| 816 // assembler. We try again (done = false) with far branches enabled. | 816 // assembler. We try again (done = false) with far branches enabled. |
| 817 done = false; | 817 done = false; |
| 818 ASSERT(!use_far_branches); | 818 ASSERT(!use_far_branches); |
| 819 use_far_branches = true; | 819 use_far_branches = true; |
| 820 } else { | 820 } else { |
| 821 // If the error isn't due to an out of range branch offset, we don't | 821 // If the error isn't due to an out of range branch offset, we don't |
| 822 // try again (done = true), and indicate that we did not finish | 822 // try again (done = true), and indicate that we did not finish |
| 823 // compiling (is_compiled = false). | 823 // compiling (is_compiled = false). |
| 824 if (FLAG_trace_bailout) { | 824 if (FLAG_trace_bailout) { |
| 825 ISL_Print("%s\n", error.ToErrorCString()); | 825 THR_Print("%s\n", error.ToErrorCString()); |
| 826 } | 826 } |
| 827 done = true; | 827 done = true; |
| 828 ASSERT(optimized); | 828 ASSERT(optimized); |
| 829 } | 829 } |
| 830 | 830 |
| 831 // Clear the error if it was not a real error, but just a bailout. | 831 // Clear the error if it was not a real error, but just a bailout. |
| 832 if (error.IsLanguageError() && | 832 if (error.IsLanguageError() && |
| 833 (LanguageError::Cast(error).kind() == Report::kBailout)) { | 833 (LanguageError::Cast(error).kind() == Report::kBailout)) { |
| 834 isolate->object_store()->clear_sticky_error(); | 834 isolate->object_store()->clear_sticky_error(); |
| 835 } | 835 } |
| 836 is_compiled = false; | 836 is_compiled = false; |
| 837 } | 837 } |
| 838 // Reset global isolate state. | 838 // Reset global isolate state. |
| 839 isolate->set_deopt_id(prev_deopt_id); | 839 isolate->set_deopt_id(prev_deopt_id); |
| 840 } | 840 } |
| 841 return is_compiled; | 841 return is_compiled; |
| 842 } | 842 } |
| 843 | 843 |
| 844 | 844 |
| 845 static void DisassembleCode(const Function& function, bool optimized) { | 845 static void DisassembleCode(const Function& function, bool optimized) { |
| 846 const char* function_fullname = function.ToFullyQualifiedCString(); | 846 const char* function_fullname = function.ToFullyQualifiedCString(); |
| 847 ISL_Print("Code for %sfunction '%s' {\n", | 847 THR_Print("Code for %sfunction '%s' {\n", |
| 848 optimized ? "optimized " : "", | 848 optimized ? "optimized " : "", |
| 849 function_fullname); | 849 function_fullname); |
| 850 const Code& code = Code::Handle(function.CurrentCode()); | 850 const Code& code = Code::Handle(function.CurrentCode()); |
| 851 code.Disassemble(); | 851 code.Disassemble(); |
| 852 ISL_Print("}\n"); | 852 THR_Print("}\n"); |
| 853 | 853 |
| 854 ISL_Print("Pointer offsets for function: {\n"); | 854 THR_Print("Pointer offsets for function: {\n"); |
| 855 // Pointer offsets are stored in descending order. | 855 // Pointer offsets are stored in descending order. |
| 856 Object& obj = Object::Handle(); | 856 Object& obj = Object::Handle(); |
| 857 for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) { | 857 for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) { |
| 858 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); | 858 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); |
| 859 obj = *reinterpret_cast<RawObject**>(addr); | 859 obj = *reinterpret_cast<RawObject**>(addr); |
| 860 ISL_Print(" %d : %#" Px " '%s'\n", | 860 THR_Print(" %d : %#" Px " '%s'\n", |
| 861 code.GetPointerOffsetAt(i), addr, obj.ToCString()); | 861 code.GetPointerOffsetAt(i), addr, obj.ToCString()); |
| 862 } | 862 } |
| 863 ISL_Print("}\n"); | 863 THR_Print("}\n"); |
| 864 | 864 |
| 865 ISL_Print("PC Descriptors for function '%s' {\n", function_fullname); | 865 THR_Print("PC Descriptors for function '%s' {\n", function_fullname); |
| 866 PcDescriptors::PrintHeaderString(); | 866 PcDescriptors::PrintHeaderString(); |
| 867 const PcDescriptors& descriptors = | 867 const PcDescriptors& descriptors = |
| 868 PcDescriptors::Handle(code.pc_descriptors()); | 868 PcDescriptors::Handle(code.pc_descriptors()); |
| 869 ISL_Print("%s}\n", descriptors.ToCString()); | 869 THR_Print("%s}\n", descriptors.ToCString()); |
| 870 | 870 |
| 871 uword start = Instructions::Handle(code.instructions()).EntryPoint(); | 871 uword start = Instructions::Handle(code.instructions()).EntryPoint(); |
| 872 const Array& deopt_table = Array::Handle(code.deopt_info_array()); | 872 const Array& deopt_table = Array::Handle(code.deopt_info_array()); |
| 873 intptr_t deopt_table_length = DeoptTable::GetLength(deopt_table); | 873 intptr_t deopt_table_length = DeoptTable::GetLength(deopt_table); |
| 874 if (deopt_table_length > 0) { | 874 if (deopt_table_length > 0) { |
| 875 ISL_Print("DeoptInfo: {\n"); | 875 THR_Print("DeoptInfo: {\n"); |
| 876 Smi& offset = Smi::Handle(); | 876 Smi& offset = Smi::Handle(); |
| 877 TypedData& info = TypedData::Handle(); | 877 TypedData& info = TypedData::Handle(); |
| 878 Smi& reason_and_flags = Smi::Handle(); | 878 Smi& reason_and_flags = Smi::Handle(); |
| 879 for (intptr_t i = 0; i < deopt_table_length; ++i) { | 879 for (intptr_t i = 0; i < deopt_table_length; ++i) { |
| 880 DeoptTable::GetEntry(deopt_table, i, &offset, &info, &reason_and_flags); | 880 DeoptTable::GetEntry(deopt_table, i, &offset, &info, &reason_and_flags); |
| 881 const intptr_t reason = | 881 const intptr_t reason = |
| 882 DeoptTable::ReasonField::decode(reason_and_flags.Value()); | 882 DeoptTable::ReasonField::decode(reason_and_flags.Value()); |
| 883 ASSERT((0 <= reason) && (reason < ICData::kDeoptNumReasons)); | 883 ASSERT((0 <= reason) && (reason < ICData::kDeoptNumReasons)); |
| 884 ISL_Print("%4" Pd ": 0x%" Px " %s (%s)\n", | 884 THR_Print("%4" Pd ": 0x%" Px " %s (%s)\n", |
| 885 i, | 885 i, |
| 886 start + offset.Value(), | 886 start + offset.Value(), |
| 887 DeoptInfo::ToCString(deopt_table, info), | 887 DeoptInfo::ToCString(deopt_table, info), |
| 888 DeoptReasonToCString( | 888 DeoptReasonToCString( |
| 889 static_cast<ICData::DeoptReasonId>(reason))); | 889 static_cast<ICData::DeoptReasonId>(reason))); |
| 890 } | 890 } |
| 891 ISL_Print("}\n"); | 891 THR_Print("}\n"); |
| 892 } | 892 } |
| 893 | 893 |
| 894 const ObjectPool& object_pool = ObjectPool::Handle(code.GetObjectPool()); | 894 const ObjectPool& object_pool = ObjectPool::Handle(code.GetObjectPool()); |
| 895 object_pool.DebugPrint(); | 895 object_pool.DebugPrint(); |
| 896 | 896 |
| 897 ISL_Print("Stackmaps for function '%s' {\n", function_fullname); | 897 THR_Print("Stackmaps for function '%s' {\n", function_fullname); |
| 898 if (code.stackmaps() != Array::null()) { | 898 if (code.stackmaps() != Array::null()) { |
| 899 const Array& stackmap_table = Array::Handle(code.stackmaps()); | 899 const Array& stackmap_table = Array::Handle(code.stackmaps()); |
| 900 Stackmap& map = Stackmap::Handle(); | 900 Stackmap& map = Stackmap::Handle(); |
| 901 for (intptr_t i = 0; i < stackmap_table.Length(); ++i) { | 901 for (intptr_t i = 0; i < stackmap_table.Length(); ++i) { |
| 902 map ^= stackmap_table.At(i); | 902 map ^= stackmap_table.At(i); |
| 903 ISL_Print("%s\n", map.ToCString()); | 903 THR_Print("%s\n", map.ToCString()); |
| 904 } | 904 } |
| 905 } | 905 } |
| 906 ISL_Print("}\n"); | 906 THR_Print("}\n"); |
| 907 | 907 |
| 908 ISL_Print("Variable Descriptors for function '%s' {\n", | 908 THR_Print("Variable Descriptors for function '%s' {\n", |
| 909 function_fullname); | 909 function_fullname); |
| 910 const LocalVarDescriptors& var_descriptors = | 910 const LocalVarDescriptors& var_descriptors = |
| 911 LocalVarDescriptors::Handle(code.GetLocalVarDescriptors()); | 911 LocalVarDescriptors::Handle(code.GetLocalVarDescriptors()); |
| 912 intptr_t var_desc_length = | 912 intptr_t var_desc_length = |
| 913 var_descriptors.IsNull() ? 0 : var_descriptors.Length(); | 913 var_descriptors.IsNull() ? 0 : var_descriptors.Length(); |
| 914 String& var_name = String::Handle(); | 914 String& var_name = String::Handle(); |
| 915 for (intptr_t i = 0; i < var_desc_length; i++) { | 915 for (intptr_t i = 0; i < var_desc_length; i++) { |
| 916 var_name = var_descriptors.GetName(i); | 916 var_name = var_descriptors.GetName(i); |
| 917 RawLocalVarDescriptors::VarInfo var_info; | 917 RawLocalVarDescriptors::VarInfo var_info; |
| 918 var_descriptors.GetInfo(i, &var_info); | 918 var_descriptors.GetInfo(i, &var_info); |
| 919 const int8_t kind = var_info.kind(); | 919 const int8_t kind = var_info.kind(); |
| 920 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { | 920 if (kind == RawLocalVarDescriptors::kSavedCurrentContext) { |
| 921 ISL_Print(" saved current CTX reg offset %d\n", var_info.index()); | 921 THR_Print(" saved current CTX reg offset %d\n", var_info.index()); |
| 922 } else { | 922 } else { |
| 923 if (kind == RawLocalVarDescriptors::kContextLevel) { | 923 if (kind == RawLocalVarDescriptors::kContextLevel) { |
| 924 ISL_Print(" context level %d scope %d", var_info.index(), | 924 THR_Print(" context level %d scope %d", var_info.index(), |
| 925 var_info.scope_id); | 925 var_info.scope_id); |
| 926 } else if (kind == RawLocalVarDescriptors::kStackVar) { | 926 } else if (kind == RawLocalVarDescriptors::kStackVar) { |
| 927 ISL_Print(" stack var '%s' offset %d", | 927 THR_Print(" stack var '%s' offset %d", |
| 928 var_name.ToCString(), var_info.index()); | 928 var_name.ToCString(), var_info.index()); |
| 929 } else if (kind == RawLocalVarDescriptors::kContextVar) { | 929 } else if (kind == RawLocalVarDescriptors::kContextVar) { |
| 930 ISL_Print(" context var '%s' level %d offset %d", | 930 THR_Print(" context var '%s' level %d offset %d", |
| 931 var_name.ToCString(), var_info.scope_id, var_info.index()); | 931 var_name.ToCString(), var_info.scope_id, var_info.index()); |
| 932 } else { | 932 } else { |
| 933 ASSERT(kind == RawLocalVarDescriptors::kAsyncOperation); | 933 ASSERT(kind == RawLocalVarDescriptors::kAsyncOperation); |
| 934 ISL_Print(" async operation '%s' level %d offset %d", | 934 THR_Print(" async operation '%s' level %d offset %d", |
| 935 var_name.ToCString(), var_info.scope_id, var_info.index()); | 935 var_name.ToCString(), var_info.scope_id, var_info.index()); |
| 936 } | 936 } |
| 937 ISL_Print(" (valid %d-%d)\n", var_info.begin_pos, var_info.end_pos); | 937 THR_Print(" (valid %d-%d)\n", var_info.begin_pos, var_info.end_pos); |
| 938 } | 938 } |
| 939 } | 939 } |
| 940 ISL_Print("}\n"); | 940 THR_Print("}\n"); |
| 941 | 941 |
| 942 ISL_Print("Exception Handlers for function '%s' {\n", function_fullname); | 942 THR_Print("Exception Handlers for function '%s' {\n", function_fullname); |
| 943 const ExceptionHandlers& handlers = | 943 const ExceptionHandlers& handlers = |
| 944 ExceptionHandlers::Handle(code.exception_handlers()); | 944 ExceptionHandlers::Handle(code.exception_handlers()); |
| 945 ISL_Print("%s}\n", handlers.ToCString()); | 945 THR_Print("%s}\n", handlers.ToCString()); |
| 946 | 946 |
| 947 { | 947 { |
| 948 ISL_Print("Static call target functions {\n"); | 948 THR_Print("Static call target functions {\n"); |
| 949 const Array& table = Array::Handle(code.static_calls_target_table()); | 949 const Array& table = Array::Handle(code.static_calls_target_table()); |
| 950 Smi& offset = Smi::Handle(); | 950 Smi& offset = Smi::Handle(); |
| 951 Function& function = Function::Handle(); | 951 Function& function = Function::Handle(); |
| 952 Code& code = Code::Handle(); | 952 Code& code = Code::Handle(); |
| 953 for (intptr_t i = 0; i < table.Length(); | 953 for (intptr_t i = 0; i < table.Length(); |
| 954 i += Code::kSCallTableEntryLength) { | 954 i += Code::kSCallTableEntryLength) { |
| 955 offset ^= table.At(i + Code::kSCallTableOffsetEntry); | 955 offset ^= table.At(i + Code::kSCallTableOffsetEntry); |
| 956 function ^= table.At(i + Code::kSCallTableFunctionEntry); | 956 function ^= table.At(i + Code::kSCallTableFunctionEntry); |
| 957 code ^= table.At(i + Code::kSCallTableCodeEntry); | 957 code ^= table.At(i + Code::kSCallTableCodeEntry); |
| 958 if (function.IsNull()) { | 958 if (function.IsNull()) { |
| 959 Class& cls = Class::Handle(); | 959 Class& cls = Class::Handle(); |
| 960 cls ^= code.owner(); | 960 cls ^= code.owner(); |
| 961 if (cls.IsNull()) { | 961 if (cls.IsNull()) { |
| 962 const String& code_name = String::Handle(code.Name()); | 962 const String& code_name = String::Handle(code.Name()); |
| 963 ISL_Print(" 0x%" Px ": %s, %p\n", | 963 THR_Print(" 0x%" Px ": %s, %p\n", |
| 964 start + offset.Value(), | 964 start + offset.Value(), |
| 965 code_name.ToCString(), | 965 code_name.ToCString(), |
| 966 code.raw()); | 966 code.raw()); |
| 967 } else { | 967 } else { |
| 968 ISL_Print(" 0x%" Px ": allocation stub for %s, %p\n", | 968 THR_Print(" 0x%" Px ": allocation stub for %s, %p\n", |
| 969 start + offset.Value(), | 969 start + offset.Value(), |
| 970 cls.ToCString(), | 970 cls.ToCString(), |
| 971 code.raw()); | 971 code.raw()); |
| 972 } | 972 } |
| 973 } else { | 973 } else { |
| 974 ISL_Print(" 0x%" Px ": %s, %p\n", | 974 THR_Print(" 0x%" Px ": %s, %p\n", |
| 975 start + offset.Value(), | 975 start + offset.Value(), |
| 976 function.ToFullyQualifiedCString(), | 976 function.ToFullyQualifiedCString(), |
| 977 code.raw()); | 977 code.raw()); |
| 978 } | 978 } |
| 979 } | 979 } |
| 980 ISL_Print("}\n"); | 980 THR_Print("}\n"); |
| 981 } | 981 } |
| 982 if (optimized && FLAG_trace_inlining_intervals) { | 982 if (optimized && FLAG_trace_inlining_intervals) { |
| 983 code.DumpInlinedIntervals(); | 983 code.DumpInlinedIntervals(); |
| 984 } | 984 } |
| 985 } | 985 } |
| 986 | 986 |
| 987 | 987 |
| 988 #if defined(DEBUG) | 988 #if defined(DEBUG) |
| 989 // Verifies that the inliner is always in the list of inlined functions. | 989 // Verifies that the inliner is always in the list of inlined functions. |
| 990 // If this fails run with --trace-inlining-intervals to get more information. | 990 // If this fails run with --trace-inlining-intervals to get more information. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1032 zone, Compiler::EnsureUnoptimizedCode(Thread::Current(), function)); | 1032 zone, Compiler::EnsureUnoptimizedCode(Thread::Current(), function)); |
| 1033 if (!error.IsNull()) { | 1033 if (!error.IsNull()) { |
| 1034 return error.raw(); | 1034 return error.raw(); |
| 1035 } | 1035 } |
| 1036 } | 1036 } |
| 1037 } | 1037 } |
| 1038 | 1038 |
| 1039 ParsedFunction* parsed_function = new(zone) ParsedFunction( | 1039 ParsedFunction* parsed_function = new(zone) ParsedFunction( |
| 1040 thread, Function::ZoneHandle(zone, function.raw())); | 1040 thread, Function::ZoneHandle(zone, function.raw())); |
| 1041 if (FLAG_trace_compiler) { | 1041 if (FLAG_trace_compiler) { |
| 1042 ISL_Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", | 1042 THR_Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", |
| 1043 (osr_id == Isolate::kNoDeoptId ? "" : "osr "), | 1043 (osr_id == Isolate::kNoDeoptId ? "" : "osr "), |
| 1044 (optimized ? "optimized " : ""), | 1044 (optimized ? "optimized " : ""), |
| 1045 function.ToFullyQualifiedCString(), | 1045 function.ToFullyQualifiedCString(), |
| 1046 function.token_pos(), | 1046 function.token_pos(), |
| 1047 (function.end_token_pos() - function.token_pos())); | 1047 (function.end_token_pos() - function.token_pos())); |
| 1048 } | 1048 } |
| 1049 INC_STAT(thread, num_functions_compiled, 1); | 1049 INC_STAT(thread, num_functions_compiled, 1); |
| 1050 if (optimized) { | 1050 if (optimized) { |
| 1051 INC_STAT(thread, num_functions_optimized, 1); | 1051 INC_STAT(thread, num_functions_optimized, 1); |
| 1052 } | 1052 } |
| 1053 { | 1053 { |
| 1054 HANDLESCOPE(thread); | 1054 HANDLESCOPE(thread); |
| 1055 const int64_t num_tokens_before = STAT_VALUE(thread, num_tokens_consumed); | 1055 const int64_t num_tokens_before = STAT_VALUE(thread, num_tokens_consumed); |
| 1056 pipeline->ParseFunction(parsed_function); | 1056 pipeline->ParseFunction(parsed_function); |
| 1057 const int64_t num_tokens_after = STAT_VALUE(thread, num_tokens_consumed); | 1057 const int64_t num_tokens_after = STAT_VALUE(thread, num_tokens_consumed); |
| 1058 INC_STAT(thread, | 1058 INC_STAT(thread, |
| 1059 num_func_tokens_compiled, | 1059 num_func_tokens_compiled, |
| 1060 num_tokens_after - num_tokens_before); | 1060 num_tokens_after - num_tokens_before); |
| 1061 } | 1061 } |
| 1062 | 1062 |
| 1063 const bool success = CompileParsedFunctionHelper(pipeline, | 1063 const bool success = CompileParsedFunctionHelper(pipeline, |
| 1064 parsed_function, | 1064 parsed_function, |
| 1065 optimized, | 1065 optimized, |
| 1066 osr_id); | 1066 osr_id); |
| 1067 if (!success) { | 1067 if (!success) { |
| 1068 if (optimized) { | 1068 if (optimized) { |
| 1069 ASSERT(!Compiler::always_optimize()); // Optimized is the only code. | 1069 ASSERT(!Compiler::always_optimize()); // Optimized is the only code. |
| 1070 // Optimizer bailed out. Disable optimizations and never try again. | 1070 // Optimizer bailed out. Disable optimizations and never try again. |
| 1071 if (FLAG_trace_compiler) { | 1071 if (FLAG_trace_compiler) { |
| 1072 ISL_Print("--> disabling optimizations for '%s'\n", | 1072 THR_Print("--> disabling optimizations for '%s'\n", |
| 1073 function.ToFullyQualifiedCString()); | 1073 function.ToFullyQualifiedCString()); |
| 1074 } else if (FLAG_trace_failed_optimization_attempts) { | 1074 } else if (FLAG_trace_failed_optimization_attempts) { |
| 1075 ISL_Print("Cannot optimize: %s\n", | 1075 THR_Print("Cannot optimize: %s\n", |
| 1076 function.ToFullyQualifiedCString()); | 1076 function.ToFullyQualifiedCString()); |
| 1077 } | 1077 } |
| 1078 function.SetIsOptimizable(false); | 1078 function.SetIsOptimizable(false); |
| 1079 return Error::null(); | 1079 return Error::null(); |
| 1080 } | 1080 } |
| 1081 UNREACHABLE(); | 1081 UNREACHABLE(); |
| 1082 } | 1082 } |
| 1083 | 1083 |
| 1084 per_compile_timer.Stop(); | 1084 per_compile_timer.Stop(); |
| 1085 | 1085 |
| 1086 if (FLAG_trace_compiler) { | 1086 if (FLAG_trace_compiler) { |
| 1087 ISL_Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n", | 1087 THR_Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n", |
| 1088 function.ToFullyQualifiedCString(), | 1088 function.ToFullyQualifiedCString(), |
| 1089 Code::Handle(function.CurrentCode()).EntryPoint(), | 1089 Code::Handle(function.CurrentCode()).EntryPoint(), |
| 1090 Code::Handle(function.CurrentCode()).Size(), | 1090 Code::Handle(function.CurrentCode()).Size(), |
| 1091 per_compile_timer.TotalElapsedTime()); | 1091 per_compile_timer.TotalElapsedTime()); |
| 1092 } | 1092 } |
| 1093 | 1093 |
| 1094 isolate->debugger()->NotifyCompilation(function); | 1094 isolate->debugger()->NotifyCompilation(function); |
| 1095 | 1095 |
| 1096 if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) { | 1096 if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) { |
| 1097 DisassembleCode(function, optimized); | 1097 DisassembleCode(function, optimized); |
| 1098 } else if (FLAG_disassemble_optimized && | 1098 } else if (FLAG_disassemble_optimized && |
| 1099 optimized && | 1099 optimized && |
| 1100 FlowGraphPrinter::ShouldPrint(function)) { | 1100 FlowGraphPrinter::ShouldPrint(function)) { |
| 1101 // TODO(fschneider): Print unoptimized code along with the optimized code. | 1101 // TODO(fschneider): Print unoptimized code along with the optimized code. |
| 1102 ISL_Print("*** BEGIN CODE\n"); | 1102 THR_Print("*** BEGIN CODE\n"); |
| 1103 DisassembleCode(function, true); | 1103 DisassembleCode(function, true); |
| 1104 ISL_Print("*** END CODE\n"); | 1104 THR_Print("*** END CODE\n"); |
| 1105 } | 1105 } |
| 1106 #if defined(DEBUG) | 1106 #if defined(DEBUG) |
| 1107 CheckInliningIntervals(function); | 1107 CheckInliningIntervals(function); |
| 1108 #endif | 1108 #endif |
| 1109 return Error::null(); | 1109 return Error::null(); |
| 1110 } else { | 1110 } else { |
| 1111 Thread* const thread = Thread::Current(); | 1111 Thread* const thread = Thread::Current(); |
| 1112 Isolate* const isolate = thread->isolate(); | 1112 Isolate* const isolate = thread->isolate(); |
| 1113 StackZone stack_zone(thread); | 1113 StackZone stack_zone(thread); |
| 1114 Error& error = Error::Handle(); | 1114 Error& error = Error::Handle(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1163 return error.raw(); | 1163 return error.raw(); |
| 1164 } | 1164 } |
| 1165 // Since CompileFunctionHelper replaces the current code, re-attach the | 1165 // Since CompileFunctionHelper replaces the current code, re-attach the |
| 1166 // the original code if the function was already compiled. | 1166 // the original code if the function was already compiled. |
| 1167 if (!original_code.IsNull() && | 1167 if (!original_code.IsNull() && |
| 1168 (original_code.raw() != function.CurrentCode())) { | 1168 (original_code.raw() != function.CurrentCode())) { |
| 1169 function.AttachCode(original_code); | 1169 function.AttachCode(original_code); |
| 1170 } | 1170 } |
| 1171 ASSERT(function.unoptimized_code() != Object::null()); | 1171 ASSERT(function.unoptimized_code() != Object::null()); |
| 1172 if (FLAG_trace_compiler) { | 1172 if (FLAG_trace_compiler) { |
| 1173 ISL_Print("Ensure unoptimized code for %s\n", function.ToCString()); | 1173 THR_Print("Ensure unoptimized code for %s\n", function.ToCString()); |
| 1174 } | 1174 } |
| 1175 return Error::null(); | 1175 return Error::null(); |
| 1176 } | 1176 } |
| 1177 | 1177 |
| 1178 | 1178 |
| 1179 RawError* Compiler::CompileOptimizedFunction(Thread* thread, | 1179 RawError* Compiler::CompileOptimizedFunction(Thread* thread, |
| 1180 const Function& function, | 1180 const Function& function, |
| 1181 intptr_t osr_id) { | 1181 intptr_t osr_id) { |
| 1182 VMTagScope tagScope(thread, VMTag::kCompileOptimizedTagId); | 1182 VMTagScope tagScope(thread, VMTag::kCompileOptimizedTagId); |
| 1183 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, | 1183 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1357 return Object::null(); | 1357 return Object::null(); |
| 1358 } | 1358 } |
| 1359 | 1359 |
| 1360 | 1360 |
| 1361 | 1361 |
| 1362 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { | 1362 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { |
| 1363 LongJumpScope jump; | 1363 LongJumpScope jump; |
| 1364 if (setjmp(*jump.Set()) == 0) { | 1364 if (setjmp(*jump.Set()) == 0) { |
| 1365 Thread* const thread = Thread::Current(); | 1365 Thread* const thread = Thread::Current(); |
| 1366 if (FLAG_trace_compiler) { | 1366 if (FLAG_trace_compiler) { |
| 1367 ISL_Print("compiling expression: "); | 1367 THR_Print("compiling expression: "); |
| 1368 AstPrinter::PrintNode(fragment); | 1368 AstPrinter::PrintNode(fragment); |
| 1369 } | 1369 } |
| 1370 | 1370 |
| 1371 // Create a dummy function object for the code generator. | 1371 // Create a dummy function object for the code generator. |
| 1372 // The function needs to be associated with a named Class: the interface | 1372 // The function needs to be associated with a named Class: the interface |
| 1373 // Function fits the bill. | 1373 // Function fits the bill. |
| 1374 const char* kEvalConst = "eval_const"; | 1374 const char* kEvalConst = "eval_const"; |
| 1375 const Function& func = Function::ZoneHandle(Function::New( | 1375 const Function& func = Function::ZoneHandle(Function::New( |
| 1376 String::Handle(Symbols::New(kEvalConst)), | 1376 String::Handle(Symbols::New(kEvalConst)), |
| 1377 RawFunction::kRegularFunction, | 1377 RawFunction::kRegularFunction, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1416 const Object& result = | 1416 const Object& result = |
| 1417 PassiveObject::Handle(isolate->object_store()->sticky_error()); | 1417 PassiveObject::Handle(isolate->object_store()->sticky_error()); |
| 1418 isolate->object_store()->clear_sticky_error(); | 1418 isolate->object_store()->clear_sticky_error(); |
| 1419 return result.raw(); | 1419 return result.raw(); |
| 1420 } | 1420 } |
| 1421 UNREACHABLE(); | 1421 UNREACHABLE(); |
| 1422 return Object::null(); | 1422 return Object::null(); |
| 1423 } | 1423 } |
| 1424 | 1424 |
| 1425 } // namespace dart | 1425 } // namespace dart |
| OLD | NEW |