First version of the MappedFile abstraction for operating system idependent
mapping of files. This first version uses mmap where its available. The
class needs to implement an alternate mechanism based on malloc'd memory
and file reading/writing for platforms without virtual memory.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16649 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/System/AIX/MappedFile.cpp b/lib/System/AIX/MappedFile.cpp
new file mode 100644
index 0000000..946ebad
--- /dev/null
+++ b/lib/System/AIX/MappedFile.cpp
@@ -0,0 +1,17 @@
+//===- AIX/MappedFile.cpp - AIX MappedFile Implementation --------*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the AIX specific implementation of the MappedFile concept.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the generic unix implementation
+#include "../Unix/MappedFile.cpp"
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Cygwin/MappedFile.cpp b/lib/System/Cygwin/MappedFile.cpp
new file mode 100644
index 0000000..09a0575
--- /dev/null
+++ b/lib/System/Cygwin/MappedFile.cpp
@@ -0,0 +1,18 @@
+//===- Cygwin/MappedFile.cpp - Cygwin MappedFile Implementation -*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Cygwin specific implementation of the MappedFile
+// concept.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the generic unix implementation
+#include "../Unix/MappedFile.cpp"
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Darwin/MappedFile.cpp b/lib/System/Darwin/MappedFile.cpp
new file mode 100644
index 0000000..c3f2656
--- /dev/null
+++ b/lib/System/Darwin/MappedFile.cpp
@@ -0,0 +1,18 @@
+//===- Darwin/MappedFile.cpp - Darwin MappedFile Implementation -*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Darwin specific implementation of the MappedFile
+// concept.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the generic unix implementation
+#include "../Unix/MappedFile.cpp"
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/FreeBSD/MappedFile.cpp b/lib/System/FreeBSD/MappedFile.cpp
new file mode 100644
index 0000000..a066919
--- /dev/null
+++ b/lib/System/FreeBSD/MappedFile.cpp
@@ -0,0 +1,18 @@
+//===- FreeBSD/MappedFile.cpp - FreeBSD MappedFile Impl. --------*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the FreeBSD specific implementation of the MappedFile
+// concept.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the generic unix implementation
+#include "../Unix/MappedFile.cpp"
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Interix/MappedFile.cpp b/lib/System/Interix/MappedFile.cpp
new file mode 100644
index 0000000..1600ea4
--- /dev/null
+++ b/lib/System/Interix/MappedFile.cpp
@@ -0,0 +1,18 @@
+//===- Interix/MappedFile.cpp - Interix MappedFile Impl. --------*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Interix specific implementation of the MappedFile
+// concept.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the generic unix implementation
+#include "../Unix/MappedFile.cpp"
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Linux/MappedFile.cpp b/lib/System/Linux/MappedFile.cpp
new file mode 100644
index 0000000..d8fb35e
--- /dev/null
+++ b/lib/System/Linux/MappedFile.cpp
@@ -0,0 +1,18 @@
+//===- Linux/MappedFile.cpp - Linux MappedFile Implementation ---*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Linux specific implementation of the MappedFile
+// concept.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the generic unix implementation
+#include "../Unix/MappedFile.cpp"
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/MappedFile.cpp b/lib/System/MappedFile.cpp
new file mode 100644
index 0000000..55e1701
--- /dev/null
+++ b/lib/System/MappedFile.cpp
@@ -0,0 +1,29 @@
+//===- MappedFile.cpp - MappedFile Support ----------------------*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file implements the mapped file concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/System/MappedFile.h"
+
+namespace llvm {
+using namespace sys;
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only TRULY operating system
+//===          independent code. 
+//===----------------------------------------------------------------------===//
+
+}
+
+// Include the platform-specific parts of this class.
+#include "platform/MappedFile.cpp"
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/SunOS/MappedFile.cpp b/lib/System/SunOS/MappedFile.cpp
new file mode 100644
index 0000000..ebde62a
--- /dev/null
+++ b/lib/System/SunOS/MappedFile.cpp
@@ -0,0 +1,18 @@
+//===- SunOS/MappedFile.cpp - SunOS MappedFile Implementation ---*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the SunOS specific implementation of the MappedFile
+// concept.
+//
+//===----------------------------------------------------------------------===//
+
+// Include the generic unix implementation
+#include "../Unix/MappedFile.cpp"
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Unix/MappedFile.cpp b/lib/System/Unix/MappedFile.cpp
new file mode 100644
index 0000000..d853ace
--- /dev/null
+++ b/lib/System/Unix/MappedFile.cpp
@@ -0,0 +1,138 @@
+//===- Unix/MappedFile.cpp - Unix MappedFile Implementation -----*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the generic Unix implementation of the MappedFile concept.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//===          is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/System/Process.h"
+#include "Unix.h"
+#include <sys/fcntl.h>
+#include <sys/mman.h>
+
+namespace llvm {
+using namespace sys;
+
+struct sys::MappedFileInfo {
+  int fd_;
+  struct stat sbuf_;
+};
+
+void MappedFile::initialize() {
+  if (path_.exists()) {
+    info_ = new MappedFileInfo;
+    int mode = 0;
+    if (options_&READ_ACCESS) 
+      if (options_&WRITE_ACCESS)
+        mode = O_RDWR;
+      else
+        mode = O_RDONLY;
+    else if (options_&WRITE_ACCESS)
+      mode = O_WRONLY;
+    info_->fd_ = ::open(path_.c_str(),mode);
+    if (info_->fd_ < 0) {
+      delete info_;
+      info_ = 0;
+      ThrowErrno(std::string("Can't open file: ") + path_.get());
+    }
+    struct stat sbuf;
+    if(::fstat(info_->fd_, &info_->sbuf_) < 0) {
+      ::close(info_->fd_);
+      delete info_;
+      info_ = 0;
+      ThrowErrno(std::string("Can't stat file: ") + path_.get());
+    }
+  }
+}
+
+void MappedFile::terminate() {
+  assert(info_ && "MappedFile not initialized");
+  if (info_->fd_ >= 0)
+    ::close(info_->fd_);
+  delete info_;
+  info_ = 0;
+}
+
+void MappedFile::unmap() {
+  assert(info_ && "MappedFile not initialized");
+  if (isMapped()) {
+    if (options_ & WRITE_ACCESS)
+      ::msync(base_, info_->sbuf_.st_size, MS_SYNC);
+    ::munmap(base_, info_->sbuf_.st_size);
+  }
+}
+
+void* MappedFile::map() {
+  if (!isMapped()) {
+    int prot = PROT_NONE;
+    int flags = MAP_FILE;
+    if (options_ == 0) {
+      prot = PROT_READ;
+      flags = MAP_PRIVATE;
+    } else {
+      if (options_ & READ_ACCESS)
+        prot |= PROT_READ;
+      if (options_ & WRITE_ACCESS)
+        prot |= PROT_WRITE;
+      if (options_ & EXEC_ACCESS)
+        prot |= PROT_EXEC;
+      if (options_ & SHARED_MAPPING)
+        flags |= MAP_SHARED;
+      else
+        flags |= MAP_PRIVATE;
+    }
+    size_t map_size = ((info_->sbuf_.st_size / Process::GetPageSize())+1) *
+      Process::GetPageSize();
+
+    base_ = ::mmap(0, map_size, prot, flags, info_->fd_, 0);
+    if (base_ == MAP_FAILED)
+      ThrowErrno(std::string("Can't map file:") + path_.get());
+  }
+  return base_;
+}
+
+size_t MappedFile::size() {
+  assert(info_ && "MappedFile not initialized");
+  return info_->sbuf_.st_size;
+}
+
+void MappedFile::size(size_t new_size) {
+  assert(info_ && "MappedFile not initialized");
+
+  // Take the mapping out of memory
+  this->unmap();
+
+  // Adjust the current size to a page boundary
+  size_t cur_size = ((info_->sbuf_.st_size / Process::GetPageSize())+1) *
+    Process::GetPageSize();
+
+  // Adjust the new_size to a page boundary
+  new_size = ((new_size / Process::GetPageSize())+1) *
+    Process::GetPageSize();
+
+  // If the file needs to be extended
+  if (new_size > cur_size) {
+    // Ensure we can allocate at least the idodes necessary to handle the
+    // file size requested. 
+    ::lseek(info_->fd_, new_size, SEEK_SET);
+    ::write(info_->fd_, "\0", 1);
+  }
+
+  // Seek to current end of file. 
+  this->map();
+}
+
+}
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Unix/MappedFile.inc b/lib/System/Unix/MappedFile.inc
new file mode 100644
index 0000000..d853ace
--- /dev/null
+++ b/lib/System/Unix/MappedFile.inc
@@ -0,0 +1,138 @@
+//===- Unix/MappedFile.cpp - Unix MappedFile Implementation -----*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the generic Unix implementation of the MappedFile concept.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+//=== WARNING: Implementation here must contain only generic UNIX code that
+//===          is guaranteed to work on *all* UNIX variants.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/System/Process.h"
+#include "Unix.h"
+#include <sys/fcntl.h>
+#include <sys/mman.h>
+
+namespace llvm {
+using namespace sys;
+
+struct sys::MappedFileInfo {
+  int fd_;
+  struct stat sbuf_;
+};
+
+void MappedFile::initialize() {
+  if (path_.exists()) {
+    info_ = new MappedFileInfo;
+    int mode = 0;
+    if (options_&READ_ACCESS) 
+      if (options_&WRITE_ACCESS)
+        mode = O_RDWR;
+      else
+        mode = O_RDONLY;
+    else if (options_&WRITE_ACCESS)
+      mode = O_WRONLY;
+    info_->fd_ = ::open(path_.c_str(),mode);
+    if (info_->fd_ < 0) {
+      delete info_;
+      info_ = 0;
+      ThrowErrno(std::string("Can't open file: ") + path_.get());
+    }
+    struct stat sbuf;
+    if(::fstat(info_->fd_, &info_->sbuf_) < 0) {
+      ::close(info_->fd_);
+      delete info_;
+      info_ = 0;
+      ThrowErrno(std::string("Can't stat file: ") + path_.get());
+    }
+  }
+}
+
+void MappedFile::terminate() {
+  assert(info_ && "MappedFile not initialized");
+  if (info_->fd_ >= 0)
+    ::close(info_->fd_);
+  delete info_;
+  info_ = 0;
+}
+
+void MappedFile::unmap() {
+  assert(info_ && "MappedFile not initialized");
+  if (isMapped()) {
+    if (options_ & WRITE_ACCESS)
+      ::msync(base_, info_->sbuf_.st_size, MS_SYNC);
+    ::munmap(base_, info_->sbuf_.st_size);
+  }
+}
+
+void* MappedFile::map() {
+  if (!isMapped()) {
+    int prot = PROT_NONE;
+    int flags = MAP_FILE;
+    if (options_ == 0) {
+      prot = PROT_READ;
+      flags = MAP_PRIVATE;
+    } else {
+      if (options_ & READ_ACCESS)
+        prot |= PROT_READ;
+      if (options_ & WRITE_ACCESS)
+        prot |= PROT_WRITE;
+      if (options_ & EXEC_ACCESS)
+        prot |= PROT_EXEC;
+      if (options_ & SHARED_MAPPING)
+        flags |= MAP_SHARED;
+      else
+        flags |= MAP_PRIVATE;
+    }
+    size_t map_size = ((info_->sbuf_.st_size / Process::GetPageSize())+1) *
+      Process::GetPageSize();
+
+    base_ = ::mmap(0, map_size, prot, flags, info_->fd_, 0);
+    if (base_ == MAP_FAILED)
+      ThrowErrno(std::string("Can't map file:") + path_.get());
+  }
+  return base_;
+}
+
+size_t MappedFile::size() {
+  assert(info_ && "MappedFile not initialized");
+  return info_->sbuf_.st_size;
+}
+
+void MappedFile::size(size_t new_size) {
+  assert(info_ && "MappedFile not initialized");
+
+  // Take the mapping out of memory
+  this->unmap();
+
+  // Adjust the current size to a page boundary
+  size_t cur_size = ((info_->sbuf_.st_size / Process::GetPageSize())+1) *
+    Process::GetPageSize();
+
+  // Adjust the new_size to a page boundary
+  new_size = ((new_size / Process::GetPageSize())+1) *
+    Process::GetPageSize();
+
+  // If the file needs to be extended
+  if (new_size > cur_size) {
+    // Ensure we can allocate at least the idodes necessary to handle the
+    // file size requested. 
+    ::lseek(info_->fd_, new_size, SEEK_SET);
+    ::write(info_->fd_, "\0", 1);
+  }
+
+  // Seek to current end of file. 
+  this->map();
+}
+
+}
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Win32/MappedFile.cpp b/lib/System/Win32/MappedFile.cpp
new file mode 100644
index 0000000..d106eb1
--- /dev/null
+++ b/lib/System/Win32/MappedFile.cpp
@@ -0,0 +1,38 @@
+//===- Win32/MappedFile.cpp - Win32 MappedFile Implementation ---*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of the MappedFile
+// concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Win32.h"
+
+void MappedFile::initialize() {
+}
+
+void MappedFile::terminate() {
+}
+
+void MappedFile::unmap() {
+}
+
+void* MappedFile::map() {
+  static char junk[4096];
+  return junk;
+}
+
+size_t MappedFile::size() {
+  return 4096;
+}
+
+void MappedFile::size(size_t new_size) {
+}
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab
diff --git a/lib/System/Win32/MappedFile.inc b/lib/System/Win32/MappedFile.inc
new file mode 100644
index 0000000..d106eb1
--- /dev/null
+++ b/lib/System/Win32/MappedFile.inc
@@ -0,0 +1,38 @@
+//===- Win32/MappedFile.cpp - Win32 MappedFile Implementation ---*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the 
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
+//
+// This file provides the Win32 specific implementation of the MappedFile
+// concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Win32.h"
+
+void MappedFile::initialize() {
+}
+
+void MappedFile::terminate() {
+}
+
+void MappedFile::unmap() {
+}
+
+void* MappedFile::map() {
+  static char junk[4096];
+  return junk;
+}
+
+size_t MappedFile::size() {
+  return 4096;
+}
+
+void MappedFile::size(size_t new_size) {
+}
+
+// vim: sw=2 smartindent smarttab tw=80 autoindent expandtab