Added typedef "SerializedPtrID" to represent the pointer handle written to disk

instead of just using "unsigned".  This gives us more flexibility in changing
the definition of the handle later, and is more self-documenting.

Added tracking of block stack in the Deserializer.  Now clients can query
if they are still within a block using the methods GetCurrentBlockLocation()
and FinishedBlock().


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43903 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ted Kremenek 2007-11-08 19:50:46 +00:00
parent b410df995c
commit ec8cd06555
5 changed files with 84 additions and 26 deletions

View File

@ -55,12 +55,12 @@ class Deserializer {
unsigned Raw; unsigned Raw;
public: 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) {} BPKey(unsigned code, unsigned) : Raw(code) {}
void MarkFinal() { Raw |= 0x1; } void MarkFinal() { Raw |= 0x1; }
bool hasFinalPtr() const { return Raw & 0x1 ? true : false; } 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 getEmptyKey() { return BPKey(0,0); }
static inline BPKey getTombstoneKey() { return BPKey(1,0); } static inline BPKey getTombstoneKey() { return BPKey(1,0); }
@ -76,26 +76,37 @@ class Deserializer {
typedef llvm::DenseMap<BPKey,BPEntry,BPKey,BPEntry> MapTy; typedef llvm::DenseMap<BPKey,BPEntry,BPKey,BPEntry> MapTy;
//===----------------------------------------------------------===// //===----------------------------------------------------------===//
// Internal data members. // Publicly visible types.
//===----------------------------------------------------------===// //===----------------------------------------------------------===//
public:
typedef uint64_t Location;
//===----------------------------------------------------------===//
// Internal data members.
//===----------------------------------------------------------===//
private:
BitstreamReader& Stream; BitstreamReader& Stream;
SmallVector<uint64_t,10> Record; SmallVector<uint64_t,10> Record;
unsigned RecIdx; unsigned RecIdx;
BumpPtrAllocator Allocator; BumpPtrAllocator Allocator;
BPNode* FreeList; BPNode* FreeList;
MapTy BPatchMap; MapTy BPatchMap;
llvm::SmallVector<uint64_t,5> BlockLocs;
//===----------------------------------------------------------===// //===----------------------------------------------------------===//
// Public Interface. // Public Interface.
//===----------------------------------------------------------===// //===----------------------------------------------------------===//
public: public:
Deserializer(BitstreamReader& stream); Deserializer(BitstreamReader& stream);
~Deserializer(); ~Deserializer();
uint64_t ReadInt(); uint64_t ReadInt();
int64_t ReadSInt(); int64_t ReadSInt();
SerializedPtrID ReadPtrID() { return (SerializedPtrID) ReadInt(); }
bool ReadBool() { bool ReadBool() {
return ReadInt() ? true : false; return ReadInt() ? true : false;
@ -117,7 +128,7 @@ public:
template <typename T> template <typename T>
inline T* ReadOwnedPtr(bool AutoRegister = true) { inline T* ReadOwnedPtr(bool AutoRegister = true) {
unsigned PtrID = ReadInt(); SerializedPtrID PtrID = ReadPtrID();
if (!PtrID) if (!PtrID)
return NULL; return NULL;
@ -139,8 +150,8 @@ public:
void BatchReadOwnedPtrs(T1*& P1, T2*& P2, void BatchReadOwnedPtrs(T1*& P1, T2*& P2,
bool A1=true, bool A2=true) { bool A1=true, bool A2=true) {
unsigned ID1 = ReadInt(); SerializedPtrID ID1 = ReadPtrID();
unsigned ID2 = ReadInt(); SerializedPtrID ID2 = ReadPtrID();
P1 = (ID1) ? SerializeTrait<T1>::Materialize(*this) : NULL; P1 = (ID1) ? SerializeTrait<T1>::Materialize(*this) : NULL;
if (ID1 && A1) RegisterPtr(ID1,P1); if (ID1 && A1) RegisterPtr(ID1,P1);
@ -153,9 +164,9 @@ public:
void BatchReadOwnedPtrs(T1*& P1, T2*& P2, T3*& P3, void BatchReadOwnedPtrs(T1*& P1, T2*& P2, T3*& P3,
bool A1=true, bool A2=true, bool A3=true) { bool A1=true, bool A2=true, bool A3=true) {
unsigned ID1 = ReadInt(); SerializedPtrID ID1 = ReadPtrID();
unsigned ID2 = ReadInt(); SerializedPtrID ID2 = ReadPtrID();
unsigned ID3 = ReadInt(); SerializedPtrID ID3 = ReadPtrID();
P1 = (ID1) ? SerializeTrait<T1>::Materialize(*this) : NULL; P1 = (ID1) ? SerializeTrait<T1>::Materialize(*this) : NULL;
if (ID1 && A1) RegisterPtr(ID1,P1); if (ID1 && A1) RegisterPtr(ID1,P1);
@ -170,10 +181,10 @@ public:
template <typename T> template <typename T>
void BatchReadOwnedPtrs(unsigned NumPtrs, T** Ptrs, bool AutoRegister=true) { void BatchReadOwnedPtrs(unsigned NumPtrs, T** Ptrs, bool AutoRegister=true) {
for (unsigned i = 0; i < NumPtrs; ++i) for (unsigned i = 0; i < NumPtrs; ++i)
reinterpret_cast<uintptr_t&>(Ptrs[i]) = ReadInt(); reinterpret_cast<SerializedPtrID&>(Ptrs[i]) = ReadPtrID();
for (unsigned i = 0; i < NumPtrs; ++i) { for (unsigned i = 0; i < NumPtrs; ++i) {
unsigned PtrID = reinterpret_cast<uintptr_t>(Ptrs[i]); SerializedPtrID PtrID = reinterpret_cast<SerializedPtrID>(Ptrs[i]);
T* p = PtrID ? SerializeTrait<T>::Materialize(*this) : NULL; T* p = PtrID ? SerializeTrait<T>::Materialize(*this) : NULL;
if (PtrID && AutoRegister) if (PtrID && AutoRegister)
@ -204,15 +215,28 @@ public:
return *p; return *p;
} }
void RegisterPtr(unsigned PtrId, const void* Ptr); void RegisterPtr(SerializedPtrID PtrId, const void* Ptr);
void RegisterPtr(const void* Ptr) { void RegisterPtr(const void* Ptr) {
RegisterPtr(ReadInt(),Ptr); RegisterPtr(ReadPtrID(),Ptr);
} }
template<typename T>
void RegisterRef(const T& x) {
RegisterPtr(&x);
}
template<typename T>
void RegisterRef(SerializedPtrID PtrID, const T& x) {
RegisterPtr(PtrID,&x);
}
Location GetCurrentBlockLocation();
bool FinishedBlock(Location BlockLoc);
bool AtEnd(); bool AtEnd();
bool inRecord(); bool inRecord();
private: private:
void ReadRecord(); void ReadRecord();
uintptr_t ReadInternalRefPtr(); uintptr_t ReadInternalRefPtr();

View File

@ -20,6 +20,8 @@ class Serializer;
class Deserializer; class Deserializer;
template <typename T> struct SerializeTrait; template <typename T> struct SerializeTrait;
typedef unsigned SerializedPtrID;
} // end namespace llvm } // end namespace llvm
#endif #endif

View File

@ -93,16 +93,17 @@ public:
for (unsigned i = 0; i < NumPtrs; ++i) for (unsigned i = 0; i < NumPtrs; ++i)
if (Ptrs[i]) SerializeTrait<T>::Emit(*this,*Ptrs[i]); if (Ptrs[i]) SerializeTrait<T>::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 EnterBlock(unsigned BlockID = 8, unsigned CodeLen = 3);
void ExitBlock(); void ExitBlock();
private: private:
void EmitRecord(); void EmitRecord();
inline bool inRecord() { return Record.size() > 0; } inline bool inRecord() { return Record.size() > 0; }
unsigned getPtrId(const void* ptr); SerializedPtrID getPtrId(const void* ptr);
}; };
} // end namespace llvm } // end namespace llvm

View File

@ -63,15 +63,16 @@ void Deserializer::ReadRecord() {
Code = Stream.ReadCode(); Code = Stream.ReadCode();
if (Code == bitc::ENTER_SUBBLOCK) { if (Code == bitc::ENTER_SUBBLOCK) {
// No known subblocks, always skip them. BlockLocs.push_back(Stream.GetCurrentBitNo());
unsigned id = Stream.ReadSubBlockID(); unsigned id = Stream.ReadSubBlockID();
Stream.EnterSubBlock(id); Stream.EnterSubBlock(id);
continue; continue;
} }
if (Code == bitc::END_BLOCK) { if (Code == bitc::END_BLOCK) {
bool x = Stream.ReadBlockEnd(); bool x = Stream.ReadBlockEnd();
assert (!x && "Error at block end."); assert (!x && "Error at block end.");
BlockLocs.pop_back();
continue; continue;
} }
@ -88,6 +89,26 @@ void Deserializer::ReadRecord() {
assert (Record.size() > 0 || Stream.AtEndOfStream()); 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<Location,5>::reverse_iterator
I=BlockLocs.rbegin(), E=BlockLocs.rend(); I!=E; ++I)
if (*I == BlockLoc)
return false;
return true;
}
bool Deserializer::AtEnd() { bool Deserializer::AtEnd() {
if (inRecord()) if (inRecord())
return false; return false;
@ -159,7 +180,7 @@ void Deserializer::RegisterPtr(unsigned PtrId, const void* Ptr) {
} }
void Deserializer::ReadUIntPtr(uintptr_t& PtrRef, bool AllowBackpatch) { void Deserializer::ReadUIntPtr(uintptr_t& PtrRef, bool AllowBackpatch) {
unsigned PtrId = ReadInt(); SerializedPtrID PtrId = ReadPtrID();
if (PtrId == 0) { if (PtrId == 0) {
PtrRef = 0; PtrRef = 0;
@ -194,7 +215,7 @@ void Deserializer::ReadUIntPtr(uintptr_t& PtrRef, bool AllowBackpatch) {
} }
uintptr_t Deserializer::ReadInternalRefPtr() { uintptr_t Deserializer::ReadInternalRefPtr() {
unsigned PtrId = ReadInt(); SerializedPtrID PtrId = ReadPtrID();
assert (PtrId != 0 && "References cannot refer the NULL address."); assert (PtrId != 0 && "References cannot refer the NULL address.");

View File

@ -14,6 +14,10 @@
#include "llvm/Bitcode/Serialize.h" #include "llvm/Bitcode/Serialize.h"
#include "string.h" #include "string.h"
#ifdef DEBUG_BACKPATCH
#include "llvm/Support/Streams.h"
#endif
using namespace llvm; using namespace llvm;
Serializer::Serializer(BitstreamWriter& stream) Serializer::Serializer(BitstreamWriter& stream)
@ -67,15 +71,13 @@ void Serializer::EmitCStr(const char* s, const char* end) {
Record.push_back(*s); Record.push_back(*s);
++s; ++s;
} }
EmitRecord();
} }
void Serializer::EmitCStr(const char* s) { void Serializer::EmitCStr(const char* s) {
EmitCStr(s,s+strlen(s)); EmitCStr(s,s+strlen(s));
} }
unsigned Serializer::getPtrId(const void* ptr) { SerializedPtrID Serializer::getPtrId(const void* ptr) {
if (!ptr) if (!ptr)
return 0; return 0;
@ -83,12 +85,20 @@ unsigned Serializer::getPtrId(const void* ptr) {
if (I == PtrMap.end()) { if (I == PtrMap.end()) {
unsigned id = PtrMap.size()+1; unsigned id = PtrMap.size()+1;
#ifdef DEBUG_BACKPATCH
llvm::cerr << "Registered PTR: " << ptr << " => " << id << "\n";
#endif
PtrMap[ptr] = id; PtrMap[ptr] = id;
return id; return id;
} }
else return I->second; 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)\ #define INT_EMIT(TYPE)\
void SerializeTrait<TYPE>::Emit(Serializer&S, TYPE X) { S.EmitInt(X); } void SerializeTrait<TYPE>::Emit(Serializer&S, TYPE X) { S.EmitInt(X); }