diff --git a/passes.cc b/passes.cc index 2a53dfe3..bb23bd0a 100644 --- a/passes.cc +++ b/passes.cc @@ -4,8 +4,6 @@ #include #include #include -#include -#include #include template @@ -344,35 +342,40 @@ void compute_section_sizes(Context &ctx) { if (osec->members.empty()) return; - struct T { - i64 offset; - i64 align; - }; + std::vector *>> slices = + split(osec->members, 10000); - T sum = tbb::parallel_scan( - tbb::blocked_range(0, osec->members.size(), 10000), - T{0, 1}, - [&](const tbb::blocked_range &r, T sum, bool is_final) { - for (i64 i = r.begin(); i < r.end(); i++) { - InputSection &isec = *osec->members[i]; - if (is_final) - isec.offset = sum.offset; + std::vector size(slices.size()); + std::vector alignments(slices.size()); - sum.offset = align_to(sum.offset, isec.shdr.sh_addralign) + - isec.shdr.sh_size; - sum.align = std::max(sum.align, isec.shdr.sh_addralign); - } - return sum; - }, - [](T lhs, T rhs) { - i64 offset = align_to(lhs.offset, rhs.align) + rhs.offset; - i64 align = std::max(lhs.align, rhs.align); - return T{offset, align}; - }, - tbb::simple_partitioner()); + tbb::parallel_for((i64)0, (i64)slices.size(), [&](i64 i) { + i64 off = 0; + i64 align = 1; - osec->shdr.sh_size = sum.offset; - osec->shdr.sh_addralign = sum.align; + for (InputSection *isec : slices[i]) { + off = align_to(off, isec->shdr.sh_addralign); + isec->offset = off; + off += isec->shdr.sh_size; + align = std::max(align, isec->shdr.sh_addralign); + } + + size[i] = off; + alignments[i] = align; + }); + + i64 align = *std::max_element(alignments.begin(), alignments.end()); + + std::vector start(slices.size()); + for (i64 i = 1; i < slices.size(); i++) + start[i] = align_to(start[i - 1] + size[i - 1], align); + + tbb::parallel_for((i64)1, (i64)slices.size(), [&](i64 i) { + for (InputSection *isec : slices[i]) + isec->offset += start[i]; + }); + + osec->shdr.sh_size = start.back() + size.back(); + osec->shdr.sh_addralign = align; }); } diff --git a/perf.cc b/perf.cc index c194af83..d6428884 100644 --- a/perf.cc +++ b/perf.cc @@ -90,8 +90,7 @@ static void print_rec(TimerRecord &rec, i64 indent) { template void Timer::print(Context &ctx) { - tbb::concurrent_vector> &records = - ctx.timer_records; + tbb::concurrent_vector> &records = ctx.timer_records; for (i64 i = records.size() - 1; i >= 0; i--) records[i]->stop(); diff --git a/test/dt_init.sh b/test/dt_init.sh index 057fbce8..0a2c7f06 100755 --- a/test/dt_init.sh +++ b/test/dt_init.sh @@ -26,9 +26,9 @@ grep -Pq '0000000000233000\s+0 FUNC GLOBAL HIDDEN \d+ _fini$' $t/log clang -fuse-ld=`pwd`/../mold -o $t/exe $t/a.o -Wl,-init,init -Wl,-fini,fini readelf -a $t/exe > $t/log -grep -Pq '\(INIT\)\s+0x233117' $t/log -grep -Pq '\(FINI\)\s+0x233118' $t/log -grep -Pq '0000000000233117\s+0 NOTYPE GLOBAL DEFAULT \d+ init$' $t/log -grep -Pq '0000000000233118\s+0 NOTYPE GLOBAL DEFAULT \d+ fini$' $t/log +grep -Pq '\(INIT\)\s+0x233119' $t/log +grep -Pq '\(FINI\)\s+0x23311a' $t/log +grep -Pq '0000000000233119\s+0 NOTYPE GLOBAL DEFAULT \d+ init$' $t/log +grep -Pq '000000000023311a\s+0 NOTYPE GLOBAL DEFAULT \d+ fini$' $t/log echo OK