2
0

StreamingMemoryObject.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. //===- StreamingMemoryObject.cpp - Streamable data interface -------------===//
  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. #include "llvm/Support/StreamingMemoryObject.h"
  10. #include <cassert>
  11. #include <cstddef>
  12. #include <cstring>
  13. using namespace llvm;
  14. namespace {
  15. class RawMemoryObject : public MemoryObject {
  16. public:
  17. RawMemoryObject(const unsigned char *Start, const unsigned char *End) :
  18. FirstChar(Start), LastChar(End) {
  19. assert(LastChar >= FirstChar && "Invalid start/end range");
  20. }
  21. uint64_t getExtent() const override {
  22. return LastChar - FirstChar;
  23. }
  24. uint64_t readBytes(uint8_t *Buf, uint64_t Size,
  25. uint64_t Address) const override;
  26. const uint8_t *getPointer(uint64_t address, uint64_t size) const override;
  27. bool isValidAddress(uint64_t address) const override {
  28. return validAddress(address);
  29. }
  30. private:
  31. const uint8_t* const FirstChar;
  32. const uint8_t* const LastChar;
  33. // These are implemented as inline functions here to avoid multiple virtual
  34. // calls per public function
  35. bool validAddress(uint64_t address) const {
  36. return static_cast<std::ptrdiff_t>(address) < LastChar - FirstChar;
  37. }
  38. RawMemoryObject(const RawMemoryObject&) = delete;
  39. void operator=(const RawMemoryObject&) = delete;
  40. };
  41. uint64_t RawMemoryObject::readBytes(uint8_t *Buf, uint64_t Size,
  42. uint64_t Address) const {
  43. uint64_t BufferSize = LastChar - FirstChar;
  44. if (Address >= BufferSize)
  45. return 0;
  46. uint64_t End = Address + Size;
  47. if (End > BufferSize)
  48. End = BufferSize;
  49. assert(static_cast<int64_t>(End - Address) >= 0);
  50. Size = End - Address;
  51. memcpy(Buf, Address + FirstChar, Size);
  52. return Size;
  53. }
  54. const uint8_t *RawMemoryObject::getPointer(uint64_t address,
  55. uint64_t size) const {
  56. return FirstChar + address;
  57. }
  58. } // anonymous namespace
  59. namespace llvm {
  60. // If the bitcode has a header, then its size is known, and we don't have to
  61. // block until we actually want to read it.
  62. bool StreamingMemoryObject::isValidAddress(uint64_t address) const {
  63. if (ObjectSize && address < ObjectSize) return true;
  64. return fetchToPos(address);
  65. }
  66. uint64_t StreamingMemoryObject::getExtent() const {
  67. if (ObjectSize) return ObjectSize;
  68. size_t pos = BytesRead + kChunkSize;
  69. // keep fetching until we run out of bytes
  70. while (fetchToPos(pos)) pos += kChunkSize;
  71. return ObjectSize;
  72. }
  73. uint64_t StreamingMemoryObject::readBytes(uint8_t *Buf, uint64_t Size,
  74. uint64_t Address) const {
  75. fetchToPos(Address + Size - 1);
  76. // Note: For wrapped bitcode files will set ObjectSize after the
  77. // first call to fetchToPos. In such cases, ObjectSize can be
  78. // smaller than BytesRead.
  79. size_t MaxAddress =
  80. (ObjectSize && ObjectSize < BytesRead) ? ObjectSize : BytesRead;
  81. if (Address >= MaxAddress)
  82. return 0;
  83. uint64_t End = Address + Size;
  84. if (End > MaxAddress)
  85. End = MaxAddress;
  86. assert(End >= Address);
  87. Size = End - Address;
  88. memcpy(Buf, &Bytes[Address + BytesSkipped], Size);
  89. return Size;
  90. }
  91. bool StreamingMemoryObject::dropLeadingBytes(size_t s) {
  92. if (BytesRead < s) return true;
  93. BytesSkipped = s;
  94. BytesRead -= s;
  95. return false;
  96. }
  97. void StreamingMemoryObject::setKnownObjectSize(size_t size) {
  98. ObjectSize = size;
  99. Bytes.reserve(size);
  100. if (ObjectSize <= BytesRead)
  101. EOFReached = true;
  102. }
  103. MemoryObject *getNonStreamedMemoryObject(const unsigned char *Start,
  104. const unsigned char *End) {
  105. return new RawMemoryObject(Start, End);
  106. }
  107. StreamingMemoryObject::StreamingMemoryObject(
  108. std::unique_ptr<DataStreamer> Streamer)
  109. : Bytes(kChunkSize), Streamer(std::move(Streamer)), BytesRead(0),
  110. BytesSkipped(0), ObjectSize(0), EOFReached(false) {
  111. BytesRead = this->Streamer->GetBytes(&Bytes[0], kChunkSize);
  112. }
  113. }