Skip to content

Commit c6f0916

Browse files
alx32Alex B
authored andcommitted
[lld-macho] Reduce memory usage of prining thunks in map file
1 parent 7d8b4eb commit c6f0916

File tree

2 files changed

+34
-23
lines changed

2 files changed

+34
-23
lines changed

lld/MachO/ConcatOutputSection.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class TextOutputSection : public ConcatOutputSection {
7272
void finalizeContents() override {}
7373
void finalize() override;
7474
bool needsThunks() const;
75-
ArrayRef<ConcatInputSection *> getThunks() const { return thunks; }
75+
const std::vector<ConcatInputSection *> &getThunks() const { return thunks; }
7676
void writeTo(uint8_t *buf) const override;
7777

7878
static bool classof(const OutputSection *sec) {

lld/MachO/MapFile.cpp

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -161,20 +161,6 @@ static uint64_t getSymSizeForMap(Defined *sym) {
161161
return sym->size;
162162
}
163163

164-
// Merges two vectors of input sections in order of their outSecOff values.
165-
// This approach creates a new (temporary) vector which is not ideal but the
166-
// ideal approach leads to a lot of code duplication.
167-
static std::vector<ConcatInputSection *>
168-
mergeOrderedInputs(ArrayRef<ConcatInputSection *> inputs1,
169-
ArrayRef<ConcatInputSection *> inputs2) {
170-
std::vector<ConcatInputSection *> vec(inputs1.size() + inputs2.size());
171-
std::merge(inputs1.begin(), inputs1.end(), inputs2.begin(), inputs2.end(),
172-
vec.begin(), [](ConcatInputSection *a, ConcatInputSection *b) {
173-
return a->outSecOff < b->outSecOff;
174-
});
175-
return vec;
176-
}
177-
178164
void macho::writeMapFile() {
179165
if (config->mapFile.empty())
180166
return;
@@ -217,15 +203,42 @@ void macho::writeMapFile() {
217203
seg->name.str().c_str(), osec->name.str().c_str());
218204
}
219205

220-
// Shared function to print an array of symbols.
221-
auto printIsecArrSyms = [&](const std::vector<ConcatInputSection *> &arr) {
222-
for (const ConcatInputSection *isec : arr) {
206+
// Shared function to print one or two arrays of ConcatInputSection in
207+
// ascending outSecOff order. The second array is optional; if provided, we
208+
// interleave the printing in sorted order without allocating a merged temp
209+
// array.
210+
auto printIsecArrSyms = [&](const std::vector<ConcatInputSection *> &arr1,
211+
const std::vector<ConcatInputSection *> *arr2 =
212+
nullptr) {
213+
// Helper lambda that prints all symbols from one ConcatInputSection.
214+
auto printOne = [&](const ConcatInputSection *isec) {
223215
for (Defined *sym : isec->symbols) {
224-
if (!(isPrivateLabel(sym->getName()) && getSymSizeForMap(sym) == 0))
216+
if (!(isPrivateLabel(sym->getName()) && getSymSizeForMap(sym) == 0)) {
225217
os << format("0x%08llX\t0x%08llX\t[%3u] %s\n", sym->getVA(),
226218
getSymSizeForMap(sym),
227-
readerToFileOrdinal[sym->getFile()],
219+
readerToFileOrdinal.lookup(sym->getFile()),
228220
sym->getName().str().data());
221+
}
222+
}
223+
};
224+
225+
// If there is only one array, print all symbols from it and return.
226+
// This simplifies the logic for the merge case below.
227+
if (!arr2) {
228+
for (const ConcatInputSection *isec : arr1)
229+
printOne(isec);
230+
return;
231+
}
232+
233+
size_t i = 0, j = 0;
234+
size_t size1 = arr1.size();
235+
size_t size2 = arr2->size();
236+
while (i < size1 || j < size2) {
237+
if (i < size1 &&
238+
(j >= size2 || arr1[i]->outSecOff <= (*arr2)[j]->outSecOff)) {
239+
printOne(arr1[i++]);
240+
} else if (j < size2) {
241+
printOne((*arr2)[j++]);
229242
}
230243
}
231244
};
@@ -235,9 +248,7 @@ void macho::writeMapFile() {
235248
for (const OutputSegment *seg : outputSegments) {
236249
for (const OutputSection *osec : seg->getSections()) {
237250
if (auto *textOsec = dyn_cast<TextOutputSection>(osec)) {
238-
auto inputsAndThunks =
239-
mergeOrderedInputs(textOsec->inputs, textOsec->getThunks());
240-
printIsecArrSyms(inputsAndThunks);
251+
printIsecArrSyms(textOsec->inputs, &textOsec->getThunks());
241252
} else if (auto *concatOsec = dyn_cast<ConcatOutputSection>(osec)) {
242253
printIsecArrSyms(concatOsec->inputs);
243254
} else if (osec == in.cStringSection || osec == in.objcMethnameSection) {

0 commit comments

Comments
 (0)