@@ -135,8 +135,6 @@ struct DebugLineTableRowRef {
135135 uint32_t DwCompileUnitIndex;
136136 uint32_t RowIndex;
137137
138- const static DebugLineTableRowRef NULL_ROW;
139-
140138 bool operator ==(const DebugLineTableRowRef &Rhs) const {
141139 return DwCompileUnitIndex == Rhs.DwCompileUnitIndex &&
142140 RowIndex == Rhs.RowIndex ;
@@ -145,24 +143,6 @@ struct DebugLineTableRowRef {
145143 bool operator !=(const DebugLineTableRowRef &Rhs) const {
146144 return !(*this == Rhs);
147145 }
148-
149- static DebugLineTableRowRef fromSMLoc (const SMLoc &Loc) {
150- union {
151- decltype (Loc.getPointer ()) Ptr;
152- DebugLineTableRowRef Ref;
153- } U;
154- U.Ptr = Loc.getPointer ();
155- return U.Ref ;
156- }
157-
158- SMLoc toSMLoc () const {
159- union {
160- decltype (SMLoc ().getPointer ()) Ptr;
161- DebugLineTableRowRef Ref;
162- } U;
163- U.Ref = *this ;
164- return SMLoc::getFromPointer (U.Ptr );
165- }
166146};
167147
168148// / Common buffer vector used for debug info handling.
@@ -210,7 +190,7 @@ class DebugRangesSectionWriter {
210190 static bool classof (const DebugRangesSectionWriter *Writer) {
211191 return Writer->getKind () == RangesWriterKind::DebugRangesWriter;
212192 }
213-
193+
214194 // / Append a range to the main buffer.
215195 void appendToRangeBuffer (const DebugBufferVector &CUBuffer);
216196
@@ -852,6 +832,97 @@ class DwarfLineTable {
852832 // Returns DWARF Version for this line table.
853833 uint16_t getDwarfVersion () const { return DwarfVersion; }
854834};
835+
836+ // / ClusteredRows represents a collection of debug line table row references.
837+ // /
838+ // / MEMORY LAYOUT AND DESIGN:
839+ // / This class uses a flexible array member pattern to store all
840+ // / DebugLineTableRowRef elements in a single contiguous memory allocation.
841+ // / The memory layout is:
842+ // /
843+ // / +------------------+
844+ // / | ClusteredRows | <- Object header (Size + first element)
845+ // / | - Size |
846+ // / | - Rows (element) | <- First DebugLineTableRowRef element
847+ // / +------------------+
848+ // / | element[1] | <- Additional DebugLineTableRowRef elements
849+ // / | element[2] | stored immediately after the object
850+ // / | ... |
851+ // / | element[Size-1] |
852+ // / +------------------+
853+ // /
854+ // / The 'Rows' member serves as both the first element storage and the base
855+ // / address for pointer arithmetic to access subsequent elements.
856+ class ClusteredRows {
857+ public:
858+ ArrayRef<DebugLineTableRowRef> getRows () const {
859+ return ArrayRef<DebugLineTableRowRef>(beginPtrConst (), Size);
860+ }
861+
862+ // / Returns the number of elements in the array.
863+ uint64_t size () const { return Size; }
864+
865+ // / We re-purpose SMLoc inside MCInst to store the pointer
866+ // / to ClusteredRows. fromSMLoc() and toSMLoc() are helper
867+ // / functions to convert between SMLoc and ClusteredRows.
868+
869+ static const ClusteredRows *fromSMLoc (const SMLoc &Loc) {
870+ return reinterpret_cast <const ClusteredRows *>(Loc.getPointer ());
871+ }
872+ SMLoc toSMLoc () const {
873+ return SMLoc::getFromPointer (reinterpret_cast <const char *>(this ));
874+ }
875+
876+ // / Given a vector of DebugLineTableRowRef, this method
877+ // / copies the elements into pre-allocated memory.
878+ template <typename T> void populate (const T Vec) {
879+ assert (Vec.size () == Size && " Sizes must match" );
880+ DebugLineTableRowRef *CurRawPtr = beginPtr ();
881+ for (DebugLineTableRowRef RowRef : Vec) {
882+ *CurRawPtr = RowRef;
883+ ++CurRawPtr;
884+ }
885+ }
886+
887+ private:
888+ uint64_t Size;
889+ DebugLineTableRowRef Rows;
890+
891+ ClusteredRows (uint64_t Size) : Size(Size) {}
892+
893+ // / Total size of the object including the array.
894+ static uint64_t getTotalSize (uint64_t Size) {
895+ assert (Size > 0 && " Size must be greater than 0" );
896+ return sizeof (ClusteredRows) + (Size - 1 ) * sizeof (DebugLineTableRowRef);
897+ }
898+ const DebugLineTableRowRef *beginPtrConst () const {
899+ return reinterpret_cast <const DebugLineTableRowRef *>(&Rows);
900+ }
901+ DebugLineTableRowRef *beginPtr () {
902+ return reinterpret_cast <DebugLineTableRowRef *>(&Rows);
903+ }
904+
905+ friend class ClusteredRowsContainer ;
906+ };
907+
908+ // / ClusteredRowsContainer manages the lifecycle of ClusteredRows objects.
909+ class ClusteredRowsContainer {
910+ public:
911+ ClusteredRows *createClusteredRows (uint64_t Size) {
912+ auto *CR = new (std::malloc (ClusteredRows::getTotalSize (Size)))
913+ ClusteredRows (Size);
914+ Clusters.push_back (CR);
915+ return CR;
916+ }
917+ ~ClusteredRowsContainer () {
918+ for (auto *CR : Clusters)
919+ std::free (CR);
920+ }
921+
922+ private:
923+ std::vector<ClusteredRows *> Clusters;
924+ };
925+
855926} // namespace bolt
856927} // namespace llvm
857928
0 commit comments