Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===- NaClBitstreamWriter.h - NaCl bitstream writer ------------*- C++ -*-===// | 1 //===- NaClBitstreamWriter.h - NaCl bitstream writer ------------*- C++ -*-===// |
| 2 // | 2 // |
| 3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This header defines the BitstreamWriter class. This class can be used to | 10 // This header defines the BitstreamWriter class. This class can be used to |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 37 NaClBitcodeSelectorAbbrev CurCodeSize; | 37 NaClBitcodeSelectorAbbrev CurCodeSize; |
| 38 | 38 |
| 39 /// BlockInfoCurBID - When emitting a BLOCKINFO_BLOCK, this is the currently | 39 /// BlockInfoCurBID - When emitting a BLOCKINFO_BLOCK, this is the currently |
| 40 /// selected BLOCK ID. | 40 /// selected BLOCK ID. |
| 41 unsigned BlockInfoCurBID; | 41 unsigned BlockInfoCurBID; |
| 42 | 42 |
| 43 /// CurAbbrevs - Abbrevs installed at in this block. | 43 /// CurAbbrevs - Abbrevs installed at in this block. |
| 44 std::vector<NaClBitCodeAbbrev*> CurAbbrevs; | 44 std::vector<NaClBitCodeAbbrev*> CurAbbrevs; |
| 45 | 45 |
| 46 struct Block { | 46 struct Block { |
| 47 NaClBitcodeSelectorAbbrev PrevCodeSize; | 47 const NaClBitcodeSelectorAbbrev PrevCodeSize; |
| 48 unsigned StartSizeWord; | 48 const unsigned StartSizeWord; |
| 49 std::vector<NaClBitCodeAbbrev*> PrevAbbrevs; | 49 std::vector<NaClBitCodeAbbrev*> PrevAbbrevs; |
| 50 Block(const NaClBitcodeSelectorAbbrev& PCS, unsigned SSW) | 50 const unsigned AbbreviationIndexLimit; |
| 51 : PrevCodeSize(PCS), StartSizeWord(SSW) {} | 51 Block(const NaClBitcodeSelectorAbbrev& PCS, unsigned SSW, |
| 52 unsigned AbbreviationIndexLimit) | |
| 53 : PrevCodeSize(PCS), StartSizeWord(SSW), | |
| 54 AbbreviationIndexLimit(AbbreviationIndexLimit) {} | |
| 52 }; | 55 }; |
| 53 | 56 |
| 54 /// BlockScope - This tracks the current blocks that we have entered. | 57 /// BlockScope - This tracks the current blocks that we have entered. |
| 55 std::vector<Block> BlockScope; | 58 std::vector<Block> BlockScope; |
| 56 | 59 |
| 57 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks. | 60 /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks. |
| 58 /// These describe abbreviations that all blocks of the specified ID inherit. | 61 /// These describe abbreviations that all blocks of the specified ID inherit. |
| 59 struct BlockInfo { | 62 struct BlockInfo { |
| 60 unsigned BlockID; | 63 unsigned BlockID; |
| 61 std::vector<NaClBitCodeAbbrev*> Abbrevs; | 64 std::vector<NaClBitCodeAbbrev*> Abbrevs; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 151 /// \brief Returns the maximum abbreviation index allowed for the | 154 /// \brief Returns the maximum abbreviation index allowed for the |
| 152 /// current block. | 155 /// current block. |
| 153 size_t getMaxCurAbbrevIndex() const { | 156 size_t getMaxCurAbbrevIndex() const { |
| 154 return CurAbbrevs.size() + naclbitc::DEFAULT_MAX_ABBREV; | 157 return CurAbbrevs.size() + naclbitc::DEFAULT_MAX_ABBREV; |
| 155 } | 158 } |
| 156 | 159 |
| 157 //===--------------------------------------------------------------------===// | 160 //===--------------------------------------------------------------------===// |
| 158 // Basic Primitives for emitting bits to the stream. | 161 // Basic Primitives for emitting bits to the stream. |
| 159 //===--------------------------------------------------------------------===// | 162 //===--------------------------------------------------------------------===// |
| 160 | 163 |
| 164 // Nax Number of bits that can be written using Emit. | |
|
jvoung (off chromium)
2015/05/21 20:57:59
Nax Number -> Max number
Karl
2015/05/22 15:30:43
Done.
| |
| 165 static const unsigned MaxEmitNumBits = 32; | |
| 166 | |
| 161 void Emit(uint32_t Val, unsigned NumBits) { | 167 void Emit(uint32_t Val, unsigned NumBits) { |
| 162 assert(NumBits && NumBits <= 32 && "Invalid value size!"); | 168 assert(NumBits && NumBits <= MaxEmitNumBits && "Invalid value size!"); |
| 163 assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!"); | 169 assert((Val & |
| 170 ~(~0U >> (MaxEmitNumBits-NumBits))) == 0 && "High bits set!"); | |
| 164 CurValue |= Val << CurBit; | 171 CurValue |= Val << CurBit; |
| 165 if (CurBit + NumBits < 32) { | 172 if (CurBit + NumBits < MaxEmitNumBits) { |
| 166 CurBit += NumBits; | 173 CurBit += NumBits; |
| 167 return; | 174 return; |
| 168 } | 175 } |
| 169 | 176 |
| 170 // Add the current word. | 177 // Add the current word. |
| 171 WriteWord(CurValue); | 178 WriteWord(CurValue); |
| 172 | 179 |
| 173 if (CurBit) | 180 if (CurBit) |
| 174 CurValue = Val >> (32-CurBit); | 181 CurValue = Val >> (MaxEmitNumBits-CurBit); |
| 175 else | 182 else |
| 176 CurValue = 0; | 183 CurValue = 0; |
| 177 CurBit = (CurBit+NumBits) & 31; | 184 CurBit = (CurBit+NumBits) & (MaxEmitNumBits-1); |
| 178 } | 185 } |
| 179 | 186 |
| 180 void Emit64(uint64_t Val, unsigned NumBits) { | 187 void Emit64(uint64_t Val, unsigned NumBits) { |
| 181 if (NumBits <= 32) | 188 while (NumBits > MaxEmitNumBits) { |
| 182 Emit((uint32_t)Val, NumBits); | 189 Emit((uint32_t)Val, MaxEmitNumBits); |
| 183 else { | 190 Val >>= MaxEmitNumBits; |
| 184 Emit((uint32_t)Val, 32); | 191 NumBits -= MaxEmitNumBits; |
| 185 Emit((uint32_t)(Val >> 32), NumBits-32); | |
| 186 } | 192 } |
| 193 Emit((uint32_t)Val, NumBits); | |
| 187 } | 194 } |
| 188 | 195 |
| 189 void flushToByte() { | 196 void flushToByte() { |
| 190 unsigned BitsToFlush = (32 - CurBit) % CHAR_BIT; | 197 unsigned BitsToFlush = (32 - CurBit) % CHAR_BIT; |
| 191 if (BitsToFlush) | 198 if (BitsToFlush) |
| 192 Emit(0, BitsToFlush); | 199 Emit(0, BitsToFlush); |
| 193 } | 200 } |
| 194 | 201 |
| 195 void flushToByteIfAligned() { | 202 void flushToByteIfAligned() { |
| 196 if (AlignBitcodeRecords) | 203 if (AlignBitcodeRecords) |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 280 unsigned BlockSizeWordIndex = GetWordIndex(); | 287 unsigned BlockSizeWordIndex = GetWordIndex(); |
| 281 NaClBitcodeSelectorAbbrev OldCodeSize(CurCodeSize); | 288 NaClBitcodeSelectorAbbrev OldCodeSize(CurCodeSize); |
| 282 | 289 |
| 283 // Emit a placeholder, which will be replaced when the block is popped. | 290 // Emit a placeholder, which will be replaced when the block is popped. |
| 284 Emit(0, naclbitc::BlockSizeWidth); | 291 Emit(0, naclbitc::BlockSizeWidth); |
| 285 | 292 |
| 286 CurCodeSize = CodeLen; | 293 CurCodeSize = CodeLen; |
| 287 | 294 |
| 288 // Push the outer block's abbrev set onto the stack, start out with an | 295 // Push the outer block's abbrev set onto the stack, start out with an |
| 289 // empty abbrev set. | 296 // empty abbrev set. |
| 290 BlockScope.push_back(Block(OldCodeSize, BlockSizeWordIndex)); | 297 BlockScope.push_back(Block(OldCodeSize, BlockSizeWordIndex, |
| 298 1 << CodeLen.NumBits)); | |
| 291 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); | 299 BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); |
| 292 | 300 |
| 293 // If there is a blockinfo for this BlockID, add all the predefined abbrevs | 301 // If there is a blockinfo for this BlockID, add all the predefined abbrevs |
| 294 // to the abbrev list. | 302 // to the abbrev list. |
| 295 if (Info) { | 303 if (Info) { |
| 296 for (unsigned i = 0, e = static_cast<unsigned>(Info->Abbrevs.size()); | 304 for (unsigned i = 0, e = static_cast<unsigned>(Info->Abbrevs.size()); |
| 297 i != e; ++i) { | 305 i != e; ++i) { |
| 298 CurAbbrevs.push_back(Info->Abbrevs[i]); | 306 CurAbbrevs.push_back(Info->Abbrevs[i]); |
| 299 Info->Abbrevs[i]->addRef(); | 307 Info->Abbrevs[i]->addRef(); |
| 300 } | 308 } |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 382 Emit(NaClBitCodeAbbrevOp::EncodeChar6((char)V), 6); | 390 Emit(NaClBitCodeAbbrevOp::EncodeChar6((char)V), 6); |
| 383 break; | 391 break; |
| 384 } | 392 } |
| 385 } | 393 } |
| 386 | 394 |
| 387 /// EmitRecordWithAbbrevImpl - This is the core implementation of the record | 395 /// EmitRecordWithAbbrevImpl - This is the core implementation of the record |
| 388 /// emission code. | 396 /// emission code. |
| 389 template<typename uintty> | 397 template<typename uintty> |
| 390 void EmitRecordWithAbbrevImpl(unsigned Abbrev, | 398 void EmitRecordWithAbbrevImpl(unsigned Abbrev, |
| 391 const AbbrevValues<uintty> &Vals) { | 399 const AbbrevValues<uintty> &Vals) { |
| 392 unsigned AbbrevNo = Abbrev-naclbitc::FIRST_APPLICATION_ABBREV; | 400 const NaClBitCodeAbbrev *Abbv = getAbbreviation(Abbrev); |
| 393 assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!"); | 401 assert(Abbv && "Abbreviation index is invalid"); |
| 394 NaClBitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo]; | |
| 395 | 402 |
| 396 EmitCode(Abbrev); | 403 EmitCode(Abbrev); |
| 397 | 404 |
| 398 unsigned RecordIdx = 0; | 405 unsigned RecordIdx = 0; |
| 399 for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos()); | 406 for (unsigned i = 0, e = static_cast<unsigned>(Abbv->getNumOperandInfos()); |
| 400 i != e; ++i) { | 407 i != e; ++i) { |
| 401 const NaClBitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); | 408 const NaClBitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); |
| 402 if (Op.getEncoding() == NaClBitCodeAbbrevOp::Array) { | 409 if (Op.getEncoding() == NaClBitCodeAbbrevOp::Array) { |
| 403 // Array case. | 410 // Array case. |
| 404 assert(i+2 == e && "array op not second to last?"); | 411 assert(i+2 == e && "array op not second to last?"); |
| 405 const NaClBitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); | 412 const NaClBitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); |
| 406 | 413 |
| 407 // Emit a vbr6 to indicate the number of elements present. | 414 // Emit a vbr6 to indicate the number of elements present. |
| 408 EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6); | 415 EmitVBR(static_cast<uint32_t>(Vals.size()-RecordIdx), 6); |
| 409 | 416 |
| 410 // Emit each field. | 417 // Emit each field. |
| 411 for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx) | 418 for (unsigned e = Vals.size(); RecordIdx != e; ++RecordIdx) |
| 412 EmitAbbreviatedField(EltEnc, Vals[RecordIdx]); | 419 EmitAbbreviatedField(EltEnc, Vals[RecordIdx]); |
| 413 } else { | 420 } else { |
| 414 assert(RecordIdx < Vals.size() && "Invalid abbrev/record"); | 421 assert(RecordIdx < Vals.size() && "Invalid abbrev/record"); |
| 415 EmitAbbreviatedField(Op, Vals[RecordIdx]); | 422 EmitAbbreviatedField(Op, Vals[RecordIdx]); |
| 416 ++RecordIdx; | 423 ++RecordIdx; |
| 417 } | 424 } |
| 418 } | 425 } |
| 419 assert(RecordIdx == Vals.size() && "Not all record operands emitted!"); | 426 assert(RecordIdx == Vals.size() && "Not all record operands emitted!"); |
| 420 } | 427 } |
| 421 | 428 |
| 422 public: | 429 public: |
| 423 | 430 |
| 424 /// Returns true if the given abbreviation index corresponds to a user-defined | 431 /// Returns a pointer to the abbreviation currently associated with |
| 425 /// abbreviation. | 432 /// the abbreviation index. Returns nullptr if no such abbreviation. |
| 426 bool isUserRecordAbbreviation(unsigned Abbrev) const { | 433 const NaClBitCodeAbbrev *getAbbreviation(unsigned Index) const { |
| 427 return Abbrev >= naclbitc::FIRST_APPLICATION_ABBREV | 434 if (Index < naclbitc::FIRST_APPLICATION_ABBREV) |
| 428 && Abbrev < (CurAbbrevs.size() + naclbitc::FIRST_APPLICATION_ABBREV); | 435 return nullptr; |
| 436 if (Index >= BlockScope.back().AbbreviationIndexLimit) | |
| 437 return nullptr; | |
| 438 unsigned AbbrevNo = Index - naclbitc::FIRST_APPLICATION_ABBREV; | |
| 439 if (AbbrevNo >= CurAbbrevs.size()) | |
| 440 return nullptr; | |
| 441 return CurAbbrevs[AbbrevNo]; | |
| 429 } | 442 } |
| 430 | 443 |
| 431 /// EmitRecord - Emit the specified record to the stream, using an abbrev if | 444 /// EmitRecord - Emit the specified record to the stream, using an abbrev if |
| 432 /// we have one to compress the output. | 445 /// we have one to compress the output. |
| 433 template<typename uintty> | 446 template<typename uintty> |
| 434 void EmitRecord(unsigned Code, const SmallVectorImpl<uintty> &Vals, | 447 void EmitRecord(unsigned Code, const SmallVectorImpl<uintty> &Vals, |
| 435 unsigned Abbrev = 0) { | 448 unsigned Abbrev = 0) { |
| 436 if (!Abbrev) { | 449 if (!Abbrev) { |
| 437 // If we don't have an abbrev to use, emit this in its fully unabbreviated | 450 // If we don't have an abbrev to use, emit this in its fully unabbreviated |
| 438 // form. | 451 // form. |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 531 Info.Abbrevs.push_back(Abbv); | 544 Info.Abbrevs.push_back(Abbv); |
| 532 | 545 |
| 533 return Info.Abbrevs.size()-1+naclbitc::FIRST_APPLICATION_ABBREV; | 546 return Info.Abbrevs.size()-1+naclbitc::FIRST_APPLICATION_ABBREV; |
| 534 } | 547 } |
| 535 }; | 548 }; |
| 536 | 549 |
| 537 | 550 |
| 538 } // End llvm namespace | 551 } // End llvm namespace |
| 539 | 552 |
| 540 #endif | 553 #endif |
| OLD | NEW |