@@ -335,6 +335,7 @@ void SourceManager::clearIDTables() {
335335 LastLineNoFileIDQuery = FileID ();
336336 LastLineNoContentCache = nullptr ;
337337 LastFileIDLookup = FileID ();
338+ LastLookupStartOffset = LastLookupEndOffset = 0 ;
338339
339340 IncludedLocMap.clear ();
340341 if (LineTable)
@@ -640,9 +641,11 @@ FileID SourceManager::createFileIDImpl(ContentCache &File, StringRef Filename,
640641 LocalSLocEntryTable.push_back (
641642 SLocEntry::get (NextLocalOffset,
642643 FileInfo::get (IncludePos, File, FileCharacter, Filename)));
644+ LastLookupStartOffset = NextLocalOffset;
643645 // We do a +1 here because we want a SourceLocation that means "the end of the
644646 // file", e.g. for the "no newline at the end of the file" diagnostic.
645647 NextLocalOffset += FileSize + 1 ;
648+ LastLookupEndOffset = NextLocalOffset;
646649 updateSlocUsageStats ();
647650
648651 // Set LastFileIDLookup to the newly created file. The next getFileID call is
@@ -812,8 +815,9 @@ FileID SourceManager::getFileIDSlow(SourceLocation::UIntTy SLocOffset) const {
812815// / loaded one.
813816FileID SourceManager::getFileIDLocal (SourceLocation::UIntTy SLocOffset) const {
814817 assert (SLocOffset < NextLocalOffset && " Bad function choice" );
815- assert (SLocOffset >= LocalSLocEntryTable[0 ].getOffset () &&
818+ assert (SLocOffset >= LocalSLocEntryTable[0 ].getOffset () && SLocOffset > 0 &&
816819 " Invalid SLocOffset" );
820+ assert (LastFileIDLookup.ID >= 0 && " Only cache local file sloc entry" );
817821
818822 // After the first and second level caches, I see two common sorts of
819823 // behavior: 1) a lot of searched FileID's are "near" the cached file
@@ -833,13 +837,11 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
833837 unsigned LessIndex = 0 ;
834838 // upper bound of the search range.
835839 unsigned GreaterIndex = LocalSLocEntryTable.size ();
836- if (LastFileIDLookup.ID >= 0 ) {
837- // Use the LastFileIDLookup to prune the search space.
838- if (LocalSLocEntryTable[LastFileIDLookup.ID ].getOffset () < SLocOffset)
839- LessIndex = LastFileIDLookup.ID ;
840- else
841- GreaterIndex = LastFileIDLookup.ID ;
842- }
840+ // Use the LastFileIDLookup to prune the search space.
841+ if (LastLookupStartOffset < SLocOffset)
842+ LessIndex = LastFileIDLookup.ID ;
843+ else
844+ GreaterIndex = LastFileIDLookup.ID ;
843845
844846 // Find the FileID that contains this.
845847 unsigned NumProbes = 0 ;
@@ -850,7 +852,12 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
850852 FileID Res = FileID::get (int (GreaterIndex));
851853 // Remember it. We have good locality across FileID lookups.
852854 LastFileIDLookup = Res;
853- NumLinearScans += NumProbes+1 ;
855+ LastLookupStartOffset = LocalSLocEntryTable[GreaterIndex].getOffset ();
856+ LastLookupEndOffset =
857+ GreaterIndex + 1 >= LocalSLocEntryTable.size ()
858+ ? NextLocalOffset
859+ : LocalSLocEntryTable[GreaterIndex + 1 ].getOffset ();
860+ NumLinearScans += NumProbes + 1 ;
854861 return Res;
855862 }
856863 if (++NumProbes == 8 )
@@ -874,6 +881,8 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
874881 // At this point, LessIndex is the index of the *first element greater than*
875882 // SLocOffset. The element we are actually looking for is the one immediately
876883 // before it.
884+ LastLookupStartOffset = LocalSLocEntryTable[LessIndex - 1 ].getOffset ();
885+ LastLookupEndOffset = LocalSLocEntryTable[LessIndex].getOffset ();
877886 return LastFileIDLookup = FileID::get (LessIndex - 1 );
878887}
879888
0 commit comments