@@ -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,56 @@ 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; }
379
-
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;
364
+ // Content-related functions manage parent's storage using ContentStart and
365
+ // ContentSize.
366
+ void clearContents () { ContentEnd = ContentStart; }
367
+ SmallVectorImpl<char > &getContentsForAppending () {
368
+ SmallVectorImpl<char > &S = getParent ()->ContentStorage ;
369
+ if (LLVM_UNLIKELY (ContentEnd != S.size ())) {
370
+ // If not at the storage end, move to the storage end.
371
+ auto Size = ContentEnd - ContentStart;
372
+ auto I = std::exchange (ContentStart, S.size ());
373
+ S.reserve (S.size () + Size);
374
+ S.append (S.begin () + I, S.begin () + I + Size);
375
+ ContentEnd = S.size ();
376
+ }
377
+ return S;
378
+ }
379
+ void doneAppending () { ContentEnd = getParent ()->ContentStorage .size (); }
380
+ void appendContents (ArrayRef<char > Contents) {
381
+ getContentsForAppending ().append (Contents.begin (), Contents.end ());
382
+ doneAppending ();
383
+ }
384
+ void appendContents (size_t Num, char Elt) {
385
+ getContentsForAppending ().append (Num, Elt);
386
+ doneAppending ();
387
+ }
388
+ void setContents (ArrayRef<char > Contents);
389
+ MutableArrayRef<char > getContents () {
390
+ return MutableArrayRef (getParent ()->ContentStorage )
391
+ .slice (ContentStart, ContentEnd - ContentStart);
385
392
}
393
+ ArrayRef<char > getContents () const {
394
+ return ArrayRef (getParent ()->ContentStorage )
395
+ .slice (ContentStart, ContentEnd - ContentStart);
396
+ }
397
+
398
+ // Fixup-related functions manage parent's storage using FixupStart and
399
+ // FixupSize.
400
+ void clearFixups () { FixupEnd = FixupStart; }
401
+ void addFixup (MCFixup Fixup);
402
+ void appendFixups (ArrayRef<MCFixup> Fixups);
403
+ void setFixups (ArrayRef<MCFixup> Fixups);
404
+ MutableArrayRef<MCFixup> getFixups ();
405
+ ArrayRef<MCFixup> getFixups () const ;
386
406
};
387
407
388
408
// / Fragment for data and encoded instructions.
389
409
// /
390
- class MCDataFragment : public MCEncodedFragmentWithFixups < 32 , 4 > {
410
+ class MCDataFragment : public MCEncodedFragment {
391
411
public:
392
- MCDataFragment () : MCEncodedFragmentWithFixups< 32 , 4 > (FT_Data, false ) {}
412
+ MCDataFragment () : MCEncodedFragment (FT_Data, false ) {}
393
413
394
414
static bool classof (const MCFragment *F) {
395
415
return F->getKind () == MCFragment::FT_Data;
@@ -402,13 +422,13 @@ class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
402
422
// / A relaxable fragment holds on to its MCInst, since it may need to be
403
423
// / relaxed during the assembler layout and relaxation stage.
404
424
// /
405
- class MCRelaxableFragment : public MCEncodedFragmentWithFixups < 8 , 1 > {
425
+ class MCRelaxableFragment : public MCEncodedFragment {
406
426
// / The instruction this is a fragment for.
407
427
MCInst Inst;
408
428
409
429
public:
410
430
MCRelaxableFragment (const MCInst &Inst, const MCSubtargetInfo &STI)
411
- : MCEncodedFragmentWithFixups (FT_Relaxable, true ), Inst(Inst) {
431
+ : MCEncodedFragment (FT_Relaxable, true ), Inst(Inst) {
412
432
this ->STI = &STI;
413
433
}
414
434
@@ -557,7 +577,7 @@ class MCOrgFragment : public MCFragment {
557
577
}
558
578
};
559
579
560
- class MCLEBFragment final : public MCEncodedFragmentWithFixups< 8 , 0 > {
580
+ class MCLEBFragment final : public MCEncodedFragment {
561
581
// / True if this is a sleb128, false if uleb128.
562
582
bool IsSigned;
563
583
@@ -566,24 +586,19 @@ class MCLEBFragment final : public MCEncodedFragmentWithFixups<8, 0> {
566
586
567
587
public:
568
588
MCLEBFragment (const MCExpr &Value, bool IsSigned)
569
- : MCEncodedFragmentWithFixups<8 , 0 >(FT_LEB, false ), IsSigned(IsSigned),
570
- Value (&Value) {
571
- getContents ().push_back (0 );
572
- }
589
+ : MCEncodedFragment(FT_LEB, false ), IsSigned(IsSigned), Value(&Value) {}
573
590
574
591
const MCExpr &getValue () const { return *Value; }
575
592
void setValue (const MCExpr *Expr) { Value = Expr; }
576
593
577
594
bool isSigned () const { return IsSigned; }
578
595
579
- // / @}
580
-
581
596
static bool classof (const MCFragment *F) {
582
597
return F->getKind () == MCFragment::FT_LEB;
583
598
}
584
599
};
585
600
586
- class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups < 8 , 1 > {
601
+ class MCDwarfLineAddrFragment : public MCEncodedFragment {
587
602
// / The value of the difference between the two line numbers
588
603
// / between two .loc dwarf directives.
589
604
int64_t LineDelta;
@@ -594,8 +609,8 @@ class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
594
609
595
610
public:
596
611
MCDwarfLineAddrFragment (int64_t LineDelta, const MCExpr &AddrDelta)
597
- : MCEncodedFragmentWithFixups< 8 , 1 > (FT_Dwarf, false ),
598
- LineDelta (LineDelta), AddrDelta(&AddrDelta) {}
612
+ : MCEncodedFragment (FT_Dwarf, false ), LineDelta(LineDelta ),
613
+ AddrDelta (&AddrDelta) {}
599
614
600
615
int64_t getLineDelta () const { return LineDelta; }
601
616
@@ -606,15 +621,14 @@ class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
606
621
}
607
622
};
608
623
609
- class MCDwarfCallFrameFragment : public MCEncodedFragmentWithFixups < 8 , 1 > {
624
+ class MCDwarfCallFrameFragment : public MCEncodedFragment {
610
625
// / The expression for the difference of the two symbols that
611
626
// / make up the address delta between two .cfi_* dwarf directives.
612
627
const MCExpr *AddrDelta;
613
628
614
629
public:
615
630
MCDwarfCallFrameFragment (const MCExpr &AddrDelta)
616
- : MCEncodedFragmentWithFixups<8 , 1 >(FT_DwarfFrame, false ),
617
- AddrDelta (&AddrDelta) {}
631
+ : MCEncodedFragment(FT_DwarfFrame, false ), AddrDelta(&AddrDelta) {}
618
632
619
633
const MCExpr &getAddrDelta () const { return *AddrDelta; }
620
634
void setAddrDelta (const MCExpr *E) { AddrDelta = E; }
@@ -642,13 +656,12 @@ class MCSymbolIdFragment : public MCFragment {
642
656
643
657
// / Fragment representing the binary annotations produced by the
644
658
// / .cv_inline_linetable directive.
645
- class MCCVInlineLineTableFragment : public MCFragment {
659
+ class MCCVInlineLineTableFragment : public MCEncodedFragment {
646
660
unsigned SiteFuncId;
647
661
unsigned StartFileId;
648
662
unsigned StartLineNum;
649
663
const MCSymbol *FnStartSym;
650
664
const MCSymbol *FnEndSym;
651
- SmallString<8 > Contents;
652
665
653
666
// / CodeViewContext has the real knowledge about this format, so let it access
654
667
// / our members.
@@ -658,24 +671,21 @@ class MCCVInlineLineTableFragment : public MCFragment {
658
671
MCCVInlineLineTableFragment (unsigned SiteFuncId, unsigned StartFileId,
659
672
unsigned StartLineNum, const MCSymbol *FnStartSym,
660
673
const MCSymbol *FnEndSym)
661
- : MCFragment (FT_CVInlineLines, false ), SiteFuncId(SiteFuncId),
674
+ : MCEncodedFragment (FT_CVInlineLines, false ), SiteFuncId(SiteFuncId),
662
675
StartFileId (StartFileId), StartLineNum(StartLineNum),
663
676
FnStartSym(FnStartSym), FnEndSym(FnEndSym) {}
664
677
665
678
const MCSymbol *getFnStartSym () const { return FnStartSym; }
666
679
const MCSymbol *getFnEndSym () const { return FnEndSym; }
667
680
668
- SmallString<8 > &getContents () { return Contents; }
669
- const SmallString<8 > &getContents () const { return Contents; }
670
-
671
681
static bool classof (const MCFragment *F) {
672
682
return F->getKind () == MCFragment::FT_CVInlineLines;
673
683
}
674
684
};
675
685
676
686
// / Fragment representing the .cv_def_range directive.
677
- class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups < 32 , 4 > {
678
- SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 2 > Ranges;
687
+ class MCCVDefRangeFragment : public MCEncodedFragment {
688
+ SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 0 > Ranges;
679
689
SmallString<32 > FixedSizePortion;
680
690
681
691
// / CodeViewContext has the real knowledge about this format, so let it access
@@ -686,14 +696,15 @@ class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups<32, 4> {
686
696
MCCVDefRangeFragment (
687
697
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
688
698
StringRef FixedSizePortion)
689
- : MCEncodedFragmentWithFixups<32 , 4 >(FT_CVDefRange, false ),
690
- Ranges (Ranges), FixedSizePortion(FixedSizePortion) {}
699
+ : MCEncodedFragment(FT_CVDefRange, false ),
700
+ Ranges (Ranges.begin(), Ranges.end()),
701
+ FixedSizePortion(FixedSizePortion) {}
691
702
692
703
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> getRanges () const {
693
704
return Ranges;
694
705
}
695
706
696
- StringRef getFixedSizePortion () const { return FixedSizePortion. str () ; }
707
+ StringRef getFixedSizePortion () const { return FixedSizePortion; }
697
708
698
709
static bool classof (const MCFragment *F) {
699
710
return F->getKind () == MCFragment::FT_CVDefRange;
@@ -739,23 +750,21 @@ class MCBoundaryAlignFragment : public MCFragment {
739
750
}
740
751
};
741
752
742
- class MCPseudoProbeAddrFragment : public MCEncodedFragmentWithFixups < 8 , 1 > {
753
+ class MCPseudoProbeAddrFragment : public MCEncodedFragment {
743
754
// / The expression for the difference of the two symbols that
744
755
// / make up the address delta between two .pseudoprobe directives.
745
756
const MCExpr *AddrDelta;
746
757
747
758
public:
748
759
MCPseudoProbeAddrFragment (const MCExpr *AddrDelta)
749
- : MCEncodedFragmentWithFixups<8 , 1 >(FT_PseudoProbe, false ),
750
- AddrDelta (AddrDelta) {}
760
+ : MCEncodedFragment(FT_PseudoProbe, false ), AddrDelta(AddrDelta) {}
751
761
752
762
const MCExpr &getAddrDelta () const { return *AddrDelta; }
753
763
754
764
static bool classof (const MCFragment *F) {
755
765
return F->getKind () == MCFragment::FT_PseudoProbe;
756
766
}
757
767
};
758
-
759
768
} // end namespace llvm
760
769
761
770
#endif // LLVM_MC_MCSECTION_H
0 commit comments