@@ -46,23 +46,79 @@ MCAssembler *MCObjectStreamer::getAssemblerPtr() {
4646 return nullptr ;
4747}
4848
49+ constexpr size_t FragBlockSize = 16384 ;
50+ // Ensure the new fragment can at least store a few bytes.
51+ constexpr size_t NewFragHeadroom = 8 ;
52+
53+ static_assert (NewFragHeadroom >= alignof (MCFragment));
54+ static_assert (FragBlockSize >= sizeof (MCFragment) + NewFragHeadroom);
55+
56+ MCFragment *MCObjectStreamer::allocFragSpace (size_t Headroom) {
57+ auto Size = std::max (FragBlockSize, sizeof (MCFragment) + Headroom);
58+ FragSpace = Size - sizeof (MCFragment);
59+ auto Block = std::unique_ptr<uint8_t []>(new uint8_t [Size]);
60+ auto *F = reinterpret_cast <MCFragment *>(Block.get ());
61+ FragStorage.push_back (std::move (Block));
62+ return F;
63+ }
64+
4965void MCObjectStreamer::newFragment () {
50- addFragment (allocFragment<MCFragment>());
66+ MCFragment *F;
67+ if (LLVM_LIKELY (sizeof (MCFragment) + NewFragHeadroom <= FragSpace)) {
68+ auto End = reinterpret_cast <size_t >(getCurFragEnd ());
69+ F = reinterpret_cast <MCFragment *>(
70+ alignToPowerOf2 (End, alignof (MCFragment)));
71+ FragSpace -= size_t (F) - End + sizeof (MCFragment);
72+ } else {
73+ F = allocFragSpace (0 );
74+ }
75+ new (F) MCFragment ();
76+ addFragment (F);
77+ }
78+
79+ void MCObjectStreamer::ensureHeadroom (size_t Headroom) {
80+ if (Headroom <= FragSpace)
81+ return ;
82+ auto *F = allocFragSpace (Headroom);
83+ new (F) MCFragment ();
84+ addFragment (F);
5185}
5286
5387void MCObjectStreamer::addSpecialFragment (MCFragment *Frag) {
5488 assert (Frag->getKind () != MCFragment::FT_Data &&
5589 " Frag should have a variable-size tail" );
90+ // Frag is not connected to FragSpace. Before modifying CurFrag with
91+ // addFragment(Frag), allocate an empty fragment to maintain FragSpace
92+ // connectivity, potentially reusing CurFrag's associated space.
93+ MCFragment *F;
94+ if (LLVM_LIKELY (sizeof (MCFragment) + NewFragHeadroom <= FragSpace)) {
95+ auto End = reinterpret_cast <size_t >(getCurFragEnd ());
96+ F = reinterpret_cast <MCFragment *>(
97+ alignToPowerOf2 (End, alignof (MCFragment)));
98+ FragSpace -= size_t (F) - End + sizeof (MCFragment);
99+ } else {
100+ F = allocFragSpace (0 );
101+ }
102+ new (F) MCFragment ();
103+
56104 addFragment (Frag);
57- newFragment ( );
105+ addFragment (F );
58106}
59107
60108void MCObjectStreamer::appendContents (ArrayRef<char > Contents) {
61- CurFrag->appendContents (Contents);
109+ ensureHeadroom (Contents.size ());
110+ assert (FragSpace >= Contents.size ());
111+ llvm::copy (Contents, getCurFragEnd ());
112+ CurFrag->FixedSize += Contents.size ();
113+ FragSpace -= Contents.size ();
62114}
63115
64- void MCObjectStreamer::appendContents (size_t Num, char Elt) {
65- CurFrag->appendContents (Num, Elt);
116+ void MCObjectStreamer::appendContents (size_t Num, uint8_t Elt) {
117+ ensureHeadroom (Num);
118+ MutableArrayRef<uint8_t > Data (getCurFragEnd (), Num);
119+ llvm::fill (Data, Elt);
120+ CurFrag->FixedSize += Num;
121+ FragSpace -= Num;
66122}
67123
68124void MCObjectStreamer::addFixup (const MCExpr *Value, MCFixupKind Kind) {
@@ -115,6 +171,8 @@ void MCObjectStreamer::reset() {
115171 }
116172 EmitEHFrame = true ;
117173 EmitDebugFrame = false ;
174+ FragStorage.clear ();
175+ FragSpace = 0 ;
118176 SpecialFragAllocator.Reset ();
119177 MCStreamer::reset ();
120178}
@@ -144,7 +202,6 @@ void MCObjectStreamer::emitCFISections(bool EH, bool Debug, bool SFrame) {
144202void MCObjectStreamer::emitValueImpl (const MCExpr *Value, unsigned Size,
145203 SMLoc Loc) {
146204 MCStreamer::emitValueImpl (Value, Size, Loc);
147- MCFragment *DF = getCurrentFragment ();
148205
149206 MCDwarfLineEntry::make (this , getCurrentSectionOnly ());
150207
@@ -159,9 +216,9 @@ void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
159216 emitIntValue (AbsValue, Size);
160217 return ;
161218 }
162- DF-> addFixup ( MCFixup::create (DF-> getContents (). size (), Value,
163- MCFixup::getDataKindForSize (Size) ));
164- DF-> appendContents (Size, 0 );
219+ ensureHeadroom (Size);
220+ addFixup (Value, MCFixup::getDataKindForSize (Size));
221+ appendContents (Size, 0 );
165222}
166223
167224MCSymbol *MCObjectStreamer::emitCFILabel () {
@@ -195,7 +252,7 @@ void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
195252 // section.
196253 MCFragment *F = CurFrag;
197254 Symbol->setFragment (F);
198- Symbol->setOffset (F->getContents (). size ());
255+ Symbol->setOffset (F->getFixedSize ());
199256
200257 emitPendingAssignments (Symbol);
201258}
@@ -261,20 +318,38 @@ void MCObjectStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
261318 F0 = CurFrag;
262319 }
263320
321+ // To maintain connectivity between CurFrag and FragSpace when CurFrag is
322+ // modified, allocate an empty fragment and append it to the fragment list.
323+ // (Subsections[I].second.Tail is not connected to FragSpace.)
324+ MCFragment *F;
325+ if (LLVM_LIKELY (sizeof (MCFragment) + NewFragHeadroom <= FragSpace)) {
326+ auto End = reinterpret_cast <size_t >(getCurFragEnd ());
327+ F = reinterpret_cast <MCFragment *>(
328+ alignToPowerOf2 (End, alignof (MCFragment)));
329+ FragSpace -= size_t (F) - End + sizeof (MCFragment);
330+ } else {
331+ F = allocFragSpace (0 );
332+ }
333+ new (F) MCFragment ();
334+ F->setParent (Section);
335+
264336 auto &Subsections = Section->Subsections ;
265337 size_t I = 0 , E = Subsections.size ();
266338 while (I != E && Subsections[I].first < Subsection)
267339 ++I;
268340 // If the subsection number is not in the sorted Subsections list, create a
269341 // new fragment list.
270342 if (I == E || Subsections[I].first != Subsection) {
271- auto *F = allocFragment<MCFragment>();
272- F->setParent (Section);
273343 Subsections.insert (Subsections.begin () + I,
274344 {Subsection, MCSection::FragList{F, F}});
345+ Section->CurFragList = &Subsections[I].second ;
346+ CurFrag = F;
347+ } else {
348+ Section->CurFragList = &Subsections[I].second ;
349+ CurFrag = Subsections[I].second .Tail ;
350+ // Ensure CurFrag is associated with FragSpace.
351+ addFragment (F);
275352 }
276- Section->CurFragList = &Subsections[I].second ;
277- CurFrag = Section->CurFragList ->Tail ;
278353
279354 // Define the section symbol at subsection 0's initial fragment if required.
280355 if (!NewSec)
@@ -345,11 +420,15 @@ void MCObjectStreamer::emitInstToData(const MCInst &Inst,
345420 MCFragment *F = getCurrentFragment ();
346421
347422 // Append the instruction to the data fragment.
348- size_t CodeOffset = F->getContents ().size ();
423+ size_t CodeOffset = getCurFragSize ();
424+ SmallString<16 > Content;
349425 SmallVector<MCFixup, 1 > Fixups;
350- getAssembler ().getEmitter ().encodeInstruction (
351- Inst, F->getContentsForAppending (), Fixups, STI);
352- F->doneAppending ();
426+ getAssembler ().getEmitter ().encodeInstruction (Inst, Content, Fixups, STI);
427+ appendContents (Content);
428+ if (CurFrag != F) {
429+ F = CurFrag;
430+ CodeOffset = 0 ;
431+ }
353432 F->setHasInstructions (STI);
354433
355434 if (Fixups.empty ())
0 commit comments