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,
// 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.
if (isolate() != nullptr) {
Register scratch1 = r7;
Register scratch2 = r8;
Push(scratch1, scratch2);
Register addr_scratch = r7;
Register scratch = r8;
Push(scratch);
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(scratch1, ExternalReference::fast_c_call_caller_pc_address(isolate()));
Move(addr_scratch,
ExternalReference::fast_c_call_caller_pc_address(isolate()));
LoadPC(r0);
StoreP(r0, MemOperand(scratch1));
Move(scratch1, ExternalReference::fast_c_call_caller_fp_address(isolate()));
StoreP(fp, MemOperand(scratch1));
mtlr(scratch2);
Pop(scratch1, scratch2);
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
// allow preemption, so the return address in the link register
......@@ -1930,15 +1942,21 @@ void TurboAssembler::CallCFunctionHelper(Register function,
Call(dest);
if (isolate() != nullptr) {
// We don't unset the PC; the FP is the source of truth.
Register scratch1 = r7;
Register scratch2 = r8;
Push(scratch1, scratch2);
Move(scratch1, ExternalReference::fast_c_call_caller_fp_address(isolate()));
mov(scratch2, Operand::Zero());
StoreP(scratch2, MemOperand(scratch1));
Pop(scratch1, scratch2);
// We don't unset the PC; the FP is the source of truth.
Register zero_scratch = r0;
mov(zero_scratch, Operand::Zero());
if (root_array_available()) {
StoreP(
zero_scratch,
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
......
......@@ -1828,16 +1828,24 @@ void TurboAssembler::CallCFunctionHelper(Register function,
// 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.
if (isolate() != nullptr) {
Register scratch = r6;
push(scratch);
Register addr_scratch = r1;
// 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());
Move(scratch, ExternalReference::fast_c_call_caller_pc_address(isolate()));
Move(addr_scratch,
ExternalReference::fast_c_call_caller_pc_address(isolate()));
LoadPC(r0);
StoreP(r0, MemOperand(scratch));
Move(scratch, ExternalReference::fast_c_call_caller_fp_address(isolate()));
StoreP(fp, MemOperand(scratch));
pop(scratch);
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
......@@ -1851,15 +1859,19 @@ void TurboAssembler::CallCFunctionHelper(Register function,
Call(dest);
if (isolate() != nullptr) {
// We don't unset the PC; the FP is the source of truth.
Register scratch1 = r6;
Register scratch2 = r7;
Push(scratch1, scratch2);
Move(scratch1, ExternalReference::fast_c_call_caller_fp_address(isolate()));
lghi(scratch2, Operand::Zero());
StoreP(scratch2, MemOperand(scratch1));
Pop(scratch1, scratch2);
// We don't unset the PC; the FP is the source of truth.
Register zero_scratch = r0;
lghi(zero_scratch, Operand::Zero());
if (root_array_available()) {
StoreP(
zero_scratch,
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 =
......
......@@ -102,6 +102,7 @@ RegExpMacroAssemblerPPC::RegExpMacroAssemblerPPC(Isolate* isolate, Zone* zone,
: NativeRegExpMacroAssembler(isolate, zone),
masm_(new MacroAssembler(isolate, CodeObjectRequired::kYes,
NewAssemblerBuffer(kRegExpCodeSize))),
no_root_array_scope_(masm_),
mode_(mode),
num_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.
}
RegExpMacroAssemblerPPC::~RegExpMacroAssemblerPPC() {
delete masm_;
// Unuse labels in case we throw away the assembler without calling GetCode.
......
......@@ -181,6 +181,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerPPC
Isolate* isolate() const { return masm_->isolate(); }
MacroAssembler* masm_;
NoRootArrayScope no_root_array_scope_;
// Which mode to generate code for (Latin1 or UC16).
Mode mode_;
......
......@@ -104,6 +104,7 @@ RegExpMacroAssemblerS390::RegExpMacroAssemblerS390(Isolate* isolate, Zone* zone,
: NativeRegExpMacroAssembler(isolate, zone),
masm_(new MacroAssembler(isolate, CodeObjectRequired::kYes,
NewAssemblerBuffer(kRegExpCodeSize))),
no_root_array_scope_(masm_),
mode_(mode),
num_registers_(registers_to_save),
num_saved_registers_(registers_to_save),
......
......@@ -183,6 +183,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerS390
Isolate* isolate() const { return masm_->isolate(); }
MacroAssembler* masm_;
NoRootArrayScope no_root_array_scope_;
// Which mode to generate code for (Latin1 or UC16).
Mode mode_;
......
......@@ -22,15 +22,15 @@ class TurboAssemblerTest : public TestWithIsolate {};
TEST_F(TurboAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
tasm.GetCode(nullptr, &desc);
tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
......@@ -40,9 +40,9 @@ TEST_F(TurboAssemblerTest, TestHardAbort) {
TEST_F(TurboAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
// Fail if the first parameter is 17.
......@@ -52,7 +52,7 @@ TEST_F(TurboAssemblerTest, TestCheck) {
__ Ret();
CodeDesc desc;
tasm.GetCode(nullptr, &desc);
tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void, int>::FromBuffer(isolate(), buffer->start());
......
......@@ -22,14 +22,15 @@ class TurboAssemblerTest : public TestWithIsolate {};
TEST_F(TurboAssemblerTest, TestHardAbort) {
auto buffer = AllocateAssemblerBuffer();
TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
__ Abort(AbortReason::kNoReason);
CodeDesc desc;
tasm.GetCode(nullptr, &desc);
tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
auto f = GeneratedCode<void>::FromBuffer(isolate(), buffer->start());
......@@ -39,8 +40,9 @@ TEST_F(TurboAssemblerTest, TestHardAbort) {
TEST_F(TurboAssemblerTest, TestCheck) {
auto buffer = AllocateAssemblerBuffer();
TurboAssembler tasm(nullptr, AssemblerOptions{}, CodeObjectRequired::kNo,
TurboAssembler tasm(isolate(), AssemblerOptions{}, CodeObjectRequired::kNo,
buffer->CreateView());
__ set_root_array_available(false);
__ set_abort_hard(true);
// Fail if the first parameter is 17.
......@@ -50,7 +52,7 @@ TEST_F(TurboAssemblerTest, TestCheck) {
__ Ret();
CodeDesc desc;
tasm.GetCode(nullptr, &desc);
tasm.GetCode(isolate(), &desc);
buffer->MakeExecutable();
// We need an isolate here to execute in the simulator.
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