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 |