@@ -132,6 +132,7 @@ class LLVM_ABI MCSection {
132
132
public:
133
133
friend MCAssembler;
134
134
friend MCObjectStreamer;
135
+ friend class MCEncodedFragment ;
135
136
static constexpr unsigned NonUniqueID = ~0U ;
136
137
137
138
enum SectionVariant {
@@ -209,6 +210,10 @@ class LLVM_ABI MCSection {
209
210
// subsections.
210
211
SmallVector<std::pair<unsigned , FragList>, 1 > Subsections;
211
212
213
+ // Content and fixup storage for fragments
214
+ SmallVector<char , 0 > ContentStorage;
215
+ SmallVector<MCFixup, 0 > FixupStorage;
216
+
212
217
protected:
213
218
// TODO Make Name private when possible.
214
219
StringRef Name;
@@ -296,10 +301,7 @@ class LLVM_ABI MCSection {
296
301
297
302
// / Interface implemented by fragments that contain encoded instructions and/or
298
303
// / data.
299
- // /
300
304
class MCEncodedFragment : public MCFragment {
301
- uint8_t BundlePadding = 0 ;
302
-
303
305
protected:
304
306
MCEncodedFragment (MCFragment::FragmentType FType, bool HasInstructions)
305
307
: MCFragment(FType, HasInstructions) {}
@@ -308,6 +310,13 @@ class MCEncodedFragment : public MCFragment {
308
310
// / It must be non-null for instructions.
309
311
const MCSubtargetInfo *STI = nullptr ;
310
312
313
+ private:
314
+ uint32_t ContentStart = 0 ;
315
+ uint32_t ContentEnd = 0 ;
316
+ uint32_t FixupStart = 0 ;
317
+ uint32_t FixupEnd = 0 ;
318
+ uint8_t BundlePadding = 0 ;
319
+
311
320
public:
312
321
static bool classof (const MCFragment *F) {
313
322
MCFragment::FragmentType Kind = F->getKind ();
@@ -318,7 +327,10 @@ class MCEncodedFragment : public MCFragment {
318
327
case MCFragment::FT_Data:
319
328
case MCFragment::FT_Dwarf:
320
329
case MCFragment::FT_DwarfFrame:
330
+ case MCFragment::FT_LEB:
321
331
case MCFragment::FT_PseudoProbe:
332
+ case MCFragment::FT_CVInlineLines:
333
+ case MCFragment::FT_CVDefRange:
322
334
return true ;
323
335
}
324
336
}
@@ -348,48 +360,64 @@ class MCEncodedFragment : public MCFragment {
348
360
HasInstructions = true ;
349
361
this ->STI = &STI;
350
362
}
351
- };
352
-
353
- // / Interface implemented by fragments that contain encoded instructions and/or
354
- // / data and also have fixups registered.
355
- // /
356
- template <unsigned ContentsSize, unsigned FixupsSize>
357
- class MCEncodedFragmentWithFixups : public MCEncodedFragment {
358
- SmallVector<char , ContentsSize> Contents;
359
-
360
- // / The list of fixups in this fragment.
361
- SmallVector<MCFixup, FixupsSize> Fixups;
362
-
363
- protected:
364
- MCEncodedFragmentWithFixups (MCFragment::FragmentType FType,
365
- bool HasInstructions)
366
- : MCEncodedFragment(FType, HasInstructions) {}
367
-
368
- public:
369
- SmallVectorImpl<char > &getContents () { return Contents; }
370
- const SmallVectorImpl<char > &getContents () const { return Contents; }
371
363
372
- void appendContents (ArrayRef<char > C) { Contents.append (C.begin (), C.end ()); }
373
- void appendContents (size_t Num, char Elt) { Contents.append (Num, Elt); }
374
- void setContents (ArrayRef<char > C) { Contents.assign (C.begin (), C.end ()); }
375
-
376
- void addFixup (MCFixup Fixup) { Fixups.push_back (Fixup); }
377
- SmallVectorImpl<MCFixup> &getFixups () { return Fixups; }
378
- const SmallVectorImpl<MCFixup> &getFixups () const { return Fixups; }
364
+ // Content-related functions manage parent's storage using ContentStart and
365
+ // ContentSize.
366
+ void clearContents () { ContentEnd = ContentStart; }
367
+ // Get a SmallVector reference. The caller should call doneAppending to update
368
+ // `ContentEnd`.
369
+ SmallVectorImpl<char > &getContentsForAppending () {
370
+ SmallVectorImpl<char > &S = getParent ()->ContentStorage ;
371
+ if (LLVM_UNLIKELY (ContentEnd != S.size ())) {
372
+ // Move the elements to the end. Reserve space to avoid invalidating
373
+ // S.begin()+I for `append`.
374
+ auto Size = ContentEnd - ContentStart;
375
+ auto I = std::exchange (ContentStart, S.size ());
376
+ S.reserve (S.size () + Size);
377
+ S.append (S.begin () + I, S.begin () + I + Size);
378
+ }
379
+ return S;
380
+ }
381
+ void doneAppending () { ContentEnd = getParent ()->ContentStorage .size (); }
382
+ void appendContents (ArrayRef<char > Contents) {
383
+ getContentsForAppending ().append (Contents.begin (), Contents.end ());
384
+ doneAppending ();
385
+ }
386
+ void appendContents (size_t Num, char Elt) {
387
+ getContentsForAppending ().append (Num, Elt);
388
+ doneAppending ();
389
+ }
390
+ void setContents (ArrayRef<char > Contents);
391
+ MutableArrayRef<char > getContents () {
392
+ return MutableArrayRef (getParent ()->ContentStorage )
393
+ .slice (ContentStart, ContentEnd - ContentStart);
394
+ }
395
+ ArrayRef<char > getContents () const {
396
+ return ArrayRef (getParent ()->ContentStorage )
397
+ .slice (ContentStart, ContentEnd - ContentStart);
398
+ }
379
399
380
- static bool classof (const MCFragment *F) {
381
- MCFragment::FragmentType Kind = F->getKind ();
382
- return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data ||
383
- Kind == MCFragment::FT_CVDefRange || Kind == MCFragment::FT_Dwarf ||
384
- Kind == MCFragment::FT_DwarfFrame;
400
+ // Fixup-related functions manage parent's storage using FixupStart and
401
+ // FixupSize.
402
+ void clearFixups () { FixupEnd = FixupStart; }
403
+ void addFixup (MCFixup Fixup);
404
+ void appendFixups (ArrayRef<MCFixup> Fixups);
405
+ void setFixups (ArrayRef<MCFixup> Fixups);
406
+ MutableArrayRef<MCFixup> getFixups () {
407
+ return MutableArrayRef (getParent ()->FixupStorage )
408
+ .slice (FixupStart, FixupEnd - FixupStart);
409
+ }
410
+ ArrayRef<MCFixup> getFixups () const {
411
+ return ArrayRef (getParent ()->FixupStorage )
412
+ .slice (FixupStart, FixupEnd - FixupStart);
385
413
}
386
414
};
387
415
388
416
// / Fragment for data and encoded instructions.
389
417
// /
390
- class MCDataFragment : public MCEncodedFragmentWithFixups < 32 , 4 > {
418
+ class MCDataFragment : public MCEncodedFragment {
391
419
public:
392
- MCDataFragment () : MCEncodedFragmentWithFixups< 32 , 4 > (FT_Data, false ) {}
420
+ MCDataFragment () : MCEncodedFragment (FT_Data, false ) {}
393
421
394
422
static bool classof (const MCFragment *F) {
395
423
return F->getKind () == MCFragment::FT_Data;
@@ -402,13 +430,13 @@ class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
402
430
// / A relaxable fragment holds on to its MCInst, since it may need to be
403
431
// / relaxed during the assembler layout and relaxation stage.
404
432
// /
405
- class MCRelaxableFragment : public MCEncodedFragmentWithFixups < 8 , 1 > {
433
+ class MCRelaxableFragment : public MCEncodedFragment {
406
434
// / The instruction this is a fragment for.
407
435
MCInst Inst;
408
436
409
437
public:
410
438
MCRelaxableFragment (const MCInst &Inst, const MCSubtargetInfo &STI)
411
- : MCEncodedFragmentWithFixups (FT_Relaxable, true ), Inst(Inst) {
439
+ : MCEncodedFragment (FT_Relaxable, true ), Inst(Inst) {
412
440
this ->STI = &STI;
413
441
}
414
442
@@ -557,7 +585,7 @@ class MCOrgFragment : public MCFragment {
557
585
}
558
586
};
559
587
560
- class MCLEBFragment final : public MCEncodedFragmentWithFixups< 8 , 0 > {
588
+ class MCLEBFragment final : public MCEncodedFragment {
561
589
// / True if this is a sleb128, false if uleb128.
562
590
bool IsSigned;
563
591
@@ -566,24 +594,19 @@ class MCLEBFragment final : public MCEncodedFragmentWithFixups<8, 0> {
566
594
567
595
public:
568
596
MCLEBFragment (const MCExpr &Value, bool IsSigned)
569
- : MCEncodedFragmentWithFixups<8 , 0 >(FT_LEB, false ), IsSigned(IsSigned),
570
- Value (&Value) {
571
- getContents ().push_back (0 );
572
- }
597
+ : MCEncodedFragment(FT_LEB, false ), IsSigned(IsSigned), Value(&Value) {}
573
598
574
599
const MCExpr &getValue () const { return *Value; }
575
600
void setValue (const MCExpr *Expr) { Value = Expr; }
576
601
577
602
bool isSigned () const { return IsSigned; }
578
603
579
- // / @}
580
-
581
604
static bool classof (const MCFragment *F) {
582
605
return F->getKind () == MCFragment::FT_LEB;
583
606
}
584
607
};
585
608
586
- class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups < 8 , 1 > {
609
+ class MCDwarfLineAddrFragment : public MCEncodedFragment {
587
610
// / The value of the difference between the two line numbers
588
611
// / between two .loc dwarf directives.
589
612
int64_t LineDelta;
@@ -594,8 +617,8 @@ class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
594
617
595
618
public:
596
619
MCDwarfLineAddrFragment (int64_t LineDelta, const MCExpr &AddrDelta)
597
- : MCEncodedFragmentWithFixups< 8 , 1 > (FT_Dwarf, false ),
598
- LineDelta (LineDelta), AddrDelta(&AddrDelta) {}
620
+ : MCEncodedFragment (FT_Dwarf, false ), LineDelta(LineDelta ),
621
+ AddrDelta (&AddrDelta) {}
599
622
600
623
int64_t getLineDelta () const { return LineDelta; }
601
624
@@ -606,15 +629,14 @@ class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
606
629
}
607
630
};
608
631
609
- class MCDwarfCallFrameFragment : public MCEncodedFragmentWithFixups < 8 , 1 > {
632
+ class MCDwarfCallFrameFragment : public MCEncodedFragment {
610
633
// / The expression for the difference of the two symbols that
611
634
// / make up the address delta between two .cfi_* dwarf directives.
612
635
const MCExpr *AddrDelta;
613
636
614
637
public:
615
638
MCDwarfCallFrameFragment (const MCExpr &AddrDelta)
616
- : MCEncodedFragmentWithFixups<8 , 1 >(FT_DwarfFrame, false ),
617
- AddrDelta (&AddrDelta) {}
639
+ : MCEncodedFragment(FT_DwarfFrame, false ), AddrDelta(&AddrDelta) {}
618
640
619
641
const MCExpr &getAddrDelta () const { return *AddrDelta; }
620
642
void setAddrDelta (const MCExpr *E) { AddrDelta = E; }
@@ -642,13 +664,12 @@ class MCSymbolIdFragment : public MCFragment {
642
664
643
665
// / Fragment representing the binary annotations produced by the
644
666
// / .cv_inline_linetable directive.
645
- class MCCVInlineLineTableFragment : public MCFragment {
667
+ class MCCVInlineLineTableFragment : public MCEncodedFragment {
646
668
unsigned SiteFuncId;
647
669
unsigned StartFileId;
648
670
unsigned StartLineNum;
649
671
const MCSymbol *FnStartSym;
650
672
const MCSymbol *FnEndSym;
651
- SmallString<8 > Contents;
652
673
653
674
// / CodeViewContext has the real knowledge about this format, so let it access
654
675
// / our members.
@@ -658,23 +679,20 @@ class MCCVInlineLineTableFragment : public MCFragment {
658
679
MCCVInlineLineTableFragment (unsigned SiteFuncId, unsigned StartFileId,
659
680
unsigned StartLineNum, const MCSymbol *FnStartSym,
660
681
const MCSymbol *FnEndSym)
661
- : MCFragment (FT_CVInlineLines, false ), SiteFuncId(SiteFuncId),
682
+ : MCEncodedFragment (FT_CVInlineLines, false ), SiteFuncId(SiteFuncId),
662
683
StartFileId (StartFileId), StartLineNum(StartLineNum),
663
684
FnStartSym(FnStartSym), FnEndSym(FnEndSym) {}
664
685
665
686
const MCSymbol *getFnStartSym () const { return FnStartSym; }
666
687
const MCSymbol *getFnEndSym () const { return FnEndSym; }
667
688
668
- SmallString<8 > &getContents () { return Contents; }
669
- const SmallString<8 > &getContents () const { return Contents; }
670
-
671
689
static bool classof (const MCFragment *F) {
672
690
return F->getKind () == MCFragment::FT_CVInlineLines;
673
691
}
674
692
};
675
693
676
694
// / Fragment representing the .cv_def_range directive.
677
- class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups < 32 , 4 > {
695
+ class MCCVDefRangeFragment : public MCEncodedFragment {
678
696
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
679
697
StringRef FixedSizePortion;
680
698
@@ -686,8 +704,9 @@ class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups<32, 4> {
686
704
MCCVDefRangeFragment (
687
705
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
688
706
StringRef FixedSizePortion)
689
- : MCEncodedFragmentWithFixups<32 , 4 >(FT_CVDefRange, false ),
690
- Ranges (Ranges), FixedSizePortion(FixedSizePortion) {}
707
+ : MCEncodedFragment(FT_CVDefRange, false ),
708
+ Ranges (Ranges.begin(), Ranges.end()),
709
+ FixedSizePortion(FixedSizePortion) {}
691
710
692
711
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> getRanges () const {
693
712
return Ranges;
@@ -739,23 +758,21 @@ class MCBoundaryAlignFragment : public MCFragment {
739
758
}
740
759
};
741
760
742
- class MCPseudoProbeAddrFragment : public MCEncodedFragmentWithFixups < 8 , 1 > {
761
+ class MCPseudoProbeAddrFragment : public MCEncodedFragment {
743
762
// / The expression for the difference of the two symbols that
744
763
// / make up the address delta between two .pseudoprobe directives.
745
764
const MCExpr *AddrDelta;
746
765
747
766
public:
748
767
MCPseudoProbeAddrFragment (const MCExpr *AddrDelta)
749
- : MCEncodedFragmentWithFixups<8 , 1 >(FT_PseudoProbe, false ),
750
- AddrDelta (AddrDelta) {}
768
+ : MCEncodedFragment(FT_PseudoProbe, false ), AddrDelta(AddrDelta) {}
751
769
752
770
const MCExpr &getAddrDelta () const { return *AddrDelta; }
753
771
754
772
static bool classof (const MCFragment *F) {
755
773
return F->getKind () == MCFragment::FT_PseudoProbe;
756
774
}
757
775
};
758
-
759
776
} // end namespace llvm
760
777
761
778
#endif // LLVM_MC_MCSECTION_H
0 commit comments