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