@@ -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)
@@ -630,9 +631,11 @@ FileID SourceManager::createFileIDImpl(ContentCache &File, StringRef Filename,
630631 LocalSLocEntryTable.push_back (
631632 SLocEntry::get (NextLocalOffset,
632633 FileInfo::get (IncludePos, File, FileCharacter, Filename)));
634+ LastLookupStartOffset = NextLocalOffset;
633635 // We do a +1 here because we want a SourceLocation that means "the end of the
634636 // file", e.g. for the "no newline at the end of the file" diagnostic.
635637 NextLocalOffset += FileSize + 1 ;
638+ LastLookupEndOffset = NextLocalOffset;
636639 updateSlocUsageStats ();
637640
638641 // Set LastFileIDLookup to the newly created file. The next getFileID call is
@@ -802,8 +805,9 @@ FileID SourceManager::getFileIDSlow(SourceLocation::UIntTy SLocOffset) const {
802805// / loaded one.
803806FileID SourceManager::getFileIDLocal (SourceLocation::UIntTy SLocOffset) const {
804807 assert (SLocOffset < NextLocalOffset && " Bad function choice" );
805- assert (SLocOffset >= LocalSLocEntryTable[0 ].getOffset () &&
808+ assert (SLocOffset >= LocalSLocEntryTable[0 ].getOffset () && SLocOffset > 0 &&
806809 " Invalid SLocOffset" );
810+ assert (LastFileIDLookup.ID >= 0 && " Only cache local file sloc entry" );
807811
808812 // After the first and second level caches, I see two common sorts of
809813 // behavior: 1) a lot of searched FileID's are "near" the cached file
@@ -823,13 +827,11 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
823827 unsigned LessIndex = 0 ;
824828 // upper bound of the search range.
825829 unsigned GreaterIndex = LocalSLocEntryTable.size ();
826- if (LastFileIDLookup.ID >= 0 ) {
827- // Use the LastFileIDLookup to prune the search space.
828- if (LocalSLocEntryTable[LastFileIDLookup.ID ].getOffset () < SLocOffset)
829- LessIndex = LastFileIDLookup.ID ;
830- else
831- GreaterIndex = LastFileIDLookup.ID ;
832- }
830+ // Use the LastFileIDLookup to prune the search space.
831+ if (LastLookupStartOffset < SLocOffset)
832+ LessIndex = LastFileIDLookup.ID ;
833+ else
834+ GreaterIndex = LastFileIDLookup.ID ;
833835
834836 // Find the FileID that contains this.
835837 unsigned NumProbes = 0 ;
@@ -840,7 +842,12 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
840842 FileID Res = FileID::get (int (GreaterIndex));
841843 // Remember it. We have good locality across FileID lookups.
842844 LastFileIDLookup = Res;
843- NumLinearScans += NumProbes+1 ;
845+ LastLookupStartOffset = LocalSLocEntryTable[GreaterIndex].getOffset ();
846+ LastLookupEndOffset =
847+ GreaterIndex + 1 >= LocalSLocEntryTable.size ()
848+ ? NextLocalOffset
849+ : LocalSLocEntryTable[GreaterIndex + 1 ].getOffset ();
850+ NumLinearScans += NumProbes + 1 ;
844851 return Res;
845852 }
846853 if (++NumProbes == 8 )
@@ -864,6 +871,8 @@ FileID SourceManager::getFileIDLocal(SourceLocation::UIntTy SLocOffset) const {
864871 // At this point, LessIndex is the index of the *first element greater than*
865872 // SLocOffset. The element we are actually looking for is the one immediately
866873 // before it.
874+ LastLookupStartOffset = LocalSLocEntryTable[LessIndex - 1 ].getOffset ();
875+ LastLookupEndOffset = LocalSLocEntryTable[LessIndex].getOffset ();
867876 return LastFileIDLookup = FileID::get (LessIndex - 1 );
868877}
869878
0 commit comments