Commit 199af662 authored by Junliang Yan's avatar Junliang Yan Committed by Commit Bot

PPC/s390: [wasm] Support encoding reference types in exceptions.

Port e893eb14

Original Commit Message:

    This adds support for having reference type values (i.e. anyref) stored
    in an exception. It is the natural combination of the reference type
    proposal and the exception handling proposal.

    Note that this also introduces support for having write barriers in
    generated WasmCode, as this is the first time we are storing references
    within generated code. Such write barriers will be needed for other uses
    of reference types (e.g. mutable global) regardless.

R=mstarzinger@chromium.org, joransiu@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=v8:8341
LOG=N

Change-Id: I6837a31791654ebe4171f6ecb563939beb3a66dd
Reviewed-on: https://chromium-review.googlesource.com/c/1299899Reviewed-by: 's avatarJoran Siu <joransiu@ca.ibm.com>
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#57009}
parent 5d41105b
......@@ -13,6 +13,7 @@
#include "src/double.h"
#include "src/optimized-compilation-info.h"
#include "src/ppc/macro-assembler-ppc.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-objects.h"
namespace v8 {
......@@ -129,7 +130,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
public:
OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register offset,
Register value, Register scratch0, Register scratch1,
RecordWriteMode mode)
RecordWriteMode mode, StubCallMode stub_mode)
: OutOfLineCode(gen),
object_(object),
offset_(offset),
......@@ -138,12 +139,13 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
scratch0_(scratch0),
scratch1_(scratch1),
mode_(mode),
stub_mode_(stub_mode),
must_save_lr_(!gen->frame_access_state()->has_frame()),
zone_(gen->zone()) {}
OutOfLineRecordWrite(CodeGenerator* gen, Register object, int32_t offset,
Register value, Register scratch0, Register scratch1,
RecordWriteMode mode)
RecordWriteMode mode, StubCallMode stub_mode)
: OutOfLineCode(gen),
object_(object),
offset_(no_reg),
......@@ -152,6 +154,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
scratch0_(scratch0),
scratch1_(scratch1),
mode_(mode),
stub_mode_(stub_mode),
must_save_lr_(!gen->frame_access_state()->has_frame()),
zone_(gen->zone()) {}
......@@ -179,8 +182,13 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
__ mflr(scratch0_);
__ Push(scratch0_);
}
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode);
if (stub_mode_ == StubCallMode::kCallWasmRuntimeStub) {
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode, wasm::WasmCode::kWasmRecordWrite);
} else {
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode);
}
if (must_save_lr_) {
// We need to save and restore lr if the frame was elided.
__ Pop(scratch0_);
......@@ -196,6 +204,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
Register const scratch0_;
Register const scratch1_;
RecordWriteMode const mode_;
StubCallMode stub_mode_;
bool must_save_lr_;
Zone* zone_;
};
......@@ -1125,14 +1134,16 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
AddressingModeField::decode(instr->opcode());
if (addressing_mode == kMode_MRI) {
int32_t offset = i.InputInt32(1);
ool = new (zone()) OutOfLineRecordWrite(this, object, offset, value,
scratch0, scratch1, mode);
ool = new (zone())
OutOfLineRecordWrite(this, object, offset, value, scratch0,
scratch1, mode, DetermineStubCallMode());
__ StoreP(value, MemOperand(object, offset));
} else {
DCHECK_EQ(kMode_MRR, addressing_mode);
Register offset(i.InputRegister(1));
ool = new (zone()) OutOfLineRecordWrite(this, object, offset, value,
scratch0, scratch1, mode);
ool = new (zone())
OutOfLineRecordWrite(this, object, offset, value, scratch0,
scratch1, mode, DetermineStubCallMode());
__ StorePX(value, MemOperand(object, offset));
}
__ CheckPageFlag(object, scratch0,
......@@ -2125,7 +2136,8 @@ void CodeGenerator::AssembleArchTrap(Instruction* instr,
} else {
gen_->AssembleSourcePosition(instr_);
// A direct call to a wasm runtime stub defined in this module.
// Just encode the stub index. This will be patched at relocation.
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ Call(static_cast<Address>(trap_id), RelocInfo::WASM_STUB_CALL);
ReferenceMap* reference_map =
new (gen_->zone()) ReferenceMap(gen_->zone());
......
......@@ -12,6 +12,7 @@
#include "src/compiler/osr.h"
#include "src/optimized-compilation-info.h"
#include "src/s390/macro-assembler-s390.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-objects.h"
namespace v8 {
......@@ -165,7 +166,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
public:
OutOfLineRecordWrite(CodeGenerator* gen, Register object, Register offset,
Register value, Register scratch0, Register scratch1,
RecordWriteMode mode)
RecordWriteMode mode, StubCallMode stub_mode)
: OutOfLineCode(gen),
object_(object),
offset_(offset),
......@@ -174,12 +175,13 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
scratch0_(scratch0),
scratch1_(scratch1),
mode_(mode),
stub_mode_(stub_mode),
must_save_lr_(!gen->frame_access_state()->has_frame()),
zone_(gen->zone()) {}
OutOfLineRecordWrite(CodeGenerator* gen, Register object, int32_t offset,
Register value, Register scratch0, Register scratch1,
RecordWriteMode mode)
RecordWriteMode mode, StubCallMode stub_mode)
: OutOfLineCode(gen),
object_(object),
offset_(no_reg),
......@@ -188,6 +190,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
scratch0_(scratch0),
scratch1_(scratch1),
mode_(mode),
stub_mode_(stub_mode),
must_save_lr_(!gen->frame_access_state()->has_frame()),
zone_(gen->zone()) {}
......@@ -213,8 +216,13 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
// We need to save and restore r14 if the frame was elided.
__ Push(r14);
}
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode);
if (stub_mode_ == StubCallMode::kCallWasmRuntimeStub) {
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode, wasm::WasmCode::kWasmRecordWrite);
} else {
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode);
}
if (must_save_lr_) {
// We need to save and restore r14 if the frame was elided.
__ Pop(r14);
......@@ -229,6 +237,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
Register const scratch0_;
Register const scratch1_;
RecordWriteMode const mode_;
StubCallMode stub_mode_;
bool must_save_lr_;
Zone* zone_;
};
......@@ -1601,14 +1610,16 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
AddressingModeField::decode(instr->opcode());
if (addressing_mode == kMode_MRI) {
int32_t offset = i.InputInt32(1);
ool = new (zone()) OutOfLineRecordWrite(this, object, offset, value,
scratch0, scratch1, mode);
ool = new (zone())
OutOfLineRecordWrite(this, object, offset, value, scratch0,
scratch1, mode, DetermineStubCallMode());
__ StoreP(value, MemOperand(object, offset));
} else {
DCHECK_EQ(kMode_MRR, addressing_mode);
Register offset(i.InputRegister(1));
ool = new (zone()) OutOfLineRecordWrite(this, object, offset, value,
scratch0, scratch1, mode);
ool = new (zone())
OutOfLineRecordWrite(this, object, offset, value, scratch0,
scratch1, mode, DetermineStubCallMode());
__ StoreP(value, MemOperand(object, offset));
}
__ CheckPageFlag(object, scratch0,
......@@ -2855,7 +2866,8 @@ void CodeGenerator::AssembleArchTrap(Instruction* instr,
} else {
gen_->AssembleSourcePosition(instr_);
// A direct call to a wasm runtime stub defined in this module.
// Just encode the stub index. This will be patched at relocation.
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ Call(static_cast<Address>(trap_id), RelocInfo::WASM_STUB_CALL);
ReferenceMap* reference_map =
new (gen_->zone()) ReferenceMap(gen_->zone());
......
......@@ -468,25 +468,43 @@ void TurboAssembler::RestoreRegisters(RegList registers) {
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode) {
CallRecordWriteStub(
object, address, remembered_set_action, fp_mode,
isolate()->builtins()->builtin_handle(Builtins::kRecordWrite),
kNullAddress);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
Address wasm_target) {
CallRecordWriteStub(object, address, remembered_set_action, fp_mode,
Handle<Code>::null(), wasm_target);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
Handle<Code> code_target, Address wasm_target) {
DCHECK_NE(code_target.is_null(), wasm_target == kNullAddress);
// TODO(albertnetymk): For now we ignore remembered_set_action and fp_mode,
// i.e. always emit remember set and save FP registers in RecordWriteStub. If
// large performance regression is observed, we should use these values to
// avoid unnecessary work.
Callable const callable =
Builtins::CallableFor(isolate(), Builtins::kRecordWrite);
RegList registers = callable.descriptor().allocatable_registers();
RecordWriteDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kObject));
Register object_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kObject));
Register slot_parameter(
callable.descriptor().GetRegisterParameter(RecordWriteDescriptor::kSlot));
Register remembered_set_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kRememberedSet));
Register fp_mode_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kFPMode));
descriptor.GetRegisterParameter(RecordWriteDescriptor::kSlot));
Register remembered_set_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kRememberedSet));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kFPMode));
push(object);
push(address);
......@@ -496,7 +514,11 @@ void TurboAssembler::CallRecordWriteStub(
Move(remembered_set_parameter, Smi::FromEnum(remembered_set_action));
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
Call(callable.code(), RelocInfo::CODE_TARGET);
if (code_target.is_null()) {
Call(wasm_target, RelocInfo::WASM_STUB_CALL);
} else {
Call(code_target, RelocInfo::CODE_TARGET);
}
RestoreRegisters(registers);
}
......
......@@ -297,7 +297,7 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void CallRecordWriteStub(Register object, Register address,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode);
SaveFPRegsMode fp_mode, Address wasm_target);
void MultiPush(RegList regs, Register location = sp);
void MultiPop(RegList regs, Register location = sp);
......@@ -659,6 +659,10 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
int num_double_arguments);
void CallCFunctionHelper(Register function, int num_reg_arguments,
int num_double_arguments);
void CallRecordWriteStub(Register object, Register address,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, Handle<Code> code_target,
Address wasm_target);
};
// MacroAssembler implements a collection of frequently used acros.
......
......@@ -500,24 +500,42 @@ void TurboAssembler::RestoreRegisters(RegList registers) {
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode) {
CallRecordWriteStub(
object, address, remembered_set_action, fp_mode,
isolate()->builtins()->builtin_handle(Builtins::kRecordWrite),
kNullAddress);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
Address wasm_target) {
CallRecordWriteStub(object, address, remembered_set_action, fp_mode,
Handle<Code>::null(), wasm_target);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
Handle<Code> code_target, Address wasm_target) {
DCHECK_NE(code_target.is_null(), wasm_target == kNullAddress);
// TODO(albertnetymk): For now we ignore remembered_set_action and fp_mode,
// i.e. always emit remember set and save FP registers in RecordWriteStub. If
// large performance regression is observed, we should use these values to
// avoid unnecessary work.
Callable const callable =
Builtins::CallableFor(isolate(), Builtins::kRecordWrite);
RegList registers = callable.descriptor().allocatable_registers();
RecordWriteDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kObject));
Register object_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kObject));
Register slot_parameter(
callable.descriptor().GetRegisterParameter(RecordWriteDescriptor::kSlot));
Register remembered_set_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kRememberedSet));
Register fp_mode_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kFPMode));
descriptor.GetRegisterParameter(RecordWriteDescriptor::kSlot));
Register remembered_set_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kRememberedSet));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kFPMode));
Push(object);
Push(address);
......@@ -527,7 +545,11 @@ void TurboAssembler::CallRecordWriteStub(
Move(remembered_set_parameter, Smi::FromEnum(remembered_set_action));
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
Call(callable.code(), RelocInfo::CODE_TARGET);
if (code_target.is_null()) {
Call(wasm_target, RelocInfo::WASM_STUB_CALL);
} else {
Call(code_target, RelocInfo::CODE_TARGET);
}
RestoreRegisters(registers);
}
......
......@@ -229,6 +229,9 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void CallRecordWriteStub(Register object, Register address,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode);
void CallRecordWriteStub(Register object, Register address,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, Address wasm_target);
void MultiPush(RegList regs, Register location = sp);
void MultiPop(RegList regs, Register location = sp);
......@@ -1018,6 +1021,11 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void CallCFunctionHelper(Register function, int num_reg_arguments,
int num_double_arguments);
void CallRecordWriteStub(Register object, Register address,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, Handle<Code> code_target,
Address wasm_target);
void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = al);
int CalculateStackPassedWords(int num_reg_arguments,
int num_double_arguments);
......
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