diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2014-11-12 03:55:46 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2014-11-12 03:55:46 +0000 |
commit | 79e1f9ff993c6d4eaf7a7ede20fe073f2af71645 (patch) | |
tree | 90fb001da474c994afa5655fd6addf6c52b7d044 /llvm/lib/Support/StreamingMemoryObject.cpp | |
parent | 28309185b28034edc1b54c4e2a01c399f5097f28 (diff) | |
download | bcm5719-llvm-79e1f9ff993c6d4eaf7a7ede20fe073f2af71645.tar.gz bcm5719-llvm-79e1f9ff993c6d4eaf7a7ede20fe073f2af71645.zip |
Merge StreamableMemoryObject into MemoryObject.
Every MemoryObject is a StreamableMemoryObject since the removal of
StringRefMemoryObject, so just merge the two.
I will clean up the MemoryObject interface in the upcoming commits.
llvm-svn: 221766
Diffstat (limited to 'llvm/lib/Support/StreamingMemoryObject.cpp')
-rw-r--r-- | llvm/lib/Support/StreamingMemoryObject.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/llvm/lib/Support/StreamingMemoryObject.cpp b/llvm/lib/Support/StreamingMemoryObject.cpp new file mode 100644 index 00000000000..7187ce013fa --- /dev/null +++ b/llvm/lib/Support/StreamingMemoryObject.cpp @@ -0,0 +1,124 @@ +//===- StreamingMemoryObject.cpp - Streamable data interface -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/StreamingMemoryObject.h" +#include "llvm/Support/Compiler.h" +#include <cassert> +#include <cstddef> +#include <cstring> + + +using namespace llvm; + +namespace { + +class RawMemoryObject : public MemoryObject { +public: + RawMemoryObject(const unsigned char *Start, const unsigned char *End) : + FirstChar(Start), LastChar(End) { + assert(LastChar >= FirstChar && "Invalid start/end range"); + } + + uint64_t getExtent() const override { + return LastChar - FirstChar; + } + int readBytes(uint64_t address, uint64_t size, + uint8_t *buf) const override; + const uint8_t *getPointer(uint64_t address, uint64_t size) const override; + bool isValidAddress(uint64_t address) const override { + return validAddress(address); + } + bool isObjectEnd(uint64_t address) const override { + return objectEnd(address); + } + +private: + const uint8_t* const FirstChar; + const uint8_t* const LastChar; + + // These are implemented as inline functions here to avoid multiple virtual + // calls per public function + bool validAddress(uint64_t address) const { + return static_cast<std::ptrdiff_t>(address) < LastChar - FirstChar; + } + bool objectEnd(uint64_t address) const { + return static_cast<std::ptrdiff_t>(address) == LastChar - FirstChar; + } + + RawMemoryObject(const RawMemoryObject&) LLVM_DELETED_FUNCTION; + void operator=(const RawMemoryObject&) LLVM_DELETED_FUNCTION; +}; + +int RawMemoryObject::readBytes(uint64_t address, + uint64_t size, + uint8_t *buf) const { + if (!validAddress(address) || !validAddress(address + size - 1)) return -1; + memcpy(buf, (uint8_t *)(uintptr_t)(address + FirstChar), size); + return size; +} + +const uint8_t *RawMemoryObject::getPointer(uint64_t address, + uint64_t size) const { + return FirstChar + address; +} +} // anonymous namespace + +namespace llvm { +// If the bitcode has a header, then its size is known, and we don't have to +// block until we actually want to read it. +bool StreamingMemoryObject::isValidAddress(uint64_t address) const { + if (ObjectSize && address < ObjectSize) return true; + return fetchToPos(address); +} + +bool StreamingMemoryObject::isObjectEnd(uint64_t address) const { + if (ObjectSize) return address == ObjectSize; + fetchToPos(address); + return address == ObjectSize && address != 0; +} + +uint64_t StreamingMemoryObject::getExtent() const { + if (ObjectSize) return ObjectSize; + size_t pos = BytesRead + kChunkSize; + // keep fetching until we run out of bytes + while (fetchToPos(pos)) pos += kChunkSize; + return ObjectSize; +} + +int StreamingMemoryObject::readBytes(uint64_t address, + uint64_t size, + uint8_t *buf) const { + if (!fetchToPos(address + size - 1)) return -1; + memcpy(buf, &Bytes[address + BytesSkipped], size); + return 0; +} + +bool StreamingMemoryObject::dropLeadingBytes(size_t s) { + if (BytesRead < s) return true; + BytesSkipped = s; + BytesRead -= s; + return false; +} + +void StreamingMemoryObject::setKnownObjectSize(size_t size) { + ObjectSize = size; + Bytes.reserve(size); +} + +MemoryObject *getNonStreamedMemoryObject(const unsigned char *Start, + const unsigned char *End) { + return new RawMemoryObject(Start, End); +} + +StreamingMemoryObject::StreamingMemoryObject(DataStreamer *streamer) : + Bytes(kChunkSize), Streamer(streamer), BytesRead(0), BytesSkipped(0), + ObjectSize(0), EOFReached(false) { + BytesRead = streamer->GetBytes(&Bytes[0], kChunkSize); +} +} |