1
1
mirror of https://github.com/rui314/mold.git synced 2024-09-11 21:17:28 +03:00
This commit is contained in:
Rui Ueyama 2022-01-16 11:09:13 +09:00
parent 1152b6eb38
commit 021463c628
4 changed files with 28 additions and 28 deletions

View File

@ -839,11 +839,9 @@ void ObjectFile<E>::merge_visibility(Context<E> &ctx, Symbol<E> &sym,
Fatal(ctx) << *this << ": unknown symbol visibility: " << sym;
};
u8 val = sym.visibility;
while (priority(visibility) < priority(val))
if (sym.visibility.compare_exchange_weak(val, visibility))
break;
update_minimum(sym.visibility, visibility, [&](u8 a, u8 b) {
return priority(a) < priority(b);
});
}
template <typename E>
@ -932,10 +930,7 @@ template <typename E>
void ObjectFile<E>::resolve_comdat_groups() {
for (auto &pair : comdat_groups) {
ComdatGroup *group = pair.first;
u32 cur = group->owner;
while (cur == -1 || cur > this->priority)
if (group->owner.compare_exchange_weak(cur, this->priority))
break;
update_minimum(group->owner, this->priority);
}
}

View File

@ -1332,8 +1332,6 @@ MergedSection<E>::get_instance(Context<E> &ctx, std::string_view name,
template <typename E>
SectionFragment<E> *
MergedSection<E>::insert(std::string_view data, u64 hash, i64 alignment) {
assert(alignment < UINT16_MAX);
std::call_once(once_flag, [&]() {
// We aim 2/3 occupation ratio
map.resize(estimator.get_cardinality() * 3 / 2);
@ -1344,9 +1342,8 @@ MergedSection<E>::insert(std::string_view data, u64 hash, i64 alignment) {
std::tie(frag, inserted) = map.insert(data, hash, SectionFragment(this));
assert(frag);
for (u16 cur = frag->alignment; cur < alignment;)
if (frag->alignment.compare_exchange_weak(cur, alignment))
break;
assert(alignment < UINT16_MAX);
update_maximum(frag->alignment, alignment);
return frag;
}

View File

@ -17,9 +17,4 @@ i64 HyperLogLog::get_cardinality() const {
return ALPHA * NBUCKETS * NBUCKETS / z;
}
void HyperLogLog::merge(const HyperLogLog &other) {
for (i64 i = 0; i < NBUCKETS; i++)
merge_one(i, other.buckets[i]);
}
} // namespace mold

31
mold.h
View File

@ -176,6 +176,22 @@ inline u64 next_power_of_two(u64 val) {
return (u64)1 << (64 - __builtin_clzl(val - 1));
}
template <typename T, typename Compare = std::less<T>>
void update_minimum(std::atomic<T> &atomic, u64 new_val,
Compare cmp = {}) {
T old_val = atomic;
while (cmp(new_val, old_val) &&
!atomic.compare_exchange_weak(old_val, new_val));
}
template <typename T, typename Compare = std::less<T>>
void update_maximum(std::atomic<T> &atomic, u64 new_val,
Compare cmp = {}) {
T old_val = atomic;
while (cmp(old_val, new_val) &&
!atomic.compare_exchange_weak(old_val, new_val));
}
template <typename T, typename U>
inline void append(std::vector<T> &vec1, std::vector<U> vec2) {
vec1.insert(vec1.end(), vec2.begin(), vec2.end());
@ -412,18 +428,15 @@ public:
HyperLogLog() : buckets(NBUCKETS) {}
void insert(u32 hash) {
merge_one(hash & (NBUCKETS - 1), __builtin_clz(hash) + 1);
}
void merge_one(i64 idx, u8 newval) {
u8 cur = buckets[idx];
while (cur < newval)
if (buckets[idx].compare_exchange_strong(cur, newval))
break;
update_maximum(buckets[hash & (NBUCKETS - 1)], __builtin_clz(hash) + 1);
}
i64 get_cardinality() const;
void merge(const HyperLogLog &other);
void merge(const HyperLogLog &other) {
for (i64 i = 0; i < NBUCKETS; i++)
update_maximum(buckets[i], other.buckets[i]);
}
private:
static constexpr i64 NBUCKETS = 2048;