aboutsummaryrefslogtreecommitdiff
path: root/lib/Support
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/APFloat.cpp6
-rw-r--r--lib/Support/APInt.cpp8
-rw-r--r--lib/Support/FileOutputBuffer.cpp4
-rw-r--r--lib/Support/MemoryBuffer.cpp78
-rw-r--r--lib/Support/PathV2.cpp24
-rw-r--r--lib/Support/Unix/Memory.inc9
-rw-r--r--lib/Support/Unix/PathV2.inc17
-rw-r--r--lib/Support/Windows/PathV2.inc61
-rw-r--r--lib/Support/raw_ostream.cpp7
9 files changed, 139 insertions, 75 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index 5b68fbb270..6182e34150 100644
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -3311,10 +3311,8 @@ namespace {
significand = significand.udiv(divisor);
- // Truncate the significand down to its active bit count, but
- // don't try to drop below 32.
- unsigned newPrecision = std::max(32U, significand.getActiveBits());
- significand = significand.trunc(newPrecision);
+ // Truncate the significand down to its active bit count.
+ significand = significand.trunc(significand.getActiveBits());
}
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index 07cb057b48..e8534753b4 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -559,12 +559,12 @@ bool APInt::slt(const APInt& RHS) const {
if (lhsNeg) {
// Sign bit is set so perform two's complement to make it positive
lhs.flipAllBits();
- lhs++;
+ ++lhs;
}
if (rhsNeg) {
// Sign bit is set so perform two's complement to make it positive
rhs.flipAllBits();
- rhs++;
+ ++rhs;
}
// Now we have unsigned values to compare so do the comparison if necessary
@@ -2116,7 +2116,7 @@ void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {
}
// If its negative, put it in two's complement form
if (isNeg) {
- (*this)--;
+ --(*this);
this->flipAllBits();
}
}
@@ -2197,7 +2197,7 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix,
// Flip the bits and add one to turn it into the equivalent positive
// value and put a '-' in the result.
Tmp.flipAllBits();
- Tmp++;
+ ++Tmp;
Str.push_back('-');
}
diff --git a/lib/Support/FileOutputBuffer.cpp b/lib/Support/FileOutputBuffer.cpp
index cd430f218b..1ee69b6023 100644
--- a/lib/Support/FileOutputBuffer.cpp
+++ b/lib/Support/FileOutputBuffer.cpp
@@ -70,8 +70,8 @@ error_code FileOutputBuffer::create(StringRef FilePath,
if (EC)
return EC;
- OwningPtr<mapped_file_region> MappedFile(
- new mapped_file_region(FD, mapped_file_region::readwrite, Size, 0, EC));
+ OwningPtr<mapped_file_region> MappedFile(new mapped_file_region(
+ FD, true, mapped_file_region::readwrite, Size, 0, EC));
if (EC)
return EC;
diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp
index 4c558b37cf..8042237253 100644
--- a/lib/Support/MemoryBuffer.cpp
+++ b/lib/Support/MemoryBuffer.cpp
@@ -72,13 +72,15 @@ static void CopyStringRef(char *Memory, StringRef Data) {
Memory[Data.size()] = 0; // Null terminate string.
}
-/// GetNamedBuffer - Allocates a new MemoryBuffer with Name copied after it.
-template <typename T>
-static T *GetNamedBuffer(StringRef Buffer, StringRef Name,
- bool RequiresNullTerminator) {
- char *Mem = static_cast<char*>(operator new(sizeof(T) + Name.size() + 1));
- CopyStringRef(Mem + sizeof(T), Name);
- return new (Mem) T(Buffer, RequiresNullTerminator);
+struct NamedBufferAlloc {
+ StringRef Name;
+ NamedBufferAlloc(StringRef Name) : Name(Name) {}
+};
+
+void *operator new(size_t N, const NamedBufferAlloc &Alloc) {
+ char *Mem = static_cast<char *>(operator new(N + Alloc.Name.size() + 1));
+ CopyStringRef(Mem + N, Alloc.Name);
+ return Mem;
}
namespace {
@@ -105,8 +107,8 @@ public:
MemoryBuffer *MemoryBuffer::getMemBuffer(StringRef InputData,
StringRef BufferName,
bool RequiresNullTerminator) {
- return GetNamedBuffer<MemoryBufferMem>(InputData, BufferName,
- RequiresNullTerminator);
+ return new (NamedBufferAlloc(BufferName))
+ MemoryBufferMem(InputData, RequiresNullTerminator);
}
/// getMemBufferCopy - Open the specified memory range as a MemoryBuffer,
@@ -183,24 +185,38 @@ error_code MemoryBuffer::getFileOrSTDIN(const char *Filename,
//===----------------------------------------------------------------------===//
namespace {
-/// MemoryBufferMMapFile - This represents a file that was mapped in with the
-/// sys::Path::MapInFilePages method. When destroyed, it calls the
-/// sys::Path::UnMapFilePages method.
-class MemoryBufferMMapFile : public MemoryBufferMem {
-public:
- MemoryBufferMMapFile(StringRef Buffer, bool RequiresNullTerminator)
- : MemoryBufferMem(Buffer, RequiresNullTerminator) { }
+/// \brief Memorry maps a file descriptor using sys::fs::mapped_file_region.
+///
+/// This handles converting the offset into a legal offset on the platform.
+class MemoryBufferMMapFile : public MemoryBuffer {
+ sys::fs::mapped_file_region MFR;
+
+ static uint64_t getLegalMapOffset(uint64_t Offset) {
+ return Offset & ~(sys::fs::mapped_file_region::alignment() - 1);
+ }
+
+ static uint64_t getLegalMapSize(uint64_t Len, uint64_t Offset) {
+ return Len + (Offset - getLegalMapOffset(Offset));
+ }
- ~MemoryBufferMMapFile() {
- static int PageSize = sys::process::get_self()->page_size();
+ const char *getStart(uint64_t Len, uint64_t Offset) {
+ return MFR.const_data() + (Offset - getLegalMapOffset(Offset));
+ }
- uintptr_t Start = reinterpret_cast<uintptr_t>(getBufferStart());
- size_t Size = getBufferSize();
- uintptr_t RealStart = Start & ~(PageSize - 1);
- size_t RealSize = Size + (Start - RealStart);
+public:
+ MemoryBufferMMapFile(bool RequiresNullTerminator, int FD, uint64_t Len,
+ uint64_t Offset, error_code EC)
+ : MFR(FD, false, sys::fs::mapped_file_region::readonly,
+ getLegalMapSize(Len, Offset), getLegalMapOffset(Offset), EC) {
+ if (!EC) {
+ const char *Start = getStart(Len, Offset);
+ init(Start, Start + Len, RequiresNullTerminator);
+ }
+ }
- sys::Path::UnMapFilePages(reinterpret_cast<const char*>(RealStart),
- RealSize);
+ virtual const char *getBufferIdentifier() const LLVM_OVERRIDE {
+ // The name is stored after the class itself.
+ return reinterpret_cast<const char *>(this + 1);
}
virtual BufferKind getBufferKind() const LLVM_OVERRIDE {
@@ -344,17 +360,11 @@ error_code MemoryBuffer::getOpenFile(int FD, const char *Filename,
if (shouldUseMmap(FD, FileSize, MapSize, Offset, RequiresNullTerminator,
PageSize)) {
- off_t RealMapOffset = Offset & ~(PageSize - 1);
- off_t Delta = Offset - RealMapOffset;
- size_t RealMapSize = MapSize + Delta;
-
- if (const char *Pages = sys::Path::MapInFilePages(FD,
- RealMapSize,
- RealMapOffset)) {
- result.reset(GetNamedBuffer<MemoryBufferMMapFile>(
- StringRef(Pages + Delta, MapSize), Filename, RequiresNullTerminator));
+ error_code EC;
+ result.reset(new (NamedBufferAlloc(Filename)) MemoryBufferMMapFile(
+ RequiresNullTerminator, FD, MapSize, Offset, EC));
+ if (!EC)
return error_code::success();
- }
}
MemoryBuffer *Buf = MemoryBuffer::getNewUninitMemBuffer(MapSize, Filename);
diff --git a/lib/Support/PathV2.cpp b/lib/Support/PathV2.cpp
index 41add96194..58a6ea720e 100644
--- a/lib/Support/PathV2.cpp
+++ b/lib/Support/PathV2.cpp
@@ -18,6 +18,9 @@
#include <cctype>
#include <cstdio>
#include <cstring>
+#ifdef __APPLE__
+#include <unistd.h>
+#endif
namespace {
using llvm::StringRef;
@@ -493,6 +496,27 @@ bool is_separator(char value) {
void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result) {
result.clear();
+#ifdef __APPLE__
+ // On Darwin, use DARWIN_USER_TEMP_DIR or DARWIN_USER_CACHE_DIR.
+ int ConfName = erasedOnReboot? _CS_DARWIN_USER_TEMP_DIR
+ : _CS_DARWIN_USER_CACHE_DIR;
+ size_t ConfLen = confstr(ConfName, 0, 0);
+ if (ConfLen > 0) {
+ do {
+ result.resize(ConfLen);
+ ConfLen = confstr(ConfName, result.data(), result.size());
+ } while (ConfLen > 0 && ConfLen != result.size());
+
+ if (ConfLen > 0) {
+ assert(result.back() == 0);
+ result.pop_back();
+ return;
+ }
+
+ result.clear();
+ }
+#endif
+
// Check whether the temporary directory is specified by an environment
// variable.
const char *EnvironmentVariable;
diff --git a/lib/Support/Unix/Memory.inc b/lib/Support/Unix/Memory.inc
index e00394ec6a..e9b26bdb80 100644
--- a/lib/Support/Unix/Memory.inc
+++ b/lib/Support/Unix/Memory.inc
@@ -332,7 +332,16 @@ void Memory::InvalidateInstructionCache(const void *Addr,
__clear_cache(const_cast<char *>(Start), const_cast<char *>(End));
# elif defined(__mips__)
const char *Start = static_cast<const char *>(Addr);
+# if defined(ANDROID)
+ // The declaration of "cacheflush" in Android bionic:
+ // extern int cacheflush(long start, long end, long flags);
+ const char *End = Start + Len;
+ long LStart = reinterpret_cast<long>(const_cast<char *>(Start));
+ long LEnd = reinterpret_cast<long>(const_cast<char *>(End));
+ cacheflush(LStart, LEnd, BCACHE);
+# else
cacheflush(const_cast<char *>(Start), Len, BCACHE);
+# endif
# endif
#endif // end apple
diff --git a/lib/Support/Unix/PathV2.inc b/lib/Support/Unix/PathV2.inc
index 44b31b3202..a3dfd4b0a3 100644
--- a/lib/Support/Unix/PathV2.inc
+++ b/lib/Support/Unix/PathV2.inc
@@ -475,12 +475,14 @@ rety_open_create:
return error_code::success();
}
-error_code mapped_file_region::init(int fd, uint64_t offset) {
- AutoFD FD(fd);
+error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) {
+ AutoFD ScopedFD(FD);
+ if (!CloseFD)
+ ScopedFD.take();
// Figure out how large the file is.
struct stat FileInfo;
- if (fstat(fd, &FileInfo) == -1)
+ if (fstat(FD, &FileInfo) == -1)
return error_code(errno, system_category());
uint64_t FileSize = FileInfo.st_size;
@@ -488,7 +490,7 @@ error_code mapped_file_region::init(int fd, uint64_t offset) {
Size = FileSize;
else if (FileSize < Size) {
// We need to grow the file.
- if (ftruncate(fd, Size) == -1)
+ if (ftruncate(FD, Size) == -1)
return error_code(errno, system_category());
}
@@ -497,7 +499,7 @@ error_code mapped_file_region::init(int fd, uint64_t offset) {
#ifdef MAP_FILE
flags |= MAP_FILE;
#endif
- Mapping = ::mmap(0, Size, prot, flags, fd, offset);
+ Mapping = ::mmap(0, Size, prot, flags, FD, Offset);
if (Mapping == MAP_FAILED)
return error_code(errno, system_category());
return error_code::success();
@@ -526,12 +528,13 @@ mapped_file_region::mapped_file_region(const Twine &path,
return;
}
- ec = init(ofd, offset);
+ ec = init(ofd, true, offset);
if (ec)
Mapping = 0;
}
mapped_file_region::mapped_file_region(int fd,
+ bool closefd,
mapmode mode,
uint64_t length,
uint64_t offset,
@@ -545,7 +548,7 @@ mapped_file_region::mapped_file_region(int fd,
return;
}
- ec = init(fd, offset);
+ ec = init(fd, closefd, offset);
if (ec)
Mapping = 0;
}
diff --git a/lib/Support/Windows/PathV2.inc b/lib/Support/Windows/PathV2.inc
index 2e6cc96e7f..23f3d14f91 100644
--- a/lib/Support/Windows/PathV2.inc
+++ b/lib/Support/Windows/PathV2.inc
@@ -593,6 +593,10 @@ retry_random_path:
random_path_utf16.push_back(0);
random_path_utf16.pop_back();
+ // Make sure we don't fall into an infinite loop by constantly trying
+ // to create the parent path.
+ bool TriedToCreateParent = false;
+
// Try to create + open the path.
retry_create_file:
HANDLE TempFileHandle = ::CreateFileW(random_path_utf16.begin(),
@@ -610,7 +614,9 @@ retry_create_file:
if (ec == windows_error::file_exists)
goto retry_random_path;
// Check for non-existing parent directories.
- if (ec == windows_error::path_not_found) {
+ if (ec == windows_error::path_not_found && !TriedToCreateParent) {
+ TriedToCreateParent = true;
+
// Create the directories using result_path as temp storage.
if (error_code ec = UTF16ToUTF8(random_path_utf16.begin(),
random_path_utf16.size(), result_path))
@@ -705,13 +711,14 @@ error_code get_magic(const Twine &path, uint32_t len,
return error_code::success();
}
-error_code mapped_file_region::init(int FD, uint64_t Offset) {
+error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) {
FileDescriptor = FD;
// Make sure that the requested size fits within SIZE_T.
if (Size > std::numeric_limits<SIZE_T>::max()) {
- if (FileDescriptor)
- _close(FileDescriptor);
- else
+ if (FileDescriptor) {
+ if (CloseFD)
+ _close(FileDescriptor);
+ } else
::CloseHandle(FileHandle);
return make_error_code(errc::invalid_argument);
}
@@ -732,9 +739,10 @@ error_code mapped_file_region::init(int FD, uint64_t Offset) {
0);
if (FileMappingHandle == NULL) {
error_code ec = windows_error(GetLastError());
- if (FileDescriptor)
- _close(FileDescriptor);
- else
+ if (FileDescriptor) {
+ if (CloseFD)
+ _close(FileDescriptor);
+ } else
::CloseHandle(FileHandle);
return ec;
}
@@ -754,9 +762,10 @@ error_code mapped_file_region::init(int FD, uint64_t Offset) {
if (Mapping == NULL) {
error_code ec = windows_error(GetLastError());
::CloseHandle(FileMappingHandle);
- if (FileDescriptor)
- _close(FileDescriptor);
- else
+ if (FileDescriptor) {
+ if (CloseFD)
+ _close(FileDescriptor);
+ } else
::CloseHandle(FileHandle);
return ec;
}
@@ -768,14 +777,24 @@ error_code mapped_file_region::init(int FD, uint64_t Offset) {
error_code ec = windows_error(GetLastError());
::UnmapViewOfFile(Mapping);
::CloseHandle(FileMappingHandle);
- if (FileDescriptor)
- _close(FileDescriptor);
- else
+ if (FileDescriptor) {
+ if (CloseFD)
+ _close(FileDescriptor);
+ } else
::CloseHandle(FileHandle);
return ec;
}
Size = mbi.RegionSize;
}
+
+ // Close all the handles except for the view. It will keep the other handles
+ // alive.
+ ::CloseHandle(FileMappingHandle);
+ if (FileDescriptor) {
+ if (CloseFD)
+ _close(FileDescriptor); // Also closes FileHandle.
+ } else
+ ::CloseHandle(FileHandle);
return error_code::success();
}
@@ -815,7 +834,7 @@ mapped_file_region::mapped_file_region(const Twine &path,
}
FileDescriptor = 0;
- ec = init(FileDescriptor, offset);
+ ec = init(FileDescriptor, true, offset);
if (ec) {
Mapping = FileMappingHandle = 0;
FileHandle = INVALID_HANDLE_VALUE;
@@ -824,6 +843,7 @@ mapped_file_region::mapped_file_region(const Twine &path,
}
mapped_file_region::mapped_file_region(int fd,
+ bool closefd,
mapmode mode,
uint64_t length,
uint64_t offset,
@@ -836,13 +856,14 @@ mapped_file_region::mapped_file_region(int fd,
, FileMappingHandle() {
FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
if (FileHandle == INVALID_HANDLE_VALUE) {
- _close(FileDescriptor);
+ if (closefd)
+ _close(FileDescriptor);
FileDescriptor = 0;
ec = make_error_code(errc::bad_file_descriptor);
return;
}
- ec = init(FileDescriptor, offset);
+ ec = init(FileDescriptor, closefd, offset);
if (ec) {
Mapping = FileMappingHandle = 0;
FileHandle = INVALID_HANDLE_VALUE;
@@ -853,12 +874,6 @@ mapped_file_region::mapped_file_region(int fd,
mapped_file_region::~mapped_file_region() {
if (Mapping)
::UnmapViewOfFile(Mapping);
- if (FileMappingHandle)
- ::CloseHandle(FileMappingHandle);
- if (FileDescriptor)
- _close(FileDescriptor);
- else if (FileHandle != INVALID_HANDLE_VALUE)
- ::CloseHandle(FileHandle);
}
#if LLVM_HAS_RVALUE_REFERENCES
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp
index f71abd3b24..da26a371a7 100644
--- a/lib/Support/raw_ostream.cpp
+++ b/lib/Support/raw_ostream.cpp
@@ -306,7 +306,12 @@ raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
if (LLVM_UNLIKELY(OutBufCur == OutBufStart)) {
size_t BytesToWrite = Size - (Size % NumBytes);
write_impl(Ptr, BytesToWrite);
- copy_to_buffer(Ptr + BytesToWrite, Size - BytesToWrite);
+ size_t BytesRemaining = Size - BytesToWrite;
+ if (BytesRemaining > size_t(OutBufEnd - OutBufCur)) {
+ // Too much left over to copy into our buffer.
+ return write(Ptr + BytesToWrite, BytesRemaining);
+ }
+ copy_to_buffer(Ptr + BytesToWrite, BytesRemaining);
return *this;
}