X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FFileOutputBuffer.cpp;h=cd430f218bc367ea23e9b4f0ebf8bc8be75e7b04;hb=2b45dd58b22da40bb08e82d1564ccecca4a700f5;hp=46d5702cad1d5797544839a9395ea2d1b338610f;hpb=d04a8d4b33ff316ca4cf961e06c9e312eff8e64f;p=oota-llvm.git diff --git a/lib/Support/FileOutputBuffer.cpp b/lib/Support/FileOutputBuffer.cpp index 46d5702cad1..cd430f218bc 100644 --- a/lib/Support/FileOutputBuffer.cpp +++ b/lib/Support/FileOutputBuffer.cpp @@ -14,34 +14,26 @@ #include "llvm/Support/FileOutputBuffer.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Support/FileSystem.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" +using llvm::sys::fs::mapped_file_region; namespace llvm { - - -FileOutputBuffer::FileOutputBuffer(uint8_t *Start, uint8_t *End, - StringRef Path, StringRef TmpPath) - : BufferStart(Start), BufferEnd(End) { - FinalPath.assign(Path); - TempPath.assign(TmpPath); +FileOutputBuffer::FileOutputBuffer(mapped_file_region * R, + StringRef Path, StringRef TmpPath) + : Region(R) + , FinalPath(Path) + , TempPath(TmpPath) { } - FileOutputBuffer::~FileOutputBuffer() { - // If not already commited, delete buffer and remove temp file. - if ( BufferStart != NULL ) { - sys::fs::unmap_file_pages((void*)BufferStart, getBufferSize()); - bool Existed; - sys::fs::remove(Twine(TempPath), Existed); - } + bool Existed; + sys::fs::remove(Twine(TempPath), Existed); } - -error_code FileOutputBuffer::create(StringRef FilePath, - size_t Size, +error_code FileOutputBuffer::create(StringRef FilePath, + size_t Size, OwningPtr &Result, unsigned Flags) { // If file already exists, it must be a regular file (to be mappable). @@ -69,34 +61,27 @@ error_code FileOutputBuffer::create(StringRef FilePath, EC = sys::fs::remove(FilePath, Existed); if (EC) return EC; - + // Create new file in same directory but with random name. SmallString<128> TempFilePath; int FD; - EC = sys::fs::unique_file(Twine(FilePath) + ".tmp%%%%%%%", - FD, TempFilePath, false, 0644); + EC = sys::fs::unique_file(Twine(FilePath) + ".tmp%%%%%%%", + FD, TempFilePath, false, 0644); if (EC) return EC; - - // The unique_file() interface leaks lower layers and returns a file - // descriptor. There is no way to directly close it, so use this hack - // to hand it off to raw_fd_ostream to close for us. - { - raw_fd_ostream Dummy(FD, /*shouldClose=*/true); - } - - // Resize file to requested initial size - EC = sys::fs::resize_file(Twine(TempFilePath), Size); + + OwningPtr MappedFile( + new mapped_file_region(FD, mapped_file_region::readwrite, Size, 0, EC)); if (EC) return EC; - + // If requested, make the output file executable. if ( Flags & F_executable ) { sys::fs::file_status Stat2; EC = sys::fs::status(Twine(TempFilePath), Stat2); if (EC) return EC; - + sys::fs::perms new_perms = Stat2.permissions(); if ( new_perms & sys::fs::owner_read ) new_perms |= sys::fs::owner_exe; @@ -110,38 +95,25 @@ error_code FileOutputBuffer::create(StringRef FilePath, return EC; } - // Memory map new file. - void *Base; - EC = sys::fs::map_file_pages(Twine(TempFilePath), 0, Size, true, Base); - if (EC) - return EC; - - // Create FileOutputBuffer object to own mapped range. - uint8_t *Start = reinterpret_cast(Base); - Result.reset(new FileOutputBuffer(Start, Start+Size, FilePath, TempFilePath)); - - return error_code::success(); -} + Result.reset(new FileOutputBuffer(MappedFile.get(), FilePath, TempFilePath)); + if (Result) + MappedFile.take(); + return error_code::success(); +} error_code FileOutputBuffer::commit(int64_t NewSmallerSize) { // Unmap buffer, letting OS flush dirty pages to file on disk. - void *Start = reinterpret_cast(BufferStart); - error_code EC = sys::fs::unmap_file_pages(Start, getBufferSize()); - if (EC) - return EC; - + Region.reset(0); + // If requested, resize file as part of commit. if ( NewSmallerSize != -1 ) { - EC = sys::fs::resize_file(Twine(TempPath), NewSmallerSize); + error_code EC = sys::fs::resize_file(Twine(TempPath), NewSmallerSize); if (EC) return EC; } - + // Rename file to final name. return sys::fs::rename(Twine(TempPath), Twine(FinalPath)); } - - } // namespace -