diff --git a/llvm/include/llvm/Bitcode/Deserialize.h b/llvm/include/llvm/Bitcode/Deserialize.h index 48f78bf9e5d9..c98b4e810a5b 100644 --- a/llvm/include/llvm/Bitcode/Deserialize.h +++ b/llvm/include/llvm/Bitcode/Deserialize.h @@ -55,12 +55,12 @@ class Deserializer { unsigned Raw; public: - BPKey(unsigned PtrId) : Raw(PtrId << 1) { assert (PtrId > 0); } + BPKey(SerializedPtrID PtrId) : Raw(PtrId << 1) { assert (PtrId > 0); } BPKey(unsigned code, unsigned) : Raw(code) {} void MarkFinal() { Raw |= 0x1; } bool hasFinalPtr() const { return Raw & 0x1 ? true : false; } - unsigned getID() const { return Raw >> 1; } + SerializedPtrID getID() const { return Raw >> 1; } static inline BPKey getEmptyKey() { return BPKey(0,0); } static inline BPKey getTombstoneKey() { return BPKey(1,0); } @@ -76,26 +76,37 @@ class Deserializer { typedef llvm::DenseMap MapTy; //===----------------------------------------------------------===// - // Internal data members. + // Publicly visible types. //===----------------------------------------------------------===// +public: + typedef uint64_t Location; + + //===----------------------------------------------------------===// + // Internal data members. + //===----------------------------------------------------------===// + +private: BitstreamReader& Stream; SmallVector Record; unsigned RecIdx; BumpPtrAllocator Allocator; BPNode* FreeList; - MapTy BPatchMap; + MapTy BPatchMap; + llvm::SmallVector BlockLocs; //===----------------------------------------------------------===// // Public Interface. //===----------------------------------------------------------===// -public: +public: Deserializer(BitstreamReader& stream); ~Deserializer(); uint64_t ReadInt(); int64_t ReadSInt(); + SerializedPtrID ReadPtrID() { return (SerializedPtrID) ReadInt(); } + bool ReadBool() { return ReadInt() ? true : false; @@ -117,7 +128,7 @@ public: template inline T* ReadOwnedPtr(bool AutoRegister = true) { - unsigned PtrID = ReadInt(); + SerializedPtrID PtrID = ReadPtrID(); if (!PtrID) return NULL; @@ -139,8 +150,8 @@ public: void BatchReadOwnedPtrs(T1*& P1, T2*& P2, bool A1=true, bool A2=true) { - unsigned ID1 = ReadInt(); - unsigned ID2 = ReadInt(); + SerializedPtrID ID1 = ReadPtrID(); + SerializedPtrID ID2 = ReadPtrID(); P1 = (ID1) ? SerializeTrait::Materialize(*this) : NULL; if (ID1 && A1) RegisterPtr(ID1,P1); @@ -153,9 +164,9 @@ public: void BatchReadOwnedPtrs(T1*& P1, T2*& P2, T3*& P3, bool A1=true, bool A2=true, bool A3=true) { - unsigned ID1 = ReadInt(); - unsigned ID2 = ReadInt(); - unsigned ID3 = ReadInt(); + SerializedPtrID ID1 = ReadPtrID(); + SerializedPtrID ID2 = ReadPtrID(); + SerializedPtrID ID3 = ReadPtrID(); P1 = (ID1) ? SerializeTrait::Materialize(*this) : NULL; if (ID1 && A1) RegisterPtr(ID1,P1); @@ -170,10 +181,10 @@ public: template void BatchReadOwnedPtrs(unsigned NumPtrs, T** Ptrs, bool AutoRegister=true) { for (unsigned i = 0; i < NumPtrs; ++i) - reinterpret_cast(Ptrs[i]) = ReadInt(); + reinterpret_cast(Ptrs[i]) = ReadPtrID(); for (unsigned i = 0; i < NumPtrs; ++i) { - unsigned PtrID = reinterpret_cast(Ptrs[i]); + SerializedPtrID PtrID = reinterpret_cast(Ptrs[i]); T* p = PtrID ? SerializeTrait::Materialize(*this) : NULL; if (PtrID && AutoRegister) @@ -204,15 +215,28 @@ public: return *p; } - void RegisterPtr(unsigned PtrId, const void* Ptr); + void RegisterPtr(SerializedPtrID PtrId, const void* Ptr); void RegisterPtr(const void* Ptr) { - RegisterPtr(ReadInt(),Ptr); + RegisterPtr(ReadPtrID(),Ptr); } + template + void RegisterRef(const T& x) { + RegisterPtr(&x); + } + + template + void RegisterRef(SerializedPtrID PtrID, const T& x) { + RegisterPtr(PtrID,&x); + } + + Location GetCurrentBlockLocation(); + bool FinishedBlock(Location BlockLoc); + bool AtEnd(); - bool inRecord(); + private: void ReadRecord(); uintptr_t ReadInternalRefPtr(); diff --git a/llvm/include/llvm/Bitcode/SerializationFwd.h b/llvm/include/llvm/Bitcode/SerializationFwd.h index 6569267ad902..772ea7ceba5d 100644 --- a/llvm/include/llvm/Bitcode/SerializationFwd.h +++ b/llvm/include/llvm/Bitcode/SerializationFwd.h @@ -20,6 +20,8 @@ class Serializer; class Deserializer; template struct SerializeTrait; +typedef unsigned SerializedPtrID; + } // end namespace llvm #endif diff --git a/llvm/include/llvm/Bitcode/Serialize.h b/llvm/include/llvm/Bitcode/Serialize.h index b11a8d736637..2cd597e90591 100644 --- a/llvm/include/llvm/Bitcode/Serialize.h +++ b/llvm/include/llvm/Bitcode/Serialize.h @@ -93,16 +93,17 @@ public: for (unsigned i = 0; i < NumPtrs; ++i) if (Ptrs[i]) SerializeTrait::Emit(*this,*Ptrs[i]); } + + bool isRegistered(const void* p) const; - void FlushRecord() { if (inRecord()) EmitRecord(); } - + void FlushRecord() { if (inRecord()) EmitRecord(); } void EnterBlock(unsigned BlockID = 8, unsigned CodeLen = 3); void ExitBlock(); private: void EmitRecord(); inline bool inRecord() { return Record.size() > 0; } - unsigned getPtrId(const void* ptr); + SerializedPtrID getPtrId(const void* ptr); }; } // end namespace llvm diff --git a/llvm/lib/Bitcode/Reader/Deserialize.cpp b/llvm/lib/Bitcode/Reader/Deserialize.cpp index 99cb5d2e3abe..5d0c724b8b9a 100644 --- a/llvm/lib/Bitcode/Reader/Deserialize.cpp +++ b/llvm/lib/Bitcode/Reader/Deserialize.cpp @@ -63,15 +63,16 @@ void Deserializer::ReadRecord() { Code = Stream.ReadCode(); if (Code == bitc::ENTER_SUBBLOCK) { - // No known subblocks, always skip them. + BlockLocs.push_back(Stream.GetCurrentBitNo()); unsigned id = Stream.ReadSubBlockID(); Stream.EnterSubBlock(id); continue; } - if (Code == bitc::END_BLOCK) { + if (Code == bitc::END_BLOCK) { bool x = Stream.ReadBlockEnd(); assert (!x && "Error at block end."); + BlockLocs.pop_back(); continue; } @@ -88,6 +89,26 @@ void Deserializer::ReadRecord() { assert (Record.size() > 0 || Stream.AtEndOfStream()); } +Deserializer::Location Deserializer::GetCurrentBlockLocation() { + if (!inRecord()) + ReadRecord(); + + assert (!BlockLocs.empty()); + return BlockLocs.back(); +} + +bool Deserializer::FinishedBlock(Location BlockLoc) { + if (!inRecord()) + ReadRecord(); + + for (llvm::SmallVector::reverse_iterator + I=BlockLocs.rbegin(), E=BlockLocs.rend(); I!=E; ++I) + if (*I == BlockLoc) + return false; + + return true; +} + bool Deserializer::AtEnd() { if (inRecord()) return false; @@ -159,7 +180,7 @@ void Deserializer::RegisterPtr(unsigned PtrId, const void* Ptr) { } void Deserializer::ReadUIntPtr(uintptr_t& PtrRef, bool AllowBackpatch) { - unsigned PtrId = ReadInt(); + SerializedPtrID PtrId = ReadPtrID(); if (PtrId == 0) { PtrRef = 0; @@ -194,7 +215,7 @@ void Deserializer::ReadUIntPtr(uintptr_t& PtrRef, bool AllowBackpatch) { } uintptr_t Deserializer::ReadInternalRefPtr() { - unsigned PtrId = ReadInt(); + SerializedPtrID PtrId = ReadPtrID(); assert (PtrId != 0 && "References cannot refer the NULL address."); diff --git a/llvm/lib/Bitcode/Writer/Serialize.cpp b/llvm/lib/Bitcode/Writer/Serialize.cpp index b97462b629e1..3baf9ad59aa9 100644 --- a/llvm/lib/Bitcode/Writer/Serialize.cpp +++ b/llvm/lib/Bitcode/Writer/Serialize.cpp @@ -14,6 +14,10 @@ #include "llvm/Bitcode/Serialize.h" #include "string.h" +#ifdef DEBUG_BACKPATCH +#include "llvm/Support/Streams.h" +#endif + using namespace llvm; Serializer::Serializer(BitstreamWriter& stream) @@ -67,15 +71,13 @@ void Serializer::EmitCStr(const char* s, const char* end) { Record.push_back(*s); ++s; } - - EmitRecord(); } void Serializer::EmitCStr(const char* s) { EmitCStr(s,s+strlen(s)); } -unsigned Serializer::getPtrId(const void* ptr) { +SerializedPtrID Serializer::getPtrId(const void* ptr) { if (!ptr) return 0; @@ -83,12 +85,20 @@ unsigned Serializer::getPtrId(const void* ptr) { if (I == PtrMap.end()) { unsigned id = PtrMap.size()+1; +#ifdef DEBUG_BACKPATCH + llvm::cerr << "Registered PTR: " << ptr << " => " << id << "\n"; +#endif PtrMap[ptr] = id; return id; } else return I->second; } +bool Serializer::isRegistered(const void* ptr) const { + MapTy::const_iterator I = PtrMap.find(ptr); + return I != PtrMap.end(); +} + #define INT_EMIT(TYPE)\ void SerializeTrait::Emit(Serializer&S, TYPE X) { S.EmitInt(X); }