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) { ...@@ -49,15 +49,22 @@ int SafepointTable::find_return_pc(int pc_offset) {
SafepointEntry SafepointTable::FindEntry(Address pc) const { SafepointEntry SafepointTable::FindEntry(Address pc) const {
int pc_offset = static_cast<int>(pc - instruction_start_); 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 if the PC is pointing at a trampoline.
CHECK_LT(0, length_); if (has_deopt_data()) {
// A single entry with pc == -1 covers all call sites in the function. int candidate = -1;
if (length_ == 1 && GetEntry(0).pc() == -1) return GetEntry(0); for (int i = 0; i < length_; ++i) {
for (int i = 0; i < length_; i++) { int trampoline_pc = GetEntry(i).trampoline_pc();
// TODO(kasperl): Replace the linear search with binary search. 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); 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; return entry;
} }
} }
...@@ -182,15 +189,12 @@ void SafepointTableBuilder::Emit(Assembler* assembler, int tagged_slots_size) { ...@@ -182,15 +189,12 @@ void SafepointTableBuilder::Emit(Assembler* assembler, int tagged_slots_size) {
} }
void SafepointTableBuilder::RemoveDuplicates() { void SafepointTableBuilder::RemoveDuplicates() {
// If the table contains more than one entry, and all entries are identical // Remove any duplicate entries, i.e. succeeding entries that are identical
// (except for the pc), replace the whole table by a single entry with pc = // except for the PC. During lookup, we will find the first entry whose PC is
// -1. This especially compacts the table for wasm code without tagged // not larger than the PC at hand, and find the first non-duplicate.
// pointers and without deoptimization info.
if (entries_.size() < 2) return; 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, auto is_identical_except_for_pc = [](const EntryBuilder& entry1,
const EntryBuilder& entry2) { const EntryBuilder& entry2) {
if (entry1.deopt_index != entry2.deopt_index) return false; if (entry1.deopt_index != entry2.deopt_index) return false;
...@@ -208,15 +212,19 @@ void SafepointTableBuilder::RemoveDuplicates() { ...@@ -208,15 +212,19 @@ void SafepointTableBuilder::RemoveDuplicates() {
return true; return true;
}; };
if (std::all_of(entries_.Find(1), entries_.end(), auto remaining_it = entries_.begin();
[&](const EntryBuilder& entry) { size_t remaining = 0;
return is_identical_except_for_pc(first_entry, entry);
})) { for (auto it = entries_.begin(), end = entries_.end(); it != end;
// All entries were identical. Rewind the list to just one ++remaining_it, ++remaining) {
// entry, and set the pc to -1. if (remaining_it != it) *remaining_it = *it;
entries_.Rewind(1); // Merge identical entries.
entries_.front().pc = -1; do {
++it;
} while (it != end && is_identical_except_for_pc(*it, *remaining_it));
} }
entries_.Rewind(remaining);
} }
void SafepointTableBuilder::TrimEntries(int* tagged_slots_size) { void SafepointTableBuilder::TrimEntries(int* tagged_slots_size) {
......
...@@ -252,7 +252,7 @@ class SafepointTableBuilder { ...@@ -252,7 +252,7 @@ class SafepointTableBuilder {
register_indexes(0) {} register_indexes(0) {}
}; };
// If all entries are identical, replace them by 1 entry with pc = kMaxUInt32. // Remove consecutive identical entries.
void RemoveDuplicates(); void RemoveDuplicates();
// Try to trim entries by removing trailing zeros (and shrinking // 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