Refactor SafepointTable and create a chokepoint

... on Code objects.

Refactors: create a dedicated WasmCode constructor, hide the internal
constructor, constify members, and let SafepointTable handle
out-of-line tables.

Expose a new Code::SafepointTableAddress() helper as the source of
truth. Some safepoint tables may move out-of-line in the near future.

Bug: v8:7777,v8:10707
Change-Id: I4e2d954ed2d157235e9dfa3e7a5ca08800896683
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2297459
Reviewed-by: Clemens Backes <clemensb@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Auto-Submit: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68837}
This commit is contained in:
Jakob Gruber 2020-07-14 12:36:31 +02:00 committed by Commit Bot
parent 2b873b94e9
commit 130d95eff9
6 changed files with 55 additions and 34 deletions

View File

@ -10,26 +10,29 @@
#include "src/diagnostics/disasm.h"
#include "src/execution/frames-inl.h"
#include "src/utils/ostreams.h"
#include "src/wasm/wasm-code-manager.h"
namespace v8 {
namespace internal {
SafepointTable::SafepointTable(Code code)
: SafepointTable(code.InstructionStart(), code.SafepointTableAddress(),
code.stack_slots(), true) {}
SafepointTable::SafepointTable(const wasm::WasmCode* code)
: SafepointTable(code->instruction_start(),
code->instruction_start() + code->safepoint_table_offset(),
code->stack_slots(), false) {}
SafepointTable::SafepointTable(Address instruction_start,
size_t safepoint_table_offset,
Address safepoint_table_address,
uint32_t stack_slots, bool has_deopt)
: instruction_start_(instruction_start),
stack_slots_(stack_slots),
has_deopt_(has_deopt) {
Address header = instruction_start_ + safepoint_table_offset;
length_ = Memory<uint32_t>(header + kLengthOffset);
entry_size_ = Memory<uint32_t>(header + kEntrySizeOffset);
pc_and_deoptimization_indexes_ = header + kHeaderSize;
entries_ = pc_and_deoptimization_indexes_ + (length_ * kFixedEntrySize);
}
SafepointTable::SafepointTable(Code code)
: SafepointTable(code.InstructionStart(), code.safepoint_table_offset(),
code.stack_slots(), true) {}
has_deopt_(has_deopt),
safepoint_table_address_(safepoint_table_address),
length_(ReadLength(safepoint_table_address)),
entry_size_(ReadEntrySize(safepoint_table_address)) {}
unsigned SafepointTable::find_return_pc(unsigned pc_offset) {
for (unsigned i = 0; i < length(); i++) {
@ -40,7 +43,6 @@ unsigned SafepointTable::find_return_pc(unsigned pc_offset) {
}
}
UNREACHABLE();
return 0;
}
SafepointEntry SafepointTable::FindEntry(Address pc) const {
@ -60,7 +62,6 @@ SafepointEntry SafepointTable::FindEntry(Address pc) const {
}
}
UNREACHABLE();
return SafepointEntry();
}
void SafepointTable::PrintEntry(unsigned index,

View File

@ -15,6 +15,10 @@
namespace v8 {
namespace internal {
namespace wasm {
class WasmCode;
}
class SafepointEntry {
public:
SafepointEntry() : deopt_index_(0), bits_(nullptr), trampoline_pc_(-1) {}
@ -64,9 +68,7 @@ class SafepointEntry {
class SafepointTable {
public:
explicit SafepointTable(Code code);
explicit SafepointTable(Address instruction_start,
size_t safepoint_table_offset, uint32_t stack_slots,
bool has_deopt = false);
explicit SafepointTable(const wasm::WasmCode* code);
int size() const {
return kHeaderSize + (length_ * (kFixedEntrySize + entry_size_));
@ -90,7 +92,7 @@ class SafepointTable {
DCHECK(index < length_);
unsigned deopt_index =
base::Memory<uint32_t>(GetEncodedInfoLocation(index));
uint8_t* bits = &base::Memory<uint8_t>(entries_ + (index * entry_size_));
uint8_t* bits = &base::Memory<uint8_t>(entries() + (index * entry_size_));
int trampoline_pc =
has_deopt_ ? base::Memory<int>(GetTrampolineLocation(index)) : -1;
return SafepointEntry(deopt_index, bits, trampoline_pc);
@ -102,9 +104,12 @@ class SafepointTable {
void PrintEntry(unsigned index, std::ostream& os) const; // NOLINT
private:
SafepointTable(Address instruction_start, Address safepoint_table_address,
uint32_t stack_slots, bool has_deopt);
static const uint8_t kNoRegisters = 0xFF;
// Layout information
// Layout information.
static const int kLengthOffset = 0;
static const int kEntrySizeOffset = kLengthOffset + kIntSize;
static const int kHeaderSize = kEntrySizeOffset + kIntSize;
@ -113,8 +118,21 @@ class SafepointTable {
static const int kTrampolinePcOffset = kEncodedInfoOffset + kIntSize;
static const int kFixedEntrySize = kTrampolinePcOffset + kIntSize;
static uint32_t ReadLength(Address table) {
return base::Memory<uint32_t>(table + kLengthOffset);
}
static uint32_t ReadEntrySize(Address table) {
return base::Memory<uint32_t>(table + kEntrySizeOffset);
}
Address pc_and_deoptimization_indexes() const {
return safepoint_table_address_ + kHeaderSize;
}
Address entries() const {
return safepoint_table_address_ + kHeaderSize + (length_ * kFixedEntrySize);
}
Address GetPcOffsetLocation(unsigned index) const {
return pc_and_deoptimization_indexes_ + (index * kFixedEntrySize);
return pc_and_deoptimization_indexes() + (index * kFixedEntrySize);
}
Address GetEncodedInfoLocation(unsigned index) const {
@ -125,18 +143,18 @@ class SafepointTable {
return GetPcOffsetLocation(index) + kTrampolinePcOffset;
}
static void PrintBits(std::ostream& os, // NOLINT
uint8_t byte, int digits);
static void PrintBits(std::ostream& os, uint8_t byte, int digits);
DISALLOW_HEAP_ALLOCATION(no_allocation_)
Address instruction_start_;
uint32_t stack_slots_;
unsigned length_;
unsigned entry_size_;
Address pc_and_deoptimization_indexes_;
Address entries_;
bool has_deopt_;
const Address instruction_start_;
const uint32_t stack_slots_;
const bool has_deopt_;
// Safepoint table layout.
const Address safepoint_table_address_;
const uint32_t length_;
const uint32_t entry_size_;
friend class SafepointTableBuilder;
friend class SafepointEntry;

View File

@ -923,9 +923,7 @@ void StandardFrame::IterateCompiledFrame(RootVisitor* v) const {
bool has_tagged_params = false;
uint32_t tagged_parameter_slots = 0;
if (wasm_code != nullptr) {
SafepointTable table(wasm_code->instruction_start(),
wasm_code->safepoint_table_offset(),
wasm_code->stack_slots());
SafepointTable table(wasm_code);
safepoint_entry = table.FindEntry(inner_pointer);
stack_slots = wasm_code->stack_slots();
has_tagged_params = wasm_code->kind() != wasm::WasmCode::kFunction &&

View File

@ -30,6 +30,10 @@
namespace v8 {
namespace internal {
Address Code::SafepointTableAddress() const {
return InstructionStart() + safepoint_table_offset();
}
int Code::safepoint_table_size() const {
DCHECK_GE(handler_table_offset() - safepoint_table_offset(), 0);
return handler_table_offset() - safepoint_table_offset();

View File

@ -150,6 +150,7 @@ class Code : public HeapObject {
// instruction stream where the safepoint table starts.
inline int safepoint_table_offset() const;
inline void set_safepoint_table_offset(int offset);
Address SafepointTableAddress() const;
int safepoint_table_size() const;
bool has_safepoint_table() const;

View File

@ -393,8 +393,7 @@ void WasmCode::Disassemble(const char* name, std::ostream& os,
}
if (safepoint_table_offset_ > 0) {
SafepointTable table(instruction_start(), safepoint_table_offset_,
stack_slots_);
SafepointTable table(this);
os << "Safepoints (size = " << table.size() << ")\n";
for (uint32_t i = 0; i < table.length(); i++) {
uintptr_t pc_offset = table.GetPcOffset(i);