aboutsummaryrefslogtreecommitdiff
path: root/lib/Bitcode/Reader/Deserialize.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Bitcode/Reader/Deserialize.cpp')
-rw-r--r--lib/Bitcode/Reader/Deserialize.cpp62
1 files changed, 38 insertions, 24 deletions
diff --git a/lib/Bitcode/Reader/Deserialize.cpp b/lib/Bitcode/Reader/Deserialize.cpp
index 66df46ea23..9caef6dae1 100644
--- a/lib/Bitcode/Reader/Deserialize.cpp
+++ b/lib/Bitcode/Reader/Deserialize.cpp
@@ -16,14 +16,14 @@
using namespace llvm;
Deserializer::Deserializer(BitstreamReader& stream)
- : Stream(stream), RecIdx(0) {
+ : Stream(stream), RecIdx(0), FreeList(NULL) {
}
Deserializer::~Deserializer() {
assert (RecIdx >= Record.size() &&
"Still scanning bitcode record when deserialization completed.");
- BackpatchPointers();
+ assert (FreeList == NULL && "Some pointers were not backpatched.");
}
@@ -96,11 +96,11 @@ void Deserializer::ReadCStr(std::vector<char>& buff, bool isNullTerm) {
void Deserializer::RegisterPtr(unsigned PtrId,void* Ptr) {
BPatchEntry& E = BPatchMap[PtrId];
- assert (E.Ptr == NULL && "Pointer already registered.");
- E.Ptr = Ptr;
+ assert (E.hasFinalPtr() && "Pointer already registered.");
+ E.setFinalPtr(FreeList,Ptr);
}
-void Deserializer::ReadPtr(void*& PtrRef) {
+void Deserializer::ReadUIntPtr(uintptr_t& PtrRef) {
unsigned PtrId = ReadInt();
if (PtrId == 0) {
@@ -110,32 +110,46 @@ void Deserializer::ReadPtr(void*& PtrRef) {
BPatchEntry& E = BPatchMap[PtrId];
- if (E.Ptr == NULL) {
- // Register backpatch.
- void* P = Allocator.Allocate<BPatchNode>();
- E.Head = new (P) BPatchNode(E.Head,PtrRef);
+ if (E.hasFinalPtr())
+ PtrRef = E.getRawPtr();
+ else {
+ // Register backpatch. Check the freelist for a BPNode.
+ BPNode* N;
+
+ if (FreeList) {
+ N = FreeList;
+ FreeList = FreeList->Next;
+ }
+ else // No available BPNode. Allocate one.
+ N = (BPNode*) Allocator.Allocate<BPNode>();
+
+ new (N) BPNode(E.getBPNode(),PtrRef);
+ E.setBPNode(N);
}
- else
- PtrRef = E.Ptr;
}
-void Deserializer::BackpatchPointers() {
- for (MapTy::iterator I=BPatchMap.begin(),E=BPatchMap.end(); I!=E; ++I) {
-
- BPatchEntry& Entry = I->second;
- assert (Entry.Ptr && "No pointer found for backpatch.");
-
- for (BPatchNode* N = Entry.Head; N != NULL; N = N->Next)
- // Bitwise-OR in the pointer to support "smart" pointers that use
- // unused bits to store extra data.
- N->PtrRef |= reinterpret_cast<uintptr_t>(Entry.Ptr);
-
- Entry.Head = NULL;
+
+void Deserializer::BPatchEntry::setFinalPtr(BPNode*& FreeList, void* P) {
+ assert (!hasFinalPtr());
+
+ // Perform backpatching.
+
+ BPNode* Last = NULL;
+
+ for (BPNode* N = getBPNode() ; N != NULL; N = N->Next) {
+ Last = N;
+ N->PtrRef |= reinterpret_cast<uintptr_t>(P);
}
- Allocator.Reset();
+ if (Last) {
+ Last->Next = FreeList;
+ FreeList = getBPNode();
+ }
+
+ Ptr = reinterpret_cast<uintptr_t>(P);
}
+
#define INT_READ(TYPE)\
void SerializeTrait<TYPE>::Read(Deserializer& D, TYPE& X) {\
X = (TYPE) D.ReadInt(); }\