Commit b51929c6 authored by Albert Mingkun Yang's avatar Albert Mingkun Yang Committed by Commit Bot

Using restricted register set for RecordWrite on all architectures

Saving/restoring only registers in the restricted set before calling
RecordWrite code stub, which prepares for turning on
`v8_enable_csa_write_barrier` on all architectures.

Bug: chromium:749486
Change-Id: I6c8ba0c1561513569218e80011673cf24c7d6127
Reviewed-on: https://chromium-review.googlesource.com/641531Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Albert Mingkun Yang <albertnetymk@google.com>
Cr-Commit-Position: refs/heads/master@{#47770}
parent e1cf815d
...@@ -24,9 +24,14 @@ void CallInterfaceDescriptor::DefaultInitializePlatformSpecific( ...@@ -24,9 +24,14 @@ void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
void RecordWriteDescriptor::InitializePlatformSpecific( void RecordWriteDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
// TODO(albertnetymk): Use default for now; should call const Register default_stub_registers[] = {r0, r1, r2, r3, r4};
// RestrictAllocatableRegisters like src/x64/interface-descriptors-x64.cc
DefaultInitializePlatformSpecific(data, kParameterCount); data->RestrictAllocatableRegisters(default_stub_registers,
arraysize(default_stub_registers));
CHECK_LE(static_cast<size_t>(kParameterCount),
arraysize(default_stub_registers));
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
} }
const Register FastNewFunctionContextDescriptor::FunctionRegister() { const Register FastNewFunctionContextDescriptor::FunctionRegister() {
......
...@@ -24,9 +24,14 @@ void CallInterfaceDescriptor::DefaultInitializePlatformSpecific( ...@@ -24,9 +24,14 @@ void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
void RecordWriteDescriptor::InitializePlatformSpecific( void RecordWriteDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
// TODO(albertnetymk): Use default for now; should call const Register default_stub_registers[] = {x0, x1, x2, x3, x4};
// RestrictAllocatableRegisters like src/x64/interface-descriptors-x64.cc
DefaultInitializePlatformSpecific(data, kParameterCount); data->RestrictAllocatableRegisters(default_stub_registers,
arraysize(default_stub_registers));
CHECK_LE(static_cast<size_t>(kParameterCount),
arraysize(default_stub_registers));
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
} }
const Register FastNewFunctionContextDescriptor::FunctionRegister() { const Register FastNewFunctionContextDescriptor::FunctionRegister() {
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "src/arm/macro-assembler-arm.h" #include "src/arm/macro-assembler-arm.h"
#include "src/assembler-inl.h" #include "src/assembler-inl.h"
#include "src/boxed-float.h" #include "src/boxed-float.h"
#include "src/callable.h"
#include "src/compilation-info.h" #include "src/compilation-info.h"
#include "src/compiler/code-generator-impl.h" #include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h" #include "src/compiler/gap-resolver.h"
...@@ -215,6 +216,29 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -215,6 +216,29 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
unwinding_info_writer_(unwinding_info_writer), unwinding_info_writer_(unwinding_info_writer),
zone_(gen->zone()) {} zone_(gen->zone()) {}
void SaveRegisters(RegList registers) {
DCHECK(NumRegs(registers) > 0);
RegList regs = 0;
for (int i = 0; i < Register::kNumRegisters; ++i) {
if ((registers >> i) & 1u) {
regs |= Register::from_code(i).bit();
}
}
__ stm(db_w, sp, regs | lr.bit());
}
void RestoreRegisters(RegList registers) {
DCHECK(NumRegs(registers) > 0);
RegList regs = 0;
for (int i = 0; i < Register::kNumRegisters; ++i) {
if ((registers >> i) & 1u) {
regs |= Register::from_code(i).bit();
}
}
__ ldm(ia_w, sp, regs | lr.bit());
}
void Generate() final { void Generate() final {
if (mode_ > RecordWriteMode::kValueIsPointer) { if (mode_ > RecordWriteMode::kValueIsPointer) {
__ JumpIfSmi(value_, exit()); __ JumpIfSmi(value_, exit());
...@@ -222,6 +246,40 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -222,6 +246,40 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
__ CheckPageFlag(value_, scratch0_, __ CheckPageFlag(value_, scratch0_,
MemoryChunk::kPointersToHereAreInterestingMask, eq, MemoryChunk::kPointersToHereAreInterestingMask, eq,
exit()); exit());
if (index_.is(no_reg)) {
__ add(scratch1_, object_, Operand(index_immediate_));
} else {
DCHECK_EQ(0, index_immediate_);
__ add(scratch1_, object_, Operand(index_));
}
#ifdef V8_CSA_WRITE_BARRIER
Callable const callable =
Builtins::CallableFor(__ isolate(), Builtins::kRecordWrite);
RegList registers = callable.descriptor().allocatable_registers();
unwinding_info_writer_->MarkLinkRegisterOnTopOfStack(__ pc_offset());
SaveRegisters(registers);
Register object_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kObject));
Register slot_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kSlot));
Register isolate_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kIsolate));
__ Push(object_);
__ Push(scratch1_);
__ Pop(slot_parameter);
__ Pop(object_parameter);
__ Move(isolate_parameter,
Operand(ExternalReference::isolate_address(__ isolate())));
__ Call(callable.code(), RelocInfo::CODE_TARGET);
RestoreRegisters(registers);
unwinding_info_writer_->MarkPopLinkRegisterFromTopOfStack(__ pc_offset());
#else
RememberedSetAction const remembered_set_action = RememberedSetAction const remembered_set_action =
mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET
: OMIT_REMEMBERED_SET; : OMIT_REMEMBERED_SET;
...@@ -232,12 +290,6 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -232,12 +290,6 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
__ Push(lr); __ Push(lr);
unwinding_info_writer_->MarkLinkRegisterOnTopOfStack(__ pc_offset()); unwinding_info_writer_->MarkLinkRegisterOnTopOfStack(__ pc_offset());
} }
if (index_.is(no_reg)) {
__ add(scratch1_, object_, Operand(index_immediate_));
} else {
DCHECK_EQ(0, index_immediate_);
__ add(scratch1_, object_, Operand(index_));
}
__ CallStubDelayed( __ CallStubDelayed(
new (zone_) RecordWriteStub(nullptr, object_, scratch0_, scratch1_, new (zone_) RecordWriteStub(nullptr, object_, scratch0_, scratch1_,
remembered_set_action, save_fp_mode)); remembered_set_action, save_fp_mode));
...@@ -245,6 +297,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -245,6 +297,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
__ Pop(lr); __ Pop(lr);
unwinding_info_writer_->MarkPopLinkRegisterFromTopOfStack(__ pc_offset()); unwinding_info_writer_->MarkPopLinkRegisterFromTopOfStack(__ pc_offset());
} }
#endif
} }
private: private:
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "src/arm64/assembler-arm64-inl.h" #include "src/arm64/assembler-arm64-inl.h"
#include "src/arm64/macro-assembler-arm64-inl.h" #include "src/arm64/macro-assembler-arm64-inl.h"
#include "src/callable.h"
#include "src/compilation-info.h" #include "src/compilation-info.h"
#include "src/compiler/code-generator-impl.h" #include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h" #include "src/compiler/gap-resolver.h"
...@@ -321,6 +322,30 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -321,6 +322,30 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
unwinding_info_writer_(unwinding_info_writer), unwinding_info_writer_(unwinding_info_writer),
zone_(gen->zone()) {} zone_(gen->zone()) {}
void SaveRegisters(RegList registers) {
DCHECK(NumRegs(registers) > 0);
CPURegList regs(lr);
for (int i = 0; i < Register::kNumRegisters; ++i) {
if ((registers >> i) & 1u) {
regs.Combine(Register::XRegFromCode(i));
}
}
__ PushCPURegList(regs);
}
void RestoreRegisters(RegList registers) {
DCHECK(NumRegs(registers) > 0);
CPURegList regs(lr);
for (int i = 0; i < Register::kNumRegisters; ++i) {
if ((registers >> i) & 1u) {
regs.Combine(Register::XRegFromCode(i));
}
}
__ PopCPURegList(regs);
}
void Generate() final { void Generate() final {
if (mode_ > RecordWriteMode::kValueIsPointer) { if (mode_ > RecordWriteMode::kValueIsPointer) {
__ JumpIfSmi(value_, exit()); __ JumpIfSmi(value_, exit());
...@@ -328,6 +353,35 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -328,6 +353,35 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
__ CheckPageFlagClear(value_, scratch0_, __ CheckPageFlagClear(value_, scratch0_,
MemoryChunk::kPointersToHereAreInterestingMask, MemoryChunk::kPointersToHereAreInterestingMask,
exit()); exit());
__ Add(scratch1_, object_, index_);
#ifdef V8_CSA_WRITE_BARRIER
Callable const callable =
Builtins::CallableFor(__ isolate(), Builtins::kRecordWrite);
RegList registers = callable.descriptor().allocatable_registers();
SaveRegisters(registers);
unwinding_info_writer_->MarkLinkRegisterOnTopOfStack(__ pc_offset(),
__ StackPointer());
Register object_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kObject));
Register slot_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kSlot));
Register isolate_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kIsolate));
__ Push(object_);
__ Push(scratch1_);
__ Pop(slot_parameter);
__ Pop(object_parameter);
__ Mov(isolate_parameter, ExternalReference::isolate_address(__ isolate()));
__ Call(callable.code(), RelocInfo::CODE_TARGET);
RestoreRegisters(registers);
unwinding_info_writer_->MarkPopLinkRegisterFromTopOfStack(__ pc_offset());
#else
RememberedSetAction const remembered_set_action = RememberedSetAction const remembered_set_action =
mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET
: OMIT_REMEMBERED_SET; : OMIT_REMEMBERED_SET;
...@@ -339,7 +393,6 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -339,7 +393,6 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
unwinding_info_writer_->MarkLinkRegisterOnTopOfStack(__ pc_offset(), unwinding_info_writer_->MarkLinkRegisterOnTopOfStack(__ pc_offset(),
__ StackPointer()); __ StackPointer());
} }
__ Add(scratch1_, object_, index_);
__ CallStubDelayed( __ CallStubDelayed(
new (zone_) RecordWriteStub(nullptr, object_, scratch0_, scratch1_, new (zone_) RecordWriteStub(nullptr, object_, scratch0_, scratch1_,
remembered_set_action, save_fp_mode)); remembered_set_action, save_fp_mode));
...@@ -347,6 +400,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -347,6 +400,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
__ Pop(lr); __ Pop(lr);
unwinding_info_writer_->MarkPopLinkRegisterFromTopOfStack(__ pc_offset()); unwinding_info_writer_->MarkPopLinkRegisterFromTopOfStack(__ pc_offset());
} }
#endif
} }
private: private:
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "src/compiler/code-generator.h" #include "src/compiler/code-generator.h"
#include "src/callable.h"
#include "src/compilation-info.h" #include "src/compilation-info.h"
#include "src/compiler/code-generator-impl.h" #include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h" #include "src/compiler/gap-resolver.h"
...@@ -253,6 +254,24 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -253,6 +254,24 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
mode_(mode), mode_(mode),
zone_(gen->zone()) {} zone_(gen->zone()) {}
void SaveRegisters(RegList registers) {
DCHECK(NumRegs(registers) > 0);
for (int i = 0; i < Register::kNumRegisters; ++i) {
if ((registers >> i) & 1u) {
__ push(Register::from_code(i));
}
}
}
void RestoreRegisters(RegList registers) {
DCHECK(NumRegs(registers) > 0);
for (int i = Register::kNumRegisters - 1; i >= 0; --i) {
if ((registers >> i) & 1u) {
__ pop(Register::from_code(i));
}
}
}
void Generate() final { void Generate() final {
if (mode_ > RecordWriteMode::kValueIsPointer) { if (mode_ > RecordWriteMode::kValueIsPointer) {
__ JumpIfSmi(value_, exit()); __ JumpIfSmi(value_, exit());
...@@ -260,15 +279,42 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -260,15 +279,42 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
__ CheckPageFlag(value_, scratch0_, __ CheckPageFlag(value_, scratch0_,
MemoryChunk::kPointersToHereAreInterestingMask, zero, MemoryChunk::kPointersToHereAreInterestingMask, zero,
exit()); exit());
__ lea(scratch1_, operand_);
#ifdef V8_CSA_WRITE_BARRIER
Callable const callable =
Builtins::CallableFor(__ isolate(), Builtins::kRecordWrite);
RegList registers = callable.descriptor().allocatable_registers();
SaveRegisters(registers);
Register object_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kObject));
Register slot_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kSlot));
Register isolate_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kIsolate));
__ push(object_);
__ push(scratch1_);
__ pop(slot_parameter);
__ pop(object_parameter);
__ mov(isolate_parameter,
Immediate(ExternalReference::isolate_address(__ isolate())));
__ Call(callable.code(), RelocInfo::CODE_TARGET);
RestoreRegisters(registers);
#else
RememberedSetAction const remembered_set_action = RememberedSetAction const remembered_set_action =
mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET
: OMIT_REMEMBERED_SET; : OMIT_REMEMBERED_SET;
SaveFPRegsMode const save_fp_mode = SaveFPRegsMode const save_fp_mode =
frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
__ lea(scratch1_, operand_);
__ CallStubDelayed( __ CallStubDelayed(
new (zone_) RecordWriteStub(nullptr, object_, scratch0_, scratch1_, new (zone_) RecordWriteStub(nullptr, object_, scratch0_, scratch1_,
remembered_set_action, save_fp_mode)); remembered_set_action, save_fp_mode));
#endif
} }
private: private:
......
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "src/compiler/code-generator.h" #include "src/callable.h"
#include "src/compilation-info.h" #include "src/compilation-info.h"
#include "src/compiler/code-generator-impl.h" #include "src/compiler/code-generator-impl.h"
#include "src/compiler/code-generator.h"
#include "src/compiler/gap-resolver.h" #include "src/compiler/gap-resolver.h"
#include "src/compiler/node-matchers.h" #include "src/compiler/node-matchers.h"
#include "src/compiler/osr.h" #include "src/compiler/osr.h"
...@@ -231,6 +232,28 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -231,6 +232,28 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
must_save_lr_(!gen->frame_access_state()->has_frame()), must_save_lr_(!gen->frame_access_state()->has_frame()),
zone_(gen->zone()) {} zone_(gen->zone()) {}
void SaveRegisters(RegList registers) {
DCHECK(NumRegs(registers) > 0);
RegList regs = 0;
for (int i = 0; i < Register::kNumRegisters; ++i) {
if ((registers >> i) & 1u) {
regs |= Register::from_code(i).bit();
}
}
__ MultiPush(regs | ra.bit());
}
void RestoreRegisters(RegList registers) {
DCHECK(NumRegs(registers) > 0);
RegList regs = 0;
for (int i = 0; i < Register::kNumRegisters; ++i) {
if ((registers >> i) & 1u) {
regs |= Register::from_code(i).bit();
}
}
__ MultiPop(regs | ra.bit());
}
void Generate() final { void Generate() final {
if (mode_ > RecordWriteMode::kValueIsPointer) { if (mode_ > RecordWriteMode::kValueIsPointer) {
__ JumpIfSmi(value_, exit()); __ JumpIfSmi(value_, exit());
...@@ -238,6 +261,32 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -238,6 +261,32 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
__ CheckPageFlag(value_, scratch0_, __ CheckPageFlag(value_, scratch0_,
MemoryChunk::kPointersToHereAreInterestingMask, eq, MemoryChunk::kPointersToHereAreInterestingMask, eq,
exit()); exit());
__ Addu(scratch1_, object_, index_);
#ifdef V8_CSA_WRITE_BARRIER
Callable const callable =
Builtins::CallableFor(__ isolate(), Builtins::kRecordWrite);
RegList registers = callable.descriptor().allocatable_registers();
SaveRegisters(registers);
Register object_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kObject));
Register slot_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kSlot));
Register isolate_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kIsolate));
__ Push(object_);
__ Push(scratch1_);
__ Pop(slot_parameter);
__ Pop(object_parameter);
__ li(isolate_parameter,
Operand(ExternalReference::isolate_address(__ isolate())));
__ Call(callable.code(), RelocInfo::CODE_TARGET);
RestoreRegisters(registers);
#else
RememberedSetAction const remembered_set_action = RememberedSetAction const remembered_set_action =
mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET
: OMIT_REMEMBERED_SET; : OMIT_REMEMBERED_SET;
...@@ -247,13 +296,13 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -247,13 +296,13 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
// We need to save and restore ra if the frame was elided. // We need to save and restore ra if the frame was elided.
__ Push(ra); __ Push(ra);
} }
__ Addu(scratch1_, object_, index_);
__ CallStubDelayed( __ CallStubDelayed(
new (zone_) RecordWriteStub(nullptr, object_, scratch0_, scratch1_, new (zone_) RecordWriteStub(nullptr, object_, scratch0_, scratch1_,
remembered_set_action, save_fp_mode)); remembered_set_action, save_fp_mode));
if (must_save_lr_) { if (must_save_lr_) {
__ Pop(ra); __ Pop(ra);
} }
#endif
} }
private: private:
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "src/callable.h"
#include "src/compilation-info.h" #include "src/compilation-info.h"
#include "src/compiler/code-generator-impl.h" #include "src/compiler/code-generator-impl.h"
#include "src/compiler/code-generator.h" #include "src/compiler/code-generator.h"
...@@ -231,6 +232,28 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -231,6 +232,28 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
must_save_lr_(!gen->frame_access_state()->has_frame()), must_save_lr_(!gen->frame_access_state()->has_frame()),
zone_(gen->zone()) {} zone_(gen->zone()) {}
void SaveRegisters(RegList registers) {
DCHECK(NumRegs(registers) > 0);
RegList regs = 0;
for (int i = 0; i < Register::kNumRegisters; ++i) {
if ((registers >> i) & 1u) {
regs |= Register::from_code(i).bit();
}
}
__ MultiPush(regs | ra.bit());
}
void RestoreRegisters(RegList registers) {
DCHECK(NumRegs(registers) > 0);
RegList regs = 0;
for (int i = 0; i < Register::kNumRegisters; ++i) {
if ((registers >> i) & 1u) {
regs |= Register::from_code(i).bit();
}
}
__ MultiPop(regs | ra.bit());
}
void Generate() final { void Generate() final {
if (mode_ > RecordWriteMode::kValueIsPointer) { if (mode_ > RecordWriteMode::kValueIsPointer) {
__ JumpIfSmi(value_, exit()); __ JumpIfSmi(value_, exit());
...@@ -238,6 +261,32 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -238,6 +261,32 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
__ CheckPageFlag(value_, scratch0_, __ CheckPageFlag(value_, scratch0_,
MemoryChunk::kPointersToHereAreInterestingMask, eq, MemoryChunk::kPointersToHereAreInterestingMask, eq,
exit()); exit());
__ Daddu(scratch1_, object_, index_);
#ifdef V8_CSA_WRITE_BARRIER
Callable const callable =
Builtins::CallableFor(__ isolate(), Builtins::kRecordWrite);
RegList registers = callable.descriptor().allocatable_registers();
SaveRegisters(registers);
Register object_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kObject));
Register slot_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kSlot));
Register isolate_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kIsolate));
__ Push(object_);
__ Push(scratch1_);
__ Pop(slot_parameter);
__ Pop(object_parameter);
__ li(isolate_parameter,
Operand(ExternalReference::isolate_address(__ isolate())));
__ Call(callable.code(), RelocInfo::CODE_TARGET);
RestoreRegisters(registers);
#else
RememberedSetAction const remembered_set_action = RememberedSetAction const remembered_set_action =
mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET
: OMIT_REMEMBERED_SET; : OMIT_REMEMBERED_SET;
...@@ -247,13 +296,13 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -247,13 +296,13 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
// We need to save and restore ra if the frame was elided. // We need to save and restore ra if the frame was elided.
__ Push(ra); __ Push(ra);
} }
__ Daddu(scratch1_, object_, index_);
__ CallStubDelayed( __ CallStubDelayed(
new (zone_) RecordWriteStub(nullptr, object_, scratch0_, scratch1_, new (zone_) RecordWriteStub(nullptr, object_, scratch0_, scratch1_,
remembered_set_action, save_fp_mode)); remembered_set_action, save_fp_mode));
if (must_save_lr_) { if (must_save_lr_) {
__ Pop(ra); __ Pop(ra);
} }
#endif
} }
private: private:
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "src/compiler/code-generator.h" #include "src/compiler/code-generator.h"
#include "src/callable.h"
#include "src/compilation-info.h" #include "src/compilation-info.h"
#include "src/compiler/code-generator-impl.h" #include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h" #include "src/compiler/gap-resolver.h"
...@@ -188,6 +189,29 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -188,6 +189,29 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
must_save_lr_(!gen->frame_access_state()->has_frame()), must_save_lr_(!gen->frame_access_state()->has_frame()),
zone_(gen->zone()) {} zone_(gen->zone()) {}
void SaveRegisters(RegList registers) {
DCHECK(NumRegs(registers) > 0);
RegList regs = 0;
for (int i = 0; i < Register::kNumRegisters; ++i) {
if ((registers >> i) & 1u) {
regs |= Register::from_code(i).bit();
}
}
__ MultiPush(regs);
}
void RestoreRegisters(RegList registers) {
DCHECK(NumRegs(registers) > 0);
RegList regs = 0;
for (int i = 0; i < Register::kNumRegisters; ++i) {
if ((registers >> i) & 1u) {
regs |= Register::from_code(i).bit();
}
}
__ MultiPop(regs);
}
void Generate() final { void Generate() final {
if (mode_ > RecordWriteMode::kValueIsPointer) { if (mode_ > RecordWriteMode::kValueIsPointer) {
__ JumpIfSmi(value_, exit()); __ JumpIfSmi(value_, exit());
...@@ -195,6 +219,42 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -195,6 +219,42 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
__ CheckPageFlag(value_, scratch0_, __ CheckPageFlag(value_, scratch0_,
MemoryChunk::kPointersToHereAreInterestingMask, eq, MemoryChunk::kPointersToHereAreInterestingMask, eq,
exit()); exit());
if (offset_.is(no_reg)) {
__ addi(scratch1_, object_, Operand(offset_immediate_));
} else {
DCHECK_EQ(0, offset_immediate_);
__ add(scratch1_, object_, offset_);
}
#ifdef V8_CSA_WRITE_BARRIER
Callable const callable =
Builtins::CallableFor(__ isolate(), Builtins::kRecordWrite);
RegList registers = callable.descriptor().allocatable_registers();
SaveRegisters(registers);
__ mflr(scratch0_);
__ Push(scratch0_);
Register object_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kObject));
Register slot_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kSlot));
Register isolate_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kIsolate));
__ push(object_);
__ push(scratch1_);
__ pop(slot_parameter);
__ pop(object_parameter);
__ mov(isolate_parameter,
Operand(ExternalReference::isolate_address(__ isolate())));
__ Call(callable.code(), RelocInfo::CODE_TARGET);
__ Pop(scratch0_);
__ mtlr(scratch0_);
RestoreRegisters(registers);
#else
RememberedSetAction const remembered_set_action = RememberedSetAction const remembered_set_action =
mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET
: OMIT_REMEMBERED_SET; : OMIT_REMEMBERED_SET;
...@@ -205,12 +265,6 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -205,12 +265,6 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
__ mflr(scratch1_); __ mflr(scratch1_);
__ Push(scratch1_); __ Push(scratch1_);
} }
if (offset_.is(no_reg)) {
__ addi(scratch1_, object_, Operand(offset_immediate_));
} else {
DCHECK_EQ(0, offset_immediate_);
__ add(scratch1_, object_, offset_);
}
if (must_save_lr_ && FLAG_enable_embedded_constant_pool) { if (must_save_lr_ && FLAG_enable_embedded_constant_pool) {
ConstantPoolUnavailableScope constant_pool_unavailable(tasm()); ConstantPoolUnavailableScope constant_pool_unavailable(tasm());
__ CallStubDelayed( __ CallStubDelayed(
...@@ -226,6 +280,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -226,6 +280,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
__ Pop(scratch1_); __ Pop(scratch1_);
__ mtlr(scratch1_); __ mtlr(scratch1_);
} }
#endif
} }
private: private:
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "src/compiler/code-generator.h" #include "src/compiler/code-generator.h"
#include "src/callable.h"
#include "src/compilation-info.h" #include "src/compilation-info.h"
#include "src/compiler/code-generator-impl.h" #include "src/compiler/code-generator-impl.h"
#include "src/compiler/gap-resolver.h" #include "src/compiler/gap-resolver.h"
...@@ -223,6 +224,28 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -223,6 +224,28 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
must_save_lr_(!gen->frame_access_state()->has_frame()), must_save_lr_(!gen->frame_access_state()->has_frame()),
zone_(gen->zone()) {} zone_(gen->zone()) {}
void SaveRegisters(RegList registers) {
DCHECK(NumRegs(registers) > 0);
RegList regs = 0;
for (int i = 0; i < Register::kNumRegisters; ++i) {
if ((registers >> i) & 1u) {
regs |= Register::from_code(i).bit();
}
}
__ MultiPush(regs | r14.bit());
}
void RestoreRegisters(RegList registers) {
DCHECK(NumRegs(registers) > 0);
RegList regs = 0;
for (int i = 0; i < Register::kNumRegisters; ++i) {
if ((registers >> i) & 1u) {
regs |= Register::from_code(i).bit();
}
}
__ MultiPop(regs | r14.bit());
}
void Generate() final { void Generate() final {
if (mode_ > RecordWriteMode::kValueIsPointer) { if (mode_ > RecordWriteMode::kValueIsPointer) {
__ JumpIfSmi(value_, exit()); __ JumpIfSmi(value_, exit());
...@@ -230,6 +253,37 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -230,6 +253,37 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
__ CheckPageFlag(value_, scratch0_, __ CheckPageFlag(value_, scratch0_,
MemoryChunk::kPointersToHereAreInterestingMask, eq, MemoryChunk::kPointersToHereAreInterestingMask, eq,
exit()); exit());
if (offset_.is(no_reg)) {
__ AddP(scratch1_, object_, Operand(offset_immediate_));
} else {
DCHECK_EQ(0, offset_immediate_);
__ AddP(scratch1_, object_, offset_);
}
#ifdef V8_CSA_WRITE_BARRIER
Callable const callable =
Builtins::CallableFor(__ isolate(), Builtins::kRecordWrite);
RegList registers = callable.descriptor().allocatable_registers();
SaveRegisters(registers);
Register object_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kObject));
Register slot_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kSlot));
Register isolate_parameter(callable.descriptor().GetRegisterParameter(
RecordWriteDescriptor::kIsolate));
__ Push(object_);
__ Push(scratch1_);
__ Pop(slot_parameter);
__ Pop(object_parameter);
__ mov(isolate_parameter,
Operand(ExternalReference::isolate_address(__ isolate())));
__ Call(callable.code(), RelocInfo::CODE_TARGET);
RestoreRegisters(registers);
#else
RememberedSetAction const remembered_set_action = RememberedSetAction const remembered_set_action =
mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET mode_ > RecordWriteMode::kValueIsMap ? EMIT_REMEMBERED_SET
: OMIT_REMEMBERED_SET; : OMIT_REMEMBERED_SET;
...@@ -239,12 +293,6 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -239,12 +293,6 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
// We need to save and restore r14 if the frame was elided. // We need to save and restore r14 if the frame was elided.
__ Push(r14); __ Push(r14);
} }
if (offset_.is(no_reg)) {
__ AddP(scratch1_, object_, Operand(offset_immediate_));
} else {
DCHECK_EQ(0, offset_immediate_);
__ AddP(scratch1_, object_, offset_);
}
__ CallStubDelayed( __ CallStubDelayed(
new (zone_) RecordWriteStub(nullptr, object_, scratch0_, scratch1_, new (zone_) RecordWriteStub(nullptr, object_, scratch0_, scratch1_,
remembered_set_action, save_fp_mode)); remembered_set_action, save_fp_mode));
...@@ -252,6 +300,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode { ...@@ -252,6 +300,7 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
// We need to save and restore r14 if the frame was elided. // We need to save and restore r14 if the frame was elided.
__ Pop(r14); __ Pop(r14);
} }
#endif
} }
private: private:
......
...@@ -22,9 +22,15 @@ void CallInterfaceDescriptor::DefaultInitializePlatformSpecific( ...@@ -22,9 +22,15 @@ void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
void RecordWriteDescriptor::InitializePlatformSpecific( void RecordWriteDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
// TODO(albertnetymk): Use default for now; should call static const Register default_stub_registers[] = {ebx, ecx, edx, edi,
// RestrictAllocatableRegisters like src/x64/interface-descriptors-x64.cc kReturnRegister0};
DefaultInitializePlatformSpecific(data, kParameterCount);
data->RestrictAllocatableRegisters(default_stub_registers,
arraysize(default_stub_registers));
CHECK_LE(static_cast<size_t>(kParameterCount),
arraysize(default_stub_registers));
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
} }
const Register FastNewFunctionContextDescriptor::FunctionRegister() { const Register FastNewFunctionContextDescriptor::FunctionRegister() {
......
...@@ -22,9 +22,14 @@ void CallInterfaceDescriptor::DefaultInitializePlatformSpecific( ...@@ -22,9 +22,14 @@ void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
void RecordWriteDescriptor::InitializePlatformSpecific( void RecordWriteDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
// TODO(albertnetymk): Use default for now; should call const Register default_stub_registers[] = {a0, a1, a2, a3, kReturnRegister0};
// RestrictAllocatableRegisters like src/x64/interface-descriptors-x64.cc
DefaultInitializePlatformSpecific(data, kParameterCount); data->RestrictAllocatableRegisters(default_stub_registers,
arraysize(default_stub_registers));
CHECK_LE(static_cast<size_t>(kParameterCount),
arraysize(default_stub_registers));
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
} }
const Register FastNewFunctionContextDescriptor::FunctionRegister() { const Register FastNewFunctionContextDescriptor::FunctionRegister() {
......
...@@ -22,9 +22,14 @@ void CallInterfaceDescriptor::DefaultInitializePlatformSpecific( ...@@ -22,9 +22,14 @@ void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
void RecordWriteDescriptor::InitializePlatformSpecific( void RecordWriteDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
// TODO(albertnetymk): Use default for now; should call const Register default_stub_registers[] = {a0, a1, a2, a3, kReturnRegister0};
// RestrictAllocatableRegisters like src/x64/interface-descriptors-x64.cc
DefaultInitializePlatformSpecific(data, kParameterCount); data->RestrictAllocatableRegisters(default_stub_registers,
arraysize(default_stub_registers));
CHECK_LE(static_cast<size_t>(kParameterCount),
arraysize(default_stub_registers));
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
} }
const Register FastNewFunctionContextDescriptor::FunctionRegister() { const Register FastNewFunctionContextDescriptor::FunctionRegister() {
......
...@@ -22,9 +22,14 @@ void CallInterfaceDescriptor::DefaultInitializePlatformSpecific( ...@@ -22,9 +22,14 @@ void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
void RecordWriteDescriptor::InitializePlatformSpecific( void RecordWriteDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
// TODO(albertnetymk): Use default for now; should call const Register default_stub_registers[] = {r3, r4, r5, r6, r7};
// RestrictAllocatableRegisters like src/x64/interface-descriptors-x64.cc
DefaultInitializePlatformSpecific(data, kParameterCount); data->RestrictAllocatableRegisters(default_stub_registers,
arraysize(default_stub_registers));
CHECK_LE(static_cast<size_t>(kParameterCount),
arraysize(default_stub_registers));
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
} }
const Register FastNewFunctionContextDescriptor::FunctionRegister() { const Register FastNewFunctionContextDescriptor::FunctionRegister() {
......
...@@ -22,9 +22,14 @@ void CallInterfaceDescriptor::DefaultInitializePlatformSpecific( ...@@ -22,9 +22,14 @@ void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
void RecordWriteDescriptor::InitializePlatformSpecific( void RecordWriteDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
// TODO(albertnetymk): Use default for now; should call const Register default_stub_registers[] = {r2, r3, r4, r5, r6};
// RestrictAllocatableRegisters like src/x64/interface-descriptors-x64.cc
DefaultInitializePlatformSpecific(data, kParameterCount); data->RestrictAllocatableRegisters(default_stub_registers,
arraysize(default_stub_registers));
CHECK_LE(static_cast<size_t>(kParameterCount),
arraysize(default_stub_registers));
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
} }
const Register FastNewFunctionContextDescriptor::FunctionRegister() { const Register FastNewFunctionContextDescriptor::FunctionRegister() {
......
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