diff --git a/elf/icf.cc b/elf/icf.cc index ac32319868..ea8160ee05 100644 --- a/elf/icf.cc +++ b/elf/icf.cc @@ -249,7 +249,7 @@ static Digest compute_digest(Context &ctx, InputSection &isec) { hash((u64)&sym); } else if (Subsection *subsec = sym.get_subsec()) { hash('2'); - hash_string(subsec->data); + hash((u64)subsec); } else if (!isec) { hash('3'); } else if (isec->leader) { @@ -298,7 +298,7 @@ static Digest compute_digest(Context &ctx, InputSection &isec) { SubsectionRef &ref = isec.rel_subsections[subsec_idx++]; hash('a'); isec.get_addend(rel); - hash_string(ref.subsec->data); + hash((u64)ref.subsec); } else { hash_symbol(*isec.file.symbols[rel.r_sym]); } diff --git a/elf/mold.h b/elf/mold.h index d1a7265cb0..7f667d9fe2 100644 --- a/elf/mold.h +++ b/elf/mold.h @@ -73,18 +73,15 @@ std::ostream &operator<<(std::ostream &out, const Symbol &sym); template struct Subsection { - Subsection(MergedSection *sec, std::string_view data) - : output_section(*sec), data(data) {} + Subsection(MergedSection *sec) : output_section(*sec) {} Subsection(const Subsection &other) - : output_section(other.output_section), data(other.data), - offset(other.offset), alignment(other.alignment.load()), - is_alive(other.is_alive.load()) {} + : output_section(other.output_section), offset(other.offset), + alignment(other.alignment.load()), is_alive(other.is_alive.load()) {} inline u64 get_addr(Context &ctx) const; MergedSection &output_section; - std::string_view data; u32 offset = -1; std::atomic_uint16_t alignment = 1; std::atomic_bool is_alive = false; diff --git a/elf/output-chunks.cc b/elf/output-chunks.cc index 6e5f6825c9..2a592b9e22 100644 --- a/elf/output-chunks.cc +++ b/elf/output-chunks.cc @@ -1175,7 +1175,7 @@ MergedSection::insert(std::string_view data, u64 hash, i64 alignment) { Subsection *subsec; bool inserted; - std::tie(subsec, inserted) = map.insert(data, hash, Subsection(this, data)); + std::tie(subsec, inserted) = map.insert(data, hash, Subsection(this)); assert(subsec); for (u16 cur = subsec->alignment; cur < alignment;) @@ -1193,32 +1193,38 @@ void MergedSection::assign_offsets(Context &ctx) { i64 shard_size = map.nbuckets / map.NUM_SHARDS; tbb::parallel_for((i64)0, map.NUM_SHARDS, [&](i64 i) { - std::vector *> subsections; + struct KeyVal { + std::string_view key; + Subsection *val; + }; + + std::vector subsections; subsections.reserve(shard_size); for (i64 j = shard_size * i; j < shard_size * (i + 1); j++) if (Subsection &subsec = map.values[j]; subsec.is_alive) - subsections.push_back(&subsec); + subsections.push_back({{map.keys[j], map.sizes[j]}, &subsec}); // Sort subsections to make output deterministic. tbb::parallel_sort(subsections.begin(), subsections.end(), - [](Subsection *a, Subsection *b) { - if (a->alignment != b->alignment) - return a->alignment < b->alignment; - if (a->data.size() != b->data.size()) - return a->data.size() < b->data.size(); - return a->data < b->data; + [](const KeyVal &a, const KeyVal &b) { + if (a.val->alignment != b.val->alignment) + return a.val->alignment < b.val->alignment; + if (a.key.size() != b.key.size()) + return a.key.size() < b.key.size(); + return a.key < b.key; }); // Assign offsets. i64 offset = 0; i64 max_alignment = 0; - for (Subsection *subsec : subsections) { - offset = align_to(offset, subsec->alignment); - subsec->offset = offset; - offset += subsec->data.size(); - max_alignment = std::max(max_alignment, subsec->alignment); + for (KeyVal &kv : subsections) { + Subsection &subsec = *kv.val; + offset = align_to(offset, subsec.alignment); + subsec.offset = offset; + offset += kv.key.size(); + max_alignment = std::max(max_alignment, subsec.alignment); } sizes[i] = offset; @@ -1260,7 +1266,7 @@ void MergedSection::write_to(Context &ctx, u8 *buf) { for (i64 j = shard_size * i; j < shard_size * (i + 1); j++) if (Subsection &subsec = map.values[j]; subsec.is_alive) - memcpy(buf + subsec.offset, subsec.data.data(), subsec.data.size()); + memcpy(buf + subsec.offset, map.keys[j], map.sizes[j]); }); }