~ubuntu-branches/ubuntu/quantal/llvm-3.1/quantal

« back to all changes in this revision

Viewing changes to include/llvm/Support/StreamableMemoryObject.h

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2012-03-29 19:09:51 UTC
  • Revision ID: package-import@ubuntu.com-20120329190951-aq83ivog4cg8bxun
Tags: upstream-3.1~svn153643
ImportĀ upstreamĀ versionĀ 3.1~svn153643

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//===- StreamableMemoryObject.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
 
 
11
#ifndef STREAMABLEMEMORYOBJECT_H_
 
12
#define STREAMABLEMEMORYOBJECT_H_
 
13
 
 
14
#include "llvm/ADT/OwningPtr.h"
 
15
#include "llvm/Support/MemoryObject.h"
 
16
#include "llvm/Support/DataStream.h"
 
17
#include <vector>
 
18
 
 
19
namespace llvm {
 
20
 
 
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 {
 
33
 public:
 
34
  /// Destructor      - Override as necessary.
 
35
  virtual ~StreamableMemoryObject();
 
36
 
 
37
  /// getBase         - Returns the lowest valid address in the region.
 
38
  ///
 
39
  /// @result         - The lowest valid address.
 
40
  virtual uint64_t getBase() const = 0;
 
41
 
 
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
 
46
  ///
 
47
  /// @result         - The size of the region.
 
48
  virtual uint64_t getExtent() const = 0;
 
49
 
 
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;
 
57
 
 
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.
 
64
  ///
 
65
  /// @param address  - The address of the first byte, in the same space as
 
66
  ///                   getBase().
 
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,
 
75
                        uint64_t size,
 
76
                        uint8_t* buf,
 
77
                        uint64_t* copied) const = 0;
 
78
 
 
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;
 
87
 
 
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;
 
94
 
 
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;
 
101
};
 
102
 
 
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 {
 
108
public:
 
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,
 
114
                        uint64_t size,
 
115
                        uint8_t* buf,
 
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");
 
123
    return NULL;
 
124
  }
 
125
  virtual bool isValidAddress(uint64_t address) const;
 
126
  virtual bool isObjectEnd(uint64_t address) const;
 
127
 
 
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);
 
133
 
 
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);
 
138
 
 
139
private:
 
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;
 
147
 
 
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],
 
158
                                        kChunkSize);
 
159
      BytesRead += bytes;
 
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;
 
165
          EOFReached = true;
 
166
          return false;
 
167
        }
 
168
      }
 
169
    }
 
170
    return true;
 
171
  }
 
172
 
 
173
  StreamingMemoryObject(const StreamingMemoryObject&);  // DO NOT IMPLEMENT
 
174
  void operator=(const StreamingMemoryObject&);  // DO NOT IMPLEMENT
 
175
};
 
176
 
 
177
StreamableMemoryObject *getNonStreamedMemoryObject(
 
178
    const unsigned char *Start, const unsigned char *End);
 
179
 
 
180
}
 
181
#endif  // STREAMABLEMEMORYOBJECT_H_