@@ -132,6 +132,7 @@ class LLVM_ABI MCSection {
132132public:
133133 friend MCAssembler;
134134 friend MCObjectStreamer;
135+ friend class MCEncodedFragment ;
135136 static constexpr unsigned NonUniqueID = ~0U ;
136137
137138 enum SectionVariant {
@@ -209,6 +210,10 @@ class LLVM_ABI MCSection {
209210 // subsections.
210211 SmallVector<std::pair<unsigned , FragList>, 1 > Subsections;
211212
213+ // Content and fixup storage for fragments
214+ SmallVector<char , 0 > ContentStorage;
215+ SmallVector<MCFixup, 0 > FixupStorage;
216+
212217protected:
213218 // TODO Make Name private when possible.
214219 StringRef Name;
@@ -296,9 +301,12 @@ class LLVM_ABI MCSection {
296301
297302// / Interface implemented by fragments that contain encoded instructions and/or
298303// / data.
299- // /
300304class MCEncodedFragment : public MCFragment {
301305 uint8_t BundlePadding = 0 ;
306+ uint32_t ContentStart = 0 ;
307+ uint32_t ContentEnd = 0 ;
308+ uint32_t FixupStart = 0 ;
309+ uint32_t FixupEnd = 0 ;
302310
303311protected:
304312 MCEncodedFragment (MCFragment::FragmentType FType, bool HasInstructions)
@@ -318,7 +326,10 @@ class MCEncodedFragment : public MCFragment {
318326 case MCFragment::FT_Data:
319327 case MCFragment::FT_Dwarf:
320328 case MCFragment::FT_DwarfFrame:
329+ case MCFragment::FT_LEB:
321330 case MCFragment::FT_PseudoProbe:
331+ case MCFragment::FT_CVInlineLines:
332+ case MCFragment::FT_CVDefRange:
322333 return true ;
323334 }
324335 }
@@ -348,48 +359,64 @@ class MCEncodedFragment : public MCFragment {
348359 HasInstructions = true ;
349360 this ->STI = &STI;
350361 }
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;
362362
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+ }
379398
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);
385412 }
386413};
387414
388415// / Fragment for data and encoded instructions.
389416// /
390- class MCDataFragment : public MCEncodedFragmentWithFixups < 32 , 4 > {
417+ class MCDataFragment : public MCEncodedFragment {
391418public:
392- MCDataFragment () : MCEncodedFragmentWithFixups< 32 , 4 > (FT_Data, false ) {}
419+ MCDataFragment () : MCEncodedFragment (FT_Data, false ) {}
393420
394421 static bool classof (const MCFragment *F) {
395422 return F->getKind () == MCFragment::FT_Data;
@@ -402,13 +429,13 @@ class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
402429// / A relaxable fragment holds on to its MCInst, since it may need to be
403430// / relaxed during the assembler layout and relaxation stage.
404431// /
405- class MCRelaxableFragment : public MCEncodedFragmentWithFixups < 8 , 1 > {
432+ class MCRelaxableFragment : public MCEncodedFragment {
406433 // / The instruction this is a fragment for.
407434 MCInst Inst;
408435
409436public:
410437 MCRelaxableFragment (const MCInst &Inst, const MCSubtargetInfo &STI)
411- : MCEncodedFragmentWithFixups (FT_Relaxable, true ), Inst(Inst) {
438+ : MCEncodedFragment (FT_Relaxable, true ), Inst(Inst) {
412439 this ->STI = &STI;
413440 }
414441
@@ -557,7 +584,7 @@ class MCOrgFragment : public MCFragment {
557584 }
558585};
559586
560- class MCLEBFragment final : public MCEncodedFragmentWithFixups< 8 , 0 > {
587+ class MCLEBFragment final : public MCEncodedFragment {
561588 // / True if this is a sleb128, false if uleb128.
562589 bool IsSigned;
563590
@@ -566,24 +593,19 @@ class MCLEBFragment final : public MCEncodedFragmentWithFixups<8, 0> {
566593
567594public:
568595 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) {}
573597
574598 const MCExpr &getValue () const { return *Value; }
575599 void setValue (const MCExpr *Expr) { Value = Expr; }
576600
577601 bool isSigned () const { return IsSigned; }
578602
579- // / @}
580-
581603 static bool classof (const MCFragment *F) {
582604 return F->getKind () == MCFragment::FT_LEB;
583605 }
584606};
585607
586- class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups < 8 , 1 > {
608+ class MCDwarfLineAddrFragment : public MCEncodedFragment {
587609 // / The value of the difference between the two line numbers
588610 // / between two .loc dwarf directives.
589611 int64_t LineDelta;
@@ -594,8 +616,8 @@ class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
594616
595617public:
596618 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) {}
599621
600622 int64_t getLineDelta () const { return LineDelta; }
601623
@@ -606,15 +628,14 @@ class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
606628 }
607629};
608630
609- class MCDwarfCallFrameFragment : public MCEncodedFragmentWithFixups < 8 , 1 > {
631+ class MCDwarfCallFrameFragment : public MCEncodedFragment {
610632 // / The expression for the difference of the two symbols that
611633 // / make up the address delta between two .cfi_* dwarf directives.
612634 const MCExpr *AddrDelta;
613635
614636public:
615637 MCDwarfCallFrameFragment (const MCExpr &AddrDelta)
616- : MCEncodedFragmentWithFixups<8 , 1 >(FT_DwarfFrame, false ),
617- AddrDelta (&AddrDelta) {}
638+ : MCEncodedFragment(FT_DwarfFrame, false ), AddrDelta(&AddrDelta) {}
618639
619640 const MCExpr &getAddrDelta () const { return *AddrDelta; }
620641 void setAddrDelta (const MCExpr *E) { AddrDelta = E; }
@@ -642,13 +663,12 @@ class MCSymbolIdFragment : public MCFragment {
642663
643664// / Fragment representing the binary annotations produced by the
644665// / .cv_inline_linetable directive.
645- class MCCVInlineLineTableFragment : public MCFragment {
666+ class MCCVInlineLineTableFragment : public MCEncodedFragment {
646667 unsigned SiteFuncId;
647668 unsigned StartFileId;
648669 unsigned StartLineNum;
649670 const MCSymbol *FnStartSym;
650671 const MCSymbol *FnEndSym;
651- SmallString<8 > Contents;
652672
653673 // / CodeViewContext has the real knowledge about this format, so let it access
654674 // / our members.
@@ -658,23 +678,20 @@ class MCCVInlineLineTableFragment : public MCFragment {
658678 MCCVInlineLineTableFragment (unsigned SiteFuncId, unsigned StartFileId,
659679 unsigned StartLineNum, const MCSymbol *FnStartSym,
660680 const MCSymbol *FnEndSym)
661- : MCFragment (FT_CVInlineLines, false ), SiteFuncId(SiteFuncId),
681+ : MCEncodedFragment (FT_CVInlineLines, false ), SiteFuncId(SiteFuncId),
662682 StartFileId (StartFileId), StartLineNum(StartLineNum),
663683 FnStartSym(FnStartSym), FnEndSym(FnEndSym) {}
664684
665685 const MCSymbol *getFnStartSym () const { return FnStartSym; }
666686 const MCSymbol *getFnEndSym () const { return FnEndSym; }
667687
668- SmallString<8 > &getContents () { return Contents; }
669- const SmallString<8 > &getContents () const { return Contents; }
670-
671688 static bool classof (const MCFragment *F) {
672689 return F->getKind () == MCFragment::FT_CVInlineLines;
673690 }
674691};
675692
676693// / Fragment representing the .cv_def_range directive.
677- class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups < 32 , 4 > {
694+ class MCCVDefRangeFragment : public MCEncodedFragment {
678695 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
679696 StringRef FixedSizePortion;
680697
@@ -686,8 +703,9 @@ class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups<32, 4> {
686703 MCCVDefRangeFragment (
687704 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
688705 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) {}
691709
692710 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> getRanges () const {
693711 return Ranges;
@@ -739,15 +757,14 @@ class MCBoundaryAlignFragment : public MCFragment {
739757 }
740758};
741759
742- class MCPseudoProbeAddrFragment : public MCEncodedFragmentWithFixups < 8 , 1 > {
760+ class MCPseudoProbeAddrFragment : public MCEncodedFragment {
743761 // / The expression for the difference of the two symbols that
744762 // / make up the address delta between two .pseudoprobe directives.
745763 const MCExpr *AddrDelta;
746764
747765public:
748766 MCPseudoProbeAddrFragment (const MCExpr *AddrDelta)
749- : MCEncodedFragmentWithFixups<8 , 1 >(FT_PseudoProbe, false ),
750- AddrDelta (AddrDelta) {}
767+ : MCEncodedFragment(FT_PseudoProbe, false ), AddrDelta(AddrDelta) {}
751768
752769 const MCExpr &getAddrDelta () const { return *AddrDelta; }
753770
0 commit comments