[cfe-commits] r39027 - in /cfe/cfe/trunk: Basic/SourceBuffer.cpp include/clang/Basic/SourceBuffer.h

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:26:57 PDT 2007


Author: sabre
Date: Wed Jul 11 11:26:57 2007
New Revision: 39027

URL: http://llvm.org/viewvc/llvm-project?rev=39027&view=rev
Log:
Use read to open small files so we don't run out of file descriptors as easily.

Modified:
    cfe/cfe/trunk/Basic/SourceBuffer.cpp
    cfe/cfe/trunk/include/clang/Basic/SourceBuffer.h

Modified: cfe/cfe/trunk/Basic/SourceBuffer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Basic/SourceBuffer.cpp?rev=39027&r1=39026&r2=39027&view=diff

==============================================================================
--- cfe/cfe/trunk/Basic/SourceBuffer.cpp (original)
+++ cfe/cfe/trunk/Basic/SourceBuffer.cpp Wed Jul 11 11:26:57 2007
@@ -17,6 +17,12 @@
 #include "llvm/System/Process.h"
 #include <cstdio>
 #include <cstring>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <cerrno>
+#include <sys/fcntl.h>
+
 using namespace llvm;
 using namespace clang;
 
@@ -77,40 +83,51 @@
   return new SourceBufferMem(StartPtr, EndPtr, BufferName);
 }
 
-/// getNewMemBuffer - Allocate a new SourceBuffer of the specified size that
+/// getNewUninitMemBuffer - Allocate a new SourceBuffer of the specified size that
 /// is completely initialized to zeros.  Note that the caller should
 /// initialize the memory allocated by this method.  The memory is owned by
 /// the SourceBuffer object.
-SourceBuffer *SourceBuffer::getNewMemBuffer(unsigned Size,
-                                            const char *BufferName) {
+SourceBuffer *SourceBuffer::getNewUninitMemBuffer(unsigned Size,
+                                                  const char *BufferName) {
   char *Buf = new char[Size+1];
-  memset(Buf, 0, Size+1);
+  Buf[Size] = 0;
   SourceBufferMem *SB = new SourceBufferMem(Buf, Buf+Size, BufferName);
   // The memory for this buffer is owned by the SourceBuffer.
   SB->MustDeleteBuffer = true;
   return SB;
 }
 
+/// getNewMemBuffer - Allocate a new SourceBuffer of the specified size that
+/// is completely initialized to zeros.  Note that the caller should
+/// initialize the memory allocated by this method.  The memory is owned by
+/// the SourceBuffer object.
+SourceBuffer *SourceBuffer::getNewMemBuffer(unsigned Size,
+                                            const char *BufferName) {
+  SourceBuffer *SB = getNewUninitMemBuffer(Size, BufferName);
+  memset(const_cast<char*>(SB->getBufferStart()), 0, Size+1);
+  return SB;
+}
+
 
 //===----------------------------------------------------------------------===//
-// SourceBufferFile implementation.
+// SourceBufferMMapFile implementation.
 //===----------------------------------------------------------------------===//
 
 namespace {
-class SourceBufferFile : public SourceBuffer {
+class SourceBufferMMapFile : public SourceBuffer {
   sys::MappedFile File;
 public:
-  SourceBufferFile(const sys::Path &Filename);
+  SourceBufferMMapFile(const sys::Path &Filename);
   
   virtual const char *getBufferIdentifier() const {
     return File.path().c_str();
   }
     
-  ~SourceBufferFile();
+  ~SourceBufferMMapFile();
 };
 }
 
-SourceBufferFile::SourceBufferFile(const sys::Path &Filename) {
+SourceBufferMMapFile::SourceBufferMMapFile(const sys::Path &Filename) {
   // FIXME: This does an extra stat syscall to figure out the size, but we
   // already know the size!
   bool Failure = File.open(Filename);
@@ -137,14 +154,49 @@
   }
 }
 
-SourceBufferFile::~SourceBufferFile() {
+SourceBufferMMapFile::~SourceBufferMMapFile() {
   File.unmap();
 }
 
+//===----------------------------------------------------------------------===//
+// SourceBufferReadFile implementation.
+//===----------------------------------------------------------------------===//
 
+#include <iostream>
 SourceBuffer *SourceBuffer::getFile(const FileEntry *FileEnt) {
   try {
-    return new SourceBufferFile(sys::Path(FileEnt->getName()));
+    // If the file is larger than some threshold, use 'read', otherwise use mmap.
+    if (FileEnt->getSize() >= 4096*4)
+      return new SourceBufferMMapFile(sys::Path(FileEnt->getName()));
+
+    SourceBuffer *SB = getNewUninitMemBuffer(FileEnt->getSize(),
+                                             FileEnt->getName().c_str());
+    char *BufPtr = const_cast<char*>(SB->getBufferStart());
+    
+    int FD = ::open(FileEnt->getName().c_str(), O_RDONLY);
+    if (FD == -1) {
+      delete SB;
+      return 0;
+    }
+    
+    unsigned BytesLeft = FileEnt->getSize();
+    while (BytesLeft) {
+      ssize_t NumRead = ::read(FD, BufPtr, BytesLeft);
+      if (NumRead != -1) {
+        BytesLeft -= NumRead;
+        BufPtr += NumRead;
+      } else if (errno == EINTR) {
+        // try again
+      } else {
+        // error reading.
+        close(FD);
+        delete SB;
+        return 0;
+      }
+    }
+    close(FD);
+    
+    return SB;
   } catch (...) {
     return 0;
   }

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

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/SourceBuffer.h (original)
+++ cfe/cfe/trunk/include/clang/Basic/SourceBuffer.h Wed Jul 11 11:26:57 2007
@@ -64,6 +64,13 @@
   static SourceBuffer *getNewMemBuffer(unsigned Size,
                                        const char *BufferName = "");
   
+  /// getNewUninitMemBuffer - Allocate a new SourceBuffer of the specified size
+  /// that is not initialized.  Note that the caller should initialize the
+  /// memory allocated by this method.  The memory is owned by the SourceBuffer
+  /// object.
+  static SourceBuffer *getNewUninitMemBuffer(unsigned Size,
+                                             const char *BufferName = "");
+  
   /// getSTDIN - Read all of stdin into a file buffer, and return it.  This
   /// fails if stdin is empty.
   static SourceBuffer *getSTDIN();





More information about the cfe-commits mailing list