@@ -46,27 +46,83 @@ 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 Chunk = std::unique_ptr<char []>(new char [Size]);
60+ auto *F = reinterpret_cast <MCFragment *>(Chunk.get ());
61+ FragStorage.push_back (std::move (Chunk));
62+ return F;
63+ }
64+
4965void MCObjectStreamer::newFragment () {
50- addFragment (getContext ().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
53- void MCObjectStreamer::insert (MCFragment *F ) {
54- assert (F ->getKind () != MCFragment::FT_Data &&
87+ void MCObjectStreamer::insert (MCFragment *Frag ) {
88+ assert (Frag ->getKind () != MCFragment::FT_Data &&
5589 " F 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+
104+ addFragment (Frag);
56105 addFragment (F);
57- newFragment ();
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
64116void MCObjectStreamer::appendContents (size_t Num, char Elt) {
65- CurFrag->appendContents (Num, Elt);
117+ ensureHeadroom (Num);
118+ MutableArrayRef<char > 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) {
69- CurFrag->addFixup (MCFixup::create (CurFrag-> getFixedSize (), Value, Kind));
125+ CurFrag->addFixup (MCFixup::create (getCurFragSize (), Value, Kind));
70126}
71127
72128// As a compile-time optimization, avoid allocating and evaluating an MCExpr
@@ -115,6 +171,8 @@ void MCObjectStreamer::reset() {
115171 }
116172 EmitEHFrame = true ;
117173 EmitDebugFrame = false ;
174+ FragStorage.clear ();
175+ FragSpace = 0 ;
118176 MCStreamer::reset ();
119177}
120178
@@ -143,7 +201,6 @@ void MCObjectStreamer::emitCFISections(bool EH, bool Debug, bool SFrame) {
143201void MCObjectStreamer::emitValueImpl (const MCExpr *Value, unsigned Size,
144202 SMLoc Loc) {
145203 MCStreamer::emitValueImpl (Value, Size, Loc);
146- MCFragment *DF = getCurrentFragment ();
147204
148205 MCDwarfLineEntry::make (this , getCurrentSectionOnly ());
149206
@@ -158,9 +215,9 @@ void MCObjectStreamer::emitValueImpl(const MCExpr *Value, unsigned Size,
158215 emitIntValue (AbsValue, Size);
159216 return ;
160217 }
161- DF-> addFixup ( MCFixup::create (DF-> getContents (). size (), Value,
162- MCFixup::getDataKindForSize (Size) ));
163- DF-> appendContents (Size, 0 );
218+ ensureHeadroom (Size);
219+ addFixup (Value, MCFixup::getDataKindForSize (Size));
220+ appendContents (Size, 0 );
164221}
165222
166223MCSymbol *MCObjectStreamer::emitCFILabel () {
@@ -194,7 +251,7 @@ void MCObjectStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
194251 // section.
195252 MCFragment *F = CurFrag;
196253 Symbol->setFragment (F);
197- Symbol->setOffset (F->getContents (). size ());
254+ Symbol->setOffset (F->getFixedSize ());
198255
199256 emitPendingAssignments (Symbol);
200257}
@@ -260,20 +317,38 @@ void MCObjectStreamer::changeSection(MCSection *Section, uint32_t Subsection) {
260317 F0 = CurFrag;
261318 }
262319
320+ // To maintain connectivity between CurFrag and FragSpace when CurFrag is
321+ // modified, allocate an empty fragment and append it to the fragment list.
322+ // (Subsections[I].second.Tail is not connected to FragSpace.)
323+ MCFragment *F;
324+ if (LLVM_LIKELY (sizeof (MCFragment) + NewFragHeadroom <= FragSpace)) {
325+ auto End = reinterpret_cast <size_t >(getCurFragEnd ());
326+ F = reinterpret_cast <MCFragment *>(
327+ alignToPowerOf2 (End, alignof (MCFragment)));
328+ FragSpace -= size_t (F) - End + sizeof (MCFragment);
329+ } else {
330+ F = allocFragSpace (0 );
331+ }
332+ new (F) MCFragment ();
333+ F->setParent (Section);
334+
263335 auto &Subsections = Section->Subsections ;
264336 size_t I = 0 , E = Subsections.size ();
265337 while (I != E && Subsections[I].first < Subsection)
266338 ++I;
267339 // If the subsection number is not in the sorted Subsections list, create a
268340 // new fragment list.
269341 if (I == E || Subsections[I].first != Subsection) {
270- auto *F = getContext ().allocFragment <MCFragment>();
271- F->setParent (Section);
272342 Subsections.insert (Subsections.begin () + I,
273343 {Subsection, MCSection::FragList{F, F}});
344+ Section->CurFragList = &Subsections[I].second ;
345+ CurFrag = F;
346+ } else {
347+ Section->CurFragList = &Subsections[I].second ;
348+ CurFrag = Subsections[I].second .Tail ;
349+ // Ensure CurFrag is associated with FragSpace.
350+ addFragment (F);
274351 }
275- Section->CurFragList = &Subsections[I].second ;
276- CurFrag = Section->CurFragList ->Tail ;
277352
278353 // Define the section symbol at subsection 0's initial fragment if required.
279354 if (!NewSec)
@@ -344,31 +419,33 @@ void MCObjectStreamer::emitInstToData(const MCInst &Inst,
344419 MCFragment *F = getCurrentFragment ();
345420
346421 // Append the instruction to the data fragment.
347- size_t CodeOffset = F->getContents ().size ();
422+ size_t CodeOffset = getCurFragSize ();
423+ SmallString<16 > Content;
348424 SmallVector<MCFixup, 1 > Fixups;
349- getAssembler ().getEmitter ().encodeInstruction (
350- Inst, F->getContentsForAppending (), Fixups, STI);
351- F->doneAppending ();
425+ getAssembler ().getEmitter ().encodeInstruction (Inst, Content, Fixups, STI);
426+ appendContents (Content);
427+ if (CurFrag != F) {
428+ F = CurFrag;
429+ CodeOffset = 0 ;
430+ }
352431 F->setHasInstructions (STI);
353432
354433 if (Fixups.empty ())
355434 return ;
356435 bool MarkedLinkerRelaxable = false ;
357436 for (auto &Fixup : Fixups) {
358437 Fixup.setOffset (Fixup.getOffset () + CodeOffset);
359- if (!Fixup.isLinkerRelaxable () || MarkedLinkerRelaxable )
438+ if (!Fixup.isLinkerRelaxable ())
360439 continue ;
361- MarkedLinkerRelaxable = true ;
362- // Set the fragment's order within the subsection for use by
363- // MCAssembler::relaxAlign.
364- auto *Sec = F->getParent ();
365- if (!Sec->isLinkerRelaxable ())
366- Sec->setLinkerRelaxable ();
440+ F->setLinkerRelaxable ();
367441 // Do not add data after a linker-relaxable instruction. The difference
368442 // between a new label and a label at or before the linker-relaxable
369443 // instruction cannot be resolved at assemble-time.
370- F->setLinkerRelaxable ();
371- newFragment ();
444+ if (!MarkedLinkerRelaxable) {
445+ MarkedLinkerRelaxable = true ;
446+ getCurrentSectionOnly ()->setLinkerRelaxable ();
447+ newFragment ();
448+ }
372449 }
373450 F->appendFixups (Fixups);
374451}
0 commit comments