/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/include/llvm/DebugInfo/MSF/MappedBlockStream.h
Line | Count | Source (jump to first uncovered line) |
1 | | //==- MappedBlockStream.h - Discontiguous stream data in an MSF --*- 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_DEBUGINFO_MSF_MAPPEDBLOCKSTREAM_H |
11 | | #define LLVM_DEBUGINFO_MSF_MAPPEDBLOCKSTREAM_H |
12 | | |
13 | | #include "llvm/ADT/ArrayRef.h" |
14 | | #include "llvm/ADT/DenseMap.h" |
15 | | #include "llvm/DebugInfo/MSF/MSFCommon.h" |
16 | | #include "llvm/Support/Allocator.h" |
17 | | #include "llvm/Support/BinaryStream.h" |
18 | | #include "llvm/Support/BinaryStreamRef.h" |
19 | | #include "llvm/Support/Endian.h" |
20 | | #include "llvm/Support/Error.h" |
21 | | #include <cstdint> |
22 | | #include <memory> |
23 | | #include <vector> |
24 | | |
25 | | namespace llvm { |
26 | | namespace msf { |
27 | | |
28 | | struct MSFLayout; |
29 | | |
30 | | /// MappedBlockStream represents data stored in an MSF file into chunks of a |
31 | | /// particular size (called the Block Size), and whose chunks may not be |
32 | | /// necessarily contiguous. The arrangement of these chunks MSF the file |
33 | | /// is described by some other metadata contained within the MSF file. In |
34 | | /// the case of a standard MSF Stream, the layout of the stream's blocks |
35 | | /// is described by the MSF "directory", but in the case of the directory |
36 | | /// itself, the layout is described by an array at a fixed location within |
37 | | /// the MSF. MappedBlockStream provides methods for reading from and writing |
38 | | /// to one of these streams transparently, as if it were a contiguous sequence |
39 | | /// of bytes. |
40 | | class MappedBlockStream : public BinaryStream { |
41 | | friend class WritableMappedBlockStream; |
42 | | |
43 | | public: |
44 | | static std::unique_ptr<MappedBlockStream> |
45 | | createStream(uint32_t BlockSize, const MSFStreamLayout &Layout, |
46 | | BinaryStreamRef MsfData, BumpPtrAllocator &Allocator); |
47 | | |
48 | | static std::unique_ptr<MappedBlockStream> |
49 | | createIndexedStream(const MSFLayout &Layout, BinaryStreamRef MsfData, |
50 | | uint32_t StreamIndex, BumpPtrAllocator &Allocator); |
51 | | |
52 | | static std::unique_ptr<MappedBlockStream> |
53 | | createFpmStream(const MSFLayout &Layout, BinaryStreamRef MsfData, |
54 | | BumpPtrAllocator &Allocator); |
55 | | |
56 | | static std::unique_ptr<MappedBlockStream> |
57 | | createDirectoryStream(const MSFLayout &Layout, BinaryStreamRef MsfData, |
58 | | BumpPtrAllocator &Allocator); |
59 | | |
60 | 1.60k | support::endianness getEndian() const override { |
61 | 1.60k | return support::little; |
62 | 1.60k | } |
63 | | |
64 | | Error readBytes(uint32_t Offset, uint32_t Size, |
65 | | ArrayRef<uint8_t> &Buffer) override; |
66 | | Error readLongestContiguousChunk(uint32_t Offset, |
67 | | ArrayRef<uint8_t> &Buffer) override; |
68 | | |
69 | | uint32_t getLength() override; |
70 | | |
71 | 0 | BumpPtrAllocator &getAllocator() { return Allocator; } |
72 | | |
73 | | void invalidateCache(); |
74 | | |
75 | 27.8k | uint32_t getBlockSize() const { return BlockSize; } |
76 | 10.4k | uint32_t getNumBlocks() const { return StreamLayout.Blocks.size(); } |
77 | 0 | uint32_t getStreamLength() const { return StreamLayout.Length; } |
78 | | |
79 | | protected: |
80 | | MappedBlockStream(uint32_t BlockSize, const MSFStreamLayout &StreamLayout, |
81 | | BinaryStreamRef MsfData, BumpPtrAllocator &Allocator); |
82 | | |
83 | | private: |
84 | 6.94k | const MSFStreamLayout &getStreamLayout() const { return StreamLayout; } |
85 | | void fixCacheAfterWrite(uint32_t Offset, ArrayRef<uint8_t> Data) const; |
86 | | |
87 | | Error readBytes(uint32_t Offset, MutableArrayRef<uint8_t> Buffer); |
88 | | bool tryReadContiguously(uint32_t Offset, uint32_t Size, |
89 | | ArrayRef<uint8_t> &Buffer); |
90 | | |
91 | | const uint32_t BlockSize; |
92 | | const MSFStreamLayout StreamLayout; |
93 | | BinaryStreamRef MsfData; |
94 | | |
95 | | using CacheEntry = MutableArrayRef<uint8_t>; |
96 | | |
97 | | // We just store the allocator by reference. We use this to allocate |
98 | | // contiguous memory for things like arrays or strings that cross a block |
99 | | // boundary, and this memory is expected to outlive the stream. For example, |
100 | | // someone could create a stream, read some stuff, then close the stream, and |
101 | | // we would like outstanding references to fields to remain valid since the |
102 | | // entire file is mapped anyway. Because of that, the user must supply the |
103 | | // allocator to allocate broken records from. |
104 | | BumpPtrAllocator &Allocator; |
105 | | DenseMap<uint32_t, std::vector<CacheEntry>> CacheMap; |
106 | | }; |
107 | | |
108 | | class WritableMappedBlockStream : public WritableBinaryStream { |
109 | | public: |
110 | | static std::unique_ptr<WritableMappedBlockStream> |
111 | | createStream(uint32_t BlockSize, const MSFStreamLayout &Layout, |
112 | | WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator); |
113 | | |
114 | | static std::unique_ptr<WritableMappedBlockStream> |
115 | | createIndexedStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData, |
116 | | uint32_t StreamIndex, BumpPtrAllocator &Allocator); |
117 | | |
118 | | static std::unique_ptr<WritableMappedBlockStream> |
119 | | createDirectoryStream(const MSFLayout &Layout, |
120 | | WritableBinaryStreamRef MsfData, |
121 | | BumpPtrAllocator &Allocator); |
122 | | |
123 | | static std::unique_ptr<WritableMappedBlockStream> |
124 | | createFpmStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData, |
125 | | BumpPtrAllocator &Allocator, bool AltFpm = false); |
126 | | |
127 | 1.90k | support::endianness getEndian() const override { |
128 | 1.90k | return support::little; |
129 | 1.90k | } |
130 | | |
131 | | Error readBytes(uint32_t Offset, uint32_t Size, |
132 | | ArrayRef<uint8_t> &Buffer) override; |
133 | | Error readLongestContiguousChunk(uint32_t Offset, |
134 | | ArrayRef<uint8_t> &Buffer) override; |
135 | | uint32_t getLength() override; |
136 | | |
137 | | Error writeBytes(uint32_t Offset, ArrayRef<uint8_t> Buffer) override; |
138 | | |
139 | | Error commit() override; |
140 | | |
141 | 6.94k | const MSFStreamLayout &getStreamLayout() const { |
142 | 6.94k | return ReadInterface.getStreamLayout(); |
143 | 6.94k | } |
144 | | |
145 | 27.8k | uint32_t getBlockSize() const { return ReadInterface.getBlockSize(); } |
146 | 0 | uint32_t getNumBlocks() const { return ReadInterface.getNumBlocks(); } |
147 | 0 | uint32_t getStreamLength() const { return ReadInterface.getStreamLength(); } |
148 | | |
149 | | protected: |
150 | | WritableMappedBlockStream(uint32_t BlockSize, |
151 | | const MSFStreamLayout &StreamLayout, |
152 | | WritableBinaryStreamRef MsfData, |
153 | | BumpPtrAllocator &Allocator); |
154 | | |
155 | | private: |
156 | | MappedBlockStream ReadInterface; |
157 | | WritableBinaryStreamRef WriteInterface; |
158 | | }; |
159 | | |
160 | | } // end namespace pdb |
161 | | } // end namespace llvm |
162 | | |
163 | | #endif // LLVM_DEBUGINFO_MSF_MAPPEDBLOCKSTREAM_H |