Commit 242d58e3 authored by Milad Farazmand's avatar Milad Farazmand Committed by Commit Bot

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

Port 6cd28b52

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/+/2078898Reviewed-by: 's avatarJunliang Yan <jyan@ca.ibm.com>
Commit-Queue: Milad Farazmand <miladfar@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#66490}
parent af7bf14f
...@@ -1897,20 +1897,32 @@ void TurboAssembler::CallCFunctionHelper(Register function, ...@@ -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.
if (root_array_available()) {
LoadPC(r0);
StoreP(r0, MemOperand(kRootRegister,
IsolateData::fast_c_call_caller_pc_offset()));
StoreP(fp, MemOperand(kRootRegister,
IsolateData::fast_c_call_caller_fp_offset()));
} else {
DCHECK_NOT_NULL(isolate());
Push(addr_scratch);
mflr(scratch2); Move(addr_scratch,
Move(scratch1, ExternalReference::fast_c_call_caller_pc_address(isolate())); ExternalReference::fast_c_call_caller_pc_address(isolate()));
LoadPC(r0); LoadPC(r0);
StoreP(r0, MemOperand(scratch1)); StoreP(r0, MemOperand(addr_scratch));
Move(scratch1, ExternalReference::fast_c_call_caller_fp_address(isolate())); Move(addr_scratch,
StoreP(fp, MemOperand(scratch1)); ExternalReference::fast_c_call_caller_fp_address(isolate()));
mtlr(scratch2); StoreP(fp, MemOperand(addr_scratch));
Pop(scratch1, scratch2); 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, ...@@ -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 scratch1 = r7; Register zero_scratch = r0;
Register scratch2 = r8; mov(zero_scratch, Operand::Zero());
Push(scratch1, scratch2);
Move(scratch1, ExternalReference::fast_c_call_caller_fp_address(isolate())); if (root_array_available()) {
mov(scratch2, Operand::Zero()); StoreP(
StoreP(scratch2, MemOperand(scratch1)); zero_scratch,
Pop(scratch1, scratch2); MemOperand(kRootRegister, IsolateData::fast_c_call_caller_fp_offset()));
} 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
......
...@@ -1828,16 +1828,24 @@ void TurboAssembler::CallCFunctionHelper(Register function, ...@@ -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()) {
LoadPC(r0);
StoreP(r0, MemOperand(kRootRegister,
IsolateData::fast_c_call_caller_pc_offset()));
StoreP(fp, MemOperand(kRootRegister,
IsolateData::fast_c_call_caller_fp_offset()));
} else {
DCHECK_NOT_NULL(isolate());
Move(scratch, ExternalReference::fast_c_call_caller_pc_address(isolate())); Move(addr_scratch,
ExternalReference::fast_c_call_caller_pc_address(isolate()));
LoadPC(r0); LoadPC(r0);
StoreP(r0, MemOperand(scratch)); StoreP(r0, MemOperand(addr_scratch));
Move(scratch, ExternalReference::fast_c_call_caller_fp_address(isolate())); Move(addr_scratch,
StoreP(fp, MemOperand(scratch)); ExternalReference::fast_c_call_caller_fp_address(isolate()));
pop(scratch); 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, ...@@ -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 scratch1 = r6; Register zero_scratch = r0;
Register scratch2 = r7; lghi(zero_scratch, Operand::Zero());
Push(scratch1, scratch2);
Move(scratch1, ExternalReference::fast_c_call_caller_fp_address(isolate())); if (root_array_available()) {
lghi(scratch2, Operand::Zero()); StoreP(
StoreP(scratch2, MemOperand(scratch1)); zero_scratch,
Pop(scratch1, scratch2); MemOperand(kRootRegister, IsolateData::fast_c_call_caller_fp_offset()));
} 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 =
......
...@@ -102,6 +102,7 @@ RegExpMacroAssemblerPPC::RegExpMacroAssemblerPPC(Isolate* isolate, Zone* zone, ...@@ -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, ...@@ -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.
......
...@@ -181,6 +181,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerPPC ...@@ -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_;
......
...@@ -104,6 +104,7 @@ RegExpMacroAssemblerS390::RegExpMacroAssemblerS390(Isolate* isolate, Zone* zone, ...@@ -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),
......
...@@ -183,6 +183,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerS390 ...@@ -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_;
......
...@@ -22,15 +22,15 @@ class TurboAssemblerTest : public TestWithIsolate {}; ...@@ -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) { ...@@ -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) { ...@@ -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());
......
...@@ -22,14 +22,15 @@ class TurboAssemblerTest : public TestWithIsolate {}; ...@@ -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) { ...@@ -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) { ...@@ -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());
......
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