| OLD | NEW | 
|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 // This clang plugin checks various invariants of the Blink garbage | 5 // This clang plugin checks various invariants of the Blink garbage | 
| 6 // collection infrastructure. | 6 // collection infrastructure. | 
| 7 // | 7 // | 
| 8 // Errors are described at: | 8 // Errors are described at: | 
| 9 // http://www.chromium.org/developers/blink-gc-plugin-errors | 9 // http://www.chromium.org/developers/blink-gc-plugin-errors | 
| 10 | 10 | 
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 565 | 565 | 
| 566   CXXMethodDecl* trace_; | 566   CXXMethodDecl* trace_; | 
| 567   RecordInfo* info_; | 567   RecordInfo* info_; | 
| 568 }; | 568 }; | 
| 569 | 569 | 
| 570 // This visitor checks that the fields of a class and the fields of | 570 // This visitor checks that the fields of a class and the fields of | 
| 571 // its part objects don't define GC roots. | 571 // its part objects don't define GC roots. | 
| 572 class CheckGCRootsVisitor : public RecursiveEdgeVisitor { | 572 class CheckGCRootsVisitor : public RecursiveEdgeVisitor { | 
| 573  public: | 573  public: | 
| 574   typedef std::vector<FieldPoint*> RootPath; | 574   typedef std::vector<FieldPoint*> RootPath; | 
|  | 575   typedef std::set<RecordInfo*> VisitingSet; | 
| 575   typedef std::vector<RootPath> Errors; | 576   typedef std::vector<RootPath> Errors; | 
| 576 | 577 | 
| 577   CheckGCRootsVisitor() {} | 578   CheckGCRootsVisitor() {} | 
| 578 | 579 | 
| 579   Errors& gc_roots() { return gc_roots_; } | 580   Errors& gc_roots() { return gc_roots_; } | 
| 580 | 581 | 
| 581   bool ContainsGCRoots(RecordInfo* info) { | 582   bool ContainsGCRoots(RecordInfo* info) { | 
| 582     for (RecordInfo::Fields::iterator it = info->GetFields().begin(); | 583     for (RecordInfo::Fields::iterator it = info->GetFields().begin(); | 
| 583          it != info->GetFields().end(); | 584          it != info->GetFields().end(); | 
| 584          ++it) { | 585          ++it) { | 
| 585       current_.push_back(&it->second); | 586       current_.push_back(&it->second); | 
| 586       it->second.edge()->Accept(this); | 587       it->second.edge()->Accept(this); | 
| 587       current_.pop_back(); | 588       current_.pop_back(); | 
| 588     } | 589     } | 
| 589     return !gc_roots_.empty(); | 590     return !gc_roots_.empty(); | 
| 590   } | 591   } | 
| 591 | 592 | 
| 592   void VisitValue(Value* edge) override { | 593   void VisitValue(Value* edge) override { | 
| 593     // TODO: what should we do to check unions? | 594     // TODO: what should we do to check unions? | 
| 594     if (edge->value()->record()->isUnion()) | 595     if (edge->value()->record()->isUnion()) | 
| 595       return; | 596       return; | 
| 596 | 597 | 
|  | 598     // Prevent infinite regress for cyclic part objects. | 
|  | 599     if (visiting_set_.find(edge->value()) != visiting_set_.end()) | 
|  | 600       return; | 
|  | 601 | 
|  | 602     visiting_set_.insert(edge->value()); | 
| 597     // If the value is a part object, then continue checking for roots. | 603     // If the value is a part object, then continue checking for roots. | 
| 598     for (Context::iterator it = context().begin(); | 604     for (Context::iterator it = context().begin(); | 
| 599          it != context().end(); | 605          it != context().end(); | 
| 600          ++it) { | 606          ++it) { | 
| 601       if (!(*it)->IsCollection()) | 607       if (!(*it)->IsCollection()) | 
| 602         return; | 608         return; | 
| 603     } | 609     } | 
| 604     ContainsGCRoots(edge->value()); | 610     ContainsGCRoots(edge->value()); | 
|  | 611     visiting_set_.erase(edge->value()); | 
| 605   } | 612   } | 
| 606 | 613 | 
| 607   void VisitPersistent(Persistent* edge) override { | 614   void VisitPersistent(Persistent* edge) override { | 
| 608     gc_roots_.push_back(current_); | 615     gc_roots_.push_back(current_); | 
| 609   } | 616   } | 
| 610 | 617 | 
| 611   void AtCollection(Collection* edge) override { | 618   void AtCollection(Collection* edge) override { | 
| 612     if (edge->is_root()) | 619     if (edge->is_root()) | 
| 613       gc_roots_.push_back(current_); | 620       gc_roots_.push_back(current_); | 
| 614   } | 621   } | 
| 615 | 622 | 
| 616  protected: | 623  protected: | 
| 617   RootPath current_; | 624   RootPath current_; | 
|  | 625   VisitingSet visiting_set_; | 
| 618   Errors gc_roots_; | 626   Errors gc_roots_; | 
| 619 }; | 627 }; | 
| 620 | 628 | 
| 621 // This visitor checks that the fields of a class are "well formed". | 629 // This visitor checks that the fields of a class are "well formed". | 
| 622 // - OwnPtr, RefPtr and RawPtr must not point to a GC derived types. | 630 // - OwnPtr, RefPtr and RawPtr must not point to a GC derived types. | 
| 623 // - Part objects must not be GC derived types. | 631 // - Part objects must not be GC derived types. | 
| 624 // - An on-heap class must never contain GC roots. | 632 // - An on-heap class must never contain GC roots. | 
| 625 // - Only stack-allocated types may point to stack-allocated types. | 633 // - Only stack-allocated types may point to stack-allocated types. | 
| 626 class CheckFieldsVisitor : public RecursiveEdgeVisitor { | 634 class CheckFieldsVisitor : public RecursiveEdgeVisitor { | 
| 627  public: | 635  public: | 
| (...skipping 1251 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1879 | 1887 | 
| 1880  private: | 1888  private: | 
| 1881   BlinkGCPluginOptions options_; | 1889   BlinkGCPluginOptions options_; | 
| 1882 }; | 1890 }; | 
| 1883 | 1891 | 
| 1884 }  // namespace | 1892 }  // namespace | 
| 1885 | 1893 | 
| 1886 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( | 1894 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( | 
| 1887     "blink-gc-plugin", | 1895     "blink-gc-plugin", | 
| 1888     "Check Blink GC invariants"); | 1896     "Check Blink GC invariants"); | 
| OLD | NEW | 
|---|