diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-10-31 20:59:50 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2012-10-31 20:59:50 +0000 |
commit | 4182ed686283b72736b287cbe28583cb641f8934 (patch) | |
tree | fc736e4110c8af9193a5aa2c0c14d6c6c8065bfc /lib/Serialization/ASTReader.cpp | |
parent | 724e65b18cfe6691668606cde59d44cf353282b8 (diff) |
[PCH] Remove the stat cache from the PCH file.
The stat cache became essentially useless ever since we started
validating all file entries in the PCH.
But the motivating reason for removing it now is that it also affected
correctness in this situation:
-You have a header without include guards (using "#pragma once" or #import)
-When creating the PCH:
-The same header is referenced in an #include with different filename cases.
-In the PCH, of course, we record only one file entry for the header file
-But we cache in the PCH file the stat info for both filename cases
-Then the source files are updated and the header file is updated in a way that
its size and modification time are the same but its inode changes
-When using the PCH:
-We validate the headers, we check that header file and we create a file entry with its current inode
-There's another #include with a filename with different case than the previously created file entry
-In order to get its stat info we go through the cached stat info of the PCH and we receive the old inode
-because of the different inodes, we think they are different files so we go ahead and include its contents.
Removing the stat cache will potentially break clients that are attempting to use the stat cache
as a way of avoiding having the actual input files available. If that use case is important, patches are welcome
to bring it back in a way that will actually work correctly (i.e., emit a PCH that is self-contained, coping with
literal strings, line/column computations, etc.).
This fixes rdar://5502805
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167172 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 116 |
1 files changed, 1 insertions, 115 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 874d2c4b1b..80fb464c3f 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -769,104 +769,6 @@ bool ASTReader::ParseLineTable(ModuleFile &F, return false; } -namespace { - -class ASTStatData { -public: - const ino_t ino; - const dev_t dev; - const mode_t mode; - const time_t mtime; - const off_t size; - - ASTStatData(ino_t i, dev_t d, mode_t mo, time_t m, off_t s) - : ino(i), dev(d), mode(mo), mtime(m), size(s) {} -}; - -class ASTStatLookupTrait { - public: - typedef const char *external_key_type; - typedef const char *internal_key_type; - - typedef ASTStatData data_type; - - static unsigned ComputeHash(const char *path) { - return llvm::HashString(path); - } - - static internal_key_type GetInternalKey(const char *path) { return path; } - - static bool EqualKey(internal_key_type a, internal_key_type b) { - return strcmp(a, b) == 0; - } - - static std::pair<unsigned, unsigned> - ReadKeyDataLength(const unsigned char*& d) { - unsigned KeyLen = (unsigned) clang::io::ReadUnalignedLE16(d); - unsigned DataLen = (unsigned) *d++; - return std::make_pair(KeyLen + 1, DataLen); - } - - static internal_key_type ReadKey(const unsigned char *d, unsigned) { - return (const char *)d; - } - - static data_type ReadData(const internal_key_type, const unsigned char *d, - unsigned /*DataLen*/) { - using namespace clang::io; - - ino_t ino = (ino_t) ReadUnalignedLE32(d); - dev_t dev = (dev_t) ReadUnalignedLE32(d); - mode_t mode = (mode_t) ReadUnalignedLE16(d); - time_t mtime = (time_t) ReadUnalignedLE64(d); - off_t size = (off_t) ReadUnalignedLE64(d); - return data_type(ino, dev, mode, mtime, size); - } -}; - -/// \brief stat() cache for precompiled headers. -/// -/// This cache is very similar to the stat cache used by pretokenized -/// headers. -class ASTStatCache : public FileSystemStatCache { - typedef OnDiskChainedHashTable<ASTStatLookupTrait> CacheTy; - CacheTy *Cache; - - unsigned &NumStatHits, &NumStatMisses; -public: - ASTStatCache(const unsigned char *Buckets, const unsigned char *Base, - unsigned &NumStatHits, unsigned &NumStatMisses) - : Cache(0), NumStatHits(NumStatHits), NumStatMisses(NumStatMisses) { - Cache = CacheTy::Create(Buckets, Base); - } - - ~ASTStatCache() { delete Cache; } - - LookupResult getStat(const char *Path, struct stat &StatBuf, - int *FileDescriptor) { - // Do the lookup for the file's data in the AST file. - CacheTy::iterator I = Cache->find(Path); - - // If we don't get a hit in the AST file just forward to 'stat'. - if (I == Cache->end()) { - ++NumStatMisses; - return statChained(Path, StatBuf, FileDescriptor); - } - - ++NumStatHits; - ASTStatData Data = *I; - - StatBuf.st_ino = Data.ino; - StatBuf.st_dev = Data.dev; - StatBuf.st_mtime = Data.mtime; - StatBuf.st_mode = Data.mode; - StatBuf.st_size = Data.size; - return CacheExists; - } -}; -} // end anonymous namespace - - /// \brief Read a source manager block bool ASTReader::ReadSourceManagerBlock(ModuleFile &F) { using namespace SrcMgr; @@ -2362,18 +2264,6 @@ bool ASTReader::ReadASTBlock(ModuleFile &F) { break; } - case STAT_CACHE: { - if (!DisableStatCache) { - ASTStatCache *MyStatCache = - new ASTStatCache((const unsigned char *)BlobStart + Record[0], - (const unsigned char *)BlobStart, - NumStatHits, NumStatMisses); - FileMgr.addStatCache(MyStatCache); - F.StatCache = MyStatCache; - } - break; - } - case EXT_VECTOR_DECLS: for (unsigned I = 0, N = Record.size(); I != N; ++I) ExtVectorDecls.push_back(getGlobalDeclID(F, Record[I])); @@ -5624,8 +5514,6 @@ void ASTReader::PrintStats() { SelectorsLoaded.end(), Selector()); - std::fprintf(stderr, " %u stat cache hits\n", NumStatHits); - std::fprintf(stderr, " %u stat cache misses\n", NumStatMisses); if (unsigned TotalNumSLocEntries = getTotalNumSLocs()) std::fprintf(stderr, " %u/%u source location entries read (%f%%)\n", NumSLocEntriesRead, TotalNumSLocEntries, @@ -7005,16 +6893,14 @@ void ASTReader::FinishedDeserializing() { ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot, bool DisableValidation, - bool DisableStatCache, bool AllowASTWithCompilerErrors) + bool AllowASTWithCompilerErrors) : Listener(new PCHValidator(PP, *this)), DeserializationListener(0), SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()), Diags(PP.getDiagnostics()), SemaObj(0), PP(PP), Context(Context), Consumer(0), ModuleMgr(PP.getFileManager()), isysroot(isysroot), DisableValidation(DisableValidation), - DisableStatCache(DisableStatCache), AllowASTWithCompilerErrors(AllowASTWithCompilerErrors), CurrentGeneration(0), CurrSwitchCaseStmts(&SwitchCaseStmts), - NumStatHits(0), NumStatMisses(0), NumSLocEntriesRead(0), TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0), TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0), |