27template <
typename Base>
class MappedBlockStreamImpl :
public Base {
29 template <
typename...
Args>
30 MappedBlockStreamImpl(Args &&... Params)
31 :
Base(std::forward<
Args>(Params)...) {}
39 return std::make_pair(std::max(I1.first, I2.first),
40 std::min(I1.second, I2.second));
47 : BlockSize(BlockSize), StreamLayout(Layout), MsfData(MsfData),
48 Allocator(Allocator) {}
53 return std::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
54 BlockSize, Layout, MsfData, Allocator);
60 assert(StreamIndex < Layout.
StreamMap.size() &&
"Invalid stream index");
64 return std::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
68std::unique_ptr<MappedBlockStream>
78std::unique_ptr<MappedBlockStream>
95 auto CacheIter = CacheMap.find(
Offset);
96 if (CacheIter != CacheMap.end()) {
98 for (
auto &Entry : CacheIter->second) {
99 if (Entry.size() >=
Size) {
109 for (
auto &CacheItem : CacheMap) {
113 if (CacheItem.first ==
Offset)
122 if (CacheItem.second.empty())
125 auto CachedAlloc = CacheItem.second.back();
129 std::make_pair(CacheItem.first, CacheItem.first + CachedAlloc.size());
130 if (RequestExtent.first >= CachedExtent.first + CachedExtent.second)
136 if (Intersection != RequestExtent)
141 Buffer = CachedAlloc.
slice(CacheRangeOffset,
Size);
153 if (CacheIter != CacheMap.end()) {
154 CacheIter->second.emplace_back(WriteBuffer,
Size);
156 std::vector<CacheEntry>
List;
157 List.emplace_back(WriteBuffer,
Size);
158 CacheMap.insert(std::make_pair(
Offset,
List));
174 if (StreamLayout.Blocks[
Last] != StreamLayout.Blocks[
Last + 1] - 1)
180 uint64_t BytesFromFirstBlock = BlockSize - OffsetInFirstBlock;
182 uint64_t ByteSpan = BytesFromFirstBlock + (BlockSpan - 1) * BlockSize;
186 if (
auto EC = MsfData.readBytes(MsfOffset, BlockSize, BlockData))
189 BlockData = BlockData.drop_front(OffsetInFirstBlock);
213 uint64_t RequiredContiguousBlocks = NumAdditionalBlocks + 1;
215 for (
uint64_t I = 0;
I < RequiredContiguousBlocks; ++
I, ++E) {
216 if (StreamLayout.
Blocks[
I + BlockNum] != E)
232 BlockData = BlockData.
drop_front(OffsetInBlock);
233 Buffer = ArrayRef<uint8_t>(BlockData.
data(),
Size);
238 MutableArrayRef<uint8_t> Buffer) {
239 uint64_t BlockNum =
Offset / BlockSize;
240 uint64_t OffsetInBlock =
Offset % BlockSize;
246 uint64_t BytesLeft = Buffer.
size();
247 uint64_t BytesWritten = 0;
248 uint8_t *WriteBuffer = Buffer.
data();
249 while (BytesLeft > 0) {
250 uint64_t StreamBlockAddr = StreamLayout.Blocks[BlockNum];
252 ArrayRef<uint8_t> BlockData;
254 if (
auto EC = MsfData.readBytes(
Offset, BlockSize, BlockData))
257 const uint8_t *ChunkStart = BlockData.
data() + OffsetInBlock;
258 uint64_t BytesInChunk = std::min(BytesLeft, BlockSize - OffsetInBlock);
259 ::memcpy(WriteBuffer + BytesWritten, ChunkStart, BytesInChunk);
261 BytesWritten += BytesInChunk;
262 BytesLeft -= BytesInChunk;
278 for (
const auto &MapEntry : CacheMap) {
283 for (
const auto &
Alloc : MapEntry.second) {
292 std::make_pair(MapEntry.first, MapEntry.first +
Alloc.size());
295 auto Intersection =
intersect(WriteInterval, CachedInterval);
296 assert(Intersection.first <= Intersection.second);
311 : ReadInterface(
BlockSize, Layout, MsfData, Allocator),
312 WriteInterface(MsfData) {}
314std::unique_ptr<WritableMappedBlockStream>
319 return std::make_unique<MappedBlockStreamImpl<WritableMappedBlockStream>>(
323std::unique_ptr<WritableMappedBlockStream>
328 assert(StreamIndex < Layout.
StreamMap.size() &&
"Invalid stream index");
335std::unique_ptr<WritableMappedBlockStream>
345std::unique_ptr<WritableMappedBlockStream>
364 std::vector<uint8_t> InitData(Layout.
SB->
BlockSize, 0xFF);
373 return ReadInterface.readBytes(
Offset,
Size, Buffer);
378 return ReadInterface.readLongestContiguousChunk(
Offset, Buffer);
382 return ReadInterface.getLength();
396 while (BytesLeft > 0) {
401 const uint8_t *Chunk = Buffer.
data() + BytesWritten;
404 MsfOffset += OffsetInBlock;
405 if (
auto EC = WriteInterface.writeBytes(MsfOffset, ChunkData))
408 BytesLeft -= BytesToWriteInChunk;
409 BytesWritten += BytesToWriteInChunk;
414 ReadInterface.fixCacheAfterWrite(
Offset, Buffer);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
std::pair< uint64_t, uint64_t > Interval
static Interval intersect(const Interval &I1, const Interval &I2)
static const int BlockSize
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
size_t size() const
size - Get the array size.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
BinaryStreamRef is to BinaryStream what ArrayRef is to an Array.
LLVM_ABI Error readBytes(uint64_t Offset, uint64_t Size, ArrayRef< uint8_t > &Buffer) const
Given an Offset into this StreamRef and a Size, return a reference to a buffer owned by the stream.
Provides write only access to a subclass of WritableBinaryStream.
uint64_t bytesRemaining() const
LLVM_ABI Error writeBytes(ArrayRef< uint8_t > Buffer)
Write the bytes specified in Buffer to the underlying stream.
Error checkOffsetForRead(uint64_t Offset, uint64_t DataSize)
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Error checkOffsetForWrite(uint64_t Offset, uint64_t DataSize)
Describes the layout of a stream in an MSF layout.
std::vector< support::ulittle32_t > Blocks
static std::unique_ptr< MappedBlockStream > createIndexedStream(const MSFLayout &Layout, BinaryStreamRef MsfData, uint32_t StreamIndex, BumpPtrAllocator &Allocator)
Error readBytes(uint64_t Offset, uint64_t Size, ArrayRef< uint8_t > &Buffer) override
Given an offset into the stream and a number of bytes, attempt to read the bytes and set the output A...
Error readLongestContiguousChunk(uint64_t Offset, ArrayRef< uint8_t > &Buffer) override
Given an offset into the stream, read as much as possible without copying any data.
static std::unique_ptr< MappedBlockStream > createStream(uint32_t BlockSize, const MSFStreamLayout &Layout, BinaryStreamRef MsfData, BumpPtrAllocator &Allocator)
uint32_t getNumBlocks() const
MappedBlockStream(uint32_t BlockSize, const MSFStreamLayout &StreamLayout, BinaryStreamRef MsfData, BumpPtrAllocator &Allocator)
static std::unique_ptr< MappedBlockStream > createDirectoryStream(const MSFLayout &Layout, BinaryStreamRef MsfData, BumpPtrAllocator &Allocator)
static std::unique_ptr< MappedBlockStream > createFpmStream(const MSFLayout &Layout, BinaryStreamRef MsfData, BumpPtrAllocator &Allocator)
uint64_t getLength() override
Return the number of bytes of data in this stream.
static std::unique_ptr< WritableMappedBlockStream > createIndexedStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData, uint32_t StreamIndex, BumpPtrAllocator &Allocator)
static std::unique_ptr< WritableMappedBlockStream > createStream(uint32_t BlockSize, const MSFStreamLayout &Layout, WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator)
Error commit() override
For buffered streams, commits changes to the backing store.
WritableMappedBlockStream(uint32_t BlockSize, const MSFStreamLayout &StreamLayout, WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator)
Error readBytes(uint64_t Offset, uint64_t Size, ArrayRef< uint8_t > &Buffer) override
Given an offset into the stream and a number of bytes, attempt to read the bytes and set the output A...
static std::unique_ptr< WritableMappedBlockStream > createFpmStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator, bool AltFpm=false)
static std::unique_ptr< WritableMappedBlockStream > createDirectoryStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator)
uint64_t getLength() override
Return the number of bytes of data in this stream.
uint32_t getBlockSize() const
const MSFStreamLayout & getStreamLayout() const
Error readLongestContiguousChunk(uint64_t Offset, ArrayRef< uint8_t > &Buffer) override
Given an offset into the stream, read as much as possible without copying any data.
Error writeBytes(uint64_t Offset, ArrayRef< uint8_t > Buffer) override
Attempt to write the given bytes into the stream at the desired offset.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
uint64_t blockToOffset(uint64_t BlockNumber, uint64_t BlockSize)
LLVM_ABI MSFStreamLayout getFpmStreamLayout(const MSFLayout &Msf, bool IncludeUnusedFpmData=false, bool AltFpm=false)
Determine the layout of the FPM stream, given the MSF layout.
This is an optimization pass for GlobalISel generic memory operations.
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr T AbsoluteDifference(U X, V Y)
Subtract two unsigned integers, X and Y, of type T and return the absolute value of the result.
void consumeError(Error Err)
Consume a Error without doing anything.
ArrayRef< support::ulittle32_t > StreamSizes
ArrayRef< support::ulittle32_t > DirectoryBlocks
std::vector< ArrayRef< support::ulittle32_t > > StreamMap
support::ulittle32_t BlockSize
support::ulittle32_t NumDirectoryBytes