]>
Commit | Line | Data |
---|---|---|
85aaf69f SL |
1 | //===- StreamingMemoryObject.h - Streamable data interface -----*- C++ -*-===// |
2 | // | |
3 | // The LLVM Compiler Infrastructure | |
4 | // | |
5 | // This file is distributed under the University of Illinois Open Source | |
6 | // License. See LICENSE.TXT for details. | |
7 | // | |
8 | //===----------------------------------------------------------------------===// | |
9 | ||
10 | #ifndef LLVM_SUPPORT_STREAMINGMEMORYOBJECT_H | |
11 | #define LLVM_SUPPORT_STREAMINGMEMORYOBJECT_H | |
12 | ||
13 | #include "llvm/Support/Compiler.h" | |
14 | #include "llvm/Support/DataStream.h" | |
15 | #include "llvm/Support/ErrorHandling.h" | |
16 | #include "llvm/Support/MemoryObject.h" | |
17 | #include <cassert> | |
18 | #include <memory> | |
19 | #include <vector> | |
20 | ||
21 | namespace llvm { | |
22 | ||
23 | /// Interface to data which is actually streamed from a DataStreamer. In | |
24 | /// addition to inherited members, it has the dropLeadingBytes and | |
25 | /// setKnownObjectSize methods which are not applicable to non-streamed objects. | |
26 | class StreamingMemoryObject : public MemoryObject { | |
27 | public: | |
28 | StreamingMemoryObject(DataStreamer *streamer); | |
29 | uint64_t getExtent() const override; | |
30 | uint64_t readBytes(uint8_t *Buf, uint64_t Size, | |
31 | uint64_t Address) const override; | |
32 | const uint8_t *getPointer(uint64_t address, uint64_t size) const override { | |
33 | // This could be fixed by ensuring the bytes are fetched and making a copy, | |
34 | // requiring that the bitcode size be known, or otherwise ensuring that | |
35 | // the memory doesn't go away/get reallocated, but it's | |
36 | // not currently necessary. Users that need the pointer don't stream. | |
37 | llvm_unreachable("getPointer in streaming memory objects not allowed"); | |
38 | return nullptr; | |
39 | } | |
40 | bool isValidAddress(uint64_t address) const override; | |
41 | ||
42 | /// Drop s bytes from the front of the stream, pushing the positions of the | |
43 | /// remaining bytes down by s. This is used to skip past the bitcode header, | |
44 | /// since we don't know a priori if it's present, and we can't put bytes | |
45 | /// back into the stream once we've read them. | |
46 | bool dropLeadingBytes(size_t s); | |
47 | ||
48 | /// If the data object size is known in advance, many of the operations can | |
49 | /// be made more efficient, so this method should be called before reading | |
50 | /// starts (although it can be called anytime). | |
51 | void setKnownObjectSize(size_t size); | |
52 | ||
53 | private: | |
54 | const static uint32_t kChunkSize = 4096 * 4; | |
55 | mutable std::vector<unsigned char> Bytes; | |
56 | std::unique_ptr<DataStreamer> Streamer; | |
57 | mutable size_t BytesRead; // Bytes read from stream | |
58 | size_t BytesSkipped;// Bytes skipped at start of stream (e.g. wrapper/header) | |
59 | mutable size_t ObjectSize; // 0 if unknown, set if wrapper seen or EOF reached | |
60 | mutable bool EOFReached; | |
61 | ||
62 | // Fetch enough bytes such that Pos can be read or EOF is reached | |
63 | // (i.e. BytesRead > Pos). Return true if Pos can be read. | |
64 | // Unlike most of the functions in BitcodeReader, returns true on success. | |
65 | // Most of the requests will be small, but we fetch at kChunkSize bytes | |
66 | // at a time to avoid making too many potentially expensive GetBytes calls | |
67 | bool fetchToPos(size_t Pos) const { | |
68 | if (EOFReached) | |
69 | return Pos < ObjectSize; | |
70 | while (Pos >= BytesRead) { | |
71 | Bytes.resize(BytesRead + BytesSkipped + kChunkSize); | |
72 | size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped], | |
73 | kChunkSize); | |
74 | BytesRead += bytes; | |
75 | if (bytes != kChunkSize) { // reached EOF/ran out of bytes | |
76 | ObjectSize = BytesRead; | |
77 | EOFReached = true; | |
78 | break; | |
79 | } | |
80 | } | |
81 | return Pos < BytesRead; | |
82 | } | |
83 | ||
84 | StreamingMemoryObject(const StreamingMemoryObject&) LLVM_DELETED_FUNCTION; | |
85 | void operator=(const StreamingMemoryObject&) LLVM_DELETED_FUNCTION; | |
86 | }; | |
87 | ||
88 | MemoryObject *getNonStreamedMemoryObject( | |
89 | const unsigned char *Start, const unsigned char *End); | |
90 | ||
91 | } | |
92 | #endif // STREAMINGMEMORYOBJECT_H_ |