1
//===- StreamableMemoryObject.h - Streamable data interface -----*- C++ -*-===//
3
// The LLVM Compiler Infrastructure
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
8
//===----------------------------------------------------------------------===//
11
#ifndef STREAMABLEMEMORYOBJECT_H_
12
#define STREAMABLEMEMORYOBJECT_H_
14
#include "llvm/ADT/OwningPtr.h"
15
#include "llvm/Support/MemoryObject.h"
16
#include "llvm/Support/DataStream.h"
21
/// StreamableMemoryObject - Interface to data which might be streamed.
22
/// Streamability has 2 important implications/restrictions. First, the data
23
/// might not yet exist in memory when the request is made. This just means
24
/// that readByte/readBytes might have to block or do some work to get it.
25
/// More significantly, the exact size of the object might not be known until
26
/// it has all been fetched. This means that to return the right result,
27
/// getExtent must also wait for all the data to arrive; therefore it should
28
/// not be called on objects which are actually streamed (this would defeat
29
/// the purpose of streaming). Instead, isValidAddress and isObjectEnd can be
30
/// used to test addresses without knowing the exact size of the stream.
31
/// Finally, getPointer can be used instead of readBytes to avoid extra copying.
32
class StreamableMemoryObject : public MemoryObject {
34
/// Destructor - Override as necessary.
35
virtual ~StreamableMemoryObject();
37
/// getBase - Returns the lowest valid address in the region.
39
/// @result - The lowest valid address.
40
virtual uint64_t getBase() const = 0;
42
/// getExtent - Returns the size of the region in bytes. (The region is
43
/// contiguous, so the highest valid address of the region
44
/// is getBase() + getExtent() - 1).
45
/// May block until all bytes in the stream have been read
47
/// @result - The size of the region.
48
virtual uint64_t getExtent() const = 0;
50
/// readByte - Tries to read a single byte from the region.
51
/// May block until (address - base) bytes have been read
52
/// @param address - The address of the byte, in the same space as getBase().
53
/// @param ptr - A pointer to a byte to be filled in. Must be non-NULL.
54
/// @result - 0 if successful; -1 if not. Failure may be due to a
55
/// bounds violation or an implementation-specific error.
56
virtual int readByte(uint64_t address, uint8_t* ptr) const = 0;
58
/// readBytes - Tries to read a contiguous range of bytes from the
59
/// region, up to the end of the region.
60
/// May block until (address - base + size) bytes have
61
/// been read. Additionally, StreamableMemoryObjects will
62
/// not do partial reads - if size bytes cannot be read,
63
/// readBytes will fail.
65
/// @param address - The address of the first byte, in the same space as
67
/// @param size - The maximum number of bytes to copy.
68
/// @param buf - A pointer to a buffer to be filled in. Must be non-NULL
69
/// and large enough to hold size bytes.
70
/// @param copied - A pointer to a nunber that is filled in with the number
71
/// of bytes actually read. May be NULL.
72
/// @result - 0 if successful; -1 if not. Failure may be due to a
73
/// bounds violation or an implementation-specific error.
74
virtual int readBytes(uint64_t address,
77
uint64_t* copied) const = 0;
79
/// getPointer - Ensures that the requested data is in memory, and returns
80
/// A pointer to it. More efficient than using readBytes if the
81
/// data is already in memory.
82
/// May block until (address - base + size) bytes have been read
83
/// @param address - address of the byte, in the same space as getBase()
84
/// @param size - amount of data that must be available on return
85
/// @result - valid pointer to the requested data
86
virtual const uint8_t *getPointer(uint64_t address, uint64_t size) const = 0;
88
/// isValidAddress - Returns true if the address is within the object
89
/// (i.e. between base and base + extent - 1 inclusive)
90
/// May block until (address - base) bytes have been read
91
/// @param address - address of the byte, in the same space as getBase()
92
/// @result - true if the address may be read with readByte()
93
virtual bool isValidAddress(uint64_t address) const = 0;
95
/// isObjectEnd - Returns true if the address is one past the end of the
96
/// object (i.e. if it is equal to base + extent)
97
/// May block until (address - base) bytes have been read
98
/// @param address - address of the byte, in the same space as getBase()
99
/// @result - true if the address is equal to base + extent
100
virtual bool isObjectEnd(uint64_t address) const = 0;
103
/// StreamingMemoryObject - interface to data which is actually streamed from
104
/// a DataStreamer. In addition to inherited members, it has the
105
/// dropLeadingBytes and setKnownObjectSize methods which are not applicable
106
/// to non-streamed objects.
107
class StreamingMemoryObject : public StreamableMemoryObject {
109
StreamingMemoryObject(DataStreamer *streamer);
110
virtual uint64_t getBase() const { return 0; }
111
virtual uint64_t getExtent() const;
112
virtual int readByte(uint64_t address, uint8_t* ptr) const;
113
virtual int readBytes(uint64_t address,
116
uint64_t* copied) const ;
117
virtual const uint8_t *getPointer(uint64_t address, uint64_t size) const {
118
// This could be fixed by ensuring the bytes are fetched and making a copy,
119
// requiring that the bitcode size be known, or otherwise ensuring that
120
// the memory doesn't go away/get reallocated, but it's
121
// not currently necessary. Users that need the pointer don't stream.
122
assert(0 && "getPointer in streaming memory objects not allowed");
125
virtual bool isValidAddress(uint64_t address) const;
126
virtual bool isObjectEnd(uint64_t address) const;
128
/// Drop s bytes from the front of the stream, pushing the positions of the
129
/// remaining bytes down by s. This is used to skip past the bitcode header,
130
/// since we don't know a priori if it's present, and we can't put bytes
131
/// back into the stream once we've read them.
132
bool dropLeadingBytes(size_t s);
134
/// If the data object size is known in advance, many of the operations can
135
/// be made more efficient, so this method should be called before reading
136
/// starts (although it can be called anytime).
137
void setKnownObjectSize(size_t size);
140
const static uint32_t kChunkSize = 4096 * 4;
141
mutable std::vector<unsigned char> Bytes;
142
OwningPtr<DataStreamer> Streamer;
143
mutable size_t BytesRead; // Bytes read from stream
144
size_t BytesSkipped;// Bytes skipped at start of stream (e.g. wrapper/header)
145
mutable size_t ObjectSize; // 0 if unknown, set if wrapper seen or EOF reached
146
mutable bool EOFReached;
148
// Fetch enough bytes such that Pos can be read or EOF is reached
149
// (i.e. BytesRead > Pos). Return true if Pos can be read.
150
// Unlike most of the functions in BitcodeReader, returns true on success.
151
// Most of the requests will be small, but we fetch at kChunkSize bytes
152
// at a time to avoid making too many potentially expensive GetBytes calls
153
bool fetchToPos(size_t Pos) const {
154
if (EOFReached) return Pos < ObjectSize;
155
while (Pos >= BytesRead) {
156
Bytes.resize(BytesRead + BytesSkipped + kChunkSize);
157
size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped],
160
if (bytes < kChunkSize) {
161
if (ObjectSize && BytesRead < Pos)
162
assert(0 && "Unexpected short read fetching bitcode");
163
if (BytesRead <= Pos) { // reached EOF/ran out of bytes
164
ObjectSize = BytesRead;
173
StreamingMemoryObject(const StreamingMemoryObject&); // DO NOT IMPLEMENT
174
void operator=(const StreamingMemoryObject&); // DO NOT IMPLEMENT
177
StreamableMemoryObject *getNonStreamedMemoryObject(
178
const unsigned char *Start, const unsigned char *End);
181
#endif // STREAMABLEMEMORYOBJECT_H_