[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