зеркало из https://github.com/microsoft/clang-1.git
Misc changes to SourceManager::ContentCache:
- 'Buffer' is now private and must be accessed via 'getBuffer()'. This paves the way for lazily mapping in source files on demand. - Added 'getSize()' (which gets the size of the content without necessarily accessing the MemBuffer) and 'getSizeBytesMapped()'. - Modifed SourceManager to use these new methods. This reduces the number of places that actually access the MemBuffer object for a file to those that actually look at the character data. These changes result in no performance change for -fsyntax-only on Cocoa.h. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61782 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
1e5f3ebb29
Коммит
c16c208e85
|
@ -48,16 +48,17 @@ namespace SrcMgr {
|
|||
|
||||
/// ContentCache - Once instance of this struct is kept for every file
|
||||
/// loaded or used. This object owns the MemoryBuffer object.
|
||||
struct ContentCache {
|
||||
class ContentCache {
|
||||
/// Buffer - The actual buffer containing the characters from the input
|
||||
/// file. This is owned by the ContentCache object.
|
||||
const llvm::MemoryBuffer* Buffer;
|
||||
|
||||
public:
|
||||
/// Reference to the file entry. This reference does not own
|
||||
/// the FileEntry object. It is possible for this to be NULL if
|
||||
/// the ContentCache encapsulates an imaginary text buffer.
|
||||
const FileEntry* Entry;
|
||||
|
||||
/// Buffer - The actual buffer containing the characters from the input
|
||||
/// file. This is owned by the ContentCache object.
|
||||
const llvm::MemoryBuffer* Buffer;
|
||||
|
||||
/// SourceLineCache - A new[]'d array of offsets for each source line. This
|
||||
/// is lazily computed. This is owned by the ContentCache object.
|
||||
unsigned* SourceLineCache;
|
||||
|
@ -66,8 +67,27 @@ namespace SrcMgr {
|
|||
/// if SourceLineCache is non-null.
|
||||
unsigned NumLines;
|
||||
|
||||
/// getBuffer - Returns the memory buffer for the associated content.
|
||||
const llvm::MemoryBuffer* getBuffer() const;
|
||||
|
||||
/// getSize - Returns the size of the content encapsulated by this
|
||||
/// ContentCache. This can be the size of the source file or the size of an
|
||||
/// arbitrary scratch buffer. If the ContentCache encapsulates a source
|
||||
/// file this size is retrieved from the file's FileEntry.
|
||||
unsigned getSize() const;
|
||||
|
||||
/// getSizeBytesMapped - Returns the number of bytes actually mapped for
|
||||
/// this ContentCache. This can be 0 if the MemBuffer was not actually
|
||||
/// instantiated.
|
||||
unsigned getSizeBytesMapped() const;
|
||||
|
||||
void setBuffer(const llvm::MemoryBuffer* B) {
|
||||
assert(!Buffer && "MemoryBuffer already set.");
|
||||
Buffer = B;
|
||||
}
|
||||
|
||||
ContentCache(const FileEntry* e = NULL)
|
||||
: Entry(e), Buffer(NULL), SourceLineCache(NULL), NumLines(0) {}
|
||||
: Buffer(NULL), Entry(e), SourceLineCache(NULL), NumLines(0) {}
|
||||
|
||||
~ContentCache();
|
||||
|
||||
|
@ -307,7 +327,7 @@ public:
|
|||
/// getBuffer - Return the buffer for the specified FileID.
|
||||
///
|
||||
const llvm::MemoryBuffer *getBuffer(unsigned FileID) const {
|
||||
return getContentCache(FileID)->Buffer;
|
||||
return getContentCache(FileID)->getBuffer();
|
||||
}
|
||||
|
||||
/// getBufferData - Return a pointer to the start and end of the character
|
||||
|
|
|
@ -29,6 +29,26 @@ ContentCache::~ContentCache() {
|
|||
delete [] SourceLineCache;
|
||||
}
|
||||
|
||||
/// getSizeBytesMapped - Returns the number of bytes actually mapped for
|
||||
/// this ContentCache. This can be 0 if the MemBuffer was not actually
|
||||
/// instantiated.
|
||||
unsigned ContentCache::getSizeBytesMapped() const {
|
||||
return Buffer ? Buffer->getBufferSize() : 0;
|
||||
}
|
||||
|
||||
/// getSize - Returns the size of the content encapsulated by this ContentCache.
|
||||
/// This can be the size of the source file or the size of an arbitrary
|
||||
/// scratch buffer. If the ContentCache encapsulates a source file, that
|
||||
/// file is not lazily brought in from disk to satisfy this query.
|
||||
unsigned ContentCache::getSize() const {
|
||||
return Entry ? Entry->getSize() : Buffer->getBufferSize();
|
||||
}
|
||||
|
||||
const llvm::MemoryBuffer* ContentCache::getBuffer() const {
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
|
||||
/// getFileInfo - Create or return a cached FileInfo for the specified file.
|
||||
///
|
||||
const ContentCache* SourceManager::getContentCache(const FileEntry *FileEnt) {
|
||||
|
@ -49,7 +69,9 @@ const ContentCache* SourceManager::getContentCache(const FileEntry *FileEnt) {
|
|||
|
||||
ContentCache& Entry = const_cast<ContentCache&>(*FileInfos.insert(I,FileEnt));
|
||||
|
||||
Entry.Buffer = File;
|
||||
// FIXME: Shortly the above logic that creates a MemBuffer will be moved
|
||||
// to ContentCache::getBuffer(). This way it can be done lazily.
|
||||
Entry.setBuffer(File);
|
||||
Entry.SourceLineCache = 0;
|
||||
Entry.NumLines = 0;
|
||||
return &Entry;
|
||||
|
@ -66,7 +88,7 @@ SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
|
|||
// temporary we would use in the call to "push_back".
|
||||
MemBufferInfos.push_back(ContentCache());
|
||||
ContentCache& Entry = const_cast<ContentCache&>(MemBufferInfos.back());
|
||||
Entry.Buffer = Buffer;
|
||||
Entry.setBuffer(Buffer);
|
||||
return &Entry;
|
||||
}
|
||||
|
||||
|
@ -81,7 +103,7 @@ unsigned SourceManager::createFileID(const ContentCache *File,
|
|||
// to fit an arbitrary position in the file in the FilePos field. To handle
|
||||
// this, we create one FileID for each chunk of the file that fits in a
|
||||
// FilePos field.
|
||||
unsigned FileSize = File->Buffer->getBufferSize();
|
||||
unsigned FileSize = File->getSize();
|
||||
if (FileSize+1 < (1 << SourceLocation::FilePosBits)) {
|
||||
FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File, FileCharacter));
|
||||
assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
|
||||
|
@ -159,7 +181,8 @@ const char *SourceManager::getCharacterData(SourceLocation SL) const {
|
|||
// heavily used by -E mode.
|
||||
SL = getPhysicalLoc(SL);
|
||||
|
||||
return getContentCache(SL.getFileID())->Buffer->getBufferStart() +
|
||||
// Note that calling 'getBuffer()' may lazily page in a source file.
|
||||
return getContentCache(SL.getFileID())->getBuffer()->getBufferStart() +
|
||||
getFullFilePos(SL);
|
||||
}
|
||||
|
||||
|
@ -187,12 +210,17 @@ unsigned SourceManager::getColumnNumber(SourceLocation Loc) const {
|
|||
const char *SourceManager::getSourceName(SourceLocation Loc) const {
|
||||
unsigned FileID = Loc.getFileID();
|
||||
if (FileID == 0) return "";
|
||||
return getContentCache(FileID)->Buffer->getBufferIdentifier();
|
||||
|
||||
// To get the source name, first consult the FileEntry (if one exists) before
|
||||
// the MemBuffer as this will avoid unnecessarily paging in the MemBuffer.
|
||||
const SrcMgr::ContentCache* C = getContentCache(FileID);
|
||||
return C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier();
|
||||
}
|
||||
|
||||
static void ComputeLineNumbers(ContentCache* FI) DISABLE_INLINE;
|
||||
static void ComputeLineNumbers(ContentCache* FI) {
|
||||
const MemoryBuffer *Buffer = FI->Buffer;
|
||||
// Note that calling 'getBuffer()' may lazily page in the file.
|
||||
const MemoryBuffer *Buffer = FI->getBuffer();
|
||||
|
||||
// Find the file offsets of all of the *physical* source lines. This does
|
||||
// not look at trigraphs, escaped newlines, or anything else tricky.
|
||||
|
@ -341,7 +369,7 @@ void SourceManager::PrintStats() const {
|
|||
for (std::set<ContentCache>::const_iterator I =
|
||||
FileInfos.begin(), E = FileInfos.end(); I != E; ++I) {
|
||||
NumLineNumsComputed += I->SourceLineCache != 0;
|
||||
NumFileBytesMapped += I->Buffer->getBufferSize();
|
||||
NumFileBytesMapped += I->getSizeBytesMapped();
|
||||
}
|
||||
|
||||
llvm::cerr << NumFileBytesMapped << " bytes of files mapped, "
|
||||
|
|
Загрузка…
Ссылка в новой задаче