[sparkplug] Use separate WriteBarrier stubs

Inline the RememberedSetAction and SaveFPMode flags directly into the
RecordWrite stubs:
- Save two register for input arguments
- Avoid branches in the RecordWrite stubs

We end up with 2 stubs for the EphemeronKeyBarrier and 4 stubs for
RecordWrite. Due to more inlined calls we have roughly 1KiB more
builtins code for RecordWrite currently. We will address this in the
future by splitting out common code into a separate stub. There is
no additional code size overhead for EphemeronKeyBarrier.

This saves 4 to 8 bytes on x64 per RecordWrite call and 2.5% sparkplug
code size reduction on d3.min.js.

Bug: v8:11420
Change-Id: Ib7170265dd6dd4b3aaf8275083f096e76fae8251
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2902731
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Andreas Haas <ahaas@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74661}
This commit is contained in:
Camillo Bruni 2021-05-19 00:02:32 +02:00 committed by V8 LUCI CQ
parent dac4a1e376
commit 2a43f8c4c7
55 changed files with 565 additions and 855 deletions

View File

@ -33,8 +33,12 @@ namespace internal {
#define BUILTIN_LIST_BASE(CPP, TFJ, TFC, TFS, TFH, ASM) \
/* GC write barrirer */ \
TFC(RecordWrite, RecordWrite) \
TFC(EphemeronKeyBarrier, EphemeronKeyBarrier) \
TFC(RecordWriteEmitRememberedSetSaveFP, WriteBarrier) \
TFC(RecordWriteOmitRememberedSetSaveFP, WriteBarrier) \
TFC(RecordWriteEmitRememberedSetIgnoreFP, WriteBarrier) \
TFC(RecordWriteOmitRememberedSetIgnoreFP, WriteBarrier) \
TFC(EphemeronKeyBarrierSaveFP, WriteBarrier) \
TFC(EphemeronKeyBarrierIgnoreFP, WriteBarrier) \
\
/* Adaptor for CPP builtin */ \
TFC(AdaptorWithBuiltinExitFrame, CppBuiltinAdaptor) \

View File

@ -113,9 +113,9 @@ TF_BUILTIN(DebugBreakTrampoline, CodeStubAssembler) {
TailCallJSCode(code, context, function, new_target, arg_count);
}
class RecordWriteCodeStubAssembler : public CodeStubAssembler {
class WriteBarrierCodeStubAssembler : public CodeStubAssembler {
public:
explicit RecordWriteCodeStubAssembler(compiler::CodeAssemblerState* state)
explicit WriteBarrierCodeStubAssembler(compiler::CodeAssemblerState* state)
: CodeStubAssembler(state) {}
TNode<BoolT> IsMarking() {
@ -172,80 +172,9 @@ class RecordWriteCodeStubAssembler : public CodeStubAssembler {
}
}
TNode<BoolT> ShouldSkipFPRegs(TNode<Smi> mode) {
return TaggedEqual(mode, SmiConstant(SaveFPRegsMode::kIgnore));
}
TNode<BoolT> ShouldEmitRememberSet(TNode<Smi> remembered_set) {
return TaggedEqual(remembered_set, SmiConstant(RememberedSetAction::kEmit));
}
template <typename Ret, typename Arg0, typename Arg1>
void CallCFunction2WithCallerSavedRegistersMode(
TNode<ExternalReference> function, TNode<Arg0> arg0, TNode<Arg1> arg1,
TNode<Smi> mode, Label* next) {
Label dont_save_fp(this), save_fp(this);
Branch(ShouldSkipFPRegs(mode), &dont_save_fp, &save_fp);
BIND(&dont_save_fp);
{
CallCFunctionWithCallerSavedRegisters(
function, MachineTypeOf<Ret>::value, SaveFPRegsMode::kIgnore,
std::make_pair(MachineTypeOf<Arg0>::value, arg0),
std::make_pair(MachineTypeOf<Arg1>::value, arg1));
Goto(next);
}
BIND(&save_fp);
{
CallCFunctionWithCallerSavedRegisters(
function, MachineTypeOf<Ret>::value, SaveFPRegsMode::kSave,
std::make_pair(MachineTypeOf<Arg0>::value, arg0),
std::make_pair(MachineTypeOf<Arg1>::value, arg1));
Goto(next);
}
}
template <typename Ret, typename Arg0, typename Arg1, typename Arg2>
void CallCFunction3WithCallerSavedRegistersMode(
TNode<ExternalReference> function, TNode<Arg0> arg0, TNode<Arg1> arg1,
TNode<Arg2> arg2, TNode<Smi> mode, Label* next) {
Label dont_save_fp(this), save_fp(this);
Branch(ShouldSkipFPRegs(mode), &dont_save_fp, &save_fp);
BIND(&dont_save_fp);
{
CallCFunctionWithCallerSavedRegisters(
function, MachineTypeOf<Ret>::value, SaveFPRegsMode::kIgnore,
std::make_pair(MachineTypeOf<Arg0>::value, arg0),
std::make_pair(MachineTypeOf<Arg1>::value, arg1),
std::make_pair(MachineTypeOf<Arg2>::value, arg2));
Goto(next);
}
BIND(&save_fp);
{
CallCFunctionWithCallerSavedRegisters(
function, MachineTypeOf<Ret>::value, SaveFPRegsMode::kSave,
std::make_pair(MachineTypeOf<Arg0>::value, arg0),
std::make_pair(MachineTypeOf<Arg1>::value, arg1),
std::make_pair(MachineTypeOf<Arg2>::value, arg2));
Goto(next);
}
}
void InsertIntoRememberedSetAndGotoSlow(TNode<IntPtrT> object,
TNode<IntPtrT> slot, TNode<Smi> mode,
Label* next) {
TNode<IntPtrT> page = PageFromAddress(object);
TNode<ExternalReference> function =
ExternalConstant(ExternalReference::insert_remembered_set_function());
CallCFunction2WithCallerSavedRegistersMode<Int32T, IntPtrT, IntPtrT>(
function, page, slot, mode, next);
}
void InsertIntoRememberedSetAndGoto(TNode<IntPtrT> object,
TNode<IntPtrT> slot, TNode<Smi> mode,
Label* next) {
Label slow_path(this);
void InsertIntoRememberedSet(TNode<IntPtrT> object, TNode<IntPtrT> slot,
SaveFPRegsMode fp_mode) {
Label slow_path(this), next(this);
TNode<IntPtrT> page = PageFromAddress(object);
// Load address of SlotSet
@ -257,11 +186,20 @@ class RecordWriteCodeStubAssembler : public CodeStubAssembler {
// Update cell
SetBitInCell(bucket, slot_offset);
Goto(next);
Goto(&next);
BIND(&slow_path);
InsertIntoRememberedSetAndGotoSlow(object, slot, mode, next);
{
TNode<ExternalReference> function =
ExternalConstant(ExternalReference::insert_remembered_set_function());
CallCFunctionWithCallerSavedRegisters(
function, MachineTypeOf<Int32T>::value, fp_mode,
std::make_pair(MachineTypeOf<IntPtrT>::value, page),
std::make_pair(MachineTypeOf<IntPtrT>::value, slot));
Goto(&next);
}
BIND(&next);
}
TNode<IntPtrT> LoadSlotSet(TNode<IntPtrT> page, Label* slow_path) {
@ -269,7 +207,6 @@ class RecordWriteCodeStubAssembler : public CodeStubAssembler {
Load(MachineType::Pointer(), page,
IntPtrConstant(MemoryChunk::kOldToNewSlotSetOffset)));
GotoIf(WordEqual(slot_set, IntPtrConstant(0)), slow_path);
return slot_set;
}
@ -306,32 +243,19 @@ class RecordWriteCodeStubAssembler : public CodeStubAssembler {
StoreNoWriteBarrier(MachineRepresentation::kWord32, cell_address,
TruncateIntPtrToInt32(new_cell_value));
}
};
TF_BUILTIN(RecordWrite, RecordWriteCodeStubAssembler) {
Label generational_wb(this);
Label incremental_wb(this);
Label exit(this);
// In this method we limit the allocatable registers so we have to use
// UncheckedParameter. Parameter does not work because the checked cast needs
// more registers.
auto remembered_set = UncheckedParameter<Smi>(Descriptor::kRememberedSet);
Branch(ShouldEmitRememberSet(remembered_set), &generational_wb,
&incremental_wb);
BIND(&generational_wb);
{
Label test_old_to_young_flags(this);
Label store_buffer_exit(this), store_buffer_incremental_wb(this);
void GenerationalWriteBarrier(SaveFPRegsMode fp_mode) {
Label incremental_wb(this), test_old_to_young_flags(this),
store_buffer_exit(this), store_buffer_incremental_wb(this), next(this);
// When incremental marking is not on, we skip cross generation pointer
// checking here, because there are checks for
// `kPointersFromHereAreInterestingMask` and
// `kPointersToHereAreInterestingMask` in
// `src/compiler/<arch>/code-generator-<arch>.cc` before calling this stub,
// which serves as the cross generation checking.
auto slot = UncheckedParameter<IntPtrT>(Descriptor::kSlot);
// `src/compiler/<arch>/code-generator-<arch>.cc` before calling this
// stub, which serves as the cross generation checking.
auto slot =
UncheckedParameter<IntPtrT>(WriteBarrierDescriptor::kSlotAddress);
Branch(IsMarking(), &test_old_to_young_flags, &store_buffer_exit);
BIND(&test_old_to_young_flags);
@ -339,14 +263,14 @@ TF_BUILTIN(RecordWrite, RecordWriteCodeStubAssembler) {
// TODO(ishell): do a new-space range check instead.
TNode<IntPtrT> value = BitcastTaggedToWord(Load<HeapObject>(slot));
// TODO(albertnetymk): Try to cache the page flag for value and object,
// instead of calling IsPageFlagSet each time.
// TODO(albertnetymk): Try to cache the page flag for value and
// object, instead of calling IsPageFlagSet each time.
TNode<BoolT> value_is_young =
IsPageFlagSet(value, MemoryChunk::kIsInYoungGenerationMask);
GotoIfNot(value_is_young, &incremental_wb);
TNode<IntPtrT> object =
BitcastTaggedToWord(UncheckedParameter<Object>(Descriptor::kObject));
TNode<IntPtrT> object = BitcastTaggedToWord(
UncheckedParameter<Object>(WriteBarrierDescriptor::kObject));
TNode<BoolT> object_is_young =
IsPageFlagSet(object, MemoryChunk::kIsInYoungGenerationMask);
Branch(object_is_young, &incremental_wb, &store_buffer_incremental_wb);
@ -354,27 +278,40 @@ TF_BUILTIN(RecordWrite, RecordWriteCodeStubAssembler) {
BIND(&store_buffer_exit);
{
auto fp_mode = UncheckedParameter<Smi>(Descriptor::kFPMode);
TNode<IntPtrT> object =
BitcastTaggedToWord(UncheckedParameter<Object>(Descriptor::kObject));
InsertIntoRememberedSetAndGoto(object, slot, fp_mode, &exit);
TNode<IntPtrT> object = BitcastTaggedToWord(
UncheckedParameter<Object>(WriteBarrierDescriptor::kObject));
InsertIntoRememberedSet(object, slot, fp_mode);
Goto(&next);
}
BIND(&store_buffer_incremental_wb);
{
auto fp_mode = UncheckedParameter<Smi>(Descriptor::kFPMode);
TNode<IntPtrT> object =
BitcastTaggedToWord(UncheckedParameter<Object>(Descriptor::kObject));
InsertIntoRememberedSetAndGoto(object, slot, fp_mode, &incremental_wb);
TNode<IntPtrT> object = BitcastTaggedToWord(
UncheckedParameter<Object>(WriteBarrierDescriptor::kObject));
InsertIntoRememberedSet(object, slot, fp_mode);
Goto(&incremental_wb);
}
BIND(&incremental_wb);
{
TNode<IntPtrT> value = BitcastTaggedToWord(Load<HeapObject>(slot));
IncrementalWriteBarrier(slot, value, fp_mode);
Goto(&next);
}
BIND(&next);
}
BIND(&incremental_wb);
{
Label call_incremental_wb(this);
auto slot = UncheckedParameter<IntPtrT>(Descriptor::kSlot);
void IncrementalWriteBarrier(SaveFPRegsMode fp_mode) {
auto slot =
UncheckedParameter<IntPtrT>(WriteBarrierDescriptor::kSlotAddress);
TNode<IntPtrT> value = BitcastTaggedToWord(Load<HeapObject>(slot));
IncrementalWriteBarrier(slot, value, fp_mode);
}
void IncrementalWriteBarrier(TNode<IntPtrT> slot, TNode<IntPtrT> value,
SaveFPRegsMode fp_mode) {
Label call_incremental_wb(this), next(this);
// There are two cases we need to call incremental write barrier.
// 1) value_is_white
@ -383,52 +320,92 @@ TF_BUILTIN(RecordWrite, RecordWriteCodeStubAssembler) {
// 2) is_compacting && value_in_EC && obj_isnt_skip
// is_compacting = true when is_marking = true
GotoIfNot(IsPageFlagSet(value, MemoryChunk::kEvacuationCandidateMask),
&exit);
&next);
TNode<IntPtrT> object =
BitcastTaggedToWord(UncheckedParameter<Object>(Descriptor::kObject));
TNode<IntPtrT> object = BitcastTaggedToWord(
UncheckedParameter<Object>(WriteBarrierDescriptor::kObject));
Branch(
IsPageFlagSet(object, MemoryChunk::kSkipEvacuationSlotsRecordingMask),
&exit, &call_incremental_wb);
&next, &call_incremental_wb);
BIND(&call_incremental_wb);
{
TNode<ExternalReference> function = ExternalConstant(
ExternalReference::write_barrier_marking_from_code_function());
auto fp_mode = UncheckedParameter<Smi>(Descriptor::kFPMode);
TNode<IntPtrT> object =
BitcastTaggedToWord(UncheckedParameter<Object>(Descriptor::kObject));
CallCFunction2WithCallerSavedRegistersMode<Int32T, IntPtrT, IntPtrT>(
function, object, slot, fp_mode, &exit);
TNode<IntPtrT> object = BitcastTaggedToWord(
UncheckedParameter<Object>(WriteBarrierDescriptor::kObject));
CallCFunctionWithCallerSavedRegisters(
function, MachineTypeOf<Int32T>::value, fp_mode,
std::make_pair(MachineTypeOf<IntPtrT>::value, object),
std::make_pair(MachineTypeOf<IntPtrT>::value, slot));
Goto(&next);
}
BIND(&next);
}
BIND(&exit);
IncrementCounter(isolate()->counters()->write_barriers(), 1);
Return(TrueConstant());
void GenerateRecordWrite(RememberedSetAction rs_mode,
SaveFPRegsMode fp_mode) {
switch (rs_mode) {
case RememberedSetAction::kEmit:
GenerationalWriteBarrier(fp_mode);
break;
case RememberedSetAction::kOmit:
IncrementalWriteBarrier(fp_mode);
break;
}
IncrementCounter(isolate()->counters()->write_barriers(), 1);
Return(TrueConstant());
}
void GenerateEphemeronKeyBarrier(SaveFPRegsMode fp_mode) {
TNode<ExternalReference> function = ExternalConstant(
ExternalReference::ephemeron_key_write_barrier_function());
TNode<ExternalReference> isolate_constant =
ExternalConstant(ExternalReference::isolate_address(isolate()));
// In this method we limit the allocatable registers so we have to use
// UncheckedParameter. Parameter does not work because the checked cast
// needs more registers.
auto address =
UncheckedParameter<IntPtrT>(WriteBarrierDescriptor::kSlotAddress);
TNode<IntPtrT> object = BitcastTaggedToWord(
UncheckedParameter<Object>(WriteBarrierDescriptor::kObject));
CallCFunctionWithCallerSavedRegisters(
function, MachineTypeOf<Int32T>::value, fp_mode,
std::make_pair(MachineTypeOf<IntPtrT>::value, object),
std::make_pair(MachineTypeOf<IntPtrT>::value, address),
std::make_pair(MachineTypeOf<ExternalReference>::value,
isolate_constant));
IncrementCounter(isolate()->counters()->write_barriers(), 1);
Return(TrueConstant());
}
};
TF_BUILTIN(RecordWriteEmitRememberedSetSaveFP, WriteBarrierCodeStubAssembler) {
GenerateRecordWrite(RememberedSetAction::kEmit, SaveFPRegsMode::kSave);
}
TF_BUILTIN(EphemeronKeyBarrier, RecordWriteCodeStubAssembler) {
Label exit(this);
TF_BUILTIN(RecordWriteOmitRememberedSetSaveFP, WriteBarrierCodeStubAssembler) {
GenerateRecordWrite(RememberedSetAction::kOmit, SaveFPRegsMode::kSave);
}
TNode<ExternalReference> function = ExternalConstant(
ExternalReference::ephemeron_key_write_barrier_function());
TNode<ExternalReference> isolate_constant =
ExternalConstant(ExternalReference::isolate_address(isolate()));
// In this method we limit the allocatable registers so we have to use
// UncheckedParameter. Parameter does not work because the checked cast needs
// more registers.
auto address = UncheckedParameter<IntPtrT>(Descriptor::kSlotAddress);
TNode<IntPtrT> object =
BitcastTaggedToWord(UncheckedParameter<Object>(Descriptor::kObject));
TNode<Smi> fp_mode = UncheckedParameter<Smi>(Descriptor::kFPMode);
CallCFunction3WithCallerSavedRegistersMode<Int32T, IntPtrT, IntPtrT,
ExternalReference>(
function, object, address, isolate_constant, fp_mode, &exit);
TF_BUILTIN(RecordWriteEmitRememberedSetIgnoreFP,
WriteBarrierCodeStubAssembler) {
GenerateRecordWrite(RememberedSetAction::kEmit, SaveFPRegsMode::kIgnore);
}
BIND(&exit);
IncrementCounter(isolate()->counters()->write_barriers(), 1);
Return(TrueConstant());
TF_BUILTIN(RecordWriteOmitRememberedSetIgnoreFP,
WriteBarrierCodeStubAssembler) {
GenerateRecordWrite(RememberedSetAction::kOmit, SaveFPRegsMode::kIgnore);
}
TF_BUILTIN(EphemeronKeyBarrierSaveFP, WriteBarrierCodeStubAssembler) {
GenerateEphemeronKeyBarrier(SaveFPRegsMode::kSave);
}
TF_BUILTIN(EphemeronKeyBarrierIgnoreFP, WriteBarrierCodeStubAssembler) {
GenerateEphemeronKeyBarrier(SaveFPRegsMode::kIgnore);
}
class DeletePropertyBaseAssembler : public AccessorAssembler {

View File

@ -83,6 +83,37 @@ class Builtins {
static BytecodeOffset GetContinuationBytecodeOffset(Name name);
static Name GetBuiltinFromBytecodeOffset(BytecodeOffset);
static Name GetRecordWriteStub(RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode) {
switch (remembered_set_action) {
case RememberedSetAction::kEmit:
switch (fp_mode) {
case SaveFPRegsMode::kIgnore:
return Builtins::kRecordWriteEmitRememberedSetIgnoreFP;
case SaveFPRegsMode::kSave:
return Builtins::kRecordWriteEmitRememberedSetSaveFP;
}
case RememberedSetAction::kOmit:
switch (fp_mode) {
case SaveFPRegsMode::kIgnore:
return Builtins::kRecordWriteOmitRememberedSetIgnoreFP;
case SaveFPRegsMode::kSave:
return Builtins::kRecordWriteOmitRememberedSetSaveFP;
}
}
UNREACHABLE();
}
static constexpr Name GetEphemeronKeyBarrierStub(SaveFPRegsMode fp_mode) {
switch (fp_mode) {
case SaveFPRegsMode::kIgnore:
return Builtins::kEphemeronKeyBarrierIgnoreFP;
case SaveFPRegsMode::kSave:
return Builtins::kEphemeronKeyBarrierSaveFP;
}
UNREACHABLE();
}
// Convenience wrappers.
Handle<Code> CallFunction(ConvertReceiverMode = ConvertReceiverMode::kAny);
Handle<Code> Call(ConvertReceiverMode = ConvertReceiverMode::kAny);

View File

@ -20,7 +20,7 @@ constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
}
// static
constexpr auto RecordWriteDescriptor::registers() {
constexpr auto WriteBarrierDescriptor::registers() {
return RegisterArray(r0, r1, r2, r3, r4, kReturnRegister0);
}
@ -29,11 +29,6 @@ constexpr auto DynamicCheckMapsDescriptor::registers() {
return RegisterArray(r0, r1, r2, r3, cp);
}
// static
constexpr auto EphemeronKeyBarrierDescriptor::registers() {
return RegisterArray(r0, r1, r2, r3, r4, kReturnRegister0);
}
// static
constexpr Register LoadDescriptor::ReceiverRegister() { return r1; }
// static

View File

@ -711,75 +711,51 @@ void TurboAssembler::RestoreRegisters(RegList registers) {
void TurboAssembler::CallEphemeronKeyBarrier(Register object, Operand offset,
SaveFPRegsMode fp_mode) {
EphemeronKeyBarrierDescriptor descriptor;
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kObject));
Register slot_parameter(descriptor.GetRegisterParameter(
EphemeronKeyBarrierDescriptor::kSlotAddress));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
MoveObjectAndSlot(object_parameter, slot_parameter, object, offset);
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
Call(isolate()->builtins()->builtin_handle(Builtins::kEphemeronKeyBarrier),
Call(isolate()->builtins()->builtin_handle(
Builtins::GetEphemeronKeyBarrierStub(fp_mode)),
RelocInfo::CODE_TARGET);
RestoreRegisters(registers);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Operand offset, RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode) {
CallRecordWriteStub(object, offset, remembered_set_action, fp_mode,
Builtins::kRecordWrite, kNullAddress);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Operand offset, RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, Address wasm_target) {
CallRecordWriteStub(object, offset, remembered_set_action, fp_mode,
Builtins::kNoBuiltinId, wasm_target);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Operand offset, RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, int builtin_index, Address wasm_target) {
DCHECK_NE(builtin_index == Builtins::kNoBuiltinId,
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.
RecordWriteDescriptor descriptor;
SaveFPRegsMode fp_mode, StubCallMode mode) {
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kObject));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kSlot));
Register remembered_set_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kRememberedSet));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
MoveObjectAndSlot(object_parameter, slot_parameter, object, offset);
Move(remembered_set_parameter, Smi::FromEnum(remembered_set_action));
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
if (builtin_index == Builtins::kNoBuiltinId) {
if (mode == StubCallMode::kCallWasmRuntimeStub) {
auto wasm_target =
wasm::WasmCode::GetRecordWriteStub(remembered_set_action, fp_mode);
Call(wasm_target, RelocInfo::WASM_STUB_CALL);
} else if (options().inline_offheap_trampolines) {
CallBuiltin(builtin_index);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(Builtins::kRecordWrite);
Call(code_target, RelocInfo::CODE_TARGET);
auto builtin_index =
Builtins::GetRecordWriteStub(remembered_set_action, fp_mode);
if (options().inline_offheap_trampolines) {
CallBuiltin(builtin_index);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(builtin_index);
Call(code_target, RelocInfo::CODE_TARGET);
}
}
RestoreRegisters(registers);

View File

@ -377,15 +377,14 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void SaveRegisters(RegList registers);
void RestoreRegisters(RegList registers);
void CallRecordWriteStub(Register object, Operand offset,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode);
void CallRecordWriteStub(Register object, Operand offset,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, Address wasm_target);
void CallEphemeronKeyBarrier(Register object, Operand offset,
SaveFPRegsMode fp_mode);
void CallRecordWriteStub(
Register object, Operand offset,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
StubCallMode mode = StubCallMode::kCallBuiltinPointer);
// For a given |object| and |offset|:
// - Move |object| to |dst_object|.
// - Compute the address of the slot pointed to by |offset| in |object| and
@ -622,11 +621,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void CallCFunctionHelper(Register function, int num_reg_arguments,
int num_double_arguments);
void CallRecordWriteStub(Register object, Operand offset,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, int builtin_index,
Address wasm_target);
};
// MacroAssembler implements a collection of frequently used macros.

View File

@ -21,7 +21,7 @@ constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
}
// static
constexpr auto RecordWriteDescriptor::registers() {
constexpr auto WriteBarrierDescriptor::registers() {
return RegisterArray(x0, x1, x2, x3, x4, kReturnRegister0);
}
@ -30,11 +30,6 @@ constexpr auto DynamicCheckMapsDescriptor::registers() {
return RegisterArray(x0, x1, x2, x3, cp);
}
// static
constexpr auto EphemeronKeyBarrierDescriptor::registers() {
return RegisterArray(x0, x1, x2, x3, x4, kReturnRegister0);
}
// static
constexpr Register LoadDescriptor::ReceiverRegister() { return x1; }
// static

View File

@ -2943,76 +2943,52 @@ void TurboAssembler::RestoreRegisters(RegList registers) {
void TurboAssembler::CallEphemeronKeyBarrier(Register object, Operand offset,
SaveFPRegsMode fp_mode) {
EphemeronKeyBarrierDescriptor descriptor;
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kObject));
Register slot_parameter(descriptor.GetRegisterParameter(
EphemeronKeyBarrierDescriptor::kSlotAddress));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
MoveObjectAndSlot(object_parameter, slot_parameter, object, offset);
Mov(fp_mode_parameter, Smi::FromEnum(fp_mode));
Call(isolate()->builtins()->builtin_handle(Builtins::kEphemeronKeyBarrier),
Call(isolate()->builtins()->builtin_handle(
Builtins::GetEphemeronKeyBarrierStub(fp_mode)),
RelocInfo::CODE_TARGET);
RestoreRegisters(registers);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Operand offset, RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode) {
CallRecordWriteStub(object, offset, remembered_set_action, fp_mode,
Builtins::kRecordWrite, kNullAddress);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Operand offset, RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, Address wasm_target) {
CallRecordWriteStub(object, offset, remembered_set_action, fp_mode,
Builtins::kNoBuiltinId, wasm_target);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Operand offset, RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, int builtin_index, Address wasm_target) {
DCHECK_NE(builtin_index == Builtins::kNoBuiltinId,
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.
RecordWriteDescriptor descriptor;
SaveFPRegsMode fp_mode, StubCallMode mode) {
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kObject));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kSlot));
Register remembered_set_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kRememberedSet));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
MoveObjectAndSlot(object_parameter, slot_parameter, object, offset);
Mov(remembered_set_parameter, Smi::FromEnum(remembered_set_action));
Mov(fp_mode_parameter, Smi::FromEnum(fp_mode));
if (builtin_index == Builtins::kNoBuiltinId) {
if (mode == StubCallMode::kCallWasmRuntimeStub) {
auto wasm_target =
wasm::WasmCode::GetRecordWriteStub(remembered_set_action, fp_mode);
Call(wasm_target, RelocInfo::WASM_STUB_CALL);
} else if (options().inline_offheap_trampolines) {
CallBuiltin(builtin_index);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(Builtins::kRecordWrite);
Call(code_target, RelocInfo::CODE_TARGET);
auto builtin_index =
Builtins::GetRecordWriteStub(remembered_set_action, fp_mode);
if (options().inline_offheap_trampolines) {
CallBuiltin(builtin_index);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(builtin_index);
Call(code_target, RelocInfo::CODE_TARGET);
}
}
RestoreRegisters(registers);

View File

@ -840,15 +840,14 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void SaveRegisters(RegList registers);
void RestoreRegisters(RegList registers);
void CallRecordWriteStub(Register object, Operand offset,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode);
void CallRecordWriteStub(Register object, Operand offset,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, Address wasm_target);
void CallEphemeronKeyBarrier(Register object, Operand offset,
SaveFPRegsMode fp_mode);
void CallRecordWriteStub(
Register object, Operand offset,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
StubCallMode mode = StubCallMode::kCallBuiltinPointer);
// For a given |object| and |offset|:
// - Move |object| to |dst_object|.
// - Compute the address of the slot pointed to by |offset| in |object| and
@ -1462,11 +1461,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
byte* pc);
void JumpHelper(int64_t offset, RelocInfo::Mode rmode, Condition cond = al);
void CallRecordWriteStub(Register object, Operand offset,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, int builtin_index,
Address wasm_target);
};
class V8_EXPORT_PRIVATE MacroAssembler : public TurboAssembler {

View File

@ -19,7 +19,7 @@ constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
}
// static
constexpr auto RecordWriteDescriptor::registers() {
constexpr auto WriteBarrierDescriptor::registers() {
return RegisterArray(ecx, edx, esi, edi, kReturnRegister0);
}
@ -28,11 +28,6 @@ constexpr auto DynamicCheckMapsDescriptor::registers() {
return RegisterArray(eax, ecx, edx, edi, esi);
}
// static
constexpr auto EphemeronKeyBarrierDescriptor::registers() {
return RegisterArray(ecx, edx, esi, edi, kReturnRegister0);
}
// static
constexpr Register LoadDescriptor::ReceiverRegister() { return edx; }
// static

View File

@ -415,17 +415,15 @@ void TurboAssembler::RestoreRegisters(RegList registers) {
void TurboAssembler::CallEphemeronKeyBarrier(Register object, Register address,
SaveFPRegsMode fp_mode) {
EphemeronKeyBarrierDescriptor descriptor;
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kObject));
Register slot_parameter(descriptor.GetRegisterParameter(
EphemeronKeyBarrierDescriptor::kSlotAddress));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
push(object);
push(address);
@ -433,52 +431,25 @@ void TurboAssembler::CallEphemeronKeyBarrier(Register object, Register address,
pop(slot_parameter);
pop(object_parameter);
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
Call(isolate()->builtins()->builtin_handle(Builtins::kEphemeronKeyBarrier),
Call(isolate()->builtins()->builtin_handle(
Builtins::GetEphemeronKeyBarrierStub(fp_mode)),
RelocInfo::CODE_TARGET);
RestoreRegisters(registers);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode) {
CallRecordWriteStub(object, address, remembered_set_action, fp_mode,
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,
Builtins::kNoBuiltinId, wasm_target);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
int builtin_index, Address wasm_target) {
DCHECK_NE(builtin_index == Builtins::kNoBuiltinId,
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.
RecordWriteDescriptor descriptor;
StubCallMode mode) {
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kObject));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kSlot));
Register remembered_set_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kRememberedSet));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
push(object);
push(address);
@ -486,17 +457,21 @@ void TurboAssembler::CallRecordWriteStub(
pop(slot_parameter);
pop(object_parameter);
Move(remembered_set_parameter, Smi::FromEnum(remembered_set_action));
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
if (builtin_index == Builtins::kNoBuiltinId) {
if (mode == StubCallMode::kCallWasmRuntimeStub) {
// Use {wasm_call} for direct Wasm call within a module.
auto wasm_target =
wasm::WasmCode::GetRecordWriteStub(remembered_set_action, fp_mode);
wasm_call(wasm_target, RelocInfo::WASM_STUB_CALL);
} else if (options().inline_offheap_trampolines) {
CallBuiltin(builtin_index);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(Builtins::kRecordWrite);
Call(code_target, RelocInfo::CODE_TARGET);
auto builtin_index =
Builtins::GetRecordWriteStub(remembered_set_action, fp_mode);
if (options().inline_offheap_trampolines) {
CallBuiltin(builtin_index);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(builtin_index);
Call(code_target, RelocInfo::CODE_TARGET);
}
}
RestoreRegisters(registers);

View File

@ -440,15 +440,14 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler {
void SaveRegisters(RegList registers);
void RestoreRegisters(RegList registers);
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 CallEphemeronKeyBarrier(Register object, Register address,
SaveFPRegsMode fp_mode);
void CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
StubCallMode mode = StubCallMode::kCallBuiltinPointer);
// Calculate how much stack space (in bytes) are required to store caller
// registers excluding those specified in the arguments.
int RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
@ -488,11 +487,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler {
void ExceptionHandler() {}
// Define an exception handler and bind a label.
void BindExceptionHandler(Label* label) { bind(label); }
void CallRecordWriteStub(Register object, Register address,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, int builtin_index,
Address wasm_target);
};
// MacroAssembler implements a collection of frequently used macros.

View File

@ -67,7 +67,6 @@ namespace internal {
V(ContextOnly) \
V(CppBuiltinAdaptor) \
V(DynamicCheckMaps) \
V(EphemeronKeyBarrier) \
V(FastNewObject) \
V(ForInPrepare) \
V(GetIteratorStackParameter) \
@ -96,7 +95,6 @@ namespace internal {
V(LoadWithReceiverBaseline) \
V(LookupBaseline) \
V(NoContext) \
V(RecordWrite) \
V(ResumeGenerator) \
V(SuspendGeneratorBaseline) \
V(ResumeGeneratorBaseline) \
@ -124,6 +122,7 @@ namespace internal {
V(WasmFloat64ToNumber) \
V(WasmI32AtomicWait32) \
V(WasmI64AtomicWait32) \
V(WriteBarrier) \
BUILTIN_LIST_TFS(V) \
TORQUE_BUILTIN_LIST_TFC(V)
@ -992,31 +991,14 @@ class FastNewObjectDescriptor
static constexpr auto registers();
};
class RecordWriteDescriptor final
: public StaticCallInterfaceDescriptor<RecordWriteDescriptor> {
class WriteBarrierDescriptor final
: public StaticCallInterfaceDescriptor<WriteBarrierDescriptor> {
public:
DEFINE_PARAMETERS_NO_CONTEXT(kObject, kSlot, kRememberedSet, kFPMode)
DEFINE_PARAMETERS_NO_CONTEXT(kObject, kSlotAddress)
DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(), // kObject
MachineType::Pointer(), // kSlot
MachineType::TaggedSigned(), // kRememberedSet
MachineType::TaggedSigned()) // kFPMode
DECLARE_DESCRIPTOR(RecordWriteDescriptor)
static constexpr auto registers();
static constexpr bool kRestrictAllocatableRegisters = true;
};
class EphemeronKeyBarrierDescriptor final
: public StaticCallInterfaceDescriptor<EphemeronKeyBarrierDescriptor> {
public:
DEFINE_PARAMETERS_NO_CONTEXT(kObject, kSlotAddress, kFPMode)
DEFINE_PARAMETER_TYPES(MachineType::TaggedPointer(), // kObject
MachineType::Pointer(), // kSlotAddress
MachineType::TaggedSigned()) // kFPMode
DECLARE_DESCRIPTOR(EphemeronKeyBarrierDescriptor)
MachineType::Pointer()) // kSlotAddress
DECLARE_DESCRIPTOR(WriteBarrierDescriptor)
static constexpr auto registers();
static constexpr bool kRestrictAllocatableRegisters = true;
};

View File

@ -28,8 +28,6 @@ enum AllocationFlags {
PRETENURE = 1 << 3,
};
enum class RememberedSetAction { kOmit, kEmit };
enum class SmiCheck { kOmit, kInline };
// This is the only place allowed to include the platform-specific headers.

View File

@ -20,7 +20,7 @@ constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
}
// static
constexpr auto RecordWriteDescriptor::registers() {
constexpr auto WriteBarrierDescriptor::registers() {
return RegisterArray(a0, a1, a2, a3, kReturnRegister0);
}
@ -29,11 +29,6 @@ constexpr auto DynamicCheckMapsDescriptor::registers() {
return RegisterArray(kReturnRegister0, a0, a1, a2, cp);
}
// static
constexpr auto EphemeronKeyBarrierDescriptor::registers() {
return RegisterArray(a0, a1, a2, a3, kReturnRegister0);
}
// static
constexpr Register LoadDescriptor::ReceiverRegister() { return a1; }
// static

View File

@ -235,17 +235,15 @@ void TurboAssembler::RestoreRegisters(RegList registers) {
void TurboAssembler::CallEphemeronKeyBarrier(Register object, Register address,
SaveFPRegsMode fp_mode) {
EphemeronKeyBarrierDescriptor descriptor;
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kObject));
Register slot_parameter(descriptor.GetRegisterParameter(
EphemeronKeyBarrierDescriptor::kSlotAddress));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
Push(object);
Push(address);
@ -253,50 +251,24 @@ void TurboAssembler::CallEphemeronKeyBarrier(Register object, Register address,
Pop(slot_parameter);
Pop(object_parameter);
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
Call(isolate()->builtins()->builtin_handle(Builtins::kEphemeronKeyBarrier),
Call(isolate()->builtins()->builtin_handle(
Builtins::GetEphemeronKeyBarrierStub(fp_mode)),
RelocInfo::CODE_TARGET);
RestoreRegisters(registers);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode) {
CallRecordWriteStub(object, address, remembered_set_action, fp_mode,
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,
Builtins::kNoBuiltinId, wasm_target);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
int builtin_index, Address wasm_target) {
DCHECK_NE(builtin_index == Builtins::kNoBuiltinId,
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.
RecordWriteDescriptor descriptor;
StubCallMode mode) {
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kObject));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kSlot));
Register remembered_set_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kRememberedSet));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
Push(object);
Push(address);
@ -304,23 +276,27 @@ void TurboAssembler::CallRecordWriteStub(
Pop(slot_parameter);
Pop(object_parameter);
Move(remembered_set_parameter, Smi::FromEnum(remembered_set_action));
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
if (builtin_index == Builtins::kNoBuiltinId) {
if (mode == StubCallMode::kCallWasmRuntimeStub) {
auto wasm_target =
wasm::WasmCode::GetRecordWriteStub(remembered_set_action, fp_mode);
Call(wasm_target, RelocInfo::WASM_STUB_CALL);
} else if (options().inline_offheap_trampolines) {
// Inline the trampoline.
DCHECK(Builtins::IsBuiltinId(builtin_index));
RecordCommentForOffHeapTrampoline(builtin_index);
CHECK_NE(builtin_index, Builtins::kNoBuiltinId);
EmbeddedData d = EmbeddedData::FromBlob();
Address entry = d.InstructionStartOfBuiltin(builtin_index);
li(t9, Operand(entry, RelocInfo::OFF_HEAP_TARGET));
Call(t9);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(Builtins::kRecordWrite);
Call(code_target, RelocInfo::CODE_TARGET);
auto builtin_index =
Builtins::GetRecordWriteStub(remembered_set_action, fp_mode);
if (options().inline_offheap_trampolines) {
// Inline the trampoline.
DCHECK(Builtins::IsBuiltinId(builtin_index));
RecordCommentForOffHeapTrampoline(builtin_index);
CHECK_NE(builtin_index, Builtins::kNoBuiltinId);
EmbeddedData d = EmbeddedData::FromBlob();
Address entry = d.InstructionStartOfBuiltin(builtin_index);
li(t9, Operand(entry, RelocInfo::OFF_HEAP_TARGET));
Call(t9);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(builtin_index);
Call(code_target, RelocInfo::CODE_TARGET);
}
}
RestoreRegisters(registers);

View File

@ -325,15 +325,14 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void SaveRegisters(RegList registers);
void RestoreRegisters(RegList registers);
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 CallEphemeronKeyBarrier(Register object, Register address,
SaveFPRegsMode fp_mode);
void CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
StubCallMode mode = StubCallMode::kCallBuiltinPointer);
// Push multiple registers on the stack.
// Registers are saved in numerical order, with higher numbered registers
// saved in higher memory addresses.
@ -905,11 +904,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
// Push a fixed frame, consisting of ra, fp.
void PushCommonFrame(Register marker_reg = no_reg);
void CallRecordWriteStub(Register object, Register address,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, int builtin_index,
Address wasm_target);
};
// MacroAssembler implements a collection of frequently used macros.

View File

@ -20,7 +20,7 @@ constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
}
// static
constexpr auto RecordWriteDescriptor::registers() {
constexpr auto WriteBarrierDescriptor::registers() {
return RegisterArray(a0, a1, a2, a3, kReturnRegister0);
}
@ -29,11 +29,6 @@ constexpr auto DynamicCheckMapsDescriptor::registers() {
return RegisterArray(kReturnRegister0, a0, a1, a2, cp);
}
// static
constexpr auto EphemeronKeyBarrierDescriptor::registers() {
return RegisterArray(a0, a1, a2, a3, kReturnRegister0);
}
// static
constexpr Register LoadDescriptor::ReceiverRegister() { return a1; }
// static

View File

@ -233,17 +233,15 @@ void TurboAssembler::RestoreRegisters(RegList registers) {
void TurboAssembler::CallEphemeronKeyBarrier(Register object, Register address,
SaveFPRegsMode fp_mode) {
EphemeronKeyBarrierDescriptor descriptor;
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kObject));
Register slot_parameter(descriptor.GetRegisterParameter(
EphemeronKeyBarrierDescriptor::kSlotAddress));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
Push(object);
Push(address);
@ -251,50 +249,24 @@ void TurboAssembler::CallEphemeronKeyBarrier(Register object, Register address,
Pop(slot_parameter);
Pop(object_parameter);
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
Call(isolate()->builtins()->builtin_handle(Builtins::kEphemeronKeyBarrier),
Call(isolate()->builtins()->builtin_handle(
Builtins::GetEphemeronKeyBarrierStub(fp_mode)),
RelocInfo::CODE_TARGET);
RestoreRegisters(registers);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode) {
CallRecordWriteStub(object, address, remembered_set_action, fp_mode,
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,
Builtins::kNoBuiltinId, wasm_target);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
int builtin_index, Address wasm_target) {
DCHECK_NE(builtin_index == Builtins::kNoBuiltinId,
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.
RecordWriteDescriptor descriptor;
StubCallMode mode) {
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kObject));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kSlot));
Register remembered_set_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kRememberedSet));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
Push(object);
Push(address);
@ -302,23 +274,27 @@ void TurboAssembler::CallRecordWriteStub(
Pop(slot_parameter);
Pop(object_parameter);
Move(remembered_set_parameter, Smi::FromEnum(remembered_set_action));
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
if (builtin_index == Builtins::kNoBuiltinId) {
if (mode == StubCallMode::kCallWasmRuntimeStub) {
auto wasm_target =
wasm::WasmCode::GetRecordWriteStub(remembered_set_action, fp_mode);
Call(wasm_target, RelocInfo::WASM_STUB_CALL);
} else if (options().inline_offheap_trampolines) {
// Inline the trampoline.
DCHECK(Builtins::IsBuiltinId(builtin_index));
RecordCommentForOffHeapTrampoline(builtin_index);
CHECK_NE(builtin_index, Builtins::kNoBuiltinId);
EmbeddedData d = EmbeddedData::FromBlob();
Address entry = d.InstructionStartOfBuiltin(builtin_index);
li(t9, Operand(entry, RelocInfo::OFF_HEAP_TARGET));
Call(t9);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(Builtins::kRecordWrite);
Call(code_target, RelocInfo::CODE_TARGET);
auto builtin_index =
Builtins::GetRecordWriteStub(remembered_set_action, fp_mode);
if (options().inline_offheap_trampolines) {
// Inline the trampoline.
DCHECK(Builtins::IsBuiltinId(builtin_index));
RecordCommentForOffHeapTrampoline(builtin_index);
CHECK_NE(builtin_index, Builtins::kNoBuiltinId);
EmbeddedData d = EmbeddedData::FromBlob();
Address entry = d.InstructionStartOfBuiltin(builtin_index);
li(t9, Operand(entry, RelocInfo::OFF_HEAP_TARGET));
Call(t9);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(builtin_index);
Call(code_target, RelocInfo::CODE_TARGET);
}
}
RestoreRegisters(registers);

View File

@ -348,15 +348,14 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void SaveRegisters(RegList registers);
void RestoreRegisters(RegList registers);
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 CallEphemeronKeyBarrier(Register object, Register address,
SaveFPRegsMode fp_mode);
void CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
StubCallMode mode = StubCallMode::kCallBuiltinPointer);
// Push multiple registers on the stack.
// Registers are saved in numerical order, with higher numbered registers
// saved in higher memory addresses.
@ -923,11 +922,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
// Push a fixed frame, consisting of ra, fp.
void PushCommonFrame(Register marker_reg = no_reg);
void CallRecordWriteStub(Register object, Register address,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, int builtin_index,
Address wasm_target);
};
// MacroAssembler implements a collection of frequently used macros.

View File

@ -20,7 +20,7 @@ constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
}
// static
constexpr auto RecordWriteDescriptor::registers() {
constexpr auto WriteBarrierDescriptor::registers() {
return RegisterArray(r3, r4, r5, r6, r7, kReturnRegister0);
}
@ -29,11 +29,6 @@ constexpr auto DynamicCheckMapsDescriptor::registers() {
return RegisterArray(r3, r4, r5, r6, cp);
}
// static
constexpr auto EphemeronKeyBarrierDescriptor::registers() {
return RegisterArray(r3, r4, r5, r6, r7, kReturnRegister0);
}
// static
constexpr Register LoadDescriptor::ReceiverRegister() { return r4; }
// static

View File

@ -653,17 +653,15 @@ void TurboAssembler::RestoreRegisters(RegList registers) {
void TurboAssembler::CallEphemeronKeyBarrier(Register object, Register address,
SaveFPRegsMode fp_mode) {
EphemeronKeyBarrierDescriptor descriptor;
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kObject));
Register slot_parameter(descriptor.GetRegisterParameter(
EphemeronKeyBarrierDescriptor::kSlotAddress));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
push(object);
push(address);
@ -671,51 +669,24 @@ void TurboAssembler::CallEphemeronKeyBarrier(Register object, Register address,
pop(slot_parameter);
pop(object_parameter);
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
Call(isolate()->builtins()->builtin_handle(Builtins::kEphemeronKeyBarrier),
Call(isolate()->builtins()->builtin_handle(
Builtins::GetEphemeronKeyBarrierStub(fp_mode)),
RelocInfo::CODE_TARGET);
RestoreRegisters(registers);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode) {
CallRecordWriteStub(object, address, remembered_set_action, fp_mode,
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,
Builtins::kNoBuiltinId, wasm_target);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
int builtin_index, Address wasm_target) {
DCHECK_NE(builtin_index == Builtins::kNoBuiltinId,
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.
RecordWriteDescriptor descriptor;
StubCallMode mode) {
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kObject));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kSlot));
Register remembered_set_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kRememberedSet));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
push(object);
push(address);
@ -723,22 +694,27 @@ void TurboAssembler::CallRecordWriteStub(
pop(slot_parameter);
pop(object_parameter);
Move(remembered_set_parameter, Smi::FromEnum(remembered_set_action));
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
if (builtin_index == Builtins::kNoBuiltinId) {
if (mode == StubCallMode::kCallWasmRuntimeStub) {
// Use {near_call} for direct Wasm call within a module.
auto wasm_target =
wasm::WasmCode::GetRecordWriteStub(remembered_set_action, fp_mode);
Call(wasm_target, RelocInfo::WASM_STUB_CALL);
} else if (options().inline_offheap_trampolines) {
RecordCommentForOffHeapTrampoline(builtin_index);
EmbeddedData d = EmbeddedData::FromBlob();
Address entry = d.InstructionStartOfBuiltin(builtin_index);
// Use ip directly instead of using UseScratchRegisterScope, as we do
// not preserve scratch registers across calls.
mov(ip, Operand(entry, RelocInfo::OFF_HEAP_TARGET));
Call(ip);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(Builtins::kRecordWrite);
Call(code_target, RelocInfo::CODE_TARGET);
auto builtin_index =
Builtins::GetRecordWriteStub(remembered_set_action, fp_mode);
if (options().inline_offheap_trampolines) {
RecordCommentForOffHeapTrampoline(builtin_index);
EmbeddedData d = EmbeddedData::FromBlob();
Address entry = d.InstructionStartOfBuiltin(builtin_index);
// Use ip directly instead of using UseScratchRegisterScope, as we do
// not preserve scratch registers across calls.
mov(ip, Operand(entry, RelocInfo::OFF_HEAP_TARGET));
Call(ip);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(builtin_index);
Call(code_target, RelocInfo::CODE_TARGET);
}
}
RestoreRegisters(registers);

View File

@ -284,15 +284,14 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void SaveRegisters(RegList registers);
void RestoreRegisters(RegList registers);
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 CallEphemeronKeyBarrier(Register object, Register address,
SaveFPRegsMode fp_mode);
void CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
StubCallMode mode = StubCallMode::kCallBuiltinPointer);
void MultiPush(RegList regs, Register location = sp);
void MultiPop(RegList regs, Register location = sp);
@ -722,10 +721,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void CallCFunctionHelper(Register function, int num_reg_arguments,
int num_double_arguments,
bool has_function_descriptor);
void CallRecordWriteStub(Register object, Register address,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, int builtin_index,
Address wasm_target);
};
// MacroAssembler implements a collection of frequently used acros.

View File

@ -21,7 +21,7 @@ constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
}
// static
constexpr auto RecordWriteDescriptor::registers() {
constexpr auto WriteBarrierDescriptor::registers() {
return RegisterArray(a0, a1, a2, a3, kReturnRegister0);
}
@ -30,11 +30,6 @@ constexpr auto DynamicCheckMapsDescriptor::registers() {
return RegisterArray(kReturnRegister0, a1, a2, a3, cp);
}
// static
constexpr auto EphemeronKeyBarrierDescriptor::registers() {
return RegisterArray(a0, a1, a2, a3, kReturnRegister0);
}
// static
constexpr Register LoadDescriptor::ReceiverRegister() { return a1; }
// static

View File

@ -234,17 +234,15 @@ void TurboAssembler::RestoreRegisters(RegList registers) {
void TurboAssembler::CallEphemeronKeyBarrier(Register object, Register address,
SaveFPRegsMode fp_mode) {
EphemeronKeyBarrierDescriptor descriptor;
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kObject));
Register slot_parameter(descriptor.GetRegisterParameter(
EphemeronKeyBarrierDescriptor::kSlotAddress));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
Push(object);
Push(address);
@ -252,50 +250,24 @@ void TurboAssembler::CallEphemeronKeyBarrier(Register object, Register address,
Pop(slot_parameter);
Pop(object_parameter);
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
Call(isolate()->builtins()->builtin_handle(Builtins::kEphemeronKeyBarrier),
Call(isolate()->builtins()->builtin_handle(
Builtins::GetEphemeronKeyBarrierStub(fp_mode)),
RelocInfo::CODE_TARGET);
RestoreRegisters(registers);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode) {
CallRecordWriteStub(object, address, remembered_set_action, fp_mode,
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,
Builtins::kNoBuiltinId, wasm_target);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
int builtin_index, Address wasm_target) {
DCHECK_NE(builtin_index == Builtins::kNoBuiltinId,
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.
RecordWriteDescriptor descriptor;
StubCallMode mode) {
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kObject));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kSlot));
Register remembered_set_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kRememberedSet));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
Push(object);
Push(address);
@ -303,27 +275,31 @@ void TurboAssembler::CallRecordWriteStub(
Pop(slot_parameter);
Pop(object_parameter);
Move(remembered_set_parameter, Smi::FromEnum(remembered_set_action));
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
if (builtin_index == Builtins::kNoBuiltinId) {
if (mode == StubCallMode::kCallWasmRuntimeStub) {
auto wasm_target =
wasm::WasmCode::GetRecordWriteStub(remembered_set_action, fp_mode);
Call(wasm_target, RelocInfo::WASM_STUB_CALL);
} else if (options().inline_offheap_trampolines) {
// Inline the trampoline. //qj
DCHECK(Builtins::IsBuiltinId(builtin_index));
RecordCommentForOffHeapTrampoline(builtin_index);
CHECK_NE(builtin_index, Builtins::kNoBuiltinId);
EmbeddedData d = EmbeddedData::FromBlob();
Address entry = d.InstructionStartOfBuiltin(builtin_index);
UseScratchRegisterScope temps(this);
BlockTrampolinePoolScope block_trampoline_pool(this);
Register scratch = temps.Acquire();
li(scratch, Operand(entry, RelocInfo::OFF_HEAP_TARGET));
Call(scratch);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(Builtins::kRecordWrite);
Call(code_target, RelocInfo::CODE_TARGET);
auto builtin_index =
Builtins::GetRecordWriteStub(remembered_set_action, fp_mode);
if (options().inline_offheap_trampolines) {
// Inline the trampoline. //qj
DCHECK(Builtins::IsBuiltinId(builtin_index));
RecordCommentForOffHeapTrampoline(builtin_index);
CHECK_NE(builtin_index, Builtins::kNoBuiltinId);
EmbeddedData d = EmbeddedData::FromBlob();
Address entry = d.InstructionStartOfBuiltin(builtin_index);
UseScratchRegisterScope temps(this);
BlockTrampolinePoolScope block_trampoline_pool(this);
Register scratch = temps.Acquire();
li(scratch, Operand(entry, RelocInfo::OFF_HEAP_TARGET));
Call(scratch);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(builtin_index);
Call(code_target, RelocInfo::CODE_TARGET);
}
}
RestoreRegisters(registers);

View File

@ -328,15 +328,14 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void SaveRegisters(RegList registers);
void RestoreRegisters(RegList registers);
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 CallEphemeronKeyBarrier(Register object, Register address,
SaveFPRegsMode fp_mode);
void CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
StubCallMode mode = StubCallMode::kCallBuiltinPointer);
// Push multiple registers on the stack.
// Registers are saved in numerical order, with higher numbered registers
// saved in higher memory addresses.
@ -901,11 +900,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
// Push a fixed frame, consisting of ra, fp.
void PushCommonFrame(Register marker_reg = no_reg);
void CallRecordWriteStub(Register object, Register address,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, int builtin_index,
Address wasm_target);
};
// MacroAssembler implements a collection of frequently used macros.

View File

@ -20,7 +20,7 @@ constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
}
// static
constexpr auto RecordWriteDescriptor::registers() {
constexpr auto WriteBarrierDescriptor::registers() {
return RegisterArray(r2, r3, r4, r5, r6, kReturnRegister0);
}
@ -28,12 +28,6 @@ constexpr auto RecordWriteDescriptor::registers() {
constexpr auto DynamicCheckMapsDescriptor::registers() {
return RegisterArray(r2, r3, r4, r5, cp);
}
// static
constexpr auto EphemeronKeyBarrierDescriptor::registers() {
return RegisterArray(r2, r3, r4, r5, r6, kReturnRegister0);
}
// static
constexpr Register LoadDescriptor::ReceiverRegister() { return r3; }
// static

View File

@ -869,17 +869,15 @@ void TurboAssembler::RestoreRegisters(RegList registers) {
void TurboAssembler::CallEphemeronKeyBarrier(Register object, Register address,
SaveFPRegsMode fp_mode) {
EphemeronKeyBarrierDescriptor descriptor;
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kObject));
Register slot_parameter(descriptor.GetRegisterParameter(
EphemeronKeyBarrierDescriptor::kSlotAddress));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
Push(object);
Push(address);
@ -887,50 +885,24 @@ void TurboAssembler::CallEphemeronKeyBarrier(Register object, Register address,
Pop(slot_parameter);
Pop(object_parameter);
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
Call(isolate()->builtins()->builtin_handle(Builtins::kEphemeronKeyBarrier),
Call(isolate()->builtins()->builtin_handle(
Builtins::GetEphemeronKeyBarrierStub(fp_mode)),
RelocInfo::CODE_TARGET);
RestoreRegisters(registers);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode) {
CallRecordWriteStub(object, address, remembered_set_action, fp_mode,
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,
Builtins::kNoBuiltinId, wasm_target);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
int builtin_index, Address wasm_target) {
DCHECK_NE(builtin_index == Builtins::kNoBuiltinId,
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.
RecordWriteDescriptor descriptor;
StubCallMode mode) {
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kObject));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kSlot));
Register remembered_set_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kRememberedSet));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
Push(object);
Push(address);
@ -938,21 +910,25 @@ void TurboAssembler::CallRecordWriteStub(
Pop(slot_parameter);
Pop(object_parameter);
Move(remembered_set_parameter, Smi::FromEnum(remembered_set_action));
Move(fp_mode_parameter, Smi::FromEnum(fp_mode));
if (builtin_index == Builtins::kNoBuiltinId) {
if (mode == StubCallMode::kCallWasmRuntimeStub) {
auto wasm_target =
wasm::WasmCode::GetRecordWriteStub(remembered_set_action, fp_mode);
Call(wasm_target, RelocInfo::WASM_STUB_CALL);
} else if (options().inline_offheap_trampolines) {
RecordCommentForOffHeapTrampoline(builtin_index);
CHECK_NE(builtin_index, Builtins::kNoBuiltinId);
EmbeddedData d = EmbeddedData::FromBlob();
Address entry = d.InstructionStartOfBuiltin(builtin_index);
mov(ip, Operand(entry, RelocInfo::OFF_HEAP_TARGET));
Call(ip);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(Builtins::kRecordWrite);
Call(code_target, RelocInfo::CODE_TARGET);
auto builtin_index =
Builtins::GetRecordWriteStub(remembered_set_action, fp_mode);
if (options().inline_offheap_trampolines) {
RecordCommentForOffHeapTrampoline(builtin_index);
CHECK_NE(builtin_index, Builtins::kNoBuiltinId);
EmbeddedData d = EmbeddedData::FromBlob();
Address entry = d.InstructionStartOfBuiltin(builtin_index);
mov(ip, Operand(entry, RelocInfo::OFF_HEAP_TARGET));
Call(ip);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(builtin_indexe);
Call(code_target, RelocInfo::CODE_TARGET);
}
}
RestoreRegisters(registers);

View File

@ -156,15 +156,14 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
void SaveRegisters(RegList registers);
void RestoreRegisters(RegList registers);
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 CallEphemeronKeyBarrier(Register object, Register address,
SaveFPRegsMode fp_mode);
void CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
StubCallMode mode = StubCallMode::kCallBuiltinPointer);
void MultiPush(RegList regs, Register location = sp);
void MultiPop(RegList regs, Register location = sp);
@ -1070,11 +1069,6 @@ 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, int builtin_index,
Address wasm_target);
void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = al);
int CalculateStackPassedWords(int num_reg_arguments,
int num_double_arguments);

View File

@ -131,6 +131,8 @@ class V8_EXPORT_PRIVATE TurboAssemblerBase : public Assembler {
RecordComment(str.str().c_str());
}
enum class RecordWriteCallMode { kDefault, kWasm };
protected:
Isolate* const isolate_ = nullptr;

View File

@ -19,7 +19,7 @@ constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
}
// static
constexpr auto RecordWriteDescriptor::registers() {
constexpr auto WriteBarrierDescriptor::registers() {
return RegisterArray(arg_reg_1, arg_reg_2, arg_reg_3, arg_reg_4,
kReturnRegister0);
}
@ -30,12 +30,6 @@ constexpr auto DynamicCheckMapsDescriptor::registers() {
kRuntimeCallFunctionRegister, kContextRegister);
}
// static
constexpr auto EphemeronKeyBarrierDescriptor::registers() {
return RegisterArray(arg_reg_1, arg_reg_2, arg_reg_3, arg_reg_4,
kReturnRegister0);
}
// static
constexpr Register LoadDescriptor::ReceiverRegister() { return rdx; }
// static

View File

@ -409,85 +409,56 @@ void TurboAssembler::RestoreRegisters(RegList registers) {
void TurboAssembler::CallEphemeronKeyBarrier(Register object, Register address,
SaveFPRegsMode fp_mode) {
EphemeronKeyBarrierDescriptor descriptor;
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kObject));
Register slot_parameter(descriptor.GetRegisterParameter(
EphemeronKeyBarrierDescriptor::kSlotAddress));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(EphemeronKeyBarrierDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
MovePair(slot_parameter, address, object_parameter, object);
Smi smi_fm = Smi::FromEnum(fp_mode);
Move(fp_mode_parameter, smi_fm);
Call(isolate()->builtins()->builtin_handle(Builtins::kEphemeronKeyBarrier),
Call(isolate()->builtins()->builtin_handle(
Builtins::GetEphemeronKeyBarrierStub(fp_mode)),
RelocInfo::CODE_TARGET);
RestoreRegisters(registers);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode) {
CallRecordWriteStub(object, address, remembered_set_action, fp_mode,
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,
Builtins::kNoBuiltinId, wasm_target);
}
void TurboAssembler::CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
int builtin_index, Address wasm_target) {
DCHECK_NE(builtin_index == Builtins::kNoBuiltinId,
wasm_target == kNullAddress);
RecordWriteDescriptor descriptor;
StubCallMode mode) {
WriteBarrierDescriptor descriptor;
RegList registers = descriptor.allocatable_registers();
SaveRegisters(registers);
Register object_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kObject));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kObject));
Register slot_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kSlot));
Register remembered_set_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kRememberedSet));
Register fp_mode_parameter(
descriptor.GetRegisterParameter(RecordWriteDescriptor::kFPMode));
descriptor.GetRegisterParameter(WriteBarrierDescriptor::kSlotAddress));
// Prepare argument registers for calling RecordWrite
// slot_parameter <= address
// object_parameter <= object
MovePair(slot_parameter, address, object_parameter, object);
Smi smi_rsa = Smi::FromEnum(remembered_set_action);
Smi smi_fm = Smi::FromEnum(fp_mode);
Move(remembered_set_parameter, smi_rsa);
if (smi_rsa != smi_fm) {
Move(fp_mode_parameter, smi_fm);
} else {
movq(fp_mode_parameter, remembered_set_parameter);
}
if (builtin_index == Builtins::kNoBuiltinId) {
if (mode == StubCallMode::kCallWasmRuntimeStub) {
// Use {near_call} for direct Wasm call within a module.
auto wasm_target =
wasm::WasmCode::GetRecordWriteStub(remembered_set_action, fp_mode);
near_call(wasm_target, RelocInfo::WASM_STUB_CALL);
} else if (options().inline_offheap_trampolines) {
CallBuiltin(builtin_index);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(Builtins::kRecordWrite);
Call(code_target, RelocInfo::CODE_TARGET);
auto builtin_index =
Builtins::GetRecordWriteStub(remembered_set_action, fp_mode);
if (options().inline_offheap_trampolines) {
CallBuiltin(builtin_index);
} else {
Handle<Code> code_target =
isolate()->builtins()->builtin_handle(builtin_index);
Call(code_target, RelocInfo::CODE_TARGET);
}
}
RestoreRegisters(registers);

View File

@ -504,15 +504,14 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler {
void SaveRegisters(RegList registers);
void RestoreRegisters(RegList registers);
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 CallEphemeronKeyBarrier(Register object, Register address,
SaveFPRegsMode fp_mode);
void CallRecordWriteStub(
Register object, Register address,
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode,
StubCallMode mode = StubCallMode::kCallBuiltinPointer);
void MoveNumber(Register dst, double value);
void MoveNonSmi(Register dst, double value);
@ -611,11 +610,6 @@ class V8_EXPORT_PRIVATE TurboAssembler : public SharedTurboAssembler {
// Returns a register holding the smi value. The register MUST NOT be
// modified. It may be the "smi 1 constant" register.
Register GetSmiConstant(Smi value);
void CallRecordWriteStub(Register object, Register address,
RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, int builtin_index,
Address wasm_target);
};
// MacroAssembler implements a collection of frequently used macros.

View File

@ -468,6 +468,8 @@ enum class StoreOrigin { kMaybeKeyed, kNamed };
enum class TypeofMode { kInside, kNotInside };
// Use by RecordWrite stubs.
enum class RememberedSetAction { kOmit, kEmit };
// Enums used by CEntry.
enum class SaveFPRegsMode { kIgnore, kSave };
enum class ArgvMode { kStack, kRegister };

View File

@ -212,7 +212,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
#if V8_ENABLE_WEBASSEMBLY
} else if (stub_mode_ == StubCallMode::kCallWasmRuntimeStub) {
__ CallRecordWriteStub(object_, offset_, remembered_set_action,
save_fp_mode, wasm::WasmCode::kRecordWrite);
save_fp_mode, StubCallMode::kCallWasmRuntimeStub);
#endif // V8_ENABLE_WEBASSEMBLY
} else {
__ CallRecordWriteStub(object_, offset_, remembered_set_action,

View File

@ -306,7 +306,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ CallRecordWriteStub(object_, offset_, remembered_set_action,
save_fp_mode, wasm::WasmCode::kRecordWrite);
save_fp_mode, StubCallMode::kCallWasmRuntimeStub);
#endif // V8_ENABLE_WEBASSEMBLY
} else {
__ CallRecordWriteStub(object_, offset_, remembered_set_action,

View File

@ -338,7 +338,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode, wasm::WasmCode::kRecordWrite);
save_fp_mode, StubCallMode::kCallWasmRuntimeStub);
} else {
#endif // V8_ENABLE_WEBASSEMBLY
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,

View File

@ -184,7 +184,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode, wasm::WasmCode::kRecordWrite);
save_fp_mode, StubCallMode::kCallWasmRuntimeStub);
#endif // V8_ENABLE_WEBASSEMBLY
} else {
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,

View File

@ -185,7 +185,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode, wasm::WasmCode::kRecordWrite);
save_fp_mode, StubCallMode::kCallWasmRuntimeStub);
#endif // V8_ENABLE_WEBASSEMBLY
} else {
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,

View File

@ -200,7 +200,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
#if V8_ENABLE_WEBASSEMBLY
} else if (stub_mode_ == StubCallMode::kCallWasmRuntimeStub) {
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode, wasm::WasmCode::kRecordWrite);
save_fp_mode, StubCallMode::kCallWasmRuntimeStub);
#endif // V8_ENABLE_WEBASSEMBLY
} else {
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,

View File

@ -178,7 +178,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode, wasm::WasmCode::kRecordWrite);
save_fp_mode, StubCallMode::kCallWasmRuntimeStub);
} else {
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode);

View File

@ -234,7 +234,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
#if V8_ENABLE_WEBASSEMBLY
} else if (stub_mode_ == StubCallMode::kCallWasmRuntimeStub) {
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode, wasm::WasmCode::kRecordWrite);
save_fp_mode, StubCallMode::kCallWasmRuntimeStub);
#endif // V8_ENABLE_WEBASSEMBLY
} else {
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,

View File

@ -299,7 +299,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
// Just encode the stub index. This will be patched when the code
// is added to the native module and copied into wasm code space.
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,
save_fp_mode, wasm::WasmCode::kRecordWrite);
save_fp_mode, StubCallMode::kCallWasmRuntimeStub);
#endif // V8_ENABLE_WEBASSEMBLY
} else {
__ CallRecordWriteStub(object_, scratch1_, remembered_set_action,

View File

@ -1039,7 +1039,10 @@ static bool TransitivelyCalledBuiltinHasNoSideEffect(Builtins::Name caller,
case Builtins::kProxyHasProperty:
case Builtins::kProxyIsExtensible:
case Builtins::kProxyGetPrototypeOf:
case Builtins::kRecordWrite:
case Builtins::kRecordWriteEmitRememberedSetSaveFP:
case Builtins::kRecordWriteOmitRememberedSetSaveFP:
case Builtins::kRecordWriteEmitRememberedSetIgnoreFP:
case Builtins::kRecordWriteOmitRememberedSetIgnoreFP:
case Builtins::kStringAdd_CheckNone:
case Builtins::kStringEqual:
case Builtins::kStringIndexOf:

View File

@ -78,7 +78,7 @@ int WriteBarrier::MarkingFromCode(Address raw_host, Address raw_slot) {
}
#endif
WriteBarrier::Marking(host, slot, MaybeObject(value));
// Called by RecordWriteCodeStubAssembler, which doesnt accept void type
// Called by WriteBarrierCodeStubAssembler, which doesnt accept void type
return 0;
}

View File

@ -101,7 +101,10 @@ bool IsUnexpectedCodeObject(Isolate* isolate, HeapObject obj) {
case Builtins::kAbort:
case Builtins::kCEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit:
case Builtins::kInterpreterEntryTrampoline:
case Builtins::kRecordWrite:
case Builtins::kRecordWriteEmitRememberedSetSaveFP:
case Builtins::kRecordWriteOmitRememberedSetSaveFP:
case Builtins::kRecordWriteEmitRememberedSetIgnoreFP:
case Builtins::kRecordWriteOmitRememberedSetIgnoreFP:
return false;
default:
return true;

View File

@ -761,7 +761,7 @@ void LiftoffAssembler::StoreTaggedPointer(Register dst_addr,
actual_offset_reg == no_reg ? Operand(offset_imm)
: Operand(actual_offset_reg),
RememberedSetAction::kEmit, SaveFPRegsMode::kSave,
wasm::WasmCode::kRecordWrite);
StubCallMode::kCallWasmRuntimeStub);
bind(&exit);
}

View File

@ -486,7 +486,7 @@ void LiftoffAssembler::StoreTaggedPointer(Register dst_addr,
? Operand(dst_op.regoffset().X())
: Operand(dst_op.offset()),
RememberedSetAction::kEmit, SaveFPRegsMode::kSave,
wasm::WasmCode::kRecordWrite);
StubCallMode::kCallWasmRuntimeStub);
bind(&exit);
}

View File

@ -383,7 +383,8 @@ void LiftoffAssembler::StoreTaggedPointer(Register dst_addr,
Label::kNear);
lea(scratch, dst_op);
CallRecordWriteStub(dst_addr, scratch, RememberedSetAction::kEmit,
SaveFPRegsMode::kSave, wasm::WasmCode::kRecordWrite);
SaveFPRegsMode::kSave,
StubCallMode::kCallWasmRuntimeStub);
bind(&exit);
}

View File

@ -486,7 +486,8 @@ void LiftoffAssembler::StoreTaggedPointer(Register dst_addr,
MemoryChunk::kPointersToHereAreInterestingMask, eq, &exit);
Addu(scratch, dst_op.rm(), dst_op.offset());
CallRecordWriteStub(dst_addr, scratch, RememberedSetAction::kEmit,
SaveFPRegsMode::kSave, wasm::WasmCode::kRecordWrite);
SaveFPRegsMode::kSave,
StubCallMode::kCallWasmRuntimeStub);
bind(&exit);
}

View File

@ -465,7 +465,8 @@ void LiftoffAssembler::StoreTaggedPointer(Register dst_addr,
&exit);
Daddu(scratch, dst_op.rm(), dst_op.offset());
CallRecordWriteStub(dst_addr, scratch, RememberedSetAction::kEmit,
SaveFPRegsMode::kSave, wasm::WasmCode::kRecordWrite);
SaveFPRegsMode::kSave,
StubCallMode::kCallWasmRuntimeStub);
bind(&exit);
}

View File

@ -454,7 +454,8 @@ void LiftoffAssembler::StoreTaggedPointer(Register dst_addr,
MemoryChunk::kPointersToHereAreInterestingMask, eq, &exit);
Add64(scratch, dst_op.rm(), dst_op.offset());
CallRecordWriteStub(dst_addr, scratch, RememberedSetAction::kEmit,
SaveFPRegsMode::kSave, wasm::WasmCode::kRecordWrite);
SaveFPRegsMode::kSave,
StubCallMode::kCallWasmRuntimeStub);
bind(&exit);
}

View File

@ -272,7 +272,8 @@ void LiftoffAssembler::StoreTaggedPointer(Register dst_addr,
eq, &exit);
lay(r1, dst_op);
CallRecordWriteStub(dst_addr, r1, RememberedSetAction::kEmit,
SaveFPRegsMode::kSave, wasm::WasmCode::kRecordWrite);
SaveFPRegsMode::kSave,
StubCallMode::kCallWasmRuntimeStub);
bind(&exit);
}

View File

@ -382,7 +382,8 @@ void LiftoffAssembler::StoreTaggedPointer(Register dst_addr,
Label::kNear);
leaq(scratch, dst_op);
CallRecordWriteStub(dst_addr, scratch, RememberedSetAction::kEmit,
SaveFPRegsMode::kSave, wasm::WasmCode::kRecordWrite);
SaveFPRegsMode::kSave,
StubCallMode::kCallWasmRuntimeStub);
bind(&exit);
}

View File

@ -51,51 +51,54 @@ struct WasmModule;
// Convenience macro listing all wasm runtime stubs. Note that the first few
// elements of the list coincide with {compiler::TrapId}, order matters.
#define WASM_RUNTIME_STUB_LIST(V, VTRAP) \
FOREACH_WASM_TRAPREASON(VTRAP) \
V(WasmCompileLazy) \
V(WasmTriggerTierUp) \
V(WasmDebugBreak) \
V(WasmInt32ToHeapNumber) \
V(WasmTaggedNonSmiToInt32) \
V(WasmFloat32ToNumber) \
V(WasmFloat64ToNumber) \
V(WasmTaggedToFloat64) \
V(WasmAllocateJSArray) \
V(WasmAllocatePair) \
V(WasmAtomicNotify) \
V(WasmI32AtomicWait32) \
V(WasmI32AtomicWait64) \
V(WasmI64AtomicWait32) \
V(WasmI64AtomicWait64) \
V(WasmGetOwnProperty) \
V(WasmRefFunc) \
V(WasmMemoryGrow) \
V(WasmTableInit) \
V(WasmTableCopy) \
V(WasmTableFill) \
V(WasmTableGrow) \
V(WasmTableGet) \
V(WasmTableSet) \
V(WasmStackGuard) \
V(WasmStackOverflow) \
V(WasmAllocateFixedArray) \
V(WasmThrow) \
V(WasmRethrow) \
V(WasmTraceEnter) \
V(WasmTraceExit) \
V(WasmTraceMemory) \
V(BigIntToI32Pair) \
V(BigIntToI64) \
V(DoubleToI) \
V(I32PairToBigInt) \
V(I64ToBigInt) \
V(RecordWrite) \
V(ToNumber) \
V(WasmAllocateArrayWithRtt) \
V(WasmAllocateRtt) \
V(WasmAllocateStructWithRtt) \
V(WasmSubtypeCheck) \
#define WASM_RUNTIME_STUB_LIST(V, VTRAP) \
FOREACH_WASM_TRAPREASON(VTRAP) \
V(WasmCompileLazy) \
V(WasmTriggerTierUp) \
V(WasmDebugBreak) \
V(WasmInt32ToHeapNumber) \
V(WasmTaggedNonSmiToInt32) \
V(WasmFloat32ToNumber) \
V(WasmFloat64ToNumber) \
V(WasmTaggedToFloat64) \
V(WasmAllocateJSArray) \
V(WasmAllocatePair) \
V(WasmAtomicNotify) \
V(WasmI32AtomicWait32) \
V(WasmI32AtomicWait64) \
V(WasmI64AtomicWait32) \
V(WasmI64AtomicWait64) \
V(WasmGetOwnProperty) \
V(WasmRefFunc) \
V(WasmMemoryGrow) \
V(WasmTableInit) \
V(WasmTableCopy) \
V(WasmTableFill) \
V(WasmTableGrow) \
V(WasmTableGet) \
V(WasmTableSet) \
V(WasmStackGuard) \
V(WasmStackOverflow) \
V(WasmAllocateFixedArray) \
V(WasmThrow) \
V(WasmRethrow) \
V(WasmTraceEnter) \
V(WasmTraceExit) \
V(WasmTraceMemory) \
V(BigIntToI32Pair) \
V(BigIntToI64) \
V(DoubleToI) \
V(I32PairToBigInt) \
V(I64ToBigInt) \
V(RecordWriteEmitRememberedSetSaveFP) \
V(RecordWriteOmitRememberedSetSaveFP) \
V(RecordWriteEmitRememberedSetIgnoreFP) \
V(RecordWriteOmitRememberedSetIgnoreFP) \
V(ToNumber) \
V(WasmAllocateArrayWithRtt) \
V(WasmAllocateRtt) \
V(WasmAllocateStructWithRtt) \
V(WasmSubtypeCheck) \
V(WasmOnStackReplace)
// Sorted, disjoint and non-overlapping memory regions. A region is of the
@ -148,6 +151,27 @@ class V8_EXPORT_PRIVATE WasmCode final {
kRuntimeStubCount
};
static constexpr RuntimeStubId GetRecordWriteStub(
RememberedSetAction remembered_set_action, SaveFPRegsMode fp_mode) {
switch (remembered_set_action) {
case RememberedSetAction::kEmit:
switch (fp_mode) {
case SaveFPRegsMode::kIgnore:
return RuntimeStubId::kRecordWriteEmitRememberedSetIgnoreFP;
case SaveFPRegsMode::kSave:
return RuntimeStubId::kRecordWriteEmitRememberedSetSaveFP;
}
case RememberedSetAction::kOmit:
switch (fp_mode) {
case SaveFPRegsMode::kIgnore:
return RuntimeStubId::kRecordWriteOmitRememberedSetIgnoreFP;
case SaveFPRegsMode::kSave:
return RuntimeStubId::kRecordWriteOmitRememberedSetSaveFP;
}
}
UNREACHABLE();
}
Vector<byte> instructions() const {
return VectorOf(instructions_, static_cast<size_t>(instructions_size_));
}