Revert "[codegen] Reduce size of safepoint table fields"
This reverts commit f68242bcb0
.
Reason for revert: UBSan error: https://logs.chromium.org/logs/v8/buildbucket/cr-buildbucket/8828943333104509889/+/u/build/compile/stdout
Original change's description:
> [codegen] Reduce size of safepoint table fields
>
> Code objects are often small and do not use the full integer range of PC
> offsets and deoptimization indexes. Reducing the size of these fields to
> the required size per table reduces the overall size of safepoint tables
> by roughly 25%.
>
> R=jkummerow@chromium.org
>
> Bug: v8:12401
> Change-Id: Ie6889a70782f5510436a1d05d31d17aac0bfec6e
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3306556
> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
> Commit-Queue: Clemens Backes <clemensb@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#78216}
Bug: v8:12401
Change-Id: I53b574558305ac25fa8f38a843c98f653af201ba
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3312488
Auto-Submit: Clemens Backes <clemensb@chromium.org>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/main@{#78217}
This commit is contained in:
parent
f68242bcb0
commit
4f34cd833b
@ -80,7 +80,7 @@ void SafepointTable::Print(std::ostream& os) const {
|
||||
for (int index = 0; index < length_; index++) {
|
||||
SafepointEntry entry = GetEntry(index);
|
||||
os << reinterpret_cast<const void*>(instruction_start_ + entry.pc()) << " "
|
||||
<< std::setw(6) << std::hex << entry.pc() << std::dec;
|
||||
<< std::setw(6) << std::hex << entry.pc();
|
||||
|
||||
if (!entry.tagged_slots().empty()) {
|
||||
os << " slots (sp->fp): ";
|
||||
@ -163,47 +163,21 @@ void SafepointTableBuilder::Emit(Assembler* assembler, int tagged_slots_size) {
|
||||
assembler->RecordComment(";;; Safepoint table.");
|
||||
offset_ = assembler->pc_offset();
|
||||
|
||||
// Compute the required sizes of the fields.
|
||||
int used_register_indexes = 0;
|
||||
int max_pc = 0;
|
||||
STATIC_ASSERT(SafepointEntry::kNoDeoptIndex == -1);
|
||||
int max_deopt_index = SafepointEntry::kNoDeoptIndex;
|
||||
for (const EntryBuilder& entry : entries_) {
|
||||
used_register_indexes |= entry.register_indexes;
|
||||
max_pc = std::max(max_pc, std::max(entry.pc, entry.trampoline));
|
||||
max_deopt_index = std::max(max_deopt_index, entry.deopt_index);
|
||||
}
|
||||
|
||||
// Derive the bytes and bools for the entry configuration from the values.
|
||||
auto value_to_bytes = [](int value) {
|
||||
if (value == 0) return 0;
|
||||
for (int bytes = 1;; ++bytes) {
|
||||
DCHECK_GE(4, bytes);
|
||||
int shifted_value = (value << (32 - 8 * bytes)) >> (32 - 8 * bytes);
|
||||
if (shifted_value == value) return bytes;
|
||||
}
|
||||
};
|
||||
bool has_deopt_data = max_deopt_index != SafepointEntry::kNoDeoptIndex;
|
||||
int register_indexes_size = value_to_bytes(used_register_indexes);
|
||||
int pc_size = value_to_bytes(max_pc);
|
||||
int deopt_index_size = value_to_bytes(max_deopt_index);
|
||||
// Compute the number of bytes for tagged slots per safepoint entry.
|
||||
int tagged_slots_bytes =
|
||||
(tagged_slots_size + kBitsPerByte - 1) / kBitsPerByte;
|
||||
|
||||
// Add a CHECK to ensure we never overflow the space in the bitfield, even for
|
||||
// huge functions which might not be covered by tests.
|
||||
CHECK(SafepointTable::RegisterIndexesSizeField::is_valid(
|
||||
register_indexes_size) &&
|
||||
SafepointTable::PcSizeField::is_valid(pc_size) &&
|
||||
SafepointTable::DeoptIndexSizeField::is_valid(deopt_index_size) &&
|
||||
SafepointTable::TaggedSlotsBytesField::is_valid(tagged_slots_bytes));
|
||||
RoundUp(tagged_slots_size, kBitsPerByte) >> kBitsPerByteLog2;
|
||||
bool has_deopt_data =
|
||||
std::any_of(entries_.begin(), entries_.end(), [](auto& entry) {
|
||||
return entry.deopt_index != SafepointEntry::kNoDeoptIndex;
|
||||
});
|
||||
bool has_register_indexes =
|
||||
std::any_of(entries_.begin(), entries_.end(),
|
||||
[](auto& entry) { return entry.register_indexes != 0; });
|
||||
|
||||
uint32_t entry_configuration =
|
||||
SafepointTable::TaggedSlotsBytesField::encode(tagged_slots_bytes) |
|
||||
SafepointTable::HasDeoptDataField::encode(has_deopt_data) |
|
||||
SafepointTable::RegisterIndexesSizeField::encode(register_indexes_size) |
|
||||
SafepointTable::PcSizeField::encode(pc_size) |
|
||||
SafepointTable::DeoptIndexSizeField::encode(deopt_index_size) |
|
||||
SafepointTable::TaggedSlotsBytesField::encode(tagged_slots_bytes);
|
||||
SafepointTable::HasRegisterIndexesField::encode(has_register_indexes);
|
||||
|
||||
// Emit the table header.
|
||||
STATIC_ASSERT(SafepointTable::kLengthOffset == 0 * kIntSize);
|
||||
@ -213,19 +187,16 @@ void SafepointTableBuilder::Emit(Assembler* assembler, int tagged_slots_size) {
|
||||
assembler->dd(length);
|
||||
assembler->dd(entry_configuration);
|
||||
|
||||
auto emit_bytes = [assembler](int value, int bytes) {
|
||||
for (int b = bytes - 1; b >= 0; --b) {
|
||||
assembler->db(value >> (8 * b));
|
||||
}
|
||||
};
|
||||
// Emit entries, sorted by pc offsets.
|
||||
for (const EntryBuilder& entry : entries_) {
|
||||
emit_bytes(entry.pc, pc_size);
|
||||
assembler->dd(entry.pc);
|
||||
if (has_deopt_data) {
|
||||
emit_bytes(entry.deopt_index, deopt_index_size);
|
||||
emit_bytes(entry.trampoline, pc_size);
|
||||
assembler->dd(entry.deopt_index);
|
||||
assembler->dd(entry.trampoline);
|
||||
}
|
||||
if (has_register_indexes) {
|
||||
assembler->dd(entry.register_indexes);
|
||||
}
|
||||
emit_bytes(entry.register_indexes, register_indexes_size);
|
||||
}
|
||||
|
||||
// Emit bitmaps of tagged stack slots.
|
||||
|
@ -109,15 +109,20 @@ class SafepointTable {
|
||||
Address entry_ptr =
|
||||
safepoint_table_address_ + kHeaderSize + index * entry_size();
|
||||
|
||||
int pc = read_bytes(&entry_ptr, pc_size());
|
||||
int pc = base::Memory<int>(entry_ptr);
|
||||
entry_ptr += kPcSize;
|
||||
int deopt_index = SafepointEntry::kNoDeoptIndex;
|
||||
int trampoline_pc = SafepointEntry::kNoTrampolinePC;
|
||||
if (has_deopt_data()) {
|
||||
deopt_index = read_bytes(&entry_ptr, deopt_index_size());
|
||||
trampoline_pc = read_bytes(&entry_ptr, pc_size());
|
||||
deopt_index = base::Memory<int>(entry_ptr);
|
||||
trampoline_pc = base::Memory<int>(entry_ptr + kIntSize);
|
||||
entry_ptr += kDeoptDataSize;
|
||||
}
|
||||
int tagged_register_indexes = 0;
|
||||
if (has_register_indexes()) {
|
||||
tagged_register_indexes = base::Memory<int>(entry_ptr);
|
||||
entry_ptr += kRegisterIndexesSize;
|
||||
}
|
||||
int tagged_register_indexes =
|
||||
read_bytes(&entry_ptr, register_indexes_size());
|
||||
|
||||
// Entry bits start after the the vector of entries (thus the pc offset of
|
||||
// the non-existing entry after the last one).
|
||||
@ -142,20 +147,21 @@ class SafepointTable {
|
||||
static constexpr int kEntryConfigurationOffset = kLengthOffset + kIntSize;
|
||||
static constexpr int kHeaderSize = kEntryConfigurationOffset + kUInt32Size;
|
||||
|
||||
using HasDeoptDataField = base::BitField<bool, 0, 1>;
|
||||
using RegisterIndexesSizeField = HasDeoptDataField::Next<int, 3>;
|
||||
using PcSizeField = RegisterIndexesSizeField::Next<int, 3>;
|
||||
using DeoptIndexSizeField = PcSizeField::Next<int, 3>;
|
||||
// In 22 bits, we can encode up to 4M bytes, corresponding to 32M frame slots,
|
||||
// which is 128MB on 32-bit and 256MB on 64-bit systems. The stack size is
|
||||
// limited to a bit below 1MB anyway (see FLAG_stack_size).
|
||||
using TaggedSlotsBytesField = DeoptIndexSizeField::Next<int, 22>;
|
||||
// An entry consists of the pc, plus optional deopt data (deopt index and
|
||||
// trampoline PC), plus optional register indexes.
|
||||
static constexpr int kPcSize = kIntSize;
|
||||
static constexpr int kDeoptDataSize = 2 * kIntSize;
|
||||
static constexpr int kRegisterIndexesSize = kIntSize;
|
||||
|
||||
using TaggedSlotsBytesField = base::BitField<int, 0, 30>;
|
||||
using HasDeoptDataField = TaggedSlotsBytesField::Next<bool, 1>;
|
||||
using HasRegisterIndexesField = HasDeoptDataField::Next<bool, 1>;
|
||||
|
||||
SafepointTable(Address instruction_start, Address safepoint_table_address);
|
||||
|
||||
int entry_size() const {
|
||||
int deopt_data_size = has_deopt_data() ? pc_size() + deopt_index_size() : 0;
|
||||
return pc_size() + deopt_data_size + register_indexes_size();
|
||||
return kPcSize + (has_deopt_data() ? kDeoptDataSize : 0) +
|
||||
(has_register_indexes() ? kRegisterIndexesSize : 0);
|
||||
}
|
||||
|
||||
int tagged_slots_bytes() const {
|
||||
@ -164,23 +170,8 @@ class SafepointTable {
|
||||
bool has_deopt_data() const {
|
||||
return HasDeoptDataField::decode(entry_configuration_);
|
||||
}
|
||||
int pc_size() const { return PcSizeField::decode(entry_configuration_); }
|
||||
int deopt_index_size() const {
|
||||
return DeoptIndexSizeField::decode(entry_configuration_);
|
||||
}
|
||||
int register_indexes_size() const {
|
||||
return RegisterIndexesSizeField::decode(entry_configuration_);
|
||||
}
|
||||
|
||||
static int read_bytes(Address* ptr, int bytes) {
|
||||
if (bytes == 0) return 0;
|
||||
// Sign-extend the first byte.
|
||||
int result = *reinterpret_cast<int8_t*>(*ptr);
|
||||
for (int b = 1; b < bytes; ++b) {
|
||||
result = result << 8 | *reinterpret_cast<uint8_t*>(*ptr + b);
|
||||
}
|
||||
*ptr += bytes;
|
||||
return result;
|
||||
bool has_register_indexes() const {
|
||||
return HasRegisterIndexesField::decode(entry_configuration_);
|
||||
}
|
||||
|
||||
DISALLOW_GARBAGE_COLLECTION(no_gc_)
|
||||
|
Loading…
Reference in New Issue
Block a user