@@ -293,42 +293,69 @@ Expected<SectionRef> SectionRef::get(Expected<ObjectFormatNodeRef> Ref) {
293293 return SectionRef (*Specific);
294294}
295295
296- static Error encodeEdge (CompileUnitBuilder &CUB, SmallVectorImpl<char > &Data,
296+ static Error encodeEdge (CompileUnitBuilder &CUB,
297+ SmallVectorImpl<data::TargetInfo> &List,
297298 const jitlink::Edge *E) {
298-
299299 auto SymbolIndex = CUB.getSymbolIndex (E->getTarget ());
300300 if (!SymbolIndex)
301301 return SymbolIndex.takeError ();
302+ List.push_back ({E->getAddend (), *SymbolIndex});
303+ return Error::success ();
304+ }
302305
303- unsigned IdxAndHasAddend = *SymbolIndex << 1 | (E->getAddend () != 0 );
304- CUB.encodeIndex (IdxAndHasAddend);
306+ Error CompileUnitBuilder::encodeTargetInfo (
307+ ArrayRef<const jitlink::Edge *> Edges) {
308+ SmallVector<data::TargetInfo> List;
309+ for (const jitlink::Edge *E : Edges)
310+ if (Error Err = encodeEdge (*this , List, E))
311+ return Err;
312+
313+ size_t Start = FlatTargetInfo.size ();
314+ data::TargetInfoList::encode (List, FlatTargetInfo);
315+ size_t Length = FlatTargetInfo.size () - Start;
316+ auto &MaybeExisting =
317+ TargetInfoPool[StringRef (FlatTargetInfo).take_back (Length)];
318+ if (MaybeExisting) {
319+ // Truncate FlatTargetInfo again since this is already in the pool.
320+ FlatTargetInfo.resize (Start);
321+ Start = MaybeExisting - 1 ;
322+ } else {
323+ MaybeExisting = Start + 1 ;
324+ }
305325
306- if (E->getAddend () != 0 )
307- encoding::writeVBR8 (E->getAddend (), Data);
326+ // FIXME: Maybe should use uint64_t, or be a different range from CAS object
327+ // indexes.
328+ assert (Start < UINT_MAX && " Index out of range" );
329+ encodeIndex (Start);
308330 return Error::success ();
309331}
310332
311- static Error decodeEdge ( LinkGraphBuilder &LGB, StringRef &Data,
312- jitlink::Block &Parent, unsigned BlockIdx,
313- const data::Fixup &Fixup) {
314- unsigned SymbolIdx = LGB. nextIdxForBlock (BlockIdx);
333+ data::TargetInfoList LinkGraphBuilder::getTargetInfoFrom ( unsigned Start) {
334+ assert (Start < FlatTargetInfo. size () && " Start out of range " );
335+ return data::TargetInfoList ( StringRef (FlatTargetInfo). drop_front (Start));
336+ }
315337
316- bool HasAddend = SymbolIdx & 1U ;
317- auto Symbol = LGB.getSymbol (SymbolIdx >> 1 );
338+ static Error decodeEdge (LinkGraphBuilder &LGB, jitlink::Block &Parent,
339+ const data::TargetInfo &TI, const data::Fixup &Fixup) {
340+ auto Symbol = LGB.getSymbol (TI.Index );
318341 if (!Symbol)
319342 return Symbol.takeError ();
320343
321- jitlink::Edge::AddendT Addend = 0 ;
322- if (HasAddend) {
323- if (auto E = encoding::consumeVBR8 (Data, Addend))
324- return E;
325- }
326- auto BlockInfo = LGB.getBlockInfo (BlockIdx);
327- if (!BlockInfo)
328- return BlockInfo.takeError ();
344+ Parent.addEdge (Fixup.Kind , Fixup.Offset , **Symbol, TI.Addend );
345+ return Error::success ();
346+ }
329347
330- Parent.addEdge (Fixup.Kind , Fixup.Offset , **Symbol, Addend);
348+ static Error decodeEdges (LinkGraphBuilder &LGB, jitlink::Block &Parent,
349+ unsigned BlockIdx, const data::FixupList &FL) {
350+ if (FL.empty ())
351+ return Error::success ();
331352
353+ unsigned TargetInfoStart = LGB.nextIdxForBlock (BlockIdx);
354+ data::TargetInfoList TIL (LGB.getTargetInfoFrom (TargetInfoStart));
355+ data::TargetInfoList::iterator TI = TIL.begin ();
356+ for (const data::Fixup &Fixup : FL)
357+ if (Error E = decodeEdge (LGB, Parent, *TI++, Fixup))
358+ return E;
332359 return Error::success ();
333360}
334361
@@ -390,23 +417,19 @@ Expected<BlockRef> BlockRef::create(CompileUnitBuilder &CUB,
390417 if (auto E = CUB.createAndReferenceContent (BlockData))
391418 return std::move (E);
392419 } else {
393- encoding::writeVBR8 (BlockData.size (), B->Data );
394420 B->Data .append (BlockData);
395421 }
396422
397- for (const auto *E : Edges) {
398- // Nest the Edge in block.
399- if (auto Err = encodeEdge (CUB, B->Data , E))
423+ if (!Edges.empty ())
424+ if (auto Err = CUB.encodeTargetInfo (Edges))
400425 return std::move (Err);
401- }
402426
403427 return get (B->build ());
404428}
405429
406430Error BlockRef::materializeBlock (LinkGraphBuilder &LGB,
407431 unsigned BlockIdx) const {
408432 uint64_t SectionIdx;
409- auto Remaining = getData ();
410433 SectionIdx = LGB.nextIdxForBlock (BlockIdx);
411434
412435 auto SectionInfo = LGB.getSectionInfo (SectionIdx);
@@ -420,21 +443,14 @@ Error BlockRef::materializeBlock(LinkGraphBuilder &LGB,
420443 return ContentRef.takeError ();
421444 ContentData = ContentRef->getData ();
422445 } else {
423- unsigned ContentSize;
424- if (auto E = encoding::consumeVBR8 (Remaining, ContentSize))
425- return E;
426- auto Data = consumeDataOfSize (Remaining, ContentSize);
427- if (!Data)
428- return Data.takeError ();
429- ContentData = *Data;
446+ ContentData = getData ();
430447 }
431448
432449 auto BlockInfo = LGB.getBlockInfo (BlockIdx);
433450 if (!BlockInfo)
434451 return BlockInfo.takeError ();
435452
436- BlockInfo->Data .emplace (ContentData);
437- auto &Block = *BlockInfo->Data ;
453+ data::BlockData Block (ContentData);
438454 auto Address =
439455 getAlignedAddress (*SectionInfo, Block.getSize (), Block.getAlignment (),
440456 Block.getAlignmentOffset ());
@@ -447,7 +463,7 @@ Error BlockRef::materializeBlock(LinkGraphBuilder &LGB,
447463 Block.getAlignment (), Block.getAlignmentOffset ());
448464
449465 BlockInfo->Block = &B;
450- BlockInfo->Remaining = Remaining. size ();
466+ BlockInfo->Fixups = Block. getFixups ();
451467 return Error::success ();
452468}
453469
@@ -458,17 +474,10 @@ Error BlockRef::materializeEdges(LinkGraphBuilder &LGB,
458474 return BlockInfo.takeError ();
459475
460476 // Nothing remains, no edges.
461- if (! BlockInfo->Remaining )
477+ if (BlockInfo->Fixups -> empty () )
462478 return Error::success ();
463479
464- auto Remaining = getData ().take_back (BlockInfo->Remaining );
465- for (const data::Fixup &Fixup : BlockInfo->Data ->getFixups ()) {
466- if (Error Err =
467- decodeEdge (LGB, Remaining, *BlockInfo->Block , BlockIdx, Fixup))
468- return Err;
469- }
470-
471- return Error::success ();
480+ return decodeEdges (LGB, *BlockInfo->Block , BlockIdx, *BlockInfo->Fixups );
472481}
473482
474483Expected<BlockRef> BlockRef::get (Expected<ObjectFormatNodeRef> Ref) {
@@ -844,6 +853,10 @@ Expected<CompileUnitRef> CompileUnitRef::create(const ObjectFileSchema &Schema,
844853 for (auto Idx : Builder.BlockIndexStarts )
845854 encoding::writeVBR8 (Idx, B->Data );
846855
856+ // / Write the flat TargetInfoList data.
857+ encoding::writeVBR8 (Builder.FlatTargetInfo .size (), B->Data );
858+ B->Data .append (Builder.FlatTargetInfo );
859+
847860 // Inlined symbols if set.
848861 if (InlineSymbols)
849862 B->Data .append (Builder.InlineBuffer );
@@ -914,6 +927,14 @@ Error CompileUnitRef::materialize(LinkGraphBuilder &LGB) const {
914927 LGB.Blocks [I].BlockIdx = Idx;
915928 }
916929
930+ // / Write the flat TargetInfoList data.
931+ size_t FlatTargetInfoSize;
932+ if (Error Err = encoding::consumeVBR8 (Remaining, FlatTargetInfoSize))
933+ return Err;
934+ if (Error Err = consumeDataOfSize (Remaining, FlatTargetInfoSize)
935+ .moveInto (LGB.FlatTargetInfo ))
936+ return Err;
937+
917938 if (InlineSymbols)
918939 LGB.InlineBuffer = Remaining;
919940 else if (!Remaining.empty ())
0 commit comments