diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -692,6 +692,9 @@ /// Positive FileIDs are indexes into this table. Entry 0 indicates an invalid /// expansion. SmallVector LocalSLocEntryTable; + /// An in-parallel SlocEntry offset table, merely used for speeding up the + /// FileID lookup. + SmallVector LocalLocOffsetTable; /// The table of SLocEntries that are loaded from other modules. /// diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -336,6 +336,7 @@ void SourceManager::clearIDTables() { MainFileID = FileID(); LocalSLocEntryTable.clear(); + LocalLocOffsetTable.clear(); LoadedSLocEntryTable.clear(); SLocEntryLoaded.clear(); LastLineNoFileIDQuery = FileID(); @@ -615,9 +616,11 @@ Diag.Report(IncludePos, diag::err_include_too_large); return FileID(); } + assert(LoadedSLocEntryTable.size() == LocalLocOffsetTable.size()); LocalSLocEntryTable.push_back( SLocEntry::get(NextLocalOffset, FileInfo::get(IncludePos, File, FileCharacter, Filename))); + LocalLocOffsetTable.push_back(NextLocalOffset); // We do a +1 here because we want a SourceLocation that means "the end of the // file", e.g. for the "no newline at the end of the file" diagnostic. NextLocalOffset += FileSize + 1; @@ -668,7 +671,9 @@ SLocEntryLoaded[Index] = true; return SourceLocation::getMacroLoc(LoadedOffset); } + assert(LocalSLocEntryTable.size() == LocalLocOffsetTable.size()); LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info)); + LocalLocOffsetTable.push_back(NextLocalOffset); assert(NextLocalOffset + Length + 1 > NextLocalOffset && NextLocalOffset + Length + 1 <= CurrentLoadedOffset && "Ran out of source locations!"); @@ -799,10 +804,10 @@ // SLocOffset. unsigned LessIndex = 0; // upper bound of the search range. - unsigned GreaterIndex = LocalSLocEntryTable.size(); + unsigned GreaterIndex = LocalLocOffsetTable.size(); if (LastFileIDLookup.ID >= 0) { // Use the LastFileIDLookup to prune the search space. - if (LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) + if (LocalLocOffsetTable[LastFileIDLookup.ID] < SLocOffset) LessIndex = LastFileIDLookup.ID; else GreaterIndex = LastFileIDLookup.ID; @@ -812,8 +817,8 @@ unsigned NumProbes = 0; while (true) { --GreaterIndex; - assert(GreaterIndex < LocalSLocEntryTable.size()); - if (LocalSLocEntryTable[GreaterIndex].getOffset() <= SLocOffset) { + assert(GreaterIndex < LocalLocOffsetTable.size()); + if (LocalLocOffsetTable[GreaterIndex] <= SLocOffset) { FileID Res = FileID::get(int(GreaterIndex)); // Remember it. We have good locality across FileID lookups. LastFileIDLookup = Res; @@ -827,8 +832,7 @@ NumProbes = 0; while (true) { unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex; - SourceLocation::UIntTy MidOffset = - getLocalSLocEntry(MiddleIndex).getOffset(); + SourceLocation::UIntTy MidOffset = LocalLocOffsetTable[MiddleIndex]; ++NumProbes; @@ -840,8 +844,8 @@ } // If the middle index contains the value, succeed and return. - if (MiddleIndex + 1 == LocalSLocEntryTable.size() || - SLocOffset < getLocalSLocEntry(MiddleIndex + 1).getOffset()) { + if (MiddleIndex + 1 == LocalLocOffsetTable.size() || + SLocOffset < LocalLocOffsetTable[MiddleIndex + 1]) { FileID Res = FileID::get(MiddleIndex); // Remember it. We have good locality across FileID lookups. @@ -2169,6 +2173,9 @@ << NumMacroArgsComputed << " files with macro args computed.\n"; llvm::errs() << "FileID scans: " << NumLinearScans << " linear, " << NumBinaryProbes << " binary.\n"; + llvm::errs() << "Total bytes: " + << getDataStructureSizes() + getContentCacheSize() + + getMemoryBufferSizes().malloc_bytes; } LLVM_DUMP_METHOD void SourceManager::dump() const { @@ -2252,6 +2259,7 @@ size_t SourceManager::getDataStructureSizes() const { size_t size = llvm::capacity_in_bytes(MemBufferInfos) + llvm::capacity_in_bytes(LocalSLocEntryTable) + + llvm::capacity_in_bytes(LocalLocOffsetTable) + llvm::capacity_in_bytes(LoadedSLocEntryTable) + llvm::capacity_in_bytes(SLocEntryLoaded) + llvm::capacity_in_bytes(FileInfos);