llvm.org GIT mirror llvm / ea3c211
Use the return of readBytes to find out if we are at the end of the stream. This allows the removal of isObjectEnd and opens the way for reading 64 bits at a time. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221804 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 6 years ago
4 changed file(s) with 58 addition(s) and 67 deletion(s). Raw diff Collapse all Expand all
168168 BitstreamReader *BitStream;
169169 size_t NextChar;
170170
171 // The size of the bicode. 0 if we don't know it yet.
172 size_t Size;
173
171174 /// This is the current data we have pulled from the stream but have not
172175 /// returned to the client. This is specifically and intentionally defined to
173176 /// follow the word size of the host machine for efficiency. We use word_t in
207210
208211 BitStream = R;
209212 NextChar = 0;
210 CurWord = 0;
213 Size = 0;
211214 BitsInCurWord = 0;
212215 CurCodeSize = 2;
213216 }
214217
215218 void freeState();
216
217 bool isEndPos(size_t pos) {
218 return BitStream->getBitcodeBytes().isObjectEnd(static_cast(pos));
219 }
220219
221220 bool canSkipToPos(size_t pos) const {
222221 // pos can be skipped to if it is a valid address or one byte past the end.
225224 }
226225
227226 bool AtEndOfStream() {
228 return BitsInCurWord == 0 && isEndPos(NextChar);
227 if (BitsInCurWord != 0)
228 return false;
229 if (Size == NextChar)
230 return true;
231 fillCurWord();
232 return BitsInCurWord == 0;
229233 }
230234
231235 /// Return the number of bits used to encode an abbrev #.
304308 // Move the cursor to the right word.
305309 NextChar = ByteNo;
306310 BitsInCurWord = 0;
307 CurWord = 0;
308311
309312 // Skip over any bits that are already consumed.
310313 if (WordBitNo) {
315318 }
316319 }
317320
321 void fillCurWord() {
322 assert(Size == 0 || NextChar < (unsigned)Size);
323
324 // Read the next word from the stream.
325 uint8_t Array[sizeof(word_t)] = {0};
326
327 uint64_t BytesRead =
328 BitStream->getBitcodeBytes().readBytes(Array, sizeof(Array), NextChar);
329
330 // If we run out of data, stop at the end of the stream.
331 if (BytesRead == 0) {
332 Size = NextChar;
333 return;
334 }
335 assert(BytesRead == sizeof(Array));
336
337 // Handle big-endian byte-swapping if necessary.
338 support::detail::packed_endian_specific_integral<
339 word_t, support::little, support::unaligned> EndianValue;
340 memcpy(&EndianValue, Array, sizeof(Array));
341
342 CurWord = EndianValue;
343 NextChar += sizeof(word_t);
344 BitsInCurWord = sizeof(word_t) * 8;
345 }
318346
319347 uint32_t Read(unsigned NumBits) {
320348 assert(NumBits && NumBits <= 32 &&
323351 // If the field is fully contained by CurWord, return it quickly.
324352 if (BitsInCurWord >= NumBits) {
325353 uint32_t R = uint32_t(CurWord) & (~0U >> (32-NumBits));
326 CurWord >>= NumBits;
354
355 // Use a mask to avoid undefined behavior.
356 CurWord >>= (NumBits & 0x1f);
357
327358 BitsInCurWord -= NumBits;
328359 return R;
329360 }
330361
362 uint32_t R = BitsInCurWord ? uint32_t(CurWord) : 0;
363 unsigned BitsLeft = NumBits - BitsInCurWord;
364
365 fillCurWord();
366
331367 // If we run out of data, stop at the end of the stream.
332 if (isEndPos(NextChar)) {
333 CurWord = 0;
334 BitsInCurWord = 0;
368 if (BitsLeft > BitsInCurWord)
335369 return 0;
336 }
337
338 uint32_t R = uint32_t(CurWord);
339
340 // Read the next word from the stream.
341 uint8_t Array[sizeof(word_t)] = {0};
342
343 BitStream->getBitcodeBytes().readBytes(Array, sizeof(Array), NextChar);
344
345 // Handle big-endian byte-swapping if necessary.
346 support::detail::packed_endian_specific_integral
347 EndianValue;
348 memcpy(&EndianValue, Array, sizeof(Array));
349
350 CurWord = EndianValue;
351
352 NextChar += sizeof(word_t);
353
354 // Extract NumBits-BitsInCurWord from what we just read.
355 unsigned BitsLeft = NumBits-BitsInCurWord;
356
357 // Be careful here, BitsLeft is in the range [1..32]/[1..64] inclusive.
358 R |= uint32_t((CurWord & (word_t(~0ULL) >> (sizeof(word_t)*8-BitsLeft)))
359 << BitsInCurWord);
360
361 // BitsLeft bits have just been used up from CurWord. BitsLeft is in the
362 // range [1..32]/[1..64] so be careful how we shift.
363 if (BitsLeft != sizeof(word_t)*8)
364 CurWord >>= BitsLeft;
365 else
366 CurWord = 0;
367 BitsInCurWord = sizeof(word_t)*8-BitsLeft;
370
371 uint32_t R2 = uint32_t(CurWord) & (~0U >> (sizeof(word_t) * 8 - BitsLeft));
372
373 // Use a mask to avoid undefined behavior.
374 CurWord >>= (BitsLeft & 0x1f);
375
376 BitsInCurWord -= BitsLeft;
377
378 R |= uint32_t(R2 << (NumBits - BitsLeft));
379
368380 return R;
369381 }
370382
425437 }
426438
427439 BitsInCurWord = 0;
428 CurWord = 0;
429440 }
430441 public:
431442
2121 /// to return the right result, getExtent must also wait for all the data to
2222 /// arrive; therefore it should not be called on objects which are actually
2323 /// streamed (this would defeat the purpose of streaming). Instead,
24 /// isValidAddress and isObjectEnd can be used to test addresses without knowing
25 /// the exact size of the stream. Finally, getPointer can be used instead of
26 /// readBytes to avoid extra copying.
24 /// isValidAddress can be used to test addresses without knowing the exact size
25 /// of the stream. Finally, getPointer can be used instead of readBytes to avoid
26 /// extra copying.
2727 class MemoryObject {
2828 public:
2929 virtual ~MemoryObject();
6060 /// @param address - address of the byte, in the same space as getBase()
6161 /// @result - true if the address may be read with readByte()
6262 virtual bool isValidAddress(uint64_t address) const = 0;
63
64 /// Returns true if the address is one past the end of the object (i.e. if it
65 /// is equal to base + extent). May block until (address - base) bytes have
66 /// been read
67 /// @param address - address of the byte, in the same space as getBase()
68 /// @result - true if the address is equal to base + extent
69 virtual bool isObjectEnd(uint64_t address) const = 0;
7063 };
7164
7265 }
3737 return nullptr;
3838 }
3939 bool isValidAddress(uint64_t address) const override;
40 bool isObjectEnd(uint64_t address) const override;
4140
4241 /// Drop s bytes from the front of the stream, pushing the positions of the
4342 /// remaining bytes down by s. This is used to skip past the bitcode header,
3333 bool isValidAddress(uint64_t address) const override {
3434 return validAddress(address);
3535 }
36 bool isObjectEnd(uint64_t address) const override {
37 return objectEnd(address);
38 }
3936
4037 private:
4138 const uint8_t* const FirstChar;
4542 // calls per public function
4643 bool validAddress(uint64_t address) const {
4744 return static_cast(address) < LastChar - FirstChar;
48 }
49 bool objectEnd(uint64_t address) const {
50 return static_cast(address) == LastChar - FirstChar;
5145 }
5246
5347 RawMemoryObject(const RawMemoryObject&) LLVM_DELETED_FUNCTION;
8276 bool StreamingMemoryObject::isValidAddress(uint64_t address) const {
8377 if (ObjectSize && address < ObjectSize) return true;
8478 return fetchToPos(address);
85 }
86
87 bool StreamingMemoryObject::isObjectEnd(uint64_t address) const {
88 if (ObjectSize) return address == ObjectSize;
89 fetchToPos(address);
90 return address == ObjectSize && address != 0;
9179 }
9280
9381 uint64_t StreamingMemoryObject::getExtent() const {