| 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 DEFINE_FLAG(bool, range_analysis, true, "Enable range analysis"); | 62 DEFINE_FLAG(bool, range_analysis, true, "Enable range analysis"); |
| 63 DEFINE_FLAG(bool, reorder_basic_blocks, true, "Enable basic-block reordering."); | 63 DEFINE_FLAG(bool, reorder_basic_blocks, true, "Enable basic-block reordering."); |
| 64 DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations."); | 64 DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations."); |
| 65 DEFINE_FLAG(bool, trace_optimizing_compiler, false, | 65 DEFINE_FLAG(bool, trace_optimizing_compiler, false, |
| 66 "Trace only optimizing compiler operations."); | 66 "Trace only optimizing compiler operations."); |
| 67 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler."); | 67 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler."); |
| 68 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining"); | 68 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining"); |
| 69 DEFINE_FLAG(bool, verify_compiler, false, | 69 DEFINE_FLAG(bool, verify_compiler, false, |
| 70 "Enable compiler verification assertions"); | 70 "Enable compiler verification assertions"); |
| 71 | 71 |
| 72 DECLARE_FLAG(bool, background_compilation); |
| 72 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size); | 73 DECLARE_FLAG(bool, huge_method_cutoff_in_code_size); |
| 74 DECLARE_FLAG(bool, load_deferred_eagerly); |
| 73 DECLARE_FLAG(bool, trace_failed_optimization_attempts); | 75 DECLARE_FLAG(bool, trace_failed_optimization_attempts); |
| 74 DECLARE_FLAG(bool, trace_irregexp); | 76 DECLARE_FLAG(bool, trace_irregexp); |
| 77 DECLARE_FLAG(bool, precompilation); |
| 75 | 78 |
| 76 | 79 |
| 77 #ifndef DART_PRECOMPILED_RUNTIME | 80 #ifndef DART_PRECOMPILED_RUNTIME |
| 78 | 81 |
| 79 void DartCompilationPipeline::ParseFunction(ParsedFunction* parsed_function) { | 82 void DartCompilationPipeline::ParseFunction(ParsedFunction* parsed_function) { |
| 80 Parser::ParseFunction(parsed_function); | 83 Parser::ParseFunction(parsed_function); |
| 81 parsed_function->AllocateVariables(); | 84 parsed_function->AllocateVariables(); |
| 82 } | 85 } |
| 83 | 86 |
| 84 | 87 |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 const uint32_t prefix_invalidation_gen_at_start_; | 413 const uint32_t prefix_invalidation_gen_at_start_; |
| 411 | 414 |
| 412 DISALLOW_COPY_AND_ASSIGN(CompileParsedFunctionHelper); | 415 DISALLOW_COPY_AND_ASSIGN(CompileParsedFunctionHelper); |
| 413 }; | 416 }; |
| 414 | 417 |
| 415 | 418 |
| 416 void CompileParsedFunctionHelper::FinalizeCompilation( | 419 void CompileParsedFunctionHelper::FinalizeCompilation( |
| 417 Assembler* assembler, | 420 Assembler* assembler, |
| 418 FlowGraphCompiler* graph_compiler, | 421 FlowGraphCompiler* graph_compiler, |
| 419 FlowGraph* flow_graph) { | 422 FlowGraph* flow_graph) { |
| 420 ASSERT(!FLAG_precompiled_mode); | 423 ASSERT(!FLAG_precompilation); |
| 421 const Function& function = parsed_function()->function(); | 424 const Function& function = parsed_function()->function(); |
| 422 Zone* const zone = thread()->zone(); | 425 Zone* const zone = thread()->zone(); |
| 423 | 426 |
| 424 CSTAT_TIMER_SCOPE(thread(), codefinalizer_timer); | 427 CSTAT_TIMER_SCOPE(thread(), codefinalizer_timer); |
| 425 // CreateDeoptInfo uses the object pool and needs to be done before | 428 // CreateDeoptInfo uses the object pool and needs to be done before |
| 426 // FinalizeCode. | 429 // FinalizeCode. |
| 427 const Array& deopt_info_array = | 430 const Array& deopt_info_array = |
| 428 Array::Handle(zone, graph_compiler->CreateDeoptInfo(assembler)); | 431 Array::Handle(zone, graph_compiler->CreateDeoptInfo(assembler)); |
| 429 INC_STAT(thread(), total_code_size, | 432 INC_STAT(thread(), total_code_size, |
| 430 deopt_info_array.Length() * sizeof(uword)); | 433 deopt_info_array.Length() * sizeof(uword)); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 546 (*prefixes)[i]->RegisterDependentCode(code); | 549 (*prefixes)[i]->RegisterDependentCode(code); |
| 547 } | 550 } |
| 548 } | 551 } |
| 549 } | 552 } |
| 550 | 553 |
| 551 | 554 |
| 552 // Return false if bailed out. | 555 // Return false if bailed out. |
| 553 // If optimized_result_code is not NULL then it is caller's responsibility | 556 // If optimized_result_code is not NULL then it is caller's responsibility |
| 554 // to install code. | 557 // to install code. |
| 555 bool CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) { | 558 bool CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) { |
| 556 ASSERT(!FLAG_precompiled_mode); | 559 ASSERT(!FLAG_precompilation); |
| 557 const Function& function = parsed_function()->function(); | 560 const Function& function = parsed_function()->function(); |
| 558 if (optimized() && !function.IsOptimizable()) { | 561 if (optimized() && !function.IsOptimizable()) { |
| 559 return false; | 562 return false; |
| 560 } | 563 } |
| 561 bool is_compiled = false; | 564 bool is_compiled = false; |
| 562 Zone* const zone = thread()->zone(); | 565 Zone* const zone = thread()->zone(); |
| 563 NOT_IN_PRODUCT( | 566 NOT_IN_PRODUCT( |
| 564 TimelineStream* compiler_timeline = isolate()->GetCompilerStream()); | 567 TimelineStream* compiler_timeline = isolate()->GetCompilerStream()); |
| 565 CSTAT_TIMER_SCOPE(thread(), codegen_timer); | 568 CSTAT_TIMER_SCOPE(thread(), codegen_timer); |
| 566 HANDLESCOPE(thread()); | 569 HANDLESCOPE(thread()); |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1076 ASSERT(inlined_functions[inlined_functions.length() - 1]->raw() == | 1079 ASSERT(inlined_functions[inlined_functions.length() - 1]->raw() == |
| 1077 function.raw()); | 1080 function.raw()); |
| 1078 } | 1081 } |
| 1079 } | 1082 } |
| 1080 ) | 1083 ) |
| 1081 | 1084 |
| 1082 static RawError* CompileFunctionHelper(CompilationPipeline* pipeline, | 1085 static RawError* CompileFunctionHelper(CompilationPipeline* pipeline, |
| 1083 const Function& function, | 1086 const Function& function, |
| 1084 bool optimized, | 1087 bool optimized, |
| 1085 intptr_t osr_id) { | 1088 intptr_t osr_id) { |
| 1086 ASSERT(!FLAG_precompiled_mode); | 1089 ASSERT(!FLAG_precompilation); |
| 1087 LongJumpScope jump; | 1090 LongJumpScope jump; |
| 1088 if (setjmp(*jump.Set()) == 0) { | 1091 if (setjmp(*jump.Set()) == 0) { |
| 1089 Thread* const thread = Thread::Current(); | 1092 Thread* const thread = Thread::Current(); |
| 1090 Isolate* const isolate = thread->isolate(); | 1093 Isolate* const isolate = thread->isolate(); |
| 1091 StackZone stack_zone(thread); | 1094 StackZone stack_zone(thread); |
| 1092 Zone* const zone = stack_zone.GetZone(); | 1095 Zone* const zone = stack_zone.GetZone(); |
| 1093 const bool trace_compiler = | 1096 const bool trace_compiler = |
| 1094 FLAG_trace_compiler || | 1097 FLAG_trace_compiler || |
| 1095 (FLAG_trace_optimizing_compiler && optimized); | 1098 (FLAG_trace_optimizing_compiler && optimized); |
| 1096 Timer per_compile_timer(trace_compiler, "Compilation time"); | 1099 Timer per_compile_timer(trace_compiler, "Compilation time"); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1190 return error.raw(); | 1193 return error.raw(); |
| 1191 } | 1194 } |
| 1192 UNREACHABLE(); | 1195 UNREACHABLE(); |
| 1193 return Error::null(); | 1196 return Error::null(); |
| 1194 } | 1197 } |
| 1195 | 1198 |
| 1196 | 1199 |
| 1197 RawError* Compiler::CompileFunction(Thread* thread, | 1200 RawError* Compiler::CompileFunction(Thread* thread, |
| 1198 const Function& function) { | 1201 const Function& function) { |
| 1199 #ifdef DART_PRECOMPILER | 1202 #ifdef DART_PRECOMPILER |
| 1200 if (FLAG_precompiled_mode) { | 1203 if (FLAG_precompilation) { |
| 1201 return Precompiler::CompileFunction(thread, function); | 1204 return Precompiler::CompileFunction(thread, function); |
| 1202 } | 1205 } |
| 1203 #endif | 1206 #endif |
| 1204 Isolate* isolate = thread->isolate(); | 1207 Isolate* isolate = thread->isolate(); |
| 1205 VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId); | 1208 VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId); |
| 1206 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "Function", function); | 1209 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "Function", function); |
| 1207 | 1210 |
| 1208 if (!isolate->compilation_allowed()) { | 1211 if (!isolate->compilation_allowed()) { |
| 1209 FATAL3("Precompilation missed function %s (%s, %s)\n", | 1212 FATAL3("Precompilation missed function %s (%s, %s)\n", |
| 1210 function.ToLibNamePrefixedQualifiedCString(), | 1213 function.ToLibNamePrefixedQualifiedCString(), |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1350 func.ClearICDataArray(); | 1353 func.ClearICDataArray(); |
| 1351 func.ClearCode(); | 1354 func.ClearCode(); |
| 1352 } | 1355 } |
| 1353 } | 1356 } |
| 1354 return error.raw(); | 1357 return error.raw(); |
| 1355 } | 1358 } |
| 1356 | 1359 |
| 1357 | 1360 |
| 1358 RawObject* Compiler::EvaluateStaticInitializer(const Field& field) { | 1361 RawObject* Compiler::EvaluateStaticInitializer(const Field& field) { |
| 1359 #ifdef DART_PRECOMPILER | 1362 #ifdef DART_PRECOMPILER |
| 1360 if (FLAG_precompiled_mode) { | 1363 if (FLAG_precompilation) { |
| 1361 return Precompiler::EvaluateStaticInitializer(field); | 1364 return Precompiler::EvaluateStaticInitializer(field); |
| 1362 } | 1365 } |
| 1363 #endif | 1366 #endif |
| 1364 ASSERT(field.is_static()); | 1367 ASSERT(field.is_static()); |
| 1365 // The VM sets the field's value to transiton_sentinel prior to | 1368 // The VM sets the field's value to transiton_sentinel prior to |
| 1366 // evaluating the initializer value. | 1369 // evaluating the initializer value. |
| 1367 ASSERT(field.StaticValue() == Object::transition_sentinel().raw()); | 1370 ASSERT(field.StaticValue() == Object::transition_sentinel().raw()); |
| 1368 LongJumpScope jump; | 1371 LongJumpScope jump; |
| 1369 if (setjmp(*jump.Set()) == 0) { | 1372 if (setjmp(*jump.Set()) == 0) { |
| 1370 // Under lazy compilation initializer has not yet been created, so create | 1373 // Under lazy compilation initializer has not yet been created, so create |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1394 return error.raw(); | 1397 return error.raw(); |
| 1395 } | 1398 } |
| 1396 UNREACHABLE(); | 1399 UNREACHABLE(); |
| 1397 return Object::null(); | 1400 return Object::null(); |
| 1398 } | 1401 } |
| 1399 | 1402 |
| 1400 | 1403 |
| 1401 | 1404 |
| 1402 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { | 1405 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { |
| 1403 #ifdef DART_PRECOMPILER | 1406 #ifdef DART_PRECOMPILER |
| 1404 if (FLAG_precompiled_mode) { | 1407 if (FLAG_precompilation) { |
| 1405 return Precompiler::ExecuteOnce(fragment); | 1408 return Precompiler::ExecuteOnce(fragment); |
| 1406 } | 1409 } |
| 1407 #endif | 1410 #endif |
| 1408 LongJumpScope jump; | 1411 LongJumpScope jump; |
| 1409 if (setjmp(*jump.Set()) == 0) { | 1412 if (setjmp(*jump.Set()) == 0) { |
| 1410 Thread* const thread = Thread::Current(); | 1413 Thread* const thread = Thread::Current(); |
| 1411 | 1414 |
| 1412 // Don't allow message interrupts while executing constant | 1415 // Don't allow message interrupts while executing constant |
| 1413 // expressions. They can cause bogus recursive compilation. | 1416 // expressions. They can cause bogus recursive compilation. |
| 1414 NoOOBMessageScope no_msg_scope(thread); | 1417 NoOOBMessageScope no_msg_scope(thread); |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1834 } | 1837 } |
| 1835 | 1838 |
| 1836 | 1839 |
| 1837 void BackgroundCompiler::EnsureInit(Thread* thread) { | 1840 void BackgroundCompiler::EnsureInit(Thread* thread) { |
| 1838 UNREACHABLE(); | 1841 UNREACHABLE(); |
| 1839 } | 1842 } |
| 1840 | 1843 |
| 1841 #endif // DART_PRECOMPILED_RUNTIME | 1844 #endif // DART_PRECOMPILED_RUNTIME |
| 1842 | 1845 |
| 1843 } // namespace dart | 1846 } // namespace dart |
| OLD | NEW |