PPC/s390: [wasm] Save FP & PC when calling C functions

Port 6cd28b522a

Original Commit Message:

    Added implementations for ia32, arm, arm64.

    mips/mips64 will be committed in separate CL once the build is green
    again in order not to stall this CL with the supported architectures.

    compilation by using alternative temp register for x64.

    macro assemblers.

R=ecmziegler@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=
LOG=N

Change-Id: Ib08e31dfa11f0254c7888ce17dd27e7d0154c752
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2078898
Reviewed-by: Junliang Yan <jyan@ca.ibm.com>
Commit-Queue: Milad Farazmand <miladfar@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#66490}
This commit is contained in:
Milad Farazmand 2020-02-27 20:41:51 +00:00 committed by Commit Bot
parent af7bf14fce
commit 242d58e3c4
8 changed files with 85 additions and 50 deletions

View File

@ -1897,20 +1897,32 @@ void TurboAssembler::CallCFunctionHelper(Register function,
// Save the frame pointer and PC so that the stack layout remains iterable, // Save the frame pointer and PC so that the stack layout remains iterable,
// even without an ExitFrame which normally exists between JS and C frames. // even without an ExitFrame which normally exists between JS and C frames.
if (isolate() != nullptr) { Register addr_scratch = r7;
Register scratch1 = r7; Register scratch = r8;
Register scratch2 = r8; Push(scratch);
Push(scratch1, scratch2); mflr(scratch);
// See x64 code for reasoning about how to address the isolate data fields.
mflr(scratch2); if (root_array_available()) {
Move(scratch1, ExternalReference::fast_c_call_caller_pc_address(isolate()));
LoadPC(r0); LoadPC(r0);
StoreP(r0, MemOperand(scratch1)); StoreP(r0, MemOperand(kRootRegister,
Move(scratch1, ExternalReference::fast_c_call_caller_fp_address(isolate())); IsolateData::fast_c_call_caller_pc_offset()));
StoreP(fp, MemOperand(scratch1)); StoreP(fp, MemOperand(kRootRegister,
mtlr(scratch2); IsolateData::fast_c_call_caller_fp_offset()));
Pop(scratch1, scratch2); } else {
DCHECK_NOT_NULL(isolate());
Push(addr_scratch);
Move(addr_scratch,
ExternalReference::fast_c_call_caller_pc_address(isolate()));
LoadPC(r0);
StoreP(r0, MemOperand(addr_scratch));
Move(addr_scratch,
ExternalReference::fast_c_call_caller_fp_address(isolate()));
StoreP(fp, MemOperand(addr_scratch));
Pop(addr_scratch);
} }
mtlr(scratch);
Pop(scratch);
// Just call directly. The function called cannot cause a GC, or // Just call directly. The function called cannot cause a GC, or
// allow preemption, so the return address in the link register // allow preemption, so the return address in the link register
@ -1930,15 +1942,21 @@ void TurboAssembler::CallCFunctionHelper(Register function,
Call(dest); Call(dest);
if (isolate() != nullptr) { // We don't unset the PC; the FP is the source of truth.
// We don't unset the PC; the FP is the source of truth. Register zero_scratch = r0;
Register scratch1 = r7; mov(zero_scratch, Operand::Zero());
Register scratch2 = r8;
Push(scratch1, scratch2); if (root_array_available()) {
Move(scratch1, ExternalReference::fast_c_call_caller_fp_address(isolate())); StoreP(
mov(scratch2, Operand::Zero()); zero_scratch,
StoreP(scratch2, MemOperand(scratch1)); MemOperand(kRootRegister, IsolateData::fast_c_call_caller_fp_offset()));
Pop(scratch1, scratch2); } else {
DCHECK_NOT_NULL(isolate());
Push(addr_scratch);
Move(addr_scratch,
ExternalReference::fast_c_call_caller_fp_address(isolate()));
StoreP(zero_scratch, MemOperand(addr_scratch));
Pop(addr_scratch);
} }
// Remove frame bought in PrepareCallCFunction // Remove frame bought in PrepareCallCFunction

View File

@ -1828,16 +1828,24 @@ void TurboAssembler::CallCFunctionHelper(Register function,
// Save the frame pointer and PC so that the stack layout remains iterable, // Save the frame pointer and PC so that the stack layout remains iterable,
// even without an ExitFrame which normally exists between JS and C frames. // even without an ExitFrame which normally exists between JS and C frames.
if (isolate() != nullptr) { Register addr_scratch = r1;
Register scratch = r6; // See x64 code for reasoning about how to address the isolate data fields.
push(scratch); if (root_array_available()) {
Move(scratch, ExternalReference::fast_c_call_caller_pc_address(isolate()));
LoadPC(r0); LoadPC(r0);
StoreP(r0, MemOperand(scratch)); StoreP(r0, MemOperand(kRootRegister,
Move(scratch, ExternalReference::fast_c_call_caller_fp_address(isolate())); IsolateData::fast_c_call_caller_pc_offset()));
StoreP(fp, MemOperand(scratch)); StoreP(fp, MemOperand(kRootRegister,
pop(scratch); IsolateData::fast_c_call_caller_fp_offset()));
} else {
DCHECK_NOT_NULL(isolate());
Move(addr_scratch,
ExternalReference::fast_c_call_caller_pc_address(isolate()));
LoadPC(r0);
StoreP(r0, MemOperand(addr_scratch));
Move(addr_scratch,
ExternalReference::fast_c_call_caller_fp_address(isolate()));
StoreP(fp, MemOperand(addr_scratch));
} }
// Just call directly. The function called cannot cause a GC, or // Just call directly. The function called cannot cause a GC, or
@ -1851,15 +1859,19 @@ void TurboAssembler::CallCFunctionHelper(Register function,
Call(dest); Call(dest);
if (isolate() != nullptr) { // We don't unset the PC; the FP is the source of truth.
// We don't unset the PC; the FP is the source of truth. Register zero_scratch = r0;
Register scratch1 = r6; lghi(zero_scratch, Operand::Zero());
Register scratch2 = r7;
Push(scratch1, scratch2); if (root_array_available()) {
Move(scratch1, ExternalReference::fast_c_call_caller_fp_address(isolate())); StoreP(
lghi(scratch2, Operand::Zero()); zero_scratch,
StoreP(scratch2, MemOperand(scratch1)); MemOperand(kRootRegister, IsolateData::fast_c_call_caller_fp_offset()));
Pop(scratch1, scratch2); } else {
DCHECK_NOT_NULL(isolate());
Move(addr_scratch,
ExternalReference::fast_c_call_caller_fp_address(isolate()));
StoreP(zero_scratch, MemOperand(addr_scratch));
} }
int stack_passed_arguments = int stack_passed_arguments =

View File

@ -102,6 +102,7 @@ RegExpMacroAssemblerPPC::RegExpMacroAssemblerPPC(Isolate* isolate, Zone* zone,
: NativeRegExpMacroAssembler(isolate, zone), : NativeRegExpMacroAssembler(isolate, zone),
masm_(new MacroAssembler(isolate, CodeObjectRequired::kYes, masm_(new MacroAssembler(isolate, CodeObjectRequired::kYes,
NewAssemblerBuffer(kRegExpCodeSize))), NewAssemblerBuffer(kRegExpCodeSize))),
no_root_array_scope_(masm_),
mode_(mode), mode_(mode),
num_registers_(registers_to_save), num_registers_(registers_to_save),
num_saved_registers_(registers_to_save), num_saved_registers_(registers_to_save),
@ -123,7 +124,6 @@ RegExpMacroAssemblerPPC::RegExpMacroAssemblerPPC(Isolate* isolate, Zone* zone,
__ bind(&start_label_); // And then continue from here. __ bind(&start_label_); // And then continue from here.
} }
RegExpMacroAssemblerPPC::~RegExpMacroAssemblerPPC() { RegExpMacroAssemblerPPC::~RegExpMacroAssemblerPPC() {
delete masm_; delete masm_;
// Unuse labels in case we throw away the assembler without calling GetCode. // Unuse labels in case we throw away the assembler without calling GetCode.

View File

@ -181,6 +181,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerPPC
Isolate* isolate() const { return masm_->isolate(); } Isolate* isolate() const { return masm_->isolate(); }
MacroAssembler* masm_; MacroAssembler* masm_;
NoRootArrayScope no_root_array_scope_;
// Which mode to generate code for (Latin1 or UC16). // Which mode to generate code for (Latin1 or UC16).
Mode mode_; Mode mode_;

View File

@ -104,6 +104,7 @@ RegExpMacroAssemblerS390::RegExpMacroAssemblerS390(Isolate* isolate, Zone* zone,
: NativeRegExpMacroAssembler(isolate, zone), : NativeRegExpMacroAssembler(isolate, zone),
masm_(new MacroAssembler(isolate, CodeObjectRequired::kYes, masm_(new MacroAssembler(isolate, CodeObjectRequired::kYes,
NewAssemblerBuffer(kRegExpCodeSize))), NewAssemblerBuffer(kRegExpCodeSize))),
no_root_array_scope_(masm_),
mode_(mode), mode_(mode),
num_registers_(registers_to_save), num_registers_(registers_to_save),
num_saved_registers_(registers_to_save), num_saved_registers_(registers_to_save),

View File

@ -183,6 +183,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerS390
Isolate* isolate() const { return masm_->isolate(); } Isolate* isolate() const { return masm_->isolate(); }
MacroAssembler* masm_; MacroAssembler* masm_;
NoRootArrayScope no_root_array_scope_;
// Which mode to generate code for (Latin1 or UC16). // Which mode to generate code for (Latin1 or UC16).
Mode mode_; Mode mode_;

View File

@ -22,15 +22,15 @@ class TurboAssemblerTest : public TestWithIsolate {};
TEST_F(TurboAssemblerTest, TestHardAbort) { TEST_F(TurboAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer(); auto buffer = AllocateAssemblerBuffer();
TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo, TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView()); buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true); __ set_abort_hard(true);
__ Abort(AbortReason::kNoReason); __ Abort(AbortReason::kNoReason);
CodeDesc desc; CodeDesc desc;
tasm.GetCode(nullptr, &desc); tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable(); buffer->MakeExecutable();
// We need an isolate here to execute in the simulator. // We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start()); auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
@ -40,9 +40,9 @@ TEST_F(TurboAssemblerTest, TestHardAbort) {
TEST_F(TurboAssemblerTest, TestCheck) { TEST_F(TurboAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer(); auto buffer = AllocateAssemblerBuffer();
TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo, TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView()); buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true); __ set_abort_hard(true);
// Fail if the first parameter is 17. // Fail if the first parameter is 17.
@ -52,7 +52,7 @@ TEST_F(TurboAssemblerTest, TestCheck) {
__ Ret(); __ Ret();
CodeDesc desc; CodeDesc desc;
tasm.GetCode(nullptr, &desc); tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable(); buffer->MakeExecutable();
// We need an isolate here to execute in the simulator. // We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start()); auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());

View File

@ -22,14 +22,15 @@ class TurboAssemblerTest : public TestWithIsolate {};
TEST_F(TurboAssemblerTest, TestHardAbort) { TEST_F(TurboAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer(); auto buffer = AllocateAssemblerBuffer();
TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo, TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView()); buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true); __ set_abort_hard(true);
__ Abort(AbortReason::kNoReason); __ Abort(AbortReason::kNoReason);
CodeDesc desc; CodeDesc desc;
tasm.GetCode(nullptr, &desc); tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable(); buffer->MakeExecutable();
// We need an isolate here to execute in the simulator. // We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start()); auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
@ -39,8 +40,9 @@ TEST_F(TurboAssemblerTest, TestHardAbort) {
TEST_F(TurboAssemblerTest, TestCheck) { TEST_F(TurboAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer(); auto buffer = AllocateAssemblerBuffer();
TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo, TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView()); buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true); __ set_abort_hard(true);
// Fail if the first parameter is 17. // Fail if the first parameter is 17.
@ -50,7 +52,7 @@ TEST_F(TurboAssemblerTest, TestCheck) {
__ Ret(); __ Ret();
CodeDesc desc; CodeDesc desc;
tasm.GetCode(nullptr, &desc); tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable(); buffer->MakeExecutable();
// We need an isolate here to execute in the simulator. // We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start()); auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());