From: Ted Kremenek Date: Wed, 31 Oct 2007 19:58:32 +0000 (+0000) Subject: Implemented deserialization of references. References are handled X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=eb9409dbb9c5fe963bf28973c5697fddfcaf48ce;p=oota-llvm.git Implemented deserialization of references. References are handled just like pointers, except that they cannot be backpatched. This means that references are essentially non-owning pointers where the referred object must be deserialized prior to the reference being deserialized. Because of the nature of references, this ordering of objects is always possible. Fixed a bug in backpatching code (returning the backpatched pointer would accidentally include a bit flag). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43570 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Bitcode/Deserialize.h b/include/llvm/Bitcode/Deserialize.h index 508b4deee82..72367e30d98 100644 --- a/include/llvm/Bitcode/Deserialize.h +++ b/include/llvm/Bitcode/Deserialize.h @@ -56,7 +56,7 @@ class Deserializer { BPatchEntry(void* P) : Ptr(reinterpret_cast(P)) {} - bool hasFinalPtr() const { return Ptr & 0x1 ? true : false; } + bool hasFinalPtr() const { return Ptr & 0x1 ? false : true; } void setFinalPtr(BPNode*& FreeList, void* P); BPNode* getBPNode() const { @@ -69,7 +69,10 @@ class Deserializer { Ptr = reinterpret_cast(N) | 0x1; } - uintptr_t getRawPtr() const { return Ptr; } + uintptr_t getFinalPtr() const { + assert (!(Ptr & 0x1) && "Backpatch pointer not yet deserialized."); + return Ptr; + } static inline bool isPod() { return true; } }; @@ -132,17 +135,30 @@ public: } template - void ReadPtr(T*& PtrRef) { ReadUIntPtr(reinterpret_cast(PtrRef));} - - void ReadPtr(uintptr_t& PtrRef) { ReadUIntPtr(PtrRef); } + void ReadPtr(T*& PtrRef) { + ReadUIntPtr(reinterpret_cast(PtrRef)); + } + template + void ReadPtr(const T*& PtrRef) { + ReadPtr(const_cast(PtrRef)); + } + void ReadUIntPtr(uintptr_t& PtrRef); + template + T& ReadRef() { + T* p = reinterpret_cast(ReadInternalRefPtr()); + return *p; + } + + void RegisterPtr(unsigned PtrId, void* Ptr); private: void ReadRecord(); bool inRecord(); + uintptr_t ReadInternalRefPtr(); }; } // end namespace llvm diff --git a/lib/Bitcode/Reader/Deserialize.cpp b/lib/Bitcode/Reader/Deserialize.cpp index ff0dd44dc25..4b58cf41dc1 100644 --- a/lib/Bitcode/Reader/Deserialize.cpp +++ b/lib/Bitcode/Reader/Deserialize.cpp @@ -115,7 +115,7 @@ void Deserializer::ReadUIntPtr(uintptr_t& PtrRef) { BPatchEntry& E = BPatchMap[PtrId]; if (E.hasFinalPtr()) - PtrRef = E.getRawPtr(); + PtrRef = E.getFinalPtr(); else { // Register backpatch. Check the freelist for a BPNode. BPNode* N; @@ -132,6 +132,18 @@ void Deserializer::ReadUIntPtr(uintptr_t& PtrRef) { } } +uintptr_t Deserializer::ReadInternalRefPtr() { + unsigned PtrId = ReadInt(); + + assert (PtrId != 0 && "References cannot refer the NULL address."); + + BPatchEntry& E = BPatchMap[PtrId]; + + assert (E.hasFinalPtr() && + "Cannot backpatch references. Object must be already deserialized."); + + return E.getFinalPtr(); +} void Deserializer::BPatchEntry::setFinalPtr(BPNode*& FreeList, void* P) { assert (!hasFinalPtr());