aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Basic/SourceManager.h
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-04-27 06:38:32 +0000
committerDouglas Gregor <dgregor@apple.com>2009-04-27 06:38:32 +0000
commit7f94b0b0c6791013d2f72ced9b4bedd3b23673a6 (patch)
tree57fafa0282abdbe9266318e87966b64fac25c05c /include/clang/Basic/SourceManager.h
parent63377d56de98cfef089a5758e8d4c7597a30269e (diff)
Load most of the source manager's information lazily from the PCH
file. In particular, only eagerly load source location entries for files and for the predefines buffer. Other buffers and macro-instantiation source location entries are loaded lazily. With the Cocoa-prefixed "Hello, World", we only load 815/26555 source location entities. This halves the amount of user time we spend in this "Hello, World" program with -fsyntax-only (down to .007s). This optimization is part 1 of 2 for the source manager. This eliminates most of the user time in loading a PCH file. We still spend too much time initialize File structures (especially in the calls to stat), so we need to either make the loading of source location entries for files lazy or import the stat cache from the PTH implementation. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70196 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Basic/SourceManager.h')
-rw-r--r--include/clang/Basic/SourceManager.h65
1 files changed, 53 insertions, 12 deletions
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index 0b47df9ad9..9fc7587e54 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -249,7 +249,16 @@ namespace SrcMgr {
}
};
} // end SrcMgr namespace.
-
+
+/// \brief External source of source location entries.
+class ExternalSLocEntrySource {
+public:
+ virtual ~ExternalSLocEntrySource();
+
+ /// \brief Read the source location entry with index ID.
+ virtual void ReadSLocEntry(unsigned ID) = 0;
+};
+
/// SourceManager - This file handles loading and caching of source files into
/// memory. This object owns the MemoryBuffer objects for all of the loaded
/// files and assigns unique FileID's for each unique #include chain.
@@ -281,7 +290,15 @@ class SourceManager {
/// NextOffset - This is the next available offset that a new SLocEntry can
/// start at. It is SLocEntryTable.back().getOffset()+size of back() entry.
unsigned NextOffset;
-
+
+ /// \brief If source location entries are being lazily loaded from
+ /// an external source, this vector indicates whether the Ith source
+ /// location entry has already been loaded from the external storage.
+ std::vector<bool> SLocEntryLoaded;
+
+ /// \brief An external source for source location entries.
+ ExternalSLocEntrySource *ExternalSLocEntries;
+
/// LastFileIDLookup - This is a one-entry cache to speed up getFileID.
/// LastFileIDLookup records the last FileID looked up or created, because it
/// is very common to look up many tokens from the same file.
@@ -308,7 +325,9 @@ class SourceManager {
explicit SourceManager(const SourceManager&);
void operator=(const SourceManager&);
public:
- SourceManager() : LineTable(0), NumLinearScans(0), NumBinaryProbes(0) {
+ SourceManager()
+ : ExternalSLocEntries(0), LineTable(0), NumLinearScans(0),
+ NumBinaryProbes(0) {
clearIDTables();
}
~SourceManager();
@@ -337,19 +356,25 @@ public:
/// createFileID - Create a new FileID that represents the specified file
/// being #included from the specified IncludePosition. This returns 0 on
/// error and translates NULL into standard input.
+ /// PreallocateID should be non-zero to specify which a pre-allocated,
+ /// lazily computed source location is being filled in by this operation.
FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
- SrcMgr::CharacteristicKind FileCharacter) {
+ SrcMgr::CharacteristicKind FileCharacter,
+ unsigned PreallocatedID = 0,
+ unsigned Offset = 0) {
const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
if (IR == 0) return FileID(); // Error opening file?
- return createFileID(IR, IncludePos, FileCharacter);
+ return createFileID(IR, IncludePos, FileCharacter, PreallocatedID, Offset);
}
/// createFileIDForMemBuffer - Create a new FileID that represents the
/// specified memory buffer. This does no caching of the buffer and takes
/// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once.
- FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
+ FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer,
+ unsigned PreallocatedID = 0,
+ unsigned Offset = 0) {
return createFileID(createMemBufferContentCache(Buffer), SourceLocation(),
- SrcMgr::C_User);
+ SrcMgr::C_User, PreallocatedID, Offset);
}
/// createMainFileIDForMembuffer - Create the FileID for a memory buffer
@@ -367,7 +392,9 @@ public:
SourceLocation createInstantiationLoc(SourceLocation Loc,
SourceLocation InstantiationLocStart,
SourceLocation InstantiationLocEnd,
- unsigned TokLength);
+ unsigned TokLength,
+ unsigned PreallocatedID = 0,
+ unsigned Offset = 0);
//===--------------------------------------------------------------------===//
// FileID manipulation methods.
@@ -411,8 +438,9 @@ public:
/// getLocForStartOfFile - Return the source location corresponding to the
/// first byte of the specified file.
SourceLocation getLocForStartOfFile(FileID FID) const {
- assert(FID.ID < SLocEntryTable.size() && SLocEntryTable[FID.ID].isFile());
- unsigned FileOffset = SLocEntryTable[FID.ID].getOffset();
+ assert(FID.ID < SLocEntryTable.size() && "FileID out of range");
+ assert(getSLocEntry(FID).isFile() && "FileID is not a file");
+ unsigned FileOffset = getSLocEntry(FID).getOffset();
return SourceLocation::getFileLoc(FileOffset);
}
@@ -616,11 +644,21 @@ public:
const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const {
assert(FID.ID < SLocEntryTable.size() && "Invalid id");
+ if (ExternalSLocEntries &&
+ FID.ID < SLocEntryLoaded.size() &&
+ !SLocEntryLoaded[FID.ID])
+ ExternalSLocEntries->ReadSLocEntry(FID.ID);
return SLocEntryTable[FID.ID];
}
unsigned getNextOffset() const { return NextOffset; }
+ /// \brief Preallocate some number of source location entries, which
+ /// will be loaded as needed from the given external source.
+ void PreallocateSLocEntries(ExternalSLocEntrySource *Source,
+ unsigned NumSLocEntries,
+ unsigned NextOffset);
+
private:
/// isOffsetInFileID - Return true if the specified FileID contains the
/// specified SourceLocation offset. This is a very hot method.
@@ -632,7 +670,8 @@ private:
// If this is the last entry than it does. Otherwise, the entry after it
// has to not include it.
if (FID.ID+1 == SLocEntryTable.size()) return true;
- return SLocOffset < SLocEntryTable[FID.ID+1].getOffset();
+
+ return SLocOffset < getSLocEntry(FileID::get(FID.ID+1)).getOffset();
}
/// createFileID - Create a new fileID for the specified ContentCache and
@@ -640,7 +679,9 @@ private:
/// corresponds to a file or some other input source.
FileID createFileID(const SrcMgr::ContentCache* File,
SourceLocation IncludePos,
- SrcMgr::CharacteristicKind DirCharacter);
+ SrcMgr::CharacteristicKind DirCharacter,
+ unsigned PreallocatedID = 0,
+ unsigned Offset = 0);
const SrcMgr::ContentCache *
getOrCreateContentCache(const FileEntry *SourceFile);