diff options
Diffstat (limited to 'llvm/lib/DebugInfo/MSF')
-rw-r--r-- | llvm/lib/DebugInfo/MSF/BinaryStreamReader.cpp | 68 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/MSF/BinaryStreamWriter.cpp | 63 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp | 48 |
3 files changed, 73 insertions, 106 deletions
diff --git a/llvm/lib/DebugInfo/MSF/BinaryStreamReader.cpp b/llvm/lib/DebugInfo/MSF/BinaryStreamReader.cpp index ba5fd213c59..567e6b1270e 100644 --- a/llvm/lib/DebugInfo/MSF/BinaryStreamReader.cpp +++ b/llvm/lib/DebugInfo/MSF/BinaryStreamReader.cpp @@ -1,4 +1,4 @@ -//===- BinaryStreamReader.cpp - Reads objects from a binary stream --------===// +//===- StreamReader.cpp - Reads bytes and objects from a stream -----------===// // // The LLVM Compiler Infrastructure // @@ -10,79 +10,53 @@ #include "llvm/DebugInfo/MSF/BinaryStreamReader.h" #include "llvm/DebugInfo/MSF/BinaryStreamRef.h" +#include "llvm/DebugInfo/MSF/MSFError.h" using namespace llvm; +using namespace llvm::msf; -BinaryStreamReader::BinaryStreamReader(BinaryStreamRef S) - : Stream(S), Offset(0) {} +StreamReader::StreamReader(ReadableStreamRef S) : Stream(S), Offset(0) {} -Error BinaryStreamReader::readLongestContiguousChunk( - ArrayRef<uint8_t> &Buffer) { +Error StreamReader::readLongestContiguousChunk(ArrayRef<uint8_t> &Buffer) { if (auto EC = Stream.readLongestContiguousChunk(Offset, Buffer)) return EC; Offset += Buffer.size(); return Error::success(); } -Error BinaryStreamReader::readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size) { +Error StreamReader::readBytes(ArrayRef<uint8_t> &Buffer, uint32_t Size) { if (auto EC = Stream.readBytes(Offset, Size, Buffer)) return EC; Offset += Size; return Error::success(); } -Error BinaryStreamReader::readInteger(uint64_t &Dest, uint32_t ByteSize) { - assert(ByteSize == 1 || ByteSize == 2 || ByteSize == 4 || ByteSize == 8); - ArrayRef<uint8_t> Bytes; - - if (auto EC = readBytes(Bytes, ByteSize)) - return EC; - switch (ByteSize) { - case 1: - Dest = Bytes[0]; - return Error::success(); - case 2: - Dest = llvm::support::endian::read16(Bytes.data(), Stream.getEndian()); - return Error::success(); - case 4: - Dest = llvm::support::endian::read32(Bytes.data(), Stream.getEndian()); - return Error::success(); - case 8: - Dest = llvm::support::endian::read64(Bytes.data(), Stream.getEndian()); - return Error::success(); - } - llvm_unreachable("Unreachable!"); - return Error::success(); -} - -Error BinaryStreamReader::readCString(StringRef &Dest) { - // TODO: This could be made more efficient by using readLongestContiguousChunk - // and searching for null terminators in the resulting buffer. - +Error StreamReader::readZeroString(StringRef &Dest) { uint32_t Length = 0; // First compute the length of the string by reading 1 byte at a time. uint32_t OriginalOffset = getOffset(); const char *C; - while (true) { + do { if (auto EC = readObject(C)) return EC; - if (*C == '\0') - break; - ++Length; - } + if (*C != '\0') + ++Length; + } while (*C != '\0'); // Now go back and request a reference for that many bytes. uint32_t NewOffset = getOffset(); setOffset(OriginalOffset); - if (auto EC = readFixedString(Dest, Length)) + ArrayRef<uint8_t> Data; + if (auto EC = readBytes(Data, Length)) return EC; + Dest = StringRef(reinterpret_cast<const char *>(Data.begin()), Data.size()); // Now set the offset back to where it was after we calculated the length. setOffset(NewOffset); return Error::success(); } -Error BinaryStreamReader::readFixedString(StringRef &Dest, uint32_t Length) { +Error StreamReader::readFixedString(StringRef &Dest, uint32_t Length) { ArrayRef<uint8_t> Bytes; if (auto EC = readBytes(Bytes, Length)) return EC; @@ -90,26 +64,26 @@ Error BinaryStreamReader::readFixedString(StringRef &Dest, uint32_t Length) { return Error::success(); } -Error BinaryStreamReader::readStreamRef(BinaryStreamRef &Ref) { +Error StreamReader::readStreamRef(ReadableStreamRef &Ref) { return readStreamRef(Ref, bytesRemaining()); } -Error BinaryStreamReader::readStreamRef(BinaryStreamRef &Ref, uint32_t Length) { +Error StreamReader::readStreamRef(ReadableStreamRef &Ref, uint32_t Length) { if (bytesRemaining() < Length) - return errorCodeToError(make_error_code(std::errc::no_buffer_space)); + return make_error<MSFError>(msf_error_code::insufficient_buffer); Ref = Stream.slice(Offset, Length); Offset += Length; return Error::success(); } -Error BinaryStreamReader::skip(uint32_t Amount) { +Error StreamReader::skip(uint32_t Amount) { if (Amount > bytesRemaining()) - return errorCodeToError(make_error_code(std::errc::no_buffer_space)); + return make_error<MSFError>(msf_error_code::insufficient_buffer); Offset += Amount; return Error::success(); } -uint8_t BinaryStreamReader::peek() const { +uint8_t StreamReader::peek() const { ArrayRef<uint8_t> Buffer; auto EC = Stream.readBytes(Offset, 1, Buffer); assert(!EC && "Cannot peek an empty buffer!"); diff --git a/llvm/lib/DebugInfo/MSF/BinaryStreamWriter.cpp b/llvm/lib/DebugInfo/MSF/BinaryStreamWriter.cpp index 08e4aef6060..54415b96c0b 100644 --- a/llvm/lib/DebugInfo/MSF/BinaryStreamWriter.cpp +++ b/llvm/lib/DebugInfo/MSF/BinaryStreamWriter.cpp @@ -1,4 +1,4 @@ -//===- BinaryStreamWriter.cpp - Writes objects to a BinaryStream ----------===// +//===- StreamWrite.cpp - Writes bytes and objects to a stream -------------===// // // The LLVM Compiler Infrastructure // @@ -11,42 +11,21 @@ #include "llvm/DebugInfo/MSF/BinaryStreamReader.h" #include "llvm/DebugInfo/MSF/BinaryStreamRef.h" +#include "llvm/DebugInfo/MSF/MSFError.h" using namespace llvm; +using namespace llvm::msf; -BinaryStreamWriter::BinaryStreamWriter(WritableBinaryStreamRef S) - : Stream(S), Offset(0) {} +StreamWriter::StreamWriter(WritableStreamRef S) : Stream(S), Offset(0) {} -Error BinaryStreamWriter::writeBytes(ArrayRef<uint8_t> Buffer) { +Error StreamWriter::writeBytes(ArrayRef<uint8_t> Buffer) { if (auto EC = Stream.writeBytes(Offset, Buffer)) return EC; Offset += Buffer.size(); return Error::success(); } -Error BinaryStreamWriter::writeInteger(uint64_t Value, uint32_t ByteSize) { - assert(ByteSize == 1 || ByteSize == 2 || ByteSize == 4 || ByteSize == 8); - uint8_t Bytes[8]; - MutableArrayRef<uint8_t> Buffer(Bytes); - Buffer = Buffer.take_front(ByteSize); - switch (ByteSize) { - case 1: - Buffer[0] = static_cast<uint8_t>(Value); - break; - case 2: - llvm::support::endian::write16(Buffer.data(), Value, Stream.getEndian()); - break; - case 4: - llvm::support::endian::write32(Buffer.data(), Value, Stream.getEndian()); - break; - case 8: - llvm::support::endian::write64(Buffer.data(), Value, Stream.getEndian()); - break; - } - return writeBytes(Buffer); -} - -Error BinaryStreamWriter::writeCString(StringRef Str) { +Error StreamWriter::writeZeroString(StringRef Str) { if (auto EC = writeFixedString(Str)) return EC; if (auto EC = writeObject('\0')) @@ -55,21 +34,31 @@ Error BinaryStreamWriter::writeCString(StringRef Str) { return Error::success(); } -Error BinaryStreamWriter::writeFixedString(StringRef Str) { - return writeBytes(ArrayRef<uint8_t>(Str.bytes_begin(), Str.bytes_end())); +Error StreamWriter::writeFixedString(StringRef Str) { + ArrayRef<uint8_t> Bytes(Str.bytes_begin(), Str.bytes_end()); + if (auto EC = Stream.writeBytes(Offset, Bytes)) + return EC; + + Offset += Str.size(); + return Error::success(); } -Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref) { - return writeStreamRef(Ref, Ref.getLength()); +Error StreamWriter::writeStreamRef(ReadableStreamRef Ref) { + if (auto EC = writeStreamRef(Ref, Ref.getLength())) + return EC; + // Don't increment Offset here, it is done by the overloaded call to + // writeStreamRef. + return Error::success(); } -Error BinaryStreamWriter::writeStreamRef(BinaryStreamRef Ref, uint32_t Length) { - BinaryStreamReader SrcReader(Ref.slice(0, Length)); +Error StreamWriter::writeStreamRef(ReadableStreamRef Ref, uint32_t Length) { + Ref = Ref.slice(0, Length); + + StreamReader SrcReader(Ref); // This is a bit tricky. If we just call readBytes, we are requiring that it - // return us the entire stream as a contiguous buffer. There is no guarantee - // this can be satisfied by returning a reference straight from the buffer, as - // an implementation may not store all data in a single contiguous buffer. So - // we iterate over each contiguous chunk, writing each one in succession. + // return us the entire stream as a contiguous buffer. For large streams this + // will allocate a huge amount of space from the pool. Instead, iterate over + // each contiguous chunk until we've consumed the entire stream. while (SrcReader.bytesRemaining() > 0) { ArrayRef<uint8_t> Chunk; if (auto EC = SrcReader.readLongestContiguousChunk(Chunk)) diff --git a/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp b/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp index c9ba25c0d7d..e52c88a5bfb 100644 --- a/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp +++ b/llvm/lib/DebugInfo/MSF/MappedBlockStream.cpp @@ -47,20 +47,22 @@ static Interval intersect(const Interval &I1, const Interval &I2) { MappedBlockStream::MappedBlockStream(uint32_t BlockSize, uint32_t NumBlocks, const MSFStreamLayout &Layout, - BinaryStreamRef MsfData) + const ReadableStream &MsfData) : BlockSize(BlockSize), NumBlocks(NumBlocks), StreamLayout(Layout), MsfData(MsfData) {} std::unique_ptr<MappedBlockStream> MappedBlockStream::createStream(uint32_t BlockSize, uint32_t NumBlocks, const MSFStreamLayout &Layout, - BinaryStreamRef MsfData) { + const ReadableStream &MsfData) { return llvm::make_unique<MappedBlockStreamImpl<MappedBlockStream>>( BlockSize, NumBlocks, Layout, MsfData); } -std::unique_ptr<MappedBlockStream> MappedBlockStream::createIndexedStream( - const MSFLayout &Layout, BinaryStreamRef MsfData, uint32_t StreamIndex) { +std::unique_ptr<MappedBlockStream> +MappedBlockStream::createIndexedStream(const MSFLayout &Layout, + const ReadableStream &MsfData, + uint32_t StreamIndex) { assert(StreamIndex < Layout.StreamMap.size() && "Invalid stream index"); MSFStreamLayout SL; SL.Blocks = Layout.StreamMap[StreamIndex]; @@ -71,7 +73,7 @@ std::unique_ptr<MappedBlockStream> MappedBlockStream::createIndexedStream( std::unique_ptr<MappedBlockStream> MappedBlockStream::createDirectoryStream(const MSFLayout &Layout, - BinaryStreamRef MsfData) { + const ReadableStream &MsfData) { MSFStreamLayout SL; SL.Blocks = Layout.DirectoryBlocks; SL.Length = Layout.SB->NumDirectoryBytes; @@ -80,14 +82,14 @@ MappedBlockStream::createDirectoryStream(const MSFLayout &Layout, std::unique_ptr<MappedBlockStream> MappedBlockStream::createFpmStream(const MSFLayout &Layout, - BinaryStreamRef MsfData) { + const ReadableStream &MsfData) { MSFStreamLayout SL; initializeFpmStreamLayout(Layout, SL); return createStream(Layout.SB->BlockSize, Layout.SB->NumBlocks, SL, MsfData); } Error MappedBlockStream::readBytes(uint32_t Offset, uint32_t Size, - ArrayRef<uint8_t> &Buffer) { + ArrayRef<uint8_t> &Buffer) const { // Make sure we aren't trying to read beyond the end of the stream. if (Size > StreamLayout.Length) return make_error<MSFError>(msf_error_code::insufficient_buffer); @@ -166,8 +168,8 @@ Error MappedBlockStream::readBytes(uint32_t Offset, uint32_t Size, return Error::success(); } -Error MappedBlockStream::readLongestContiguousChunk(uint32_t Offset, - ArrayRef<uint8_t> &Buffer) { +Error MappedBlockStream::readLongestContiguousChunk( + uint32_t Offset, ArrayRef<uint8_t> &Buffer) const { // Make sure we aren't trying to read beyond the end of the stream. if (Offset >= StreamLayout.Length) return make_error<MSFError>(msf_error_code::insufficient_buffer); @@ -195,10 +197,10 @@ Error MappedBlockStream::readLongestContiguousChunk(uint32_t Offset, return Error::success(); } -uint32_t MappedBlockStream::getLength() { return StreamLayout.Length; } +uint32_t MappedBlockStream::getLength() const { return StreamLayout.Length; } bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size, - ArrayRef<uint8_t> &Buffer) { + ArrayRef<uint8_t> &Buffer) const { if (Size == 0) { Buffer = ArrayRef<uint8_t>(); return true; @@ -239,7 +241,7 @@ bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size, } Error MappedBlockStream::readBytes(uint32_t Offset, - MutableArrayRef<uint8_t> Buffer) { + MutableArrayRef<uint8_t> Buffer) const { uint32_t BlockNum = Offset / BlockSize; uint32_t OffsetInBlock = Offset % BlockSize; @@ -317,21 +319,21 @@ void MappedBlockStream::fixCacheAfterWrite(uint32_t Offset, WritableMappedBlockStream::WritableMappedBlockStream( uint32_t BlockSize, uint32_t NumBlocks, const MSFStreamLayout &Layout, - WritableBinaryStreamRef MsfData) + const WritableStream &MsfData) : ReadInterface(BlockSize, NumBlocks, Layout, MsfData), WriteInterface(MsfData) {} std::unique_ptr<WritableMappedBlockStream> WritableMappedBlockStream::createStream(uint32_t BlockSize, uint32_t NumBlocks, const MSFStreamLayout &Layout, - WritableBinaryStreamRef MsfData) { + const WritableStream &MsfData) { return llvm::make_unique<MappedBlockStreamImpl<WritableMappedBlockStream>>( BlockSize, NumBlocks, Layout, MsfData); } std::unique_ptr<WritableMappedBlockStream> WritableMappedBlockStream::createIndexedStream(const MSFLayout &Layout, - WritableBinaryStreamRef MsfData, + const WritableStream &MsfData, uint32_t StreamIndex) { assert(StreamIndex < Layout.StreamMap.size() && "Invalid stream index"); MSFStreamLayout SL; @@ -342,7 +344,7 @@ WritableMappedBlockStream::createIndexedStream(const MSFLayout &Layout, std::unique_ptr<WritableMappedBlockStream> WritableMappedBlockStream::createDirectoryStream( - const MSFLayout &Layout, WritableBinaryStreamRef MsfData) { + const MSFLayout &Layout, const WritableStream &MsfData) { MSFStreamLayout SL; SL.Blocks = Layout.DirectoryBlocks; SL.Length = Layout.SB->NumDirectoryBytes; @@ -351,28 +353,28 @@ WritableMappedBlockStream::createDirectoryStream( std::unique_ptr<WritableMappedBlockStream> WritableMappedBlockStream::createFpmStream(const MSFLayout &Layout, - WritableBinaryStreamRef MsfData) { + const WritableStream &MsfData) { MSFStreamLayout SL; initializeFpmStreamLayout(Layout, SL); return createStream(Layout.SB->BlockSize, Layout.SB->NumBlocks, SL, MsfData); } Error WritableMappedBlockStream::readBytes(uint32_t Offset, uint32_t Size, - ArrayRef<uint8_t> &Buffer) { + ArrayRef<uint8_t> &Buffer) const { return ReadInterface.readBytes(Offset, Size, Buffer); } Error WritableMappedBlockStream::readLongestContiguousChunk( - uint32_t Offset, ArrayRef<uint8_t> &Buffer) { + uint32_t Offset, ArrayRef<uint8_t> &Buffer) const { return ReadInterface.readLongestContiguousChunk(Offset, Buffer); } -uint32_t WritableMappedBlockStream::getLength() { +uint32_t WritableMappedBlockStream::getLength() const { return ReadInterface.getLength(); } Error WritableMappedBlockStream::writeBytes(uint32_t Offset, - ArrayRef<uint8_t> Buffer) { + ArrayRef<uint8_t> Buffer) const { // Make sure we aren't trying to write beyond the end of the stream. if (Buffer.size() > getStreamLength()) return make_error<MSFError>(msf_error_code::insufficient_buffer); @@ -408,4 +410,6 @@ Error WritableMappedBlockStream::writeBytes(uint32_t Offset, return Error::success(); } -Error WritableMappedBlockStream::commit() { return WriteInterface.commit(); } +Error WritableMappedBlockStream::commit() const { + return WriteInterface.commit(); +} |