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" |
11 #include "vm/branch_optimizer.h" | 11 #include "vm/branch_optimizer.h" |
12 #include "vm/cha.h" | 12 #include "vm/cha.h" |
13 #include "vm/code_generator.h" | 13 #include "vm/code_generator.h" |
14 #include "vm/code_patcher.h" | 14 #include "vm/code_patcher.h" |
15 #include "vm/constant_propagator.h" | 15 #include "vm/constant_propagator.h" |
16 #include "vm/dart_entry.h" | 16 #include "vm/dart_entry.h" |
17 #include "vm/debugger.h" | 17 #include "vm/debugger.h" |
18 #include "vm/deopt_instructions.h" | 18 #include "vm/deopt_instructions.h" |
| 19 #include "vm/kernel.h" |
| 20 #include "vm/kernel_to_il.h" |
19 #include "vm/disassembler.h" | 21 #include "vm/disassembler.h" |
20 #include "vm/exceptions.h" | 22 #include "vm/exceptions.h" |
21 #include "vm/flags.h" | 23 #include "vm/flags.h" |
22 #include "vm/flow_graph.h" | 24 #include "vm/flow_graph.h" |
23 #include "vm/flow_graph_allocator.h" | 25 #include "vm/flow_graph_allocator.h" |
24 #include "vm/flow_graph_builder.h" | 26 #include "vm/flow_graph_builder.h" |
25 #include "vm/flow_graph_compiler.h" | 27 #include "vm/flow_graph_compiler.h" |
26 #include "vm/flow_graph_inliner.h" | 28 #include "vm/flow_graph_inliner.h" |
27 #include "vm/flow_graph_range_analysis.h" | 29 #include "vm/flow_graph_range_analysis.h" |
28 #include "vm/flow_graph_type_propagator.h" | 30 #include "vm/flow_graph_type_propagator.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 DEFINE_FLAG(bool, verify_compiler, false, | 79 DEFINE_FLAG(bool, verify_compiler, false, |
78 "Enable compiler verification assertions"); | 80 "Enable compiler verification assertions"); |
79 | 81 |
80 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size); | 82 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size); |
81 DECLARE_FLAG(bool, trace_failed_optimization_attempts); | 83 DECLARE_FLAG(bool, trace_failed_optimization_attempts); |
82 DECLARE_FLAG(bool, trace_irregexp); | 84 DECLARE_FLAG(bool, trace_irregexp); |
83 | 85 |
84 | 86 |
85 #ifndef DART_PRECOMPILED_RUNTIME | 87 #ifndef DART_PRECOMPILED_RUNTIME |
86 | 88 |
87 void DartCompilationPipeline::ParseFunction(ParsedFunction* parsed_function) { | 89 |
88 Parser::ParseFunction(parsed_function); | 90 bool UseKernelFrontEndFor(ParsedFunction* parsed_function) { |
89 parsed_function->AllocateVariables(); | 91 const Function& function = parsed_function->function(); |
| 92 return (function.kernel_function() != NULL) || |
| 93 (function.kind() == RawFunction::kNoSuchMethodDispatcher) || |
| 94 (function.kind() == RawFunction::kInvokeFieldDispatcher); |
90 } | 95 } |
91 | 96 |
92 | 97 |
| 98 void DartCompilationPipeline::ParseFunction(ParsedFunction* parsed_function) { |
| 99 if (!UseKernelFrontEndFor(parsed_function)) { |
| 100 Parser::ParseFunction(parsed_function); |
| 101 parsed_function->AllocateVariables(); |
| 102 } |
| 103 } |
| 104 |
| 105 |
93 FlowGraph* DartCompilationPipeline::BuildFlowGraph( | 106 FlowGraph* DartCompilationPipeline::BuildFlowGraph( |
94 Zone* zone, | 107 Zone* zone, |
95 ParsedFunction* parsed_function, | 108 ParsedFunction* parsed_function, |
96 const ZoneGrowableArray<const ICData*>& ic_data_array, | 109 const ZoneGrowableArray<const ICData*>& ic_data_array, |
97 intptr_t osr_id) { | 110 intptr_t osr_id) { |
98 // Build the flow graph. | 111 if (UseKernelFrontEndFor(parsed_function)) { |
| 112 kernel::TreeNode* node = static_cast<kernel::TreeNode*>( |
| 113 parsed_function->function().kernel_function()); |
| 114 kernel::FlowGraphBuilder builder( |
| 115 node, parsed_function, ic_data_array, NULL, osr_id); |
| 116 FlowGraph* graph = builder.BuildGraph(); |
| 117 ASSERT(graph != NULL); |
| 118 return graph; |
| 119 } |
99 FlowGraphBuilder builder(*parsed_function, | 120 FlowGraphBuilder builder(*parsed_function, |
100 ic_data_array, | 121 ic_data_array, |
101 NULL, // NULL = not inlining. | 122 NULL, // NULL = not inlining. |
102 osr_id); | 123 osr_id); |
103 | 124 |
104 return builder.BuildGraph(); | 125 return builder.BuildGraph(); |
105 } | 126 } |
106 | 127 |
107 | 128 |
108 void DartCompilationPipeline::FinalizeCompilation(FlowGraph* flow_graph) { } | 129 void DartCompilationPipeline::FinalizeCompilation(FlowGraph* flow_graph) { } |
(...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1021 } | 1042 } |
1022 | 1043 |
1023 if (flow_graph->Canonicalize()) { | 1044 if (flow_graph->Canonicalize()) { |
1024 flow_graph->Canonicalize(); | 1045 flow_graph->Canonicalize(); |
1025 } | 1046 } |
1026 | 1047 |
1027 // Attempt to sink allocations of temporary non-escaping objects to | 1048 // Attempt to sink allocations of temporary non-escaping objects to |
1028 // the deoptimization path. | 1049 // the deoptimization path. |
1029 AllocationSinking* sinking = NULL; | 1050 AllocationSinking* sinking = NULL; |
1030 if (FLAG_allocation_sinking && | 1051 if (FLAG_allocation_sinking && |
1031 (flow_graph->graph_entry()->SuccessorCount() == 1)) { | 1052 (flow_graph->graph_entry()->SuccessorCount() == 1)) { |
1032 NOT_IN_PRODUCT(TimelineDurationScope tds2( | 1053 NOT_IN_PRODUCT(TimelineDurationScope tds2( |
1033 thread(), compiler_timeline, "AllocationSinking::Optimize")); | 1054 thread(), compiler_timeline, "AllocationSinking::Optimize")); |
1034 // TODO(fschneider): Support allocation sinking with try-catch. | 1055 // TODO(fschneider): Support allocation sinking with try-catch. |
1035 sinking = new AllocationSinking(flow_graph); | 1056 sinking = new AllocationSinking(flow_graph); |
1036 sinking->Optimize(); | 1057 sinking->Optimize(); |
1037 } | 1058 } |
1038 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 1059 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
1039 | 1060 |
1040 DeadCodeElimination::EliminateDeadPhis(flow_graph); | 1061 DeadCodeElimination::EliminateDeadPhis(flow_graph); |
1041 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 1062 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1697 NOT_IN_PRODUCT( | 1718 NOT_IN_PRODUCT( |
1698 VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId); | 1719 VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId); |
1699 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), | 1720 TimelineDurationScope tds(thread, Timeline::GetCompilerStream(), |
1700 "CompileStaticInitializer"); | 1721 "CompileStaticInitializer"); |
1701 if (tds.enabled()) { | 1722 if (tds.enabled()) { |
1702 tds.SetNumArguments(1); | 1723 tds.SetNumArguments(1); |
1703 tds.CopyArgument(0, "field", field.ToCString()); | 1724 tds.CopyArgument(0, "field", field.ToCString()); |
1704 } | 1725 } |
1705 ) | 1726 ) |
1706 | 1727 |
1707 StackZone zone(thread); | 1728 StackZone stack_zone(thread); |
1708 ParsedFunction* parsed_function = | 1729 Zone* zone = stack_zone.GetZone(); |
1709 Parser::ParseStaticFieldInitializer(field); | 1730 ParsedFunction* parsed_function; |
1710 | 1731 |
1711 parsed_function->AllocateVariables(); | 1732 // Create a one-time-use function to evaluate the initializer and invoke |
| 1733 // it immediately. |
| 1734 if (field.kernel_field() != NULL) { |
| 1735 // kImplicitStaticFinalGetter is used for both implicit static getters |
| 1736 // and static initializers. The Kernel graph builder will tell the |
| 1737 // difference by pattern matching on the name. |
| 1738 const String& name = String::Handle(zone, |
| 1739 Symbols::FromConcat(thread, |
| 1740 Symbols::InitPrefix(), String::Handle(zone, field.name()))); |
| 1741 const Script& script = Script::Handle(zone, field.Script()); |
| 1742 Object& owner = Object::Handle(zone, field.Owner()); |
| 1743 owner = PatchClass::New(Class::Cast(owner), script); |
| 1744 const Function& function = Function::ZoneHandle(zone, |
| 1745 Function::New(name, |
| 1746 RawFunction::kImplicitStaticFinalGetter, |
| 1747 true, // is_static |
| 1748 false, // is_const |
| 1749 false, // is_abstract |
| 1750 false, // is_external |
| 1751 false, // is_native |
| 1752 owner, |
| 1753 TokenPosition::kNoSource)); |
| 1754 function.set_kernel_function(field.kernel_field()); |
| 1755 function.set_result_type(AbstractType::Handle(zone, field.type())); |
| 1756 function.set_is_reflectable(false); |
| 1757 function.set_is_debuggable(false); |
| 1758 function.set_is_inlinable(false); |
| 1759 parsed_function = new(zone) ParsedFunction(thread, function); |
| 1760 } else { |
| 1761 parsed_function = Parser::ParseStaticFieldInitializer(field); |
| 1762 parsed_function->AllocateVariables(); |
| 1763 } |
| 1764 |
1712 // Non-optimized code generator. | 1765 // Non-optimized code generator. |
1713 DartCompilationPipeline pipeline; | 1766 DartCompilationPipeline pipeline; |
1714 CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId); | 1767 CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId); |
1715 helper.Compile(&pipeline); | 1768 helper.Compile(&pipeline); |
1716 initializer = parsed_function->function().raw(); | 1769 initializer = parsed_function->function().raw(); |
1717 Code::Handle(initializer.unoptimized_code()).set_var_descriptors( | 1770 Code::Handle(initializer.unoptimized_code()).set_var_descriptors( |
1718 Object::empty_var_descriptors()); | 1771 Object::empty_var_descriptors()); |
1719 } | 1772 } |
1720 // Invoke the function to evaluate the expression. | 1773 // Invoke the function to evaluate the expression. |
1721 return DartEntry::InvokeFunction(initializer, Object::empty_array()); | 1774 return DartEntry::InvokeFunction(initializer, Object::empty_array()); |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2158 } | 2211 } |
2159 if (start_task) { | 2212 if (start_task) { |
2160 Dart::thread_pool()->Run(isolate->background_compiler()); | 2213 Dart::thread_pool()->Run(isolate->background_compiler()); |
2161 } | 2214 } |
2162 } | 2215 } |
2163 | 2216 |
2164 | 2217 |
2165 #else // DART_PRECOMPILED_RUNTIME | 2218 #else // DART_PRECOMPILED_RUNTIME |
2166 | 2219 |
2167 | 2220 |
| 2221 bool UseKernelFrontEndFor(ParsedFunction* parsed_function) { |
| 2222 UNREACHABLE(); |
| 2223 return false; |
| 2224 } |
| 2225 |
| 2226 |
2168 CompilationPipeline* CompilationPipeline::New(Zone* zone, | 2227 CompilationPipeline* CompilationPipeline::New(Zone* zone, |
2169 const Function& function) { | 2228 const Function& function) { |
2170 UNREACHABLE(); | 2229 UNREACHABLE(); |
2171 return NULL; | 2230 return NULL; |
2172 } | 2231 } |
2173 | 2232 |
2174 | 2233 |
2175 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) { | 2234 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) { |
2176 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); | 2235 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
2177 FATAL3("Precompilation missed function %s (%" Pd ", %s)\n", | 2236 FATAL3("Precompilation missed function %s (%" Pd ", %s)\n", |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2307 | 2366 |
2308 | 2367 |
2309 bool BackgroundCompiler::IsDisabled() { | 2368 bool BackgroundCompiler::IsDisabled() { |
2310 UNREACHABLE(); | 2369 UNREACHABLE(); |
2311 return true; | 2370 return true; |
2312 } | 2371 } |
2313 | 2372 |
2314 #endif // DART_PRECOMPILED_RUNTIME | 2373 #endif // DART_PRECOMPILED_RUNTIME |
2315 | 2374 |
2316 } // namespace dart | 2375 } // namespace dart |
OLD | NEW |