kuganv added inline comments.

================
Comment at: clang-tools-extra/clangd/Preamble.cpp:106-113
+    CI.setSema(nullptr);
+    CI.setASTConsumer(nullptr);
+    if (CI.getASTReader()) {
+      CI.getASTReader()->setDeserializationListener(nullptr);
+      /* This just sets consumer to null when DeserializationListener is null 
*/
+      CI.getASTReader()->StartTranslationUnit(nullptr);
     }
----------------
kadircet wrote:
> kuganv wrote:
> > kadircet wrote:
> > > kuganv wrote:
> > > > kadircet wrote:
> > > > > why are we triggering destructors for all of these objects eagerly? 
> > > > > if this is deliberate to "fix" some issue, could you mention that in 
> > > > > comments?
> > > > > why are we triggering destructors for all of these objects eagerly? 
> > > > > if this is deliberate to "fix" some issue, could you mention that in 
> > > > > comments?
> > > > 
> > > > Thanks a lot for the review.
> > > > If we don't destruct and set it to null, CapturedASTCtx will also have 
> > > > to keep instances such as ASTConsumer including other related callbacks 
> > > > such PreambleCallbacks. This was making the CapturedASTCtx interface 
> > > > and implementation complex.
> > > > If we don't destruct and set it to null, CapturedASTCtx will also have 
> > > > to keep instances such as ASTConsumer 
> > > 
> > > Sorry if I am being dense but I can't actually see any references to 
> > > those objects in the structs we preseve. AFAICT, Sema, ASTConsumer and 
> > > ASTReader are members of CompilerInstance, which we don't keep around. 
> > > Can you point me towards any references to the rest of the objects you're 
> > > setting to null in case I am missing any?
> > > 
> > > `ASTMutationListener` seems to be the only one that's relevant. It's 
> > > indeed exposed through `ASTContext` and our indexing operations can 
> > > trigger various callbacks to fire. Can you set only that one to nullptr 
> > > and leave a comment explaining the situation?
> > > > If we don't destruct and set it to null, CapturedASTCtx will also have 
> > > > to keep instances such as ASTConsumer 
> > > 
> > > Sorry if I am being dense but I can't actually see any references to 
> > > those objects in the structs we preseve. AFAICT, Sema, ASTConsumer and 
> > > ASTReader are members of CompilerInstance, which we don't keep around. 
> > > Can you point me towards any references to the rest of the objects you're 
> > > setting to null in case I am missing any?
> > > 
> > > `ASTMutationListener` seems to be the only one that's relevant. It's 
> > > indeed exposed through `ASTContext` and our indexing operations can 
> > > trigger various callbacks to fire. Can you set only that one to nullptr 
> > > and leave a comment explaining the situation?
> > 
> > Thanks for the review.  I will revise based on the feedback. 
> > 
> > In buildPreamble, we create CppFilePreambleCallbacks in stack to be used in 
> > PrecompiledPreamble::Build which becomes part of 
> > PrecompilePreambleConsumer. I think this this need to be reset. Probably 
> > this has to be done in a different way. If I dont reset, I am seeing crash 
> > in some cases. See:
> > 
> > ```
> > 85c0c79f in clang::ASTReader::DecodeIdentifierInfo(unsigned int) 
> > /home/kugan/local/llvm-project/clang/lib/Serialization/ASTReader.cpp:8695:32
> >     #1 0x558285c75266 in 
> > clang::ASTReader::readIdentifier(clang::serialization::ModuleFile&, 
> > llvm::SmallVector<unsigned long, 64u> const&, unsigned int&) 
> > /home/kugan/local/llvm-project/clang/include/clang/Seriali
> > zation/ASTReader.h:2126:12
> >     #2 0x558285c75266 in clang::ASTRecordReader::readIdentifier() 
> > /home/kugan/local/llvm-project/clang/include/clang/Serialization/ASTRecordReader.h:211:20
> >     #3 0x558285c75266 in 
> > clang::serialization::BasicReaderBase<clang::ASTRecordReader>::readDeclarationName()
> >  
> > /home/kugan/local/llvm-project/build/tools/clang/include/clang/AST/AbstractBasicReader.inc:780:58
> >     #4 0x558285ce10bc in 
> > clang::ASTDeclReader::VisitNamedDecl(clang::NamedDecl*) 
> > /home/kugan/local/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:694:26
> >     #5 0x558285ce10bc in 
> > clang::ASTDeclReader::VisitNamespaceDecl(clang::NamespaceDecl*) 
> > /home/kugan/local/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:1785:3
> >     #6 0x558285cbc6e8 in clang::ASTDeclReader::Visit(clang::Decl*) 
> > /home/kugan/local/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:543:37
> >     #7 0x558285d5a133 in clang::ASTReader::ReadDeclRecord(unsigned int) 
> > /home/kugan/local/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp:4052:10
> >     #8 0x558285c73677 in clang::ASTReader::GetDecl(unsigned int) 
> > /home/kugan/local/llvm-project/clang/lib/Serialization/ASTReader.cpp:7607:5
> >     #9 0x558285c73677 in 
> > clang::ASTReader::GetLocalDecl(clang::serialization::ModuleFile&, unsigned 
> > int) 
> > /home/kugan/local/llvm-project/clang/include/clang/Serialization/ASTReader.h:1913:12
> >     #10 0x558285bfd741 in 
> > clang::ASTReader::FindExternalLexicalDecls(clang::DeclContext const*, 
> > llvm::function_ref<bool (clang::Decl::Kind)>, 
> > llvm::SmallVectorImpl<clang::Decl*>&)::$_9::operator()(clang::serializ
> > ation::ModuleFile*, 
> > llvm::ArrayRef<llvm::support::detail::packed_endian_specific_integral<unsigned
> >  int, (llvm::support::endianness)2, 1ul, 1ul>>) const 
> > /home/kugan/local/llvm-project/clang/lib/Serialization/ASTRe
> > ader.cpp:7687:21
> >     #11 0x558285bfd741 in 
> > clang::ASTReader::FindExternalLexicalDecls(clang::DeclContext const*, 
> > llvm::function_ref<bool (clang::Decl::Kind)>, 
> > llvm::SmallVectorImpl<clang::Decl*>&) /home/kugan/local/llvm-project/c
> > lang/lib/Serialization/ASTReader.cpp:7697:7
> >     #12 0x55827e942de7 in 
> > clang::ExternalASTSource::FindExternalLexicalDecls(clang::DeclContext 
> > const*, llvm::SmallVectorImpl<clang::Decl*>&) 
> > /home/kugan/local/llvm-project/clang/include/clang/AST/ExternalASTSour
> > ce.h:185:5
> >     #13 0x55827e942de7 in 
> > clang::DeclContext::LoadLexicalDeclsFromExternalStorage() const 
> > /home/kugan/local/llvm-project/clang/lib/AST/DeclBase.cpp:1421:11
> >     #14 0x55827e94436b in clang::DeclContext::decls_begin() const 
> > /home/kugan/local/llvm-project/clang/lib/AST/DeclBase.cpp:1477:5
> >     #15 0x5582822787ab in clang::DeclContext::decls() const 
> > /home/kugan/local/llvm-project/clang/include/clang/AST/DeclBase.h:2188:48
> >     #16 0x5582822787ab in 
> > clang::clangd::indexHeaderSymbols(llvm::StringRef, clang::ASTContext&, 
> > clang::Preprocessor&, clang::clangd::CanonicalIncludes const&) 
> > /home/kugan/local/llvm-project/clang-tools-extra/cla
> > ngd/index/FileIndex.cpp:233:37
> >     #17 0x558282281be9 in 
> > clang::clangd::FileIndex::updatePreamble(llvm::StringRef, llvm::StringRef, 
> > clang::ASTContext&, clang::Preprocessor&, clang::clangd::CanonicalIncludes 
> > const&) /home/kugan/local/llvm-proje
> > ct/clang-tools-extra/clangd/index/FileIndex.cpp:464:7
> > ```
> > 
> > 
> > 
> ah, this one is unfortunately a little bit more involved, and triggers only 
> in the cases where we have modules enabled (which is incidentally working in 
> clangd today, but effect is wider as -std=c++20 implicitly turns on 
> -fmodules).
> 
> tl;dr; astcontext is keeping references to pchgenerator in module-enabled 
> builds.
> 
> TBH the safest option here seems like clearing external source in astcontext 
> completely. As we can't really risk callbacks to PCHGenerator, even if we 
> fixed all the life-time concerns (ast consumer keeps references to 
> frontendaction alive, so both the callbacks we pass here and the action 
> itself needs to outlive the consumer).
> 
> But that's likely going to break preamble-indexing completely for codebases 
> that use modules (we'll likely only index top-level decls from the current 
> modules, but I am not sure). The alternative suggested here strikes some 
> middle ground (there's still going to be behavior change, previously all the 
> modules accessed during indexing would effect the final serialized preamble, 
> they won't anymore) but I am afraid it's too fragile. The dependency between 
> these clang-internals were so subtle that it took ~hours for me to analyze, 
> despite me specifically looking for them, hence I don't think anyone that's 
> unaware can preserve these invariants (i.e. make sure we don't have 
> references to astconsumer in other places.).
> 
> I am not sure how these work for you today, but can you check if just setting 
> external source on the astcontext to null is good enough?
Thanks for checking.  Unfortunately, just setting external source on the 
astcontext to null is not working. Setting 
PrecompilePreambleConsumer/PCHGenerator  and ASTMutationListener  to null seem 
to be sufficient.

I checked the Preamble index size with and without the patch for some files and 
they are the same. Updating to the revised patch.



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D148088/new/

https://reviews.llvm.org/D148088

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D148088: [R... Kugan Vivekanandarajah via Phabricator via cfe-commits
    • [PATCH] D14808... Kugan Vivekanandarajah via Phabricator via cfe-commits
    • [PATCH] D14808... Kadir Cetinkaya via Phabricator via cfe-commits
    • [PATCH] D14808... Kugan Vivekanandarajah via Phabricator via cfe-commits

Reply via email to