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 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 | 371 |
372 class CompileParsedFunctionHelper : public ValueObject { | 372 class CompileParsedFunctionHelper : public ValueObject { |
373 public: | 373 public: |
374 CompileParsedFunctionHelper(ParsedFunction* parsed_function, | 374 CompileParsedFunctionHelper(ParsedFunction* parsed_function, |
375 bool optimized, | 375 bool optimized, |
376 intptr_t osr_id) | 376 intptr_t osr_id) |
377 : parsed_function_(parsed_function), | 377 : parsed_function_(parsed_function), |
378 optimized_(optimized), | 378 optimized_(optimized), |
379 osr_id_(osr_id), | 379 osr_id_(osr_id), |
380 thread_(Thread::Current()), | 380 thread_(Thread::Current()), |
381 cha_invalidation_gen_at_start_(isolate()->cha_invalidation_gen()), | |
382 field_invalidation_gen_at_start_(isolate()->field_invalidation_gen()), | 381 field_invalidation_gen_at_start_(isolate()->field_invalidation_gen()), |
383 prefix_invalidation_gen_at_start_( | 382 loading_invalidation_gen_at_start_( |
384 isolate()->prefix_invalidation_gen()) { | 383 isolate()->loading_invalidation_gen()) { |
385 } | 384 } |
386 | 385 |
387 bool Compile(CompilationPipeline* pipeline); | 386 bool Compile(CompilationPipeline* pipeline); |
388 uint32_t prefix_invalidation_gen_at_start() const { | |
389 return prefix_invalidation_gen_at_start_; | |
390 } | |
391 | 387 |
392 private: | 388 private: |
393 ParsedFunction* parsed_function() const { return parsed_function_; } | 389 ParsedFunction* parsed_function() const { return parsed_function_; } |
394 bool optimized() const { return optimized_; } | 390 bool optimized() const { return optimized_; } |
395 intptr_t osr_id() const { return osr_id_; } | 391 intptr_t osr_id() const { return osr_id_; } |
396 Thread* thread() const { return thread_; } | 392 Thread* thread() const { return thread_; } |
397 Isolate* isolate() const { return thread_->isolate(); } | 393 Isolate* isolate() const { return thread_->isolate(); } |
398 uint32_t cha_invalidation_gen_at_start() const { | 394 intptr_t field_invalidation_gen_at_start() const { |
399 return cha_invalidation_gen_at_start_; | 395 return field_invalidation_gen_at_start_; |
400 } | 396 } |
401 uint32_t field_invalidation_gen_at_start() const { | 397 intptr_t loading_invalidation_gen_at_start() const { |
402 return field_invalidation_gen_at_start_; | 398 return loading_invalidation_gen_at_start_; |
403 } | 399 } |
404 void FinalizeCompilation(Assembler* assembler, | 400 void FinalizeCompilation(Assembler* assembler, |
405 FlowGraphCompiler* graph_compiler, | 401 FlowGraphCompiler* graph_compiler, |
406 FlowGraph* flow_graph); | 402 FlowGraph* flow_graph); |
407 | 403 |
408 ParsedFunction* parsed_function_; | 404 ParsedFunction* parsed_function_; |
409 const bool optimized_; | 405 const bool optimized_; |
410 const intptr_t osr_id_; | 406 const intptr_t osr_id_; |
411 Thread* const thread_; | 407 Thread* const thread_; |
412 const uint32_t cha_invalidation_gen_at_start_; | 408 const intptr_t field_invalidation_gen_at_start_; |
413 const uint32_t field_invalidation_gen_at_start_; | 409 const intptr_t loading_invalidation_gen_at_start_; |
414 const uint32_t prefix_invalidation_gen_at_start_; | |
415 | 410 |
416 DISALLOW_COPY_AND_ASSIGN(CompileParsedFunctionHelper); | 411 DISALLOW_COPY_AND_ASSIGN(CompileParsedFunctionHelper); |
417 }; | 412 }; |
418 | 413 |
419 | 414 |
420 void CompileParsedFunctionHelper::FinalizeCompilation( | 415 void CompileParsedFunctionHelper::FinalizeCompilation( |
421 Assembler* assembler, | 416 Assembler* assembler, |
422 FlowGraphCompiler* graph_compiler, | 417 FlowGraphCompiler* graph_compiler, |
423 FlowGraph* flow_graph) { | 418 FlowGraph* flow_graph) { |
424 ASSERT(!FLAG_precompiled_mode); | 419 ASSERT(!FLAG_precompiled_mode); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 const bool is_osr = osr_id() != Compiler::kNoOSRDeoptId; | 489 const bool is_osr = osr_id() != Compiler::kNoOSRDeoptId; |
495 function.InstallOptimizedCode(code, is_osr); | 490 function.InstallOptimizedCode(code, is_osr); |
496 code_was_installed = true; | 491 code_was_installed = true; |
497 } else { | 492 } else { |
498 // Background compilation. | 493 // Background compilation. |
499 // Before installing code check generation counts if the code may | 494 // Before installing code check generation counts if the code may |
500 // have become invalid. | 495 // have become invalid. |
501 const bool trace_compiler = | 496 const bool trace_compiler = |
502 FLAG_trace_compiler || FLAG_trace_optimizing_compiler; | 497 FLAG_trace_compiler || FLAG_trace_optimizing_compiler; |
503 bool code_is_valid = true; | 498 bool code_is_valid = true; |
504 if (!thread()->cha()->leaf_classes().is_empty()) { | |
505 if (cha_invalidation_gen_at_start() != | |
506 isolate()->cha_invalidation_gen()) { | |
507 code_is_valid = false; | |
508 if (trace_compiler) { | |
509 THR_Print("--> FAIL: CHA invalidation."); | |
510 } | |
511 } | |
512 } | |
513 if (!flow_graph->parsed_function().guarded_fields()->is_empty()) { | 499 if (!flow_graph->parsed_function().guarded_fields()->is_empty()) { |
514 if (field_invalidation_gen_at_start() != | 500 if (field_invalidation_gen_at_start() != |
515 isolate()->field_invalidation_gen()) { | 501 isolate()->field_invalidation_gen()) { |
516 code_is_valid = false; | 502 code_is_valid = false; |
517 if (trace_compiler) { | 503 if (trace_compiler) { |
518 THR_Print("--> FAIL: Field invalidation."); | 504 THR_Print("--> FAIL: Field invalidation."); |
519 } | 505 } |
520 } | 506 } |
521 } | 507 } |
522 if (parsed_function()->HasDeferredPrefixes()) { | 508 if (loading_invalidation_gen_at_start() != |
523 if (prefix_invalidation_gen_at_start() != | 509 isolate()->loading_invalidation_gen()) { |
524 isolate()->prefix_invalidation_gen()) { | 510 code_is_valid = false; |
525 code_is_valid = false; | 511 if (trace_compiler) { |
526 if (trace_compiler) { | 512 THR_Print("--> FAIL: Loading invalidation."); |
527 THR_Print("--> FAIL: Prefix invalidation."); | |
528 } | |
529 } | 513 } |
530 } | 514 } |
531 if (code_is_valid) { | 515 if (code_is_valid) { |
532 const bool is_osr = osr_id() != Compiler::kNoOSRDeoptId; | 516 const bool is_osr = osr_id() != Compiler::kNoOSRDeoptId; |
533 ASSERT(!is_osr); // OSR is not compiled in background. | 517 ASSERT(!is_osr); // OSR is not compiled in background. |
534 function.InstallOptimizedCode(code, is_osr); | 518 function.InstallOptimizedCode(code, is_osr); |
535 code_was_installed = true; | 519 code_was_installed = true; |
536 } | 520 } |
537 if (function.usage_counter() < 0) { | 521 if (function.usage_counter() < 0) { |
538 // Reset to 0 so that it can be recompiled if needed. | 522 // Reset to 0 so that it can be recompiled if needed. |
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1147 (optimized ? "optimized " : ""), | 1131 (optimized ? "optimized " : ""), |
1148 (Compiler::IsBackgroundCompilation() ? "(background)" : ""), | 1132 (Compiler::IsBackgroundCompilation() ? "(background)" : ""), |
1149 function.ToFullyQualifiedCString(), | 1133 function.ToFullyQualifiedCString(), |
1150 function.token_pos().ToCString(), | 1134 function.token_pos().ToCString(), |
1151 token_size); | 1135 token_size); |
1152 } | 1136 } |
1153 INC_STAT(thread, num_functions_compiled, 1); | 1137 INC_STAT(thread, num_functions_compiled, 1); |
1154 if (optimized) { | 1138 if (optimized) { |
1155 INC_STAT(thread, num_functions_optimized, 1); | 1139 INC_STAT(thread, num_functions_optimized, 1); |
1156 } | 1140 } |
1157 // Makes sure no libraries are loaded during parsing. | 1141 // Makes sure no classes are loaded during parsing in background. |
1158 const uint32_t prefix_invalidation_gen_at_start = | 1142 const intptr_t loading_invalidation_gen_at_start = |
1159 isolate->prefix_invalidation_gen(); | 1143 isolate->loading_invalidation_gen(); |
1160 { | 1144 { |
1161 HANDLESCOPE(thread); | 1145 HANDLESCOPE(thread); |
1162 const int64_t num_tokens_before = STAT_VALUE(thread, num_tokens_consumed); | 1146 const int64_t num_tokens_before = STAT_VALUE(thread, num_tokens_consumed); |
1163 pipeline->ParseFunction(parsed_function); | 1147 pipeline->ParseFunction(parsed_function); |
1164 const int64_t num_tokens_after = STAT_VALUE(thread, num_tokens_consumed); | 1148 const int64_t num_tokens_after = STAT_VALUE(thread, num_tokens_consumed); |
1165 INC_STAT(thread, | 1149 INC_STAT(thread, |
1166 num_func_tokens_compiled, | 1150 num_func_tokens_compiled, |
1167 num_tokens_after - num_tokens_before); | 1151 num_tokens_after - num_tokens_before); |
1168 } | 1152 } |
1169 | 1153 |
| 1154 |
1170 CompileParsedFunctionHelper helper(parsed_function, optimized, osr_id); | 1155 CompileParsedFunctionHelper helper(parsed_function, optimized, osr_id); |
1171 if (prefix_invalidation_gen_at_start != | 1156 |
1172 helper.prefix_invalidation_gen_at_start()) { | 1157 if (Compiler::IsBackgroundCompilation()) { |
1173 ASSERT(Compiler::IsBackgroundCompilation()); | 1158 if (isolate->IsTopLevelParsing() || |
1174 // Deferred loading occured while parsing or copying ICData. We need | 1159 (loading_invalidation_gen_at_start != |
1175 // to abort here because deopt-ids may have changed. | 1160 isolate->loading_invalidation_gen())) { |
1176 Compiler::AbortBackgroundCompilation(Thread::kNoDeoptId); | 1161 // Loading occured while parsing. We need to abort here because state |
| 1162 // changed while compiling. |
| 1163 Compiler::AbortBackgroundCompilation(Thread::kNoDeoptId); |
| 1164 } |
1177 } | 1165 } |
| 1166 |
1178 const bool success = helper.Compile(pipeline); | 1167 const bool success = helper.Compile(pipeline); |
1179 if (!success) { | 1168 if (!success) { |
1180 if (optimized) { | 1169 if (optimized) { |
1181 if (Compiler::IsBackgroundCompilation()) { | 1170 if (Compiler::IsBackgroundCompilation()) { |
1182 // Try again later, background compilation may abort because of | 1171 // Try again later, background compilation may abort because of |
1183 // state change during compilation. | 1172 // state change during compilation. |
1184 if (FLAG_trace_compiler) { | 1173 if (FLAG_trace_compiler) { |
1185 THR_Print("Aborted background compilation: %s\n", | 1174 THR_Print("Aborted background compilation: %s\n", |
1186 function.ToFullyQualifiedCString()); | 1175 function.ToFullyQualifiedCString()); |
1187 } | 1176 } |
(...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1908 } | 1897 } |
1909 | 1898 |
1910 | 1899 |
1911 void BackgroundCompiler::EnsureInit(Thread* thread) { | 1900 void BackgroundCompiler::EnsureInit(Thread* thread) { |
1912 UNREACHABLE(); | 1901 UNREACHABLE(); |
1913 } | 1902 } |
1914 | 1903 |
1915 #endif // DART_PRECOMPILED_RUNTIME | 1904 #endif // DART_PRECOMPILED_RUNTIME |
1916 | 1905 |
1917 } // namespace dart | 1906 } // namespace dart |
OLD | NEW |