diff --git a/main.cc b/main.cc index 17a030fc..6399f814 100644 --- a/main.cc +++ b/main.cc @@ -140,6 +140,16 @@ static std::vector> split(const std::vector &input, int unit) { return vec; } +static void eliminate_comdats(std::vector &files) { + tbb::parallel_for_each(files, [](ObjectFile *file) { + file->resolve_comdat_groups(); + }); + + tbb::parallel_for_each(files, [](ObjectFile *file) { + file->eliminate_duplicate_comdat_groups(); + }); +} + static void handle_mergeable_strings(std::vector &files) { // Resolve mergeable string pieces tbb::parallel_for_each(files, [](ObjectFile *file) { @@ -778,9 +788,7 @@ int main(int argc, char **argv) { // Eliminate duplicate comdat groups. { MyTimer t("comdat", before_copy); - tbb::parallel_for_each(files, [](ObjectFile *file) { - file->eliminate_duplicate_comdat_groups(); - }); + eliminate_comdats(files); } // Resolve mergeable strings diff --git a/mold.h b/mold.h index 1cf298f0..525a8c11 100644 --- a/mold.h +++ b/mold.h @@ -557,7 +557,6 @@ struct ComdatGroup { ComdatGroup(const ComdatGroup &other) : file(other.file.load()), section_idx(other.section_idx) {} - tbb::spin_mutex mu; std::atomic file; u32 section_idx; }; @@ -571,6 +570,7 @@ public: void resolve_symbols(); void mark_live_archive_members(tbb::parallel_do_feeder &feeder); void hanlde_undefined_weak_symbols(); + void resolve_comdat_groups(); void eliminate_duplicate_comdat_groups(); void assign_mergeable_string_offsets(); void convert_common_symbols(); diff --git a/object_file.cc b/object_file.cc index a6148fa5..3cfe0716 100644 --- a/object_file.cc +++ b/object_file.cc @@ -408,40 +408,22 @@ void ObjectFile::hanlde_undefined_weak_symbols() { } } +void ObjectFile::resolve_comdat_groups() { + for (auto &pair : comdat_groups) { + ComdatGroup *group = pair.first; + ObjectFile *cur = group->file; + while (!cur || cur->priority > this->priority) + if (group->file.compare_exchange_strong(cur, this)) + break; + } +} + void ObjectFile::eliminate_duplicate_comdat_groups() { for (auto &pair : comdat_groups) { - ComdatGroup *g = pair.first; + ComdatGroup *group = pair.first; u32 section_idx = pair.second; - - ObjectFile *other = g->file; - if (other && other->priority < this->priority) { - this->remove_comdat_members(section_idx); - continue; - } - - ObjectFile *file; - u32 idx; - - { - std::lock_guard lock(g->mu); - if (g->file == nullptr) { - g->file = this; - g->section_idx = section_idx; - continue; - } - - if (g->file.load()->priority < this->priority) { - file = this; - idx = section_idx; - } else { - file = g->file; - idx = g->section_idx; - g->file = this; - g->section_idx = section_idx; - } - } - - file->remove_comdat_members(idx); + if (group->file != this) + remove_comdat_members(section_idx); } }