mirror of
https://github.com/rui314/mold.git
synced 2024-12-29 11:24:36 +03:00
Use concurrent_unordered_set
This commit is contained in:
parent
9d41800b20
commit
bd415ae935
@ -333,7 +333,8 @@ MergeableSection::MergeableSection(InputSection *isec, std::string_view data)
|
|||||||
std::string_view substr = data.substr(0, end + 1);
|
std::string_view substr = data.substr(0, end + 1);
|
||||||
data = data.substr(end + 1);
|
data = data.substr(end + 1);
|
||||||
|
|
||||||
StringPiece *piece = parent.map.insert(substr, StringPiece(substr));
|
auto [it, inserted] = parent.set.insert(StringPiece(substr));
|
||||||
|
StringPiece *piece = &*it;
|
||||||
pieces.push_back({piece, offset});
|
pieces.push_back({piece, offset});
|
||||||
offset += substr.size();
|
offset += substr.size();
|
||||||
}
|
}
|
||||||
|
2
main.cc
2
main.cc
@ -1057,7 +1057,7 @@ static void show_stats() {
|
|||||||
|
|
||||||
static Counter merged_strings("merged_strings");
|
static Counter merged_strings("merged_strings");
|
||||||
for (MergedSection *osec : MergedSection::instances)
|
for (MergedSection *osec : MergedSection::instances)
|
||||||
merged_strings.inc(osec->map.size());
|
merged_strings.inc(osec->set.size());
|
||||||
|
|
||||||
Counter num_output_chunks("output_out::chunks", out::chunks.size());
|
Counter num_output_chunks("output_out::chunks", out::chunks.size());
|
||||||
Counter num_objs("num_objs", out::objs.size());
|
Counter num_objs("num_objs", out::objs.size());
|
||||||
|
54
mold.h
54
mold.h
@ -7,6 +7,7 @@
|
|||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
|
|
||||||
#include "tbb/concurrent_hash_map.h"
|
#include "tbb/concurrent_hash_map.h"
|
||||||
|
#include "tbb/concurrent_unordered_set.h"
|
||||||
#include "tbb/parallel_for_each.h"
|
#include "tbb/parallel_for_each.h"
|
||||||
#include "tbb/parallel_invoke.h"
|
#include "tbb/parallel_invoke.h"
|
||||||
#include "tbb/parallel_reduce.h"
|
#include "tbb/parallel_reduce.h"
|
||||||
@ -110,28 +111,6 @@ struct tbb_hash_compare<std::string_view> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ValueT>
|
|
||||||
class ConcurrentMap {
|
|
||||||
public:
|
|
||||||
typedef tbb::concurrent_hash_map<std::string_view, ValueT> MapT;
|
|
||||||
|
|
||||||
ValueT *insert(std::string_view key, const ValueT &val) {
|
|
||||||
typename MapT::const_accessor acc;
|
|
||||||
map.insert(acc, std::make_pair(key, val));
|
|
||||||
return const_cast<ValueT *>(&acc->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
void for_each_value(std::function<void(const ValueT &)> fn) {
|
|
||||||
for (typename MapT::const_iterator it = map.begin(); it != map.end(); ++it)
|
|
||||||
fn(it->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() const { return map.size(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
MapT map;
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Symbol
|
// Symbol
|
||||||
//
|
//
|
||||||
@ -144,6 +123,18 @@ struct StringPiece {
|
|||||||
: isec(other.isec.load()), data(other.data), size(other.size),
|
: isec(other.isec.load()), data(other.data), size(other.size),
|
||||||
output_offset(other.output_offset) {}
|
output_offset(other.output_offset) {}
|
||||||
|
|
||||||
|
struct hash {
|
||||||
|
size_t operator()(const StringPiece &piece) const {
|
||||||
|
return std::hash<std::string_view>()({(char *)piece.data, piece.size});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct equal {
|
||||||
|
bool operator()(const StringPiece &a, const StringPiece &b) const {
|
||||||
|
return a.size == b.size && memcmp(a.data, b.data, a.size) == 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
inline u64 get_addr() const;
|
inline u64 get_addr() const;
|
||||||
|
|
||||||
std::atomic<MergeableSection *> isec = ATOMIC_VAR_INIT(nullptr);
|
std::atomic<MergeableSection *> isec = ATOMIC_VAR_INIT(nullptr);
|
||||||
@ -173,9 +164,22 @@ public:
|
|||||||
Symbol(std::string_view name) : name(name) {}
|
Symbol(std::string_view name) : name(name) {}
|
||||||
Symbol(const Symbol &other) : Symbol(other.name) {}
|
Symbol(const Symbol &other) : Symbol(other.name) {}
|
||||||
|
|
||||||
|
struct hash {
|
||||||
|
size_t operator()(const Symbol &sym) const {
|
||||||
|
return std::hash<std::string_view>()(sym.name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct equal {
|
||||||
|
bool operator()(const Symbol &a, const Symbol &b) const {
|
||||||
|
return a.name == b.name;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static Symbol *intern(std::string_view name) {
|
static Symbol *intern(std::string_view name) {
|
||||||
static ConcurrentMap<Symbol> map;
|
static tbb::concurrent_unordered_set<Symbol, Symbol::hash, Symbol::equal> set;
|
||||||
return map.insert(name, Symbol(name));
|
auto [it, inserted] = set.insert(Symbol(name));
|
||||||
|
return &*it;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u64 get_addr() const;
|
inline u64 get_addr() const;
|
||||||
@ -565,7 +569,7 @@ public:
|
|||||||
static MergedSection *get_instance(std::string_view name, u32 type, u64 flags);
|
static MergedSection *get_instance(std::string_view name, u32 type, u64 flags);
|
||||||
|
|
||||||
static inline std::vector<MergedSection *> instances;
|
static inline std::vector<MergedSection *> instances;
|
||||||
ConcurrentMap<StringPiece> map;
|
tbb::concurrent_unordered_set<StringPiece, StringPiece::hash, StringPiece::equal> set;
|
||||||
|
|
||||||
void copy_buf() override;
|
void copy_buf() override;
|
||||||
|
|
||||||
|
@ -130,8 +130,10 @@ void ObjectFile::initialize_sections() {
|
|||||||
if (entries[0] != GRP_COMDAT)
|
if (entries[0] != GRP_COMDAT)
|
||||||
error(to_string(this) + ": unsupported SHT_GROUP format");
|
error(to_string(this) + ": unsupported SHT_GROUP format");
|
||||||
|
|
||||||
static ConcurrentMap<ComdatGroup> map;
|
static tbb::concurrent_hash_map<std::string_view, ComdatGroup> map;
|
||||||
ComdatGroup *group = map.insert(signature, ComdatGroup(nullptr, 0));
|
decltype(map)::const_accessor acc;
|
||||||
|
map.insert(acc, {signature, ComdatGroup(nullptr, 0)});
|
||||||
|
ComdatGroup *group = const_cast<ComdatGroup *>(&acc->second);
|
||||||
comdat_groups.push_back({group, entries});
|
comdat_groups.push_back({group, entries});
|
||||||
|
|
||||||
static Counter counter("comdats");
|
static Counter counter("comdats");
|
||||||
|
@ -663,10 +663,11 @@ MergedSection::get_instance(std::string_view name, u32 type, u64 flags) {
|
|||||||
void MergedSection::copy_buf() {
|
void MergedSection::copy_buf() {
|
||||||
u8 *base = out::buf + shdr.sh_offset;
|
u8 *base = out::buf + shdr.sh_offset;
|
||||||
|
|
||||||
map.for_each_value([&](const StringPiece &piece) {
|
for (decltype(set)::const_iterator it = set.begin(); it != set.end(); ++it) {
|
||||||
|
StringPiece &piece = *it;
|
||||||
if (MergeableSection *m = piece.isec)
|
if (MergeableSection *m = piece.isec)
|
||||||
memcpy(base + m->offset + piece.output_offset, piece.data, piece.size);
|
memcpy(base + m->offset + piece.output_offset, piece.data, piece.size);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyrelSection::add_symbol(Symbol *sym) {
|
void CopyrelSection::add_symbol(Symbol *sym) {
|
||||||
|
Loading…
Reference in New Issue
Block a user