LLVM API Documentation
00001 //==- Deserialize.cpp - Generic Object Serialization to Bitcode --*- C++ -*-==// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the internal methods used for object serialization. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/Bitcode/Deserialize.h" 00015 00016 #ifdef DEBUG_BACKPATCH 00017 #include "llvm/Support/Streams.h" 00018 #endif 00019 00020 using namespace llvm; 00021 00022 Deserializer::Deserializer(BitstreamReader& stream) 00023 : Stream(stream), RecIdx(0), FreeList(NULL), AbbrevNo(0), RecordCode(0) { 00024 00025 StreamStart = Stream.GetCurrentBitNo(); 00026 } 00027 00028 Deserializer::~Deserializer() { 00029 assert (RecIdx >= Record.size() && 00030 "Still scanning bitcode record when deserialization completed."); 00031 00032 #ifdef DEBUG_BACKPATCH 00033 for (MapTy::iterator I=BPatchMap.begin(), E=BPatchMap.end(); I!=E; ++I) 00034 assert (I->first.hasFinalPtr() && 00035 "Some pointers were not backpatched."); 00036 #endif 00037 } 00038 00039 00040 bool Deserializer::inRecord() { 00041 if (Record.size() > 0) { 00042 if (RecIdx >= Record.size()) { 00043 RecIdx = 0; 00044 Record.clear(); 00045 AbbrevNo = 0; 00046 return false; 00047 } 00048 else 00049 return true; 00050 } 00051 00052 return false; 00053 } 00054 00055 bool Deserializer::AdvanceStream() { 00056 assert (!inRecord() && 00057 "Cannot advance stream. Still processing a record."); 00058 00059 if (AbbrevNo == bitc::ENTER_SUBBLOCK || 00060 AbbrevNo >= bitc::UNABBREV_RECORD) 00061 return true; 00062 00063 while (!Stream.AtEndOfStream()) { 00064 00065 uint64_t Pos = Stream.GetCurrentBitNo(); 00066 AbbrevNo = Stream.ReadCode(); 00067 00068 switch (AbbrevNo) { 00069 case bitc::ENTER_SUBBLOCK: { 00070 unsigned id = Stream.ReadSubBlockID(); 00071 00072 // Determine the extent of the block. This is useful for jumping around 00073 // the stream. This is hack: we read the header of the block, save 00074 // the length, and then revert the bitstream to a location just before 00075 // the block is entered. 00076 uint64_t BPos = Stream.GetCurrentBitNo(); 00077 Stream.ReadVBR(bitc::CodeLenWidth); // Skip the code size. 00078 Stream.SkipToWord(); 00079 unsigned NumWords = Stream.Read(bitc::BlockSizeWidth); 00080 Stream.JumpToBit(BPos); 00081 00082 BlockStack.push_back(Location(Pos,id,NumWords)); 00083 break; 00084 } 00085 00086 case bitc::END_BLOCK: { 00087 bool x = Stream.ReadBlockEnd(); 00088 assert(!x && "Error at block end."); x=x; 00089 BlockStack.pop_back(); 00090 continue; 00091 } 00092 00093 case bitc::DEFINE_ABBREV: 00094 Stream.ReadAbbrevRecord(); 00095 continue; 00096 00097 default: 00098 break; 00099 } 00100 00101 return true; 00102 } 00103 00104 return false; 00105 } 00106 00107 void Deserializer::ReadRecord() { 00108 00109 while (AdvanceStream() && AbbrevNo == bitc::ENTER_SUBBLOCK) { 00110 assert (!BlockStack.empty()); 00111 Stream.EnterSubBlock(BlockStack.back().BlockID); 00112 AbbrevNo = 0; 00113 } 00114 00115 if (Stream.AtEndOfStream()) 00116 return; 00117 00118 assert (Record.empty()); 00119 assert (AbbrevNo >= bitc::UNABBREV_RECORD); 00120 RecordCode = Stream.ReadRecord(AbbrevNo,Record); 00121 assert (Record.size() > 0); 00122 } 00123 00124 void Deserializer::SkipBlock() { 00125 assert (!inRecord()); 00126 00127 if (AtEnd()) 00128 return; 00129 00130 AdvanceStream(); 00131 00132 assert (AbbrevNo == bitc::ENTER_SUBBLOCK); 00133 BlockStack.pop_back(); 00134 Stream.SkipBlock(); 00135 00136 AbbrevNo = 0; 00137 AdvanceStream(); 00138 } 00139 00140 bool Deserializer::SkipToBlock(unsigned BlockID) { 00141 assert (!inRecord()); 00142 00143 AdvanceStream(); 00144 assert (AbbrevNo == bitc::ENTER_SUBBLOCK); 00145 00146 unsigned BlockLevel = BlockStack.size(); 00147 00148 while (!AtEnd() && 00149 BlockLevel == BlockStack.size() && 00150 getCurrentBlockID() != BlockID) 00151 SkipBlock(); 00152 00153 return !(AtEnd() || BlockLevel != BlockStack.size()); 00154 } 00155 00156 Deserializer::Location Deserializer::getCurrentBlockLocation() { 00157 if (!inRecord()) 00158 AdvanceStream(); 00159 00160 return BlockStack.back(); 00161 } 00162 00163 bool Deserializer::JumpTo(const Location& Loc) { 00164 00165 assert (!inRecord()); 00166 00167 AdvanceStream(); 00168 00169 assert (!BlockStack.empty() || AtEnd()); 00170 00171 uint64_t LastBPos = StreamStart; 00172 00173 while (!BlockStack.empty()) { 00174 00175 LastBPos = BlockStack.back().BitNo; 00176 00177 // Determine of the current block contains the location of the block 00178 // we are looking for. 00179 if (BlockStack.back().contains(Loc)) { 00180 // We found the enclosing block. We must first POP it off to 00181 // destroy any accumulated context within the block scope. We then 00182 // jump to the position of the block and enter it. 00183 Stream.JumpToBit(LastBPos); 00184 00185 if (BlockStack.size() == Stream.BlockScope.size()) 00186 Stream.PopBlockScope(); 00187 00188 BlockStack.pop_back(); 00189 00190 AbbrevNo = 0; 00191 AdvanceStream(); 00192 assert (AbbrevNo == bitc::ENTER_SUBBLOCK); 00193 00194 Stream.EnterSubBlock(BlockStack.back().BlockID); 00195 break; 00196 } 00197 00198 // This block does not contain the block we are looking for. Pop it. 00199 if (BlockStack.size() == Stream.BlockScope.size()) 00200 Stream.PopBlockScope(); 00201 00202 BlockStack.pop_back(); 00203 00204 } 00205 00206 // Check if we have popped our way to the outermost scope. If so, 00207 // we need to adjust our position. 00208 if (BlockStack.empty()) { 00209 assert (Stream.BlockScope.empty()); 00210 00211 Stream.JumpToBit(Loc.BitNo < LastBPos ? StreamStart : LastBPos); 00212 AbbrevNo = 0; 00213 AdvanceStream(); 00214 } 00215 00216 assert (AbbrevNo == bitc::ENTER_SUBBLOCK); 00217 assert (!BlockStack.empty()); 00218 00219 while (!AtEnd() && BlockStack.back() != Loc) { 00220 if (BlockStack.back().contains(Loc)) { 00221 Stream.EnterSubBlock(BlockStack.back().BlockID); 00222 AbbrevNo = 0; 00223 AdvanceStream(); 00224 continue; 00225 } 00226 else 00227 SkipBlock(); 00228 } 00229 00230 if (AtEnd()) 00231 return false; 00232 00233 assert (BlockStack.back() == Loc); 00234 00235 return true; 00236 } 00237 00238 void Deserializer::Rewind() { 00239 while (!Stream.BlockScope.empty()) 00240 Stream.PopBlockScope(); 00241 00242 while (!BlockStack.empty()) 00243 BlockStack.pop_back(); 00244 00245 Stream.JumpToBit(StreamStart); 00246 AbbrevNo = 0; 00247 } 00248 00249 00250 unsigned Deserializer::getCurrentBlockID() { 00251 if (!inRecord()) 00252 AdvanceStream(); 00253 00254 return BlockStack.back().BlockID; 00255 } 00256 00257 unsigned Deserializer::getRecordCode() { 00258 if (!inRecord()) { 00259 AdvanceStream(); 00260 assert (AbbrevNo >= bitc::UNABBREV_RECORD); 00261 ReadRecord(); 00262 } 00263 00264 return RecordCode; 00265 } 00266 00267 bool Deserializer::FinishedBlock(Location BlockLoc) { 00268 if (!inRecord()) 00269 AdvanceStream(); 00270 00271 for (llvm::SmallVector<Location,8>::reverse_iterator 00272 I=BlockStack.rbegin(), E=BlockStack.rend(); I!=E; ++I) 00273 if (*I == BlockLoc) 00274 return false; 00275 00276 return true; 00277 } 00278 00279 unsigned Deserializer::getAbbrevNo() { 00280 if (!inRecord()) 00281 AdvanceStream(); 00282 00283 return AbbrevNo; 00284 } 00285 00286 bool Deserializer::AtEnd() { 00287 if (inRecord()) 00288 return false; 00289 00290 if (!AdvanceStream()) 00291 return true; 00292 00293 return false; 00294 } 00295 00296 uint64_t Deserializer::ReadInt() { 00297 // FIXME: Any error recovery/handling with incomplete or bad files? 00298 if (!inRecord()) 00299 ReadRecord(); 00300 00301 return Record[RecIdx++]; 00302 } 00303 00304 int64_t Deserializer::ReadSInt() { 00305 uint64_t x = ReadInt(); 00306 int64_t magnitude = x >> 1; 00307 return x & 0x1 ? -magnitude : magnitude; 00308 } 00309 00310 char* Deserializer::ReadCStr(char* cstr, unsigned MaxLen, bool isNullTerm) { 00311 if (cstr == NULL) 00312 MaxLen = 0; // Zero this just in case someone does something funny. 00313 00314 unsigned len = ReadInt(); 00315 00316 assert (MaxLen == 0 || (len + (isNullTerm ? 1 : 0)) <= MaxLen); 00317 00318 if (!cstr) 00319 cstr = new char[len + (isNullTerm ? 1 : 0)]; 00320 00321 assert (cstr != NULL); 00322 00323 for (unsigned i = 0; i < len; ++i) 00324 cstr[i] = (char) ReadInt(); 00325 00326 if (isNullTerm) 00327 cstr[len] = '\0'; 00328 00329 return cstr; 00330 } 00331 00332 void Deserializer::ReadCStr(std::vector<char>& buff, bool isNullTerm, 00333 unsigned Idx) { 00334 00335 unsigned len = ReadInt(); 00336 00337 // If Idx is beyond the current before size, reduce Idx to refer to the 00338 // element after the last element. 00339 if (Idx > buff.size()) 00340 Idx = buff.size(); 00341 00342 buff.reserve(len+Idx); 00343 buff.resize(Idx); 00344 00345 for (unsigned i = 0; i < len; ++i) 00346 buff.push_back((char) ReadInt()); 00347 00348 if (isNullTerm) 00349 buff.push_back('\0'); 00350 } 00351 00352 void Deserializer::RegisterPtr(const SerializedPtrID& PtrId, 00353 const void* Ptr) { 00354 00355 MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId)); 00356 00357 assert (!HasFinalPtr(E) && "Pointer already registered."); 00358 00359 #ifdef DEBUG_BACKPATCH 00360 llvm::cerr << "RegisterPtr: " << PtrId << " => " << Ptr << "\n"; 00361 #endif 00362 00363 SetPtr(E,Ptr); 00364 } 00365 00366 void Deserializer::ReadUIntPtr(uintptr_t& PtrRef, 00367 const SerializedPtrID& PtrId, 00368 bool AllowBackpatch) { 00369 if (PtrId == 0) { 00370 PtrRef = 0; 00371 return; 00372 } 00373 00374 MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId)); 00375 00376 if (HasFinalPtr(E)) { 00377 PtrRef = GetFinalPtr(E); 00378 00379 #ifdef DEBUG_BACKPATCH 00380 llvm::cerr << "ReadUintPtr: " << PtrId 00381 << " <-- " << (void*) GetFinalPtr(E) << '\n'; 00382 #endif 00383 } 00384 else { 00385 assert (AllowBackpatch && 00386 "Client forbids backpatching for this pointer."); 00387 00388 #ifdef DEBUG_BACKPATCH 00389 llvm::cerr << "ReadUintPtr: " << PtrId << " (NO PTR YET)\n"; 00390 #endif 00391 00392 // Register backpatch. Check the freelist for a BPNode. 00393 BPNode* N; 00394 00395 if (FreeList) { 00396 N = FreeList; 00397 FreeList = FreeList->Next; 00398 } 00399 else // No available BPNode. Allocate one. 00400 N = (BPNode*) Allocator.Allocate<BPNode>(); 00401 00402 new (N) BPNode(GetBPNode(E),PtrRef); 00403 SetBPNode(E,N); 00404 } 00405 } 00406 00407 uintptr_t Deserializer::ReadInternalRefPtr() { 00408 SerializedPtrID PtrId = ReadPtrID(); 00409 00410 assert (PtrId != 0 && "References cannot refer the NULL address."); 00411 00412 MapTy::value_type& E = BPatchMap.FindAndConstruct(BPKey(PtrId)); 00413 00414 assert (HasFinalPtr(E) && 00415 "Cannot backpatch references. Object must be already deserialized."); 00416 00417 return GetFinalPtr(E); 00418 } 00419 00420 void Deserializer::BPEntry::SetPtr(BPNode*& FreeList, void* P) { 00421 BPNode* Last = NULL; 00422 00423 for (BPNode* N = Head; N != NULL; N=N->Next) { 00424 Last = N; 00425 N->PtrRef |= reinterpret_cast<uintptr_t>(P); 00426 } 00427 00428 if (Last) { 00429 Last->Next = FreeList; 00430 FreeList = Head; 00431 } 00432 00433 Ptr = const_cast<void*>(P); 00434 } 00435 00436 00437 #define INT_READ(TYPE)\ 00438 void SerializeTrait<TYPE>::Read(Deserializer& D, TYPE& X) {\ 00439 X = (TYPE) D.ReadInt(); } 00440 00441 INT_READ(bool) 00442 INT_READ(unsigned char) 00443 INT_READ(unsigned short) 00444 INT_READ(unsigned int) 00445 INT_READ(unsigned long) 00446 00447 #define SINT_READ(TYPE)\ 00448 void SerializeTrait<TYPE>::Read(Deserializer& D, TYPE& X) {\ 00449 X = (TYPE) D.ReadSInt(); } 00450 00451 INT_READ(signed char) 00452 INT_READ(signed short) 00453 INT_READ(signed int) 00454 INT_READ(signed long)