StreamingMemoryObject.h 3.7 KB

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