mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Source manager] Improve the performance of findBufferContainingLocInternal()
This function was performing a linear scan through the set of known buffers to find the buffer containing a given source location. This linear scan can show up in hot loops, and the number of buffers in a program is increasing due to macros, so this has become a performance problem. Replace the linear scan with a logarithmic lookup into a sorted vector of the buffer IDs, with a one-element most-recently-used cache so that repeated lookups in the same buffer require constant time. This mirrors what we already do with source files in a module. Unfortunately, we cannot reuse that code because there is no link from buffers to source files. We should look to consolidate this in the future. Fixes rdar://116184248.
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace swift {
|
||||
|
||||
@@ -134,6 +135,28 @@ private:
|
||||
std::map<const char *, VirtualFile> VirtualFiles;
|
||||
mutable std::pair<const char *, const VirtualFile*> CachedVFile = {nullptr, nullptr};
|
||||
|
||||
/// A cache that improves the speed of location -> buffer lookups.
|
||||
struct BufferLocCache {
|
||||
/// The set of memory buffers IDs, sorted by the start of their source range.
|
||||
std::vector<unsigned> sortedBuffers;
|
||||
|
||||
/// The number of buffers that were present when sortedBuffers was formed.
|
||||
///
|
||||
/// There can be multiple buffers that refer to the same source range,
|
||||
/// and we remove duplicates as part of the processing of forming the
|
||||
/// vector of sorted buffers. This number is the number of original buffers,
|
||||
/// used to determine when the sorted buffers are out of date.
|
||||
unsigned numBuffersOriginal = 0;
|
||||
|
||||
/// The last buffer we looked in. This acts as a one-element MRU cache for
|
||||
/// lookups based on source locations.
|
||||
llvm::Optional<unsigned> lastBufferID;
|
||||
};
|
||||
|
||||
/// The cache that's used to quickly map a source location to a particular
|
||||
/// buffer ID.
|
||||
mutable BufferLocCache LocCache;
|
||||
|
||||
llvm::Optional<unsigned> findBufferContainingLocInternal(SourceLoc Loc) const;
|
||||
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user