mirror of
https://github.com/opnsense/src.git
synced 2026-02-22 09:21:31 -05:00
all of the features in the current working draft of the upcoming C++ standard, provisionally named C++1y. The code generator's performance is greatly increased, and the loop auto-vectorizer is now enabled at -Os and -O2 in addition to -O3. The PowerPC backend has made several major improvements to code generation quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ backends have all seen major feature work. Release notes for llvm and clang can be found here: <http://llvm.org/releases/3.4/docs/ReleaseNotes.html> <http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html> MFC after: 1 month
141 lines
4.5 KiB
C++
141 lines
4.5 KiB
C++
//===- StreamableMemoryObject.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/StreamableMemoryObject.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
#include <cassert>
|
|
#include <cstring>
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
namespace {
|
|
|
|
class RawMemoryObject : public StreamableMemoryObject {
|
|
public:
|
|
RawMemoryObject(const unsigned char *Start, const unsigned char *End) :
|
|
FirstChar(Start), LastChar(End) {
|
|
assert(LastChar >= FirstChar && "Invalid start/end range");
|
|
}
|
|
|
|
virtual uint64_t getBase() const LLVM_OVERRIDE { return 0; }
|
|
virtual uint64_t getExtent() const LLVM_OVERRIDE {
|
|
return LastChar - FirstChar;
|
|
}
|
|
virtual int readByte(uint64_t address, uint8_t* ptr) const LLVM_OVERRIDE;
|
|
virtual int readBytes(uint64_t address,
|
|
uint64_t size,
|
|
uint8_t *buf) const LLVM_OVERRIDE;
|
|
virtual const uint8_t *getPointer(uint64_t address,
|
|
uint64_t size) const LLVM_OVERRIDE;
|
|
virtual bool isValidAddress(uint64_t address) const LLVM_OVERRIDE {
|
|
return validAddress(address);
|
|
}
|
|
virtual bool isObjectEnd(uint64_t address) const LLVM_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<ptrdiff_t>(address) < LastChar - FirstChar;
|
|
}
|
|
bool objectEnd(uint64_t address) const {
|
|
return static_cast<ptrdiff_t>(address) == LastChar - FirstChar;
|
|
}
|
|
|
|
RawMemoryObject(const RawMemoryObject&) LLVM_DELETED_FUNCTION;
|
|
void operator=(const RawMemoryObject&) LLVM_DELETED_FUNCTION;
|
|
};
|
|
|
|
int RawMemoryObject::readByte(uint64_t address, uint8_t* ptr) const {
|
|
if (!validAddress(address)) return -1;
|
|
*ptr = *((uint8_t *)(uintptr_t)(address + FirstChar));
|
|
return 0;
|
|
}
|
|
|
|
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::readByte(uint64_t address, uint8_t* ptr) const {
|
|
if (!fetchToPos(address)) return -1;
|
|
*ptr = Bytes[address + BytesSkipped];
|
|
return 0;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
StreamableMemoryObject *getNonStreamedMemoryObject(
|
|
const unsigned char *Start, const unsigned char *End) {
|
|
return new RawMemoryObject(Start, End);
|
|
}
|
|
|
|
StreamableMemoryObject::~StreamableMemoryObject() { }
|
|
|
|
StreamingMemoryObject::StreamingMemoryObject(DataStreamer *streamer) :
|
|
Bytes(kChunkSize), Streamer(streamer), BytesRead(0), BytesSkipped(0),
|
|
ObjectSize(0), EOFReached(false) {
|
|
BytesRead = streamer->GetBytes(&Bytes[0], kChunkSize);
|
|
}
|
|
}
|