Go to the documentation of this file.
47 FreeBlocks[BlockMapAddr] =
false;
52 uint32_t MinBlockCount,
bool CanGrow) {
55 "The requested block size is unsupported");
63 if (
Addr == BlockMapAddr)
69 "Cannot grow the number of blocks");
74 return make_error<MSFError>(
76 "Requested block map address is already in use");
77 FreeBlocks[BlockMapAddr] =
true;
78 FreeBlocks[
Addr] =
false;
88 for (
auto B : DirectoryBlocks)
90 for (
auto B : DirBlocks) {
93 "Attempt to reuse an allocated block");
95 FreeBlocks[
B] =
false;
98 DirectoryBlocks = DirBlocks;
108 if (NumFreeBlocks < NumBlocks) {
111 "There are no free Blocks in the file");
112 uint32_t AllocBlocks = NumBlocks - NumFreeBlocks;
114 uint32_t NewBlockCount = AllocBlocks + OldBlockCount;
116 FreeBlocks.
resize(NewBlockCount,
true);
124 while (NextFpmBlock < NewBlockCount) {
126 FreeBlocks.
resize(NewBlockCount,
true);
127 FreeBlocks.
reset(NextFpmBlock, NextFpmBlock + 2);
128 NextFpmBlock += BlockSize;
135 assert(Block != -1 &&
"We ran out of Blocks!");
138 Blocks[
I++] = NextBlock;
139 FreeBlocks.
reset(NextBlock);
141 }
while (--NumBlocks > 0);
161 if (ReqBlocks != Blocks.
size())
162 return make_error<MSFError>(
164 "Incorrect number of blocks for requested stream size");
165 for (
auto Block : Blocks) {
166 if (Block >= FreeBlocks.
size())
167 FreeBlocks.
resize(Block + 1,
true);
169 if (!FreeBlocks.
test(Block))
170 return make_error<MSFError>(
172 "Attempt to re-use an already allocated block");
175 for (
auto Block : Blocks) {
176 FreeBlocks.
reset(Block);
178 StreamData.push_back(std::make_pair(Size, Blocks));
179 return StreamData.size() - 1;
184 std::vector<uint32_t> NewBlocks;
185 NewBlocks.resize(ReqBlocks);
186 if (
auto EC = allocateBlocks(ReqBlocks, NewBlocks))
188 StreamData.push_back(std::make_pair(Size, NewBlocks));
189 return StreamData.size() - 1;
200 if (NewBlocks > OldBlocks) {
201 uint32_t AddedBlocks = NewBlocks - OldBlocks;
203 std::vector<uint32_t> AddedBlockList;
204 AddedBlockList.resize(AddedBlocks);
205 if (
auto EC = allocateBlocks(AddedBlocks, AddedBlockList))
207 auto &CurrentBlocks = StreamData[Idx].second;
209 }
else if (OldBlocks > NewBlocks) {
212 uint32_t RemovedBlocks = OldBlocks - NewBlocks;
214 auto RemovedBlockList = CurrentBlocks.drop_front(NewBlocks);
215 for (
auto P : RemovedBlockList)
216 FreeBlocks[
P] =
true;
217 StreamData[Idx].second = CurrentBlocks.drop_back(RemovedBlocks);
220 StreamData[Idx].first = Size;
227 return StreamData[StreamIdx].first;
231 return StreamData[StreamIdx].second;
234 uint32_t MSFBuilder::computeDirectoryByteSize()
const {
241 for (
const auto &
D : StreamData) {
243 assert(ExpectedNumBlocks ==
D.second.size() &&
244 "Unexpected number of blocks");
263 if (NumDirectoryBlocks > DirectoryBlocks.size()) {
266 std::vector<uint32_t> ExtraBlocks;
267 uint32_t NumExtraBlocks = NumDirectoryBlocks - DirectoryBlocks.size();
268 ExtraBlocks.resize(NumExtraBlocks);
269 if (
auto EC = allocateBlocks(NumExtraBlocks, ExtraBlocks))
272 }
else if (NumDirectoryBlocks < DirectoryBlocks.size()) {
273 uint32_t NumUnnecessaryBlocks = DirectoryBlocks.size() - NumDirectoryBlocks;
276 FreeBlocks[
B] =
true;
277 DirectoryBlocks.resize(NumDirectoryBlocks);
286 std::uninitialized_copy_n(DirectoryBlocks.begin(), NumDirectoryBlocks,
292 if (!StreamData.empty()) {
295 L.StreamMap.resize(StreamData.size());
297 Sizes[
I] = StreamData[
I].first;
300 std::uninitialized_copy_n(StreamData[
I].second.begin(),
301 StreamData[
I].second.size(), BlockList);
307 L.FreePageMap = FreeBlocks;
323 while (BI < Layout.SB->NumBlocks) {
324 uint8_t ThisByte = 0;
328 uint8_t
Mask = uint8_t(IsFree) <<
I;
361 return make_error<MSFError>(
363 formatv(
"File size {0,1:N} too large for current PDB page size {1}",
368 if (
auto EC = OutFileOrError.takeError())
387 Layout, Buffer, Allocator);
395 for (
const auto &Blocks : Layout.
StreamMap) {
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
This is an optimization pass for GlobalISel generic memory operations.
Expected< MSFLayout > generateLayout()
Finalize the layout and build the headers and structures that describe the MSF layout and can be writ...
Error writeInteger(T Value)
Write the integer Value to the underlying stream in the specified endianness.
static const int BlockSize
static void commitFpm(WritableBinaryStream &MsfBuffer, const MSFLayout &Layout, BumpPtrAllocator &Allocator)
ArrayRef< support::ulittle32_t > DirectoryBlocks
uint64_t bytesToBlocks(uint64_t NumBytes, uint64_t BlockSize)
Error setBlockMapAddr(uint32_t Addr)
Request the block map to be at a specific block address.
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
uint32_t getMinimumBlockCount()
Provides write only access to a subclass of WritableBinaryStream.
static ErrorSuccess success()
Create a success value.
support::ulittle32_t NumDirectoryBytes
uint64_t blockToOffset(uint64_t BlockNumber, uint64_t BlockSize)
bool isValidBlockSize(uint32_t Size)
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
static const uint32_t kSuperBlockBlock
void setOffset(uint64_t Off)
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Expected< uint32_t > addStream(uint32_t Size, ArrayRef< uint32_t > Blocks)
Add a stream to the MSF file with the given size, occupying the given list of blocks.
Error writeArray(ArrayRef< T > Array)
Writes an array of objects of type T to the underlying stream, as if by using memcpy.
Tagged union holding either a T or a Error.
uint64_t getMaxFileSizeFromBlockSize(uint32_t Size)
Given the specified block size, returns the maximum possible file size.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
static std::unique_ptr< WritableMappedBlockStream > createFpmStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator, bool AltFpm=false)
Expected< FileBufferByteStream > commit(StringRef Path, MSFLayout &Layout)
Write the MSF layout to the underlying file.
size_type count() const
count - Returns the number of bits which are set.
size_type size() const
size - Returns the number of bits in this bitvector.
bool isBlockFree(uint32_t Idx) const
Check whether a particular block is allocated or free.
static const uint32_t kDefaultBlockMapAddr
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
uint32_t getNumFreeBlocks() const
Get the total number of blocks that exist in the MSF file but are not allocated to any valid data.
Error setDirectoryBlocksHint(ArrayRef< uint32_t > DirBlocks)
static const uint32_t kDefaultFreePageMap
support::ulittle32_t NumBlocks
uint32_t getStreamSize(uint32_t StreamIdx) const
Get the size of a stream by index.
ArrayRef< support::ulittle32_t > StreamSizes
ArrayRef< uint32_t > getStreamBlocks(uint32_t StreamIdx) const
Get the list of blocks allocated to a particular stream.
detail::packed_endian_specific_integral< uint32_t, little, unaligned > ulittle32_t
static const uint32_t kNumReservedPages
uint64_t bytesRemaining() const
uint32_t getNumUsedBlocks() const
Get the total number of blocks that will be allocated to actual data in this MSF file.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
void setUnknown1(uint32_t Unk1)
Allocate memory in an ever growing pool, as if by bump-pointer.
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
support::ulittle32_t FreeBlockMapBlock
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
uint32_t getTotalBlockCount() const
Get the total number of blocks in the MSF file.
Error setStreamSize(uint32_t Idx, uint32_t Size)
Update the size of an existing stream.
Error writeObject(const T &Obj)
Writes the object Obj to the underlying stream, as if by using memcpy.
StringRef - Represent a constant reference to a string, i.e.
static const uint32_t kFreePageMap1Block
static const char Magic[]
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
char MagicBytes[sizeof(Magic)]
static Expected< std::unique_ptr< FileOutputBuffer > > create(StringRef FilePath, size_t Size, unsigned Flags=0)
Factory method to create an OutputBuffer object which manages a read/write buffer of the specified si...
bool test(unsigned Idx) const
An implementation of WritableBinaryStream backed by an llvm FileOutputBuffer.
support::ulittle32_t BlockSize
support::ulittle32_t Unknown1
uint32_t getNumStreams() const
Get the total number of streams in the MSF layout.
Lightweight error class with error context and mandatory checking.
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
std::vector< ArrayRef< support::ulittle32_t > > StreamMap
int find_next(unsigned Prev) const
find_next - Returns the index of the next set bit following the "Prev" bit.
static const uint32_t kFreePageMap0Block
void setFreePageMap(uint32_t Fpm)
Error takeError()
Take ownership of the stored error.
static std::unique_ptr< WritableMappedBlockStream > createDirectoryStream(const MSFLayout &Layout, WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator)
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
size_t size() const
size - Get the array size.
support::ulittle32_t BlockMapAddr
A BinaryStream which can be read from as well as written to.