Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(477)

Side by Side Diff: runtime/vm/compiler.cc

Issue 2006793002: VM: Fix race between background compiler and guarded cid update. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: rework how we invalidate background compiled code Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | runtime/vm/isolate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 441
442 class CompileParsedFunctionHelper : public ValueObject { 442 class CompileParsedFunctionHelper : public ValueObject {
443 public: 443 public:
444 CompileParsedFunctionHelper(ParsedFunction* parsed_function, 444 CompileParsedFunctionHelper(ParsedFunction* parsed_function,
445 bool optimized, 445 bool optimized,
446 intptr_t osr_id) 446 intptr_t osr_id)
447 : parsed_function_(parsed_function), 447 : parsed_function_(parsed_function),
448 optimized_(optimized), 448 optimized_(optimized),
449 osr_id_(osr_id), 449 osr_id_(osr_id),
450 thread_(Thread::Current()), 450 thread_(Thread::Current()),
451 field_invalidation_gen_at_start_(isolate()->field_invalidation_gen()),
452 loading_invalidation_gen_at_start_( 451 loading_invalidation_gen_at_start_(
453 isolate()->loading_invalidation_gen()) { 452 isolate()->loading_invalidation_gen()) {
454 if (Compiler::IsBackgroundCompilation()) {
455 isolate()->ClearDisablingFieldList();
456 }
457 } 453 }
458 454
459 bool Compile(CompilationPipeline* pipeline); 455 bool Compile(CompilationPipeline* pipeline);
460 456
461 private: 457 private:
462 ParsedFunction* parsed_function() const { return parsed_function_; } 458 ParsedFunction* parsed_function() const { return parsed_function_; }
463 bool optimized() const { return optimized_; } 459 bool optimized() const { return optimized_; }
464 intptr_t osr_id() const { return osr_id_; } 460 intptr_t osr_id() const { return osr_id_; }
465 Thread* thread() const { return thread_; } 461 Thread* thread() const { return thread_; }
466 Isolate* isolate() const { return thread_->isolate(); } 462 Isolate* isolate() const { return thread_->isolate(); }
467 intptr_t field_invalidation_gen_at_start() const {
468 return field_invalidation_gen_at_start_;
469 }
470 intptr_t loading_invalidation_gen_at_start() const { 463 intptr_t loading_invalidation_gen_at_start() const {
471 return loading_invalidation_gen_at_start_; 464 return loading_invalidation_gen_at_start_;
472 } 465 }
473 void FinalizeCompilation(Assembler* assembler, 466 void FinalizeCompilation(Assembler* assembler,
474 FlowGraphCompiler* graph_compiler, 467 FlowGraphCompiler* graph_compiler,
475 FlowGraph* flow_graph); 468 FlowGraph* flow_graph);
476 void CheckIfBackgroundCompilerIsBeingStopped(); 469 void CheckIfBackgroundCompilerIsBeingStopped();
477 470
478 ParsedFunction* parsed_function_; 471 ParsedFunction* parsed_function_;
479 const bool optimized_; 472 const bool optimized_;
480 const intptr_t osr_id_; 473 const intptr_t osr_id_;
481 Thread* const thread_; 474 Thread* const thread_;
482 const intptr_t field_invalidation_gen_at_start_;
483 const intptr_t loading_invalidation_gen_at_start_; 475 const intptr_t loading_invalidation_gen_at_start_;
484 476
485 DISALLOW_COPY_AND_ASSIGN(CompileParsedFunctionHelper); 477 DISALLOW_COPY_AND_ASSIGN(CompileParsedFunctionHelper);
486 }; 478 };
487 479
488 480
489 // Returns true if any of disabling fields is inside the guarded_fields.
490 // The number of guarded_fields and disabling-fields is expected to be small
491 // (less than 5).
492 static bool CheckDisablingFields(
493 Thread* thread,
494 const ZoneGrowableArray<const Field*>& guarded_fields) {
495 Isolate* isolate = thread->isolate();
496 Zone* zone = thread->zone();
497 Field& field = Field::Handle(zone, isolate->GetDisablingField());
498 while (!field.IsNull()) {
499 for (intptr_t i = 0; i < guarded_fields.length(); i++) {
500 if (guarded_fields.At(i)->raw() == field.raw()) {
501 return true;
502 }
503 }
504 // Get next field.
505 field = isolate->GetDisablingField();
506 }
507 return false;
508 }
509
510
511 void CompileParsedFunctionHelper::FinalizeCompilation( 481 void CompileParsedFunctionHelper::FinalizeCompilation(
512 Assembler* assembler, 482 Assembler* assembler,
513 FlowGraphCompiler* graph_compiler, 483 FlowGraphCompiler* graph_compiler,
514 FlowGraph* flow_graph) { 484 FlowGraph* flow_graph) {
515 ASSERT(!FLAG_precompiled_mode); 485 ASSERT(!FLAG_precompiled_mode);
516 const Function& function = parsed_function()->function(); 486 const Function& function = parsed_function()->function();
517 Zone* const zone = thread()->zone(); 487 Zone* const zone = thread()->zone();
518 488
519 CSTAT_TIMER_SCOPE(thread(), codefinalizer_timer); 489 CSTAT_TIMER_SCOPE(thread(), codefinalizer_timer);
520 // CreateDeoptInfo uses the object pool and needs to be done before 490 // CreateDeoptInfo uses the object pool and needs to be done before
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 function.InstallOptimizedCode(code, is_osr); 556 function.InstallOptimizedCode(code, is_osr);
587 code_was_installed = true; 557 code_was_installed = true;
588 } else { 558 } else {
589 // Background compilation. 559 // Background compilation.
590 // Before installing code check generation counts if the code may 560 // Before installing code check generation counts if the code may
591 // have become invalid. 561 // have become invalid.
592 const bool trace_compiler = 562 const bool trace_compiler =
593 FLAG_trace_compiler || FLAG_trace_optimizing_compiler; 563 FLAG_trace_compiler || FLAG_trace_optimizing_compiler;
594 bool code_is_valid = true; 564 bool code_is_valid = true;
595 if (!flow_graph->parsed_function().guarded_fields()->is_empty()) { 565 if (!flow_graph->parsed_function().guarded_fields()->is_empty()) {
596 if (field_invalidation_gen_at_start() != 566 const ZoneGrowableArray<const Field*>& guarded_fields =
597 isolate()->field_invalidation_gen()) { 567 *flow_graph->parsed_function().guarded_fields();
598 const ZoneGrowableArray<const Field*>& guarded_fields = 568 Field& original = Field::Handle();
599 *flow_graph->parsed_function().guarded_fields(); 569 for (intptr_t i = 0; i < guarded_fields.length(); i++) {
600 bool field_conflict = CheckDisablingFields(thread(), guarded_fields); 570 const Field& field = *guarded_fields[i];
601 if (field_conflict) { 571 ASSERT(!field.IsOriginal());
572 original = field.Original();
573 if (!field.IsConsistentWith(original)) {
602 code_is_valid = false; 574 code_is_valid = false;
603 if (trace_compiler) { 575 if (trace_compiler) {
604 THR_Print("--> FAIL: Field invalidation."); 576 THR_Print("--> FAIL: Field %s guarded state changed.",
577 field.ToCString());
605 } 578 }
606 } 579 break;
580 }
607 } 581 }
608 } 582 }
609 if (loading_invalidation_gen_at_start() != 583 if (loading_invalidation_gen_at_start() !=
610 isolate()->loading_invalidation_gen()) { 584 isolate()->loading_invalidation_gen()) {
611 code_is_valid = false; 585 code_is_valid = false;
612 if (trace_compiler) { 586 if (trace_compiler) {
613 THR_Print("--> FAIL: Loading invalidation."); 587 THR_Print("--> FAIL: Loading invalidation.");
614 } 588 }
615 } 589 }
616 if (!thread()->cha()->IsConsistentWithCurrentHierarchy()) { 590 if (!thread()->cha()->IsConsistentWithCurrentHierarchy()) {
(...skipping 22 matching lines...) Expand all
639 } 613 }
640 614
641 if (code_was_installed) { 615 if (code_was_installed) {
642 // The generated code was compiled under certain assumptions about 616 // The generated code was compiled under certain assumptions about
643 // class hierarchy and field types. Register these dependencies 617 // class hierarchy and field types. Register these dependencies
644 // to ensure that the code will be deoptimized if they are violated. 618 // to ensure that the code will be deoptimized if they are violated.
645 thread()->cha()->RegisterDependencies(code); 619 thread()->cha()->RegisterDependencies(code);
646 620
647 const ZoneGrowableArray<const Field*>& guarded_fields = 621 const ZoneGrowableArray<const Field*>& guarded_fields =
648 *flow_graph->parsed_function().guarded_fields(); 622 *flow_graph->parsed_function().guarded_fields();
623 Field& field = Field::Handle();
649 for (intptr_t i = 0; i < guarded_fields.length(); i++) { 624 for (intptr_t i = 0; i < guarded_fields.length(); i++) {
650 const Field* field = guarded_fields[i]; 625 field = guarded_fields[i]->Original();
651 field->RegisterDependentCode(code); 626 field.RegisterDependentCode(code);
652 } 627 }
653 } 628 }
654 } else { // not optimized. 629 } else { // not optimized.
655 if (function.ic_data_array() == Array::null()) { 630 if (function.ic_data_array() == Array::null()) {
656 function.SaveICDataMap( 631 function.SaveICDataMap(
657 graph_compiler->deopt_id_to_ic_data(), 632 graph_compiler->deopt_id_to_ic_data(),
658 Array::Handle(zone, graph_compiler->edge_counters_array())); 633 Array::Handle(zone, graph_compiler->edge_counters_array()));
659 } 634 }
660 function.set_unoptimized_code(code); 635 function.set_unoptimized_code(code);
661 function.AttachCode(code); 636 function.AttachCode(code);
(...skipping 1523 matching lines...) Expand 10 before | Expand all | Expand 10 after
2185 2160
2186 2161
2187 bool BackgroundCompiler::IsDisabled() { 2162 bool BackgroundCompiler::IsDisabled() {
2188 UNREACHABLE(); 2163 UNREACHABLE();
2189 return true; 2164 return true;
2190 } 2165 }
2191 2166
2192 #endif // DART_PRECOMPILED_RUNTIME 2167 #endif // DART_PRECOMPILED_RUNTIME
2193 2168
2194 } // namespace dart 2169 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698