summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/Windows/Path.inc
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2019-07-10 00:34:13 +0000
committerReid Kleckner <rnk@google.com>2019-07-10 00:34:13 +0000
commitcc418a3af45adbe740f868a31bde6155083f0b9d (patch)
treed0b24abef24564f0f5a81d17df58ec768b2de356 /llvm/lib/Support/Windows/Path.inc
parent9c147bd40bc93376df274e8a5d51c69a55199044 (diff)
downloadbcm5719-llvm-cc418a3af45adbe740f868a31bde6155083f0b9d.tar.gz
bcm5719-llvm-cc418a3af45adbe740f868a31bde6155083f0b9d.zip
[Support] Move llvm::MemoryBuffer to sys::fs::file_t
Summary: On Windows, Posix integer file descriptors are a compatibility layer over native file handles provided by the C runtime. There is a hard limit on the maximum number of file descriptors that a process can open, and the limit is 8192. LLD typically doesn't run into this limit because it opens input files, maps them into memory, and then immediately closes the file descriptor. This prevents it from running out of FDs. For various reasons, I'd like to open handles to every input file and keep them open during linking. That requires migrating MemoryBuffer over to taking open native file handles instead of integer FDs. Reviewers: aganea, Bigcheese Reviewed By: aganea Subscribers: smeenai, silvas, mehdi_amini, hiraditya, steven_wu, dexonsmith, dang, llvm-commits, zturner Tags: #llvm Differential Revision: https://reviews.llvm.org/D63453 llvm-svn: 365588
Diffstat (limited to 'llvm/lib/Support/Windows/Path.inc')
-rw-r--r--llvm/lib/Support/Windows/Path.inc82
1 files changed, 75 insertions, 7 deletions
diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc
index 9adda233c02..045d0b9ed58 100644
--- a/llvm/lib/Support/Windows/Path.inc
+++ b/llvm/lib/Support/Windows/Path.inc
@@ -734,6 +734,10 @@ std::error_code status(int FD, file_status &Result) {
return getStatus(FileHandle, Result);
}
+std::error_code status(file_t FileHandle, file_status &Result) {
+ return getStatus(FileHandle, Result);
+}
+
unsigned getUmask() {
return 0;
}
@@ -780,10 +784,9 @@ std::error_code setLastAccessAndModificationTime(int FD, TimePoint<> AccessTime,
return std::error_code();
}
-std::error_code mapped_file_region::init(int FD, uint64_t Offset,
- mapmode Mode) {
+std::error_code mapped_file_region::init(sys::fs::file_t OrigFileHandle,
+ uint64_t Offset, mapmode Mode) {
this->Mode = Mode;
- HANDLE OrigFileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
if (OrigFileHandle == INVALID_HANDLE_VALUE)
return make_error_code(errc::bad_file_descriptor);
@@ -850,8 +853,9 @@ std::error_code mapped_file_region::init(int FD, uint64_t Offset,
return std::error_code();
}
-mapped_file_region::mapped_file_region(int fd, mapmode mode, size_t length,
- uint64_t offset, std::error_code &ec)
+mapped_file_region::mapped_file_region(sys::fs::file_t fd, mapmode mode,
+ size_t length, uint64_t offset,
+ std::error_code &ec)
: Size(length), Mapping() {
ec = init(fd, offset, mode);
if (ec)
@@ -1201,9 +1205,73 @@ Expected<file_t> openNativeFileForRead(const Twine &Name, OpenFlags Flags,
return Result;
}
-void closeFile(file_t &F) {
- ::CloseHandle(F);
+file_t convertFDToNativeFile(int FD) {
+ return reinterpret_cast<HANDLE>(::_get_osfhandle(FD));
+}
+
+file_t getStdinHandle() { return ::GetStdHandle(STD_INPUT_HANDLE); }
+file_t getStdoutHandle() { return ::GetStdHandle(STD_OUTPUT_HANDLE); }
+file_t getStderrHandle() { return ::GetStdHandle(STD_ERROR_HANDLE); }
+
+std::error_code readNativeFileImpl(file_t FileHandle, char *BufPtr, size_t BytesToRead,
+ size_t *BytesRead, OVERLAPPED *Overlap) {
+ // ReadFile can only read 2GB at a time. The caller should check the number of
+ // bytes and read in a loop until termination.
+ DWORD BytesToRead32 =
+ std::min(size_t(std::numeric_limits<DWORD>::max()), BytesToRead);
+ DWORD BytesRead32 = 0;
+ bool Success =
+ ::ReadFile(FileHandle, BufPtr, BytesToRead32, &BytesRead32, Overlap);
+ *BytesRead = BytesRead32;
+ if (!Success) {
+ DWORD Err = ::GetLastError();
+ // Pipe EOF is not an error.
+ if (Err == ERROR_BROKEN_PIPE)
+ return std::error_code();
+ return mapWindowsError(Err);
+ }
+ return std::error_code();
+}
+
+std::error_code readNativeFile(file_t FileHandle, MutableArrayRef<char> Buf,
+ size_t *BytesRead) {
+ return readNativeFileImpl(FileHandle, Buf.data(), Buf.size(), BytesRead,
+ /*Overlap=*/nullptr);
+}
+
+std::error_code readNativeFileSlice(file_t FileHandle,
+ MutableArrayRef<char> Buf, size_t Offset) {
+ char *BufPtr = Buf.data();
+ size_t BytesLeft = Buf.size();
+
+ while (BytesLeft) {
+ uint64_t CurOff = Buf.size() - BytesLeft + Offset;
+ OVERLAPPED Overlapped = {};
+ Overlapped.Offset = uint32_t(CurOff);
+ Overlapped.OffsetHigh = uint32_t(uint64_t(CurOff) >> 32);
+
+ size_t BytesRead = 0;
+ if (auto EC = readNativeFileImpl(FileHandle, BufPtr, BytesLeft, &BytesRead,
+ &Overlapped))
+ return EC;
+
+ // Once we reach EOF, zero the remaining bytes in the buffer.
+ if (BytesRead == 0) {
+ memset(BufPtr, 0, BytesLeft);
+ break;
+ }
+ BytesLeft -= BytesRead;
+ BufPtr += BytesRead;
+ }
+ return std::error_code();
+}
+
+std::error_code closeFile(file_t &F) {
+ file_t TmpF = F;
F = kInvalidFile;
+ if (!::CloseHandle(TmpF))
+ return mapWindowsError(::GetLastError());
+ return std::error_code();
}
std::error_code remove_directories(const Twine &path, bool IgnoreErrors) {
OpenPOWER on IntegriCloud