private:
BitstreamReader& Stream;
- SmallVector<uint64_t,10> Record;
+ SmallVector<uint64_t,20> Record;
unsigned RecIdx;
BumpPtrAllocator Allocator;
BPNode* FreeList;
MapTy BPatchMap;
- llvm::SmallVector<uint64_t,5> BlockLocs;
+ llvm::SmallVector<std::pair<Location,unsigned>,5> BlockStack;
+ unsigned AbbrevNo;
+ unsigned RecordCode;
//===----------------------------------------------------------===//
// Public Interface.
RegisterPtr(PtrID,&x);
}
- Location GetCurrentBlockLocation();
+ Location getCurrentBlockLocation();
+ unsigned getCurrentBlockID();
+ unsigned getAbbrevNo();
+
bool FinishedBlock(Location BlockLoc);
bool AtEnd();
bool inRecord();
+ void SkipBlock();
+
+ unsigned getRecordCode();
private:
- void ReadRecord();
+ bool AdvanceStream();
+ void ReadRecord();
+
uintptr_t ReadInternalRefPtr();
static inline bool HasFinalPtr(MapTy::value_type& V) {
using namespace llvm;
Deserializer::Deserializer(BitstreamReader& stream)
- : Stream(stream), RecIdx(0), FreeList(NULL) {
+ : Stream(stream), RecIdx(0), FreeList(NULL), AbbrevNo(0), RecordCode(0) {
}
Deserializer::~Deserializer() {
assert (RecIdx >= Record.size() &&
"Still scanning bitcode record when deserialization completed.");
-#ifdef NDEBUG
+#ifdef DEBUG_BACKPATCH
for (MapTy::iterator I=BPatchMap.begin(), E=BPatchMap.end(); I!=E; ++I)
assert (I->first.hasFinalPtr() &&
"Some pointers were not backpatched.");
if (RecIdx >= Record.size()) {
RecIdx = 0;
Record.clear();
+ AbbrevNo = 0;
return false;
}
- else return true;
+ else
+ return true;
}
- else return false;
-}
-void Deserializer::ReadRecord() {
- // FIXME: Check if we haven't run off the edge of the stream.
- // FIXME: Handle abbreviations.
+ return false;
+}
- assert (Record.size() == 0);
+bool Deserializer::AdvanceStream() {
+ assert (!inRecord() &&
+ "Cannot advance stream. Still processing a record.");
- unsigned Code;
-
- while (true) {
-
- if (Stream.AtEndOfStream())
- return;
-
- Code = Stream.ReadCode();
+ if (AbbrevNo == bitc::ENTER_SUBBLOCK ||
+ AbbrevNo >= bitc::UNABBREV_RECORD)
+ return true;
- if (Code == bitc::ENTER_SUBBLOCK) {
- BlockLocs.push_back(Stream.GetCurrentBitNo());
- unsigned id = Stream.ReadSubBlockID();
- Stream.EnterSubBlock(id);
- continue;
- }
-
- if (Code == bitc::END_BLOCK) {
- bool x = Stream.ReadBlockEnd();
- assert (!x && "Error at block end.");
- BlockLocs.pop_back();
- continue;
- }
+ while (!Stream.AtEndOfStream()) {
- if (Code == bitc::DEFINE_ABBREV) {
- Stream.ReadAbbrevRecord();
- continue;
+ AbbrevNo = Stream.ReadCode();
+
+ switch (AbbrevNo) {
+ case bitc::ENTER_SUBBLOCK: {
+ unsigned id = Stream.ReadSubBlockID();
+ BlockStack.push_back(std::make_pair(Stream.GetCurrentBitNo(),id));
+ break;
+ }
+
+ case bitc::END_BLOCK: {
+ bool x = Stream.ReadBlockEnd();
+ assert (!x && "Error at block end.");
+ BlockStack.pop_back();
+ continue;
+ }
+
+ case bitc::DEFINE_ABBREV:
+ Stream.ReadAbbrevRecord();
+ continue;
+
+ default:
+ break;
}
- break;
+ return true;
}
- assert (Record.size() == 0);
- Stream.ReadRecord(Code,Record);
- assert (Record.size() > 0 || Stream.AtEndOfStream());
+ return false;
}
-Deserializer::Location Deserializer::GetCurrentBlockLocation() {
+void Deserializer::ReadRecord() {
+
+ while (AdvanceStream() && AbbrevNo == bitc::ENTER_SUBBLOCK) {
+ assert (!BlockStack.empty());
+ Stream.EnterSubBlock(BlockStack.back().second);
+ AbbrevNo = 0;
+ }
+
+ if (Stream.AtEndOfStream())
+ return;
+
+ assert (Record.size() == 0);
+ assert (AbbrevNo >= bitc::UNABBREV_RECORD);
+ RecordCode = Stream.ReadRecord(AbbrevNo,Record);
+ assert (Record.size() > 0);
+}
+
+void Deserializer::SkipBlock() {
+ assert (!inRecord());
+ assert (AbbrevNo == bitc::ENTER_SUBBLOCK);
+ Stream.SkipBlock();
+ AbbrevNo = 0;
+}
+
+Deserializer::Location Deserializer::getCurrentBlockLocation() {
if (!inRecord())
- ReadRecord();
+ AdvanceStream();
- assert (!BlockLocs.empty());
- return BlockLocs.back();
+ return BlockStack.back().first;
}
-bool Deserializer::FinishedBlock(Location BlockLoc) {
+unsigned Deserializer::getCurrentBlockID() {
if (!inRecord())
+ AdvanceStream();
+
+ return BlockStack.back().second;
+}
+
+unsigned Deserializer::getRecordCode() {
+ if (!inRecord()) {
+ AdvanceStream();
+ assert (AbbrevNo >= bitc::UNABBREV_RECORD);
ReadRecord();
+ }
- for (llvm::SmallVector<Location,5>::reverse_iterator
- I=BlockLocs.rbegin(), E=BlockLocs.rend(); I!=E; ++I)
- if (*I == BlockLoc)
- return false;
+ return RecordCode;
+}
+
+bool Deserializer::FinishedBlock(Location BlockLoc) {
+ if (!inRecord())
+ AdvanceStream();
+
+ for (llvm::SmallVector<std::pair<Location,unsigned>,5>::reverse_iterator
+ I=BlockStack.rbegin(), E=BlockStack.rend(); I!=E; ++I)
+ if (I->first == BlockLoc)
+ return false;
return true;
}
+unsigned Deserializer::getAbbrevNo() {
+ if (!inRecord())
+ AdvanceStream();
+
+ return AbbrevNo;
+}
+
bool Deserializer::AtEnd() {
if (inRecord())
return false;
- ReadRecord();
+ if (!AdvanceStream())
+ return true;
- return Stream.AtEndOfStream();
+ return false;
}
uint64_t Deserializer::ReadInt() {