Commit 060f868e authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[Liftoff] Store safepoint info

This CL prepares support for memory operations, where we will need to
call runtime functions for trapping, and hence need safepoint
information for iterating the frames correctly.

R=titzer@chromium.org

Bug: v8:6600
Change-Id: I8c65d80cd69747d13d9084e7427253413fb4b808
Reviewed-on: https://chromium-review.googlesource.com/810784
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49952}
parent c0fe7846
......@@ -5011,7 +5011,14 @@ WasmCodeWrapper WasmCompilationUnit::FinishLiftoffCompilation(
WasmCodeWrapper ret;
if (!FLAG_wasm_jit_to_native) {
Handle<Code> code;
code = isolate_->factory()->NewCode(desc, Code::WASM_FUNCTION, code);
code = isolate_->factory()->NewCode(
desc, Code::WASM_FUNCTION, code, Builtins::kNoBuiltinId,
MaybeHandle<HandlerTable>(), MaybeHandle<ByteArray>(),
MaybeHandle<DeoptimizationData>(), kMovable,
0, // stub_key
false, // is_turbofanned
liftoff_.asm_.GetTotalFrameSlotCount(), // stack_slots
liftoff_.safepoint_table_offset_);
#ifdef ENABLE_DISASSEMBLER
if (FLAG_print_code || FLAG_print_wasm_code) {
// TODO(wasm): Use proper log files, here and elsewhere.
......@@ -5036,8 +5043,7 @@ WasmCodeWrapper WasmCompilationUnit::FinishLiftoffCompilation(
// Consider lifting them both to FinishCompilation.
return WasmCodeWrapper(native_module_->AddCode(
desc, liftoff_.asm_.GetTotalFrameSlotCount(), func_index_,
liftoff_.asm_.GetSafepointTableOffset(), protected_instructions_,
true));
liftoff_.safepoint_table_offset_, protected_instructions_, true));
}
}
......
......@@ -119,6 +119,7 @@ class WasmCompilationUnit final {
struct LiftoffData {
wasm::LiftoffAssembler asm_;
int safepoint_table_offset_;
explicit LiftoffData(Isolate* isolate) : asm_(isolate) {}
};
struct TurbofanData {
......
......@@ -14530,7 +14530,8 @@ void Code::Disassemble(const char* name, std::ostream& os) { // NOLINT
{
Isolate* isolate = GetIsolate();
int size = instruction_size();
int safepoint_offset = is_turbofanned() ? safepoint_table_offset() : size;
int safepoint_offset =
has_safepoint_info() ? safepoint_table_offset() : size;
int constant_pool_offset = FLAG_enable_embedded_constant_pool
? this->constant_pool_offset()
: size;
......@@ -14573,7 +14574,7 @@ void Code::Disassemble(const char* name, std::ostream& os) { // NOLINT
}
os << "\n";
if (is_turbofanned()) {
if (has_safepoint_info()) {
SafepointTable table(this);
os << "Safepoints (size = " << table.size() << ")\n";
for (unsigned i = 0; i < table.length(); i++) {
......
......@@ -291,13 +291,13 @@ Code::Kind Code::kind() const {
void Code::initialize_flags(Kind kind, bool has_unwinding_info,
bool is_turbofanned, int stack_slots) {
CHECK(0 <= stack_slots && stack_slots < StackSlotsField::kMax);
DCHECK_IMPLIES(stack_slots != 0, is_turbofanned);
static_assert(Code::NUMBER_OF_KINDS <= KindField::kMax + 1, "field overflow");
uint32_t flags = HasUnwindingInfoField::encode(has_unwinding_info) |
KindField::encode(kind) |
IsTurbofannedField::encode(is_turbofanned) |
StackSlotsField::encode(stack_slots);
WRITE_UINT32_FIELD(this, kFlagsOffset, flags);
DCHECK_IMPLIES(stack_slots != 0, has_safepoint_info());
}
inline bool Code::is_interpreter_trampoline_builtin() const {
......@@ -411,19 +411,23 @@ void Code::set_builtin_index(int index) {
bool Code::is_builtin() const { return builtin_index() != -1; }
bool Code::has_safepoint_info() const {
return is_turbofanned() || is_wasm_code();
}
int Code::stack_slots() const {
DCHECK(is_turbofanned());
DCHECK(has_safepoint_info());
return StackSlotsField::decode(READ_UINT32_FIELD(this, kFlagsOffset));
}
int Code::safepoint_table_offset() const {
DCHECK(is_turbofanned());
DCHECK(has_safepoint_info());
return READ_INT32_FIELD(this, kSafepointTableOffsetOffset);
}
void Code::set_safepoint_table_offset(int offset) {
CHECK_LE(0, offset);
DCHECK(is_turbofanned() || offset == 0); // Allow zero initialization.
DCHECK(has_safepoint_info() || offset == 0); // Allow zero initialization.
DCHECK(IsAligned(offset, static_cast<unsigned>(kIntSize)));
WRITE_INT32_FIELD(this, kSafepointTableOffsetOffset, offset);
}
......
......@@ -233,12 +233,14 @@ class Code : public HeapObject {
inline void set_builtin_index(int id);
inline bool is_builtin() const;
// [stack_slots]: For kind OPTIMIZED_FUNCTION, the number of stack slots
inline bool has_safepoint_info() const;
// [stack_slots]: If {has_safepoint_info()}, the number of stack slots
// reserved in the code prologue.
inline int stack_slots() const;
// [safepoint_table_start]: For kind OPTIMIZED_FUNCTION, the offset in
// the instruction stream where the safepoint table starts.
// [safepoint_table_offset]: If {has_safepoint_info()}, the offset in the
// instruction stream where the safepoint table starts.
inline int safepoint_table_offset() const;
inline void set_safepoint_table_offset(int offset);
......
......@@ -52,9 +52,7 @@ SafepointTable::SafepointTable(Address instruction_start,
SafepointTable::SafepointTable(Code* code)
: SafepointTable(code->instruction_start(), code->safepoint_table_offset(),
code->stack_slots(), true) {
DCHECK(code->is_turbofanned());
}
code->stack_slots(), true) {}
unsigned SafepointTable::find_return_pc(unsigned pc_offset) {
for (unsigned i = 0; i < length(); i++) {
......
......@@ -387,7 +387,7 @@ void LiftoffAssembler::set_num_locals(uint32_t num_locals) {
}
uint32_t LiftoffAssembler::GetTotalFrameSlotCount() const {
return kPointerSize * (num_locals() + kMaxValueStackHeight);
return num_locals() + kMaxValueStackHeight;
}
#undef __
......
......@@ -287,7 +287,6 @@ class LiftoffAssembler : public TurboAssembler {
void set_num_locals(uint32_t num_locals);
uint32_t GetTotalFrameSlotCount() const;
size_t GetSafepointTableOffset() const { return 0; }
ValueType local_type(uint32_t index) {
DCHECK_GT(num_locals_, index);
......
......@@ -72,9 +72,13 @@ class LiftoffCompiler {
using Decoder = WasmFullDecoder<validate, LiftoffCompiler>;
LiftoffCompiler(LiftoffAssembler* liftoff_asm,
compiler::CallDescriptor* call_desc,
const compiler::ModuleEnv* env)
: asm_(liftoff_asm), call_desc_(call_desc), env_(env) {}
compiler::CallDescriptor* call_desc, compiler::ModuleEnv* env)
: asm_(liftoff_asm),
call_desc_(call_desc),
env_(env),
compilation_zone_(liftoff_asm->isolate()->allocator(),
"liftoff compilation"),
safepoint_table_builder_(&compilation_zone_) {}
bool ok() const { return ok_; }
......@@ -85,6 +89,10 @@ class LiftoffCompiler {
BindUnboundLabels(decoder);
}
int GetSafepointTableOffset() const {
return safepoint_table_builder_.GetCodeOffset();
}
void BindUnboundLabels(Decoder* decoder) {
#ifdef DEBUG
// Bind all labels now, otherwise their destructor will fire a DCHECK error
......@@ -214,7 +222,9 @@ class LiftoffCompiler {
CheckStackSizeLimit(decoder);
}
void FinishFunction(Decoder* decoder) {}
void FinishFunction(Decoder* decoder) {
safepoint_table_builder_.Emit(asm_, __ GetTotalFrameSlotCount());
}
void OnFirstError(Decoder* decoder) {
ok_ = false;
......@@ -562,10 +572,15 @@ class LiftoffCompiler {
}
private:
LiftoffAssembler* asm_;
compiler::CallDescriptor* call_desc_;
const compiler::ModuleEnv* env_;
LiftoffAssembler* const asm_;
compiler::CallDescriptor* const call_desc_;
compiler::ModuleEnv* const env_;
bool ok_ = true;
// Zone used to store information during compilation. The result will be
// stored independently, such that this zone can die together with the
// LiftoffCompiler after compilation.
Zone compilation_zone_;
SafepointTableBuilder safepoint_table_builder_;
};
} // namespace
......@@ -601,6 +616,8 @@ bool compiler::WasmCompilationUnit::ExecuteLiftoffCompilation() {
// Record the memory cost this unit places on the system until
// it is finalized.
memory_cost_ = liftoff_.asm_.pc_offset();
liftoff_.safepoint_table_offset_ =
decoder.interface().GetSafepointTableOffset();
isolate_->counters()->liftoff_compiled_functions()->Increment();
return true;
}
......
......@@ -348,8 +348,8 @@ WasmCode* NativeModule::AddAnonymousCode(Handle<Code> code,
static_cast<size_t>(code->instruction_size())},
std::move(reloc_info), static_cast<size_t>(code->relocation_size()),
Nothing<uint32_t>(), kind, code->constant_pool_offset(),
(code->is_turbofanned() ? code->stack_slots() : 0),
(code->is_turbofanned() ? code->safepoint_table_offset() : 0), {});
(code->has_safepoint_info() ? code->stack_slots() : 0),
(code->has_safepoint_info() ? code->safepoint_table_offset() : 0), {});
if (ret == nullptr) return nullptr;
intptr_t delta = ret->instructions().start() - code->instruction_start();
int mask = RelocInfo::kApplyMask | RelocInfo::kCodeTargetMask |
......
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