[cfe-commits] r61782 - in /cfe/trunk: include/clang/Basic/SourceManager.h lib/Basic/SourceManager.cpp

Ted Kremenek kremenek at apple.com
Mon Jan 5 17:55:27 PST 2009


Author: kremenek
Date: Mon Jan  5 19:55:26 2009
New Revision: 61782

URL: http://llvm.org/viewvc/llvm-project?rev=61782&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/Basic/SourceManager.h
    cfe/trunk/lib/Basic/SourceManager.cpp

Modified: cfe/trunk/include/clang/Basic/SourceManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/SourceManager.h?rev=61782&r1=61781&r2=61782&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/SourceManager.h (original)
+++ cfe/trunk/include/clang/Basic/SourceManager.h Mon Jan  5 19:55:26 2009
@@ -48,16 +48,17 @@
   
   /// 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;
@@ -65,9 +66,28 @@
     /// NumLines - The number of lines in this ContentCache.  This is only valid
     /// 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 @@
   /// 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
@@ -506,7 +526,7 @@
   /// getContentCache - Create or return a cached ContentCache for the specified
   ///  file.  This returns null on failure.
   const SrcMgr::ContentCache* getContentCache(const FileEntry* SourceFile);
-  
+
   /// createMemBufferContentCache - Create a new ContentCache for the specified
   ///  memory buffer.
   const SrcMgr::ContentCache* 

Modified: cfe/trunk/lib/Basic/SourceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/SourceManager.cpp?rev=61782&r1=61781&r2=61782&view=diff

==============================================================================
--- cfe/trunk/lib/Basic/SourceManager.cpp (original)
+++ cfe/trunk/lib/Basic/SourceManager.cpp Mon Jan  5 19:55:26 2009
@@ -29,6 +29,26 @@
   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 @@
 
   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 @@
   // 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 @@
   // 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 @@
   // 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 @@
 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;
+static void ComputeLineNumbers(ContentCache* FI) {  
+  // 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 @@
   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, "





More information about the cfe-commits mailing list