Commit aadb1c97 authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

[codegen] Collapse succeeding identical safepoint entries

This saves a lot of memory on bigger Wasm functions, which typically do
not contain a lot of references (and no deoptimization data). Most
entries can be collapsed there. We might also see some improvements on
JavaScript code.

R=jkummerow@chromium.org

Bug: v8:12401
Change-Id: Ia12611de52c1ccd755d0a48ea0569ceb18716884
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3306975
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78147}
parent 6643c059
......@@ -49,15 +49,22 @@ int SafepointTable::find_return_pc(int pc_offset) {
SafepointEntry SafepointTable::FindEntry(Address pc) const {
int pc_offset = static_cast<int>(pc - instruction_start_);
// We use kMaxUInt32 as sentinel value, so check that we don't hit that.
DCHECK_NE(kMaxUInt32, pc_offset);
CHECK_LT(0, length_);
// A single entry with pc == -1 covers all call sites in the function.
if (length_ == 1 && GetEntry(0).pc() == -1) return GetEntry(0);
for (int i = 0; i < length_; i++) {
// TODO(kasperl): Replace the linear search with binary search.
// Check if the PC is pointing at a trampoline.
if (has_deopt_data()) {
int candidate = -1;
for (int i = 0; i < length_; ++i) {
int trampoline_pc = GetEntry(i).trampoline_pc();
if (trampoline_pc != -1 && trampoline_pc <= pc_offset) candidate = i;
if (trampoline_pc > pc_offset) break;
}
if (candidate != -1) return GetEntry(candidate);
}
for (int i = 0; i < length_; ++i) {
SafepointEntry entry = GetEntry(i);
if (entry.pc() == pc_offset || entry.trampoline_pc() == pc_offset) {
if (i == length_ - 1 || GetEntry(i + 1).pc() > pc_offset) {
DCHECK_LE(entry.pc(), pc_offset);
return entry;
}
}
......@@ -182,15 +189,12 @@ void SafepointTableBuilder::Emit(Assembler* assembler, int tagged_slots_size) {
}
void SafepointTableBuilder::RemoveDuplicates() {
// If the table contains more than one entry, and all entries are identical
// (except for the pc), replace the whole table by a single entry with pc =
// -1. This especially compacts the table for wasm code without tagged
// pointers and without deoptimization info.
// Remove any duplicate entries, i.e. succeeding entries that are identical
// except for the PC. During lookup, we will find the first entry whose PC is
// not larger than the PC at hand, and find the first non-duplicate.
if (entries_.size() < 2) return;
// Check that all entries (1, size] are identical to entry 0.
const EntryBuilder& first_entry = entries_.front();
auto is_identical_except_for_pc = [](const EntryBuilder& entry1,
const EntryBuilder& entry2) {
if (entry1.deopt_index != entry2.deopt_index) return false;
......@@ -208,15 +212,19 @@ void SafepointTableBuilder::RemoveDuplicates() {
return true;
};
if (std::all_of(entries_.Find(1), entries_.end(),
[&](const EntryBuilder& entry) {
return is_identical_except_for_pc(first_entry, entry);
})) {
// All entries were identical. Rewind the list to just one
// entry, and set the pc to -1.
entries_.Rewind(1);
entries_.front().pc = -1;
auto remaining_it = entries_.begin();
size_t remaining = 0;
for (auto it = entries_.begin(), end = entries_.end(); it != end;
++remaining_it, ++remaining) {
if (remaining_it != it) *remaining_it = *it;
// Merge identical entries.
do {
++it;
} while (it != end && is_identical_except_for_pc(*it, *remaining_it));
}
entries_.Rewind(remaining);
}
void SafepointTableBuilder::TrimEntries(int* tagged_slots_size) {
......
......@@ -252,7 +252,7 @@ class SafepointTableBuilder {
register_indexes(0) {}
};
// If all entries are identical, replace them by 1 entry with pc = kMaxUInt32.
// Remove consecutive identical entries.
void RemoveDuplicates();
// Try to trim entries by removing trailing zeros (and shrinking
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment