[PATCH] D109895: [lld-macho] Construct CFString literals by copying the ConcatInputSection
Jez Ng via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 16 08:53:18 PDT 2021
int3 created this revision.
int3 added a reviewer: lld-macho.
Herald added a reviewer: gkm.
Herald added a project: lld-macho.
int3 requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
... instead of constructing a new one each time. This allows us
to take advantage of D105305: [lld-macho] Factor out common InputSection members <https://reviews.llvm.org/D105305>.
I didn't see a substantial difference when linking chromium_framework,
but this paves the way for reusing similar logic for splitting compact
unwind entries into sections. There are a lot more of those, so the
performance impact is significant.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D109895
Files:
lld/MachO/InputFiles.cpp
Index: lld/MachO/InputFiles.cpp
===================================================================
--- lld/MachO/InputFiles.cpp
+++ lld/MachO/InputFiles.cpp
@@ -227,6 +227,20 @@
InputFile::InputFile(Kind kind, const InterfaceFile &interface)
: id(idCount++), fileKind(kind), name(saver.save(interface.getPath())) {}
+// Some sections comprise of fixed-size records, so instead of splitting them at
+// symbol boundaries, we split them based on size. Records are distinct from
+// literals in that they may contain references to other sections, instead of
+// being leaf nodes in the InputSection graph.
+//
+// Note that "record" is a term I came up with. In contrast, "literal" is a term
+// used by the Mach-O format.
+static Optional<size_t> getRecordSize(StringRef segname, StringRef name) {
+ if (name == section_names::cfString)
+ if (config->icfLevel != ICFLevel::none && segname == segment_names::data)
+ return target->wordSize == 8 ? 32 : 16;
+ return {};
+}
+
template <class Section>
void ObjFile::parseSections(ArrayRef<Section> sections) {
subsections.reserve(sections.size());
@@ -249,6 +263,24 @@
uint32_t align = 1 << sec.align;
uint32_t flags = sec.flags;
+ auto splitRecords = [&](int recordSize) -> void {
+ subsections.push_back({});
+ if (data.size() == 0)
+ return;
+
+ SubsectionMap &subsecMap = subsections.back();
+ subsecMap.reserve(data.size() / recordSize);
+ auto *isec = make<ConcatInputSection>(
+ segname, name, this, data.slice(0, recordSize), align, flags);
+ subsecMap.push_back({0, isec});
+ for (uint64_t off = recordSize; off < data.size(); off += recordSize) {
+ // Copying requires less memory than constructing a fresh InputSection.
+ auto *copy = make<ConcatInputSection>(*isec);
+ copy->data = data.slice(off, recordSize);
+ subsecMap.push_back({off, copy});
+ }
+ };
+
if (sectionType(sec.flags) == S_CSTRING_LITERALS ||
(config->dedupLiterals && isWordLiteralSection(sec.flags))) {
if (sec.nreloc && config->dedupLiterals)
@@ -268,17 +300,8 @@
flags);
}
subsections.push_back({{0, isec}});
- } else if (config->icfLevel != ICFLevel::none &&
- (name == section_names::cfString &&
- segname == segment_names::data)) {
- uint64_t literalSize = target->wordSize == 8 ? 32 : 16;
- subsections.push_back({});
- SubsectionMap &subsecMap = subsections.back();
- for (uint64_t off = 0; off < data.size(); off += literalSize)
- subsecMap.push_back(
- {off, make<ConcatInputSection>(segname, name, this,
- data.slice(off, literalSize), align,
- flags)});
+ } else if (auto recordSize = getRecordSize(segname, name)) {
+ splitRecords(*recordSize);
} else if (segname == segment_names::llvm) {
// ld64 does not appear to emit contents from sections within the __LLVM
// segment. Symbols within those sections point to bitcode metadata
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D109895.372967.patch
Type: text/x-patch
Size: 3156 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210916/5bed1bf2/attachment.bin>
More information about the llvm-commits
mailing list