diff --git a/input_sections.cc b/input_sections.cc index 8e648825..8dad1924 100644 --- a/input_sections.cc +++ b/input_sections.cc @@ -460,7 +460,7 @@ MergeableSection::MergeableSection(InputSection *isec, std::string_view data) std::string_view substr = data.substr(0, end + 1); data = data.substr(end + 1); - SectionFragment *frag = parent.insert(substr); + SectionFragment *frag = parent.map.insert(substr, SectionFragment(substr)); fragments.push_back(frag); frag_offsets.push_back(offset); offset += substr.size(); diff --git a/main.cc b/main.cc index 03a3de15..5ff7fb01 100644 --- a/main.cc +++ b/main.cc @@ -217,7 +217,7 @@ static void handle_mergeable_strings() { for (SectionFragment *frag : m->fragments) { if (frag->isec == m && frag->output_offset == -1) { frag->output_offset = offset; - offset += frag->data.size(); + offset += frag->size; } } m->size = offset; @@ -981,6 +981,10 @@ static void show_stats() { for (ObjectFile *file : out::objs) num_input_sections.inc(file->sections.size()); + static Counter merged_strings("merged_strings"); + for (MergedSection *osec : MergedSection::instances) + merged_strings.inc(osec->map.size()); + Counter num_output_chunks("output_out::chunks", out::chunks.size()); Counter num_objs("num_objs", out::objs.size()); Counter num_dsos("num_dsos", out::dsos.size()); diff --git a/mold.h b/mold.h index 0b366399..363264bb 100644 --- a/mold.h +++ b/mold.h @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -158,11 +157,11 @@ std::ostream &operator<<(std::ostream &out, const InputFile &file); namespace tbb { template<> struct tbb_hash_compare { - static size_t hash(const std::string_view &k) { + static size_t hash(const std::string_view& k) { return std::hash()(k); } - static bool equal(const std::string_view &k1, const std::string_view &k2) { + static bool equal(const std::string_view& k1, const std::string_view& k2) { return k1 == k2; } }; @@ -197,16 +196,18 @@ private: // struct SectionFragment { - SectionFragment(std::string_view data) : data(data) {} + SectionFragment(std::string_view view) + : data((const char *)view.data()), size(view.size()) {} SectionFragment(const SectionFragment &other) - : isec(other.isec.load()), data(other.data), + : isec(other.isec.load()), data(other.data), size(other.size), output_offset(other.output_offset) {} inline u64 get_addr() const; std::atomic isec = nullptr; - std::string_view data; + const char *data; + u32 size; u32 output_offset = -1; }; @@ -228,10 +229,14 @@ enum { class Symbol { public: Symbol() {} - Symbol(std::string_view name) : name(name) {} Symbol(const Symbol &other) : name(other.name) {} - static inline Symbol *intern(std::string_view name); + static Symbol *intern(std::string_view name) { + static ConcurrentMap map; + Symbol sym; + sym.name = name; + return map.insert(name, sym); + } inline u64 get_addr() const; inline u64 get_got_addr() const; @@ -277,38 +282,6 @@ public: u8 has_copyrel : 1 = false; }; -namespace tbb { -template<> struct tbb_hash { - size_t operator()(const SectionFragment &frag) const { - return std::hash()(frag.data); - } -}; - -template<> struct tbb_hash { - size_t operator()(const Symbol &sym) const { - return std::hash()(sym.name); - } -}; -} - -template<> struct std::equal_to { - bool operator()(const SectionFragment &lhs, const SectionFragment &rhs) const { - return lhs.data == rhs.data; - } -}; - -template<> struct std::equal_to { - bool operator()(const Symbol &lhs, const Symbol &rhs) const { - return lhs.name == rhs.name; - } -}; - -inline Symbol *Symbol::intern(std::string_view name) { - static tbb::concurrent_unordered_set set; - auto [it, inserted] = set.emplace(name); - return &*it; -} - // // input_sections.cc // @@ -662,8 +635,7 @@ public: static MergedSection *get_instance(std::string_view name, u32 type, u64 flags); static inline std::vector instances; - - inline SectionFragment *insert(std::string_view data); + ConcurrentMap map; void copy_buf() override; @@ -675,8 +647,6 @@ private: shdr.sh_type = type; shdr.sh_addralign = 1; } - - tbb::concurrent_unordered_set set; }; struct EhReloc { @@ -1248,8 +1218,3 @@ template inline void sort(T &vec, U less) { std::stable_sort(vec.begin(), vec.end(), less); } - -inline SectionFragment *MergedSection::insert(std::string_view data) { - auto [it, inserted] = set.emplace(data); - return &*it; -} diff --git a/output_chunks.cc b/output_chunks.cc index 90bd4cf2..c4e16028 100644 --- a/output_chunks.cc +++ b/output_chunks.cc @@ -700,13 +700,10 @@ MergedSection::get_instance(std::string_view name, u32 type, u64 flags) { void MergedSection::copy_buf() { u8 *base = out::buf + shdr.sh_offset; - for (const SectionFragment &frag : set) + map.for_each_value([&](const SectionFragment &frag) { if (MergeableSection *m = frag.isec) - memcpy(base + m->offset + frag.output_offset, - frag.data.data(), frag.data.size()); - - static Counter merged_strings("merged_strings"); - merged_strings.inc(set.size()); + memcpy(base + m->offset + frag.output_offset, frag.data, frag.size); + }); } void EhFrameSection::construct() {