Commit 5d3f17f4 authored by Milad Fa's avatar Milad Fa Committed by V8 LUCI CQ

PPC/s390 [regexp]: Allow reentrant irregexp execution

Port: bba7c09a

Original Commit Message:
 .. by reusing the regexp stack from potentially multiple nested
 irregexp activations.

 To do this, we now maintain a stack pointer in RegExpStack. This stack
 pointer is synchronized at all boundaries between generated irregexp
 code and the outside world, i.e. when entering or returning from
 irregexp code, and when calling into C functions such as GrowStack.

Fixed: v8:11382
Change-Id: I0f97363a069c65f4fbe081b2f9fa796f9d950f43
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3179030Reviewed-by: 's avatarJunliang Yan <junyan@redhat.com>
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/main@{#77023}
parent 99365554
...@@ -6,14 +6,13 @@ ...@@ -6,14 +6,13 @@
#include "src/regexp/ppc/regexp-macro-assembler-ppc.h" #include "src/regexp/ppc/regexp-macro-assembler-ppc.h"
#include "src/base/bits.h"
#include "src/codegen/assembler-inl.h"
#include "src/codegen/macro-assembler.h" #include "src/codegen/macro-assembler.h"
#include "src/codegen/ppc/assembler-ppc-inl.h"
#include "src/heap/factory.h"
#include "src/logging/log.h" #include "src/logging/log.h"
#include "src/regexp/regexp-macro-assembler.h" #include "src/objects/code-inl.h"
#include "src/regexp/regexp-stack.h" #include "src/regexp/regexp-stack.h"
#include "src/snapshot/embedded/embedded-data.h" #include "src/snapshot/embedded/embedded-data.h"
#include "src/strings/unicode.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -102,6 +101,7 @@ RegExpMacroAssemblerPPC::RegExpMacroAssemblerPPC(Isolate* isolate, Zone* zone, ...@@ -102,6 +101,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),
...@@ -111,8 +111,6 @@ RegExpMacroAssemblerPPC::RegExpMacroAssemblerPPC(Isolate* isolate, Zone* zone, ...@@ -111,8 +111,6 @@ RegExpMacroAssemblerPPC::RegExpMacroAssemblerPPC(Isolate* isolate, Zone* zone,
backtrack_label_(), backtrack_label_(),
exit_label_(), exit_label_(),
internal_failure_label_() { internal_failure_label_() {
masm_->set_root_array_available(false);
DCHECK_EQ(0, registers_to_save % 2); DCHECK_EQ(0, registers_to_save % 2);
...@@ -652,6 +650,42 @@ void RegExpMacroAssemblerPPC::Fail() { ...@@ -652,6 +650,42 @@ void RegExpMacroAssemblerPPC::Fail() {
__ b(&exit_label_); __ b(&exit_label_);
} }
void RegExpMacroAssemblerPPC::LoadRegExpStackPointerFromMemory(Register dst) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_stack_pointer(isolate());
__ mov(dst, Operand(ref));
__ LoadU64(dst, MemOperand(dst));
}
void RegExpMacroAssemblerPPC::StoreRegExpStackPointerToMemory(
Register src, Register scratch) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_stack_pointer(isolate());
__ mov(scratch, Operand(ref));
__ StoreU64(src, MemOperand(scratch));
}
void RegExpMacroAssemblerPPC::PushRegExpBasePointer(Register scratch1,
Register scratch2) {
LoadRegExpStackPointerFromMemory(scratch1);
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ mov(scratch2, Operand(ref));
__ LoadU64(scratch2, MemOperand(scratch2));
__ SubS64(scratch2, scratch1, scratch2);
__ StoreU64(scratch2, MemOperand(frame_pointer(), kRegExpStackBasePointer));
}
void RegExpMacroAssemblerPPC::PopRegExpBasePointer(Register scratch1,
Register scratch2) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ LoadU64(scratch1, MemOperand(frame_pointer(), kRegExpStackBasePointer));
__ mov(scratch2, Operand(ref));
__ LoadU64(scratch2, MemOperand(scratch2));
__ AddS64(scratch1, scratch1, scratch2);
StoreRegExpStackPointerToMemory(scratch1, scratch2);
}
Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) { Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) {
Label return_r3; Label return_r3;
...@@ -705,6 +739,13 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) { ...@@ -705,6 +739,13 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) {
__ push(r3); // Make room for "string start - 1" constant. __ push(r3); // Make room for "string start - 1" constant.
STATIC_ASSERT(kBacktrackCount == kStringStartMinusOne - kSystemPointerSize); STATIC_ASSERT(kBacktrackCount == kStringStartMinusOne - kSystemPointerSize);
__ push(r3); // The backtrack counter. __ push(r3); // The backtrack counter.
STATIC_ASSERT(kRegExpStackBasePointer ==
kBacktrackCount - kSystemPointerSize);
__ push(r3); // The regexp stack base ptr.
// Store the regexp base pointer - we'll later restore it / write it to
// memory when returning from this irregexp code object.
PushRegExpBasePointer(r3, r4);
// Check if we have space on the stack for registers. // Check if we have space on the stack for registers.
Label stack_limit_hit; Label stack_limit_hit;
...@@ -793,8 +834,7 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) { ...@@ -793,8 +834,7 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) {
} }
// Initialize backtrack stack pointer. // Initialize backtrack stack pointer.
__ LoadU64(backtrack_stackpointer(), LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
MemOperand(frame_pointer(), kStackHighEnd));
__ b(&start_label_); __ b(&start_label_);
...@@ -896,6 +936,10 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) { ...@@ -896,6 +936,10 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) {
} }
__ bind(&return_r3); __ bind(&return_r3);
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(r4, r5);
// Skip sp past regexp registers and local variables.. // Skip sp past regexp registers and local variables..
__ mr(sp, frame_pointer()); __ mr(sp, frame_pointer());
// Restore registers r25..r31 and return (restoring lr to pc). // Restore registers r25..r31 and return (restoring lr to pc).
...@@ -916,12 +960,16 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) { ...@@ -916,12 +960,16 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) {
if (check_preempt_label_.is_linked()) { if (check_preempt_label_.is_linked()) {
SafeCallTarget(&check_preempt_label_); SafeCallTarget(&check_preempt_label_);
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), r4);
CallCheckStackGuardState(r3); CallCheckStackGuardState(r3);
__ cmpi(r3, Operand::Zero()); __ cmpi(r3, Operand::Zero());
// If returning non-zero, we should end execution with the given // If returning non-zero, we should end execution with the given
// result as return value. // result as return value.
__ bne(&return_r3); __ bne(&return_r3);
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
// String might have moved: Reload end of string from frame. // String might have moved: Reload end of string from frame.
__ LoadU64(end_of_input_address(), __ LoadU64(end_of_input_address(),
MemOperand(frame_pointer(), kInputEnd)); MemOperand(frame_pointer(), kInputEnd));
...@@ -932,17 +980,18 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) { ...@@ -932,17 +980,18 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) {
if (stack_overflow_label_.is_linked()) { if (stack_overflow_label_.is_linked()) {
SafeCallTarget(&stack_overflow_label_); SafeCallTarget(&stack_overflow_label_);
// Call GrowStack(backtrack_stackpointer(), &stack_base) // Call GrowStack(isolate).
static const int num_arguments = 3;
__ PrepareCallCFunction(num_arguments, r3); StoreRegExpStackPointerToMemory(backtrack_stackpointer(), r4);
__ mr(r3, backtrack_stackpointer());
__ addi(r4, frame_pointer(), Operand(kStackHighEnd)); static constexpr int kNumArguments = 1;
__ mov(r5, Operand(ExternalReference::isolate_address(isolate()))); __ PrepareCallCFunction(kNumArguments, r3);
__ mov(r3, Operand(ExternalReference::isolate_address(isolate())));
ExternalReference grow_stack = ExternalReference grow_stack =
ExternalReference::re_grow_stack(isolate()); ExternalReference::re_grow_stack(isolate());
__ CallCFunction(grow_stack, num_arguments); __ CallCFunction(grow_stack, kNumArguments);
// If return nullptr, we have failed to grow the stack, and // If nullptr is returned, we have failed to grow the stack, and must exit
// must exit with a stack-overflow exception. // with a stack-overflow exception.
__ cmpi(r3, Operand::Zero()); __ cmpi(r3, Operand::Zero());
__ beq(&exit_with_exception); __ beq(&exit_with_exception);
// Otherwise use return value as new stack pointer. // Otherwise use return value as new stack pointer.
...@@ -1045,14 +1094,24 @@ void RegExpMacroAssemblerPPC::ReadCurrentPositionFromRegister(int reg) { ...@@ -1045,14 +1094,24 @@ void RegExpMacroAssemblerPPC::ReadCurrentPositionFromRegister(int reg) {
__ LoadU64(current_input_offset(), register_location(reg), r0); __ LoadU64(current_input_offset(), register_location(reg), r0);
} }
void RegExpMacroAssemblerPPC::WriteStackPointerToRegister(int reg) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ mov(r4, Operand(ref));
__ LoadU64(r4, MemOperand(r4));
__ SubS64(r3, backtrack_stackpointer(), r4);
__ StoreU64(r3, register_location(reg));
}
void RegExpMacroAssemblerPPC::ReadStackPointerFromRegister(int reg) { void RegExpMacroAssemblerPPC::ReadStackPointerFromRegister(int reg) {
__ LoadU64(backtrack_stackpointer(), register_location(reg), r0); ExternalReference ref =
__ LoadU64(r3, MemOperand(frame_pointer(), kStackHighEnd)); ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ add(backtrack_stackpointer(), backtrack_stackpointer(), r3); __ mov(r3, Operand(ref));
__ LoadU64(r3, MemOperand(r3));
__ LoadU64(backtrack_stackpointer(), register_location(reg));
__ AddS64(backtrack_stackpointer(), backtrack_stackpointer(), r3);
} }
void RegExpMacroAssemblerPPC::SetCurrentPositionFromEnd(int by) { void RegExpMacroAssemblerPPC::SetCurrentPositionFromEnd(int by) {
Label after_position; Label after_position;
__ CmpS64(current_input_offset(), Operand(-by * char_size()), r0); __ CmpS64(current_input_offset(), Operand(-by * char_size()), r0);
...@@ -1099,14 +1158,6 @@ void RegExpMacroAssemblerPPC::ClearRegisters(int reg_from, int reg_to) { ...@@ -1099,14 +1158,6 @@ void RegExpMacroAssemblerPPC::ClearRegisters(int reg_from, int reg_to) {
} }
} }
void RegExpMacroAssemblerPPC::WriteStackPointerToRegister(int reg) {
__ LoadU64(r4, MemOperand(frame_pointer(), kStackHighEnd));
__ sub(r3, backtrack_stackpointer(), r4);
__ StoreU64(r3, register_location(reg), r0);
}
// Private methods: // Private methods:
void RegExpMacroAssemblerPPC::CallCheckStackGuardState(Register scratch) { void RegExpMacroAssemblerPPC::CallCheckStackGuardState(Register scratch) {
......
...@@ -5,9 +5,7 @@ ...@@ -5,9 +5,7 @@
#ifndef V8_REGEXP_PPC_REGEXP_MACRO_ASSEMBLER_PPC_H_ #ifndef V8_REGEXP_PPC_REGEXP_MACRO_ASSEMBLER_PPC_H_
#define V8_REGEXP_PPC_REGEXP_MACRO_ASSEMBLER_PPC_H_ #define V8_REGEXP_PPC_REGEXP_MACRO_ASSEMBLER_PPC_H_
#include "src/base/strings.h"
#include "src/codegen/macro-assembler.h" #include "src/codegen/macro-assembler.h"
#include "src/codegen/ppc/assembler-ppc.h"
#include "src/regexp/regexp-macro-assembler.h" #include "src/regexp/regexp-macro-assembler.h"
namespace v8 { namespace v8 {
...@@ -116,8 +114,14 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerPPC ...@@ -116,8 +114,14 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerPPC
static const int kStringStartMinusOne = static const int kStringStartMinusOne =
kSuccessfulCaptures - kSystemPointerSize; kSuccessfulCaptures - kSystemPointerSize;
static const int kBacktrackCount = kStringStartMinusOne - kSystemPointerSize; static const int kBacktrackCount = kStringStartMinusOne - kSystemPointerSize;
// Stores the initial value of the regexp stack pointer in a
// position-independent representation (in case the regexp stack grows and
// thus moves).
static const int kRegExpStackBasePointer =
kBacktrackCount - kSystemPointerSize;
// First register address. Following registers are below it on the stack. // First register address. Following registers are below it on the stack.
static const int kRegisterZero = kBacktrackCount - kSystemPointerSize; static const int kRegisterZero = kRegExpStackBasePointer - kSystemPointerSize;
// Initial size of code buffer. // Initial size of code buffer.
static const int kRegExpCodeSize = 1024; static const int kRegExpCodeSize = 1024;
...@@ -137,27 +141,27 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerPPC ...@@ -137,27 +141,27 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerPPC
// Register holding the current input position as negative offset from // Register holding the current input position as negative offset from
// the end of the string. // the end of the string.
inline Register current_input_offset() { return r27; } static constexpr Register current_input_offset() { return r27; }
// The register containing the current character after LoadCurrentCharacter. // The register containing the current character after LoadCurrentCharacter.
inline Register current_character() { return r28; } static constexpr Register current_character() { return r28; }
// Register holding address of the end of the input string. // Register holding address of the end of the input string.
inline Register end_of_input_address() { return r30; } static constexpr Register end_of_input_address() { return r30; }
// Register holding the frame address. Local variables, parameters and // Register holding the frame address. Local variables, parameters and
// regexp registers are addressed relative to this. // regexp registers are addressed relative to this.
inline Register frame_pointer() { return fp; } static constexpr Register frame_pointer() { return fp; }
// The register containing the backtrack stack top. Provides a meaningful // The register containing the backtrack stack top. Provides a meaningful
// name to the register. // name to the register.
inline Register backtrack_stackpointer() { return r29; } static constexpr Register backtrack_stackpointer() { return r29; }
// Register holding pointer to the current code object. // Register holding pointer to the current code object.
inline Register code_pointer() { return r26; } static constexpr Register code_pointer() { return r26; }
// Byte size of chars in the string to match (decided by the Mode argument) // Byte size of chars in the string to match (decided by the Mode argument)
inline int char_size() { return static_cast<int>(mode_); } inline int char_size() const { return static_cast<int>(mode_); }
// Equivalent to a conditional branch to the label, unless the label // Equivalent to a conditional branch to the label, unless the label
// is nullptr, in which case it is a conditional Backtrack. // is nullptr, in which case it is a conditional Backtrack.
...@@ -177,19 +181,25 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerPPC ...@@ -177,19 +181,25 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerPPC
// and increments it by a word size. // and increments it by a word size.
inline void Pop(Register target); inline void Pop(Register target);
void LoadRegExpStackPointerFromMemory(Register dst);
void StoreRegExpStackPointerToMemory(Register src, Register scratch);
void PushRegExpBasePointer(Register scratch1, Register scratch2);
void PopRegExpBasePointer(Register scratch1, Register scratch2);
Isolate* isolate() const { return masm_->isolate(); } Isolate* isolate() const { return masm_->isolate(); }
MacroAssembler* masm_; MacroAssembler* const masm_;
const 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_; const Mode mode_;
// One greater than maximal register index actually used. // One greater than maximal register index actually used.
int num_registers_; int num_registers_;
// Number of registers to output at the end (the saved registers // Number of registers to output at the end (the saved registers
// are always 0..num_saved_registers_-1) // are always 0..num_saved_registers_-1)
int num_saved_registers_; const int num_saved_registers_;
// Labels used internally. // Labels used internally.
Label entry_label_; Label entry_label_;
......
...@@ -6,15 +6,14 @@ ...@@ -6,15 +6,14 @@
#if V8_TARGET_ARCH_S390 #if V8_TARGET_ARCH_S390
#include "src/base/bits.h"
#include "src/codegen/assembler-inl.h"
#include "src/codegen/macro-assembler.h" #include "src/codegen/macro-assembler.h"
#include "src/codegen/s390/assembler-s390-inl.h"
#include "src/heap/factory.h"
#include "src/logging/log.h" #include "src/logging/log.h"
#include "src/regexp/regexp-macro-assembler.h" #include "src/objects/code-inl.h"
#include "src/regexp/regexp-stack.h" #include "src/regexp/regexp-stack.h"
#include "src/regexp/s390/regexp-macro-assembler-s390.h" #include "src/regexp/s390/regexp-macro-assembler-s390.h"
#include "src/snapshot/embedded/embedded-data.h" #include "src/snapshot/embedded/embedded-data.h"
#include "src/strings/unicode.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -104,6 +103,7 @@ RegExpMacroAssemblerS390::RegExpMacroAssemblerS390(Isolate* isolate, Zone* zone, ...@@ -104,6 +103,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),
...@@ -113,8 +113,6 @@ RegExpMacroAssemblerS390::RegExpMacroAssemblerS390(Isolate* isolate, Zone* zone, ...@@ -113,8 +113,6 @@ RegExpMacroAssemblerS390::RegExpMacroAssemblerS390(Isolate* isolate, Zone* zone,
backtrack_label_(), backtrack_label_(),
exit_label_(), exit_label_(),
internal_failure_label_() { internal_failure_label_() {
masm_->set_root_array_available(false);
DCHECK_EQ(0, registers_to_save % 2); DCHECK_EQ(0, registers_to_save % 2);
__ b(&entry_label_); // We'll write the entry code later. __ b(&entry_label_); // We'll write the entry code later.
...@@ -629,6 +627,43 @@ void RegExpMacroAssemblerS390::Fail() { ...@@ -629,6 +627,43 @@ void RegExpMacroAssemblerS390::Fail() {
__ b(&exit_label_); __ b(&exit_label_);
} }
void RegExpMacroAssemblerS390::LoadRegExpStackPointerFromMemory(Register dst) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_stack_pointer(isolate());
__ mov(dst, Operand(ref));
__ LoadU64(dst, MemOperand(dst));
}
void RegExpMacroAssemblerS390::StoreRegExpStackPointerToMemory(
Register src, Register scratch) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_stack_pointer(isolate());
__ mov(scratch, Operand(ref));
__ StoreU64(src, MemOperand(scratch));
}
void RegExpMacroAssemblerS390::PushRegExpBasePointer(Register scratch1,
Register scratch2) {
LoadRegExpStackPointerFromMemory(scratch1);
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ mov(scratch2, Operand(ref));
__ LoadU64(scratch2, MemOperand(scratch2));
__ SubS64(scratch2, scratch1, scratch2);
__ StoreU64(scratch2, MemOperand(frame_pointer(), kRegExpStackBasePointer));
}
void RegExpMacroAssemblerS390::PopRegExpBasePointer(Register scratch1,
Register scratch2) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ LoadU64(scratch1, MemOperand(frame_pointer(), kRegExpStackBasePointer));
__ mov(scratch2, Operand(ref));
__ LoadU64(scratch2, MemOperand(scratch2));
__ AddS64(scratch1, scratch1, scratch2);
StoreRegExpStackPointerToMemory(scratch1, scratch2);
}
Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) { Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) {
Label return_r2; Label return_r2;
...@@ -689,6 +724,14 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) { ...@@ -689,6 +724,14 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) {
__ StoreMultipleP(r0, r9, MemOperand(sp, 0)); __ StoreMultipleP(r0, r9, MemOperand(sp, 0));
STATIC_ASSERT(kBacktrackCount == kStringStartMinusOne - kSystemPointerSize); STATIC_ASSERT(kBacktrackCount == kStringStartMinusOne - kSystemPointerSize);
__ Push(r1); // The backtrack counter. __ Push(r1); // The backtrack counter.
STATIC_ASSERT(kRegExpStackBasePointer ==
kBacktrackCount - kSystemPointerSize);
__ push(r1); // The regexp stack base ptr.
// Store the regexp base pointer - we'll later restore it / write it to
// memory when returning from this irregexp code object.
PushRegExpBasePointer(r2, r3);
// Check if we have space on the stack for registers. // Check if we have space on the stack for registers.
Label stack_limit_hit; Label stack_limit_hit;
Label stack_ok; Label stack_ok;
...@@ -777,8 +820,7 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) { ...@@ -777,8 +820,7 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) {
} }
// Initialize backtrack stack pointer. // Initialize backtrack stack pointer.
__ LoadU64(backtrack_stackpointer(), LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
MemOperand(frame_pointer(), kStackHighEnd));
__ b(&start_label_); __ b(&start_label_);
...@@ -901,6 +943,10 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) { ...@@ -901,6 +943,10 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) {
} }
__ bind(&return_r2); __ bind(&return_r2);
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(r3, r4);
// Skip sp past regexp registers and local variables.. // Skip sp past regexp registers and local variables..
__ mov(sp, frame_pointer()); __ mov(sp, frame_pointer());
// Restore registers r6..r15. // Restore registers r6..r15.
...@@ -920,12 +966,16 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) { ...@@ -920,12 +966,16 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) {
if (check_preempt_label_.is_linked()) { if (check_preempt_label_.is_linked()) {
SafeCallTarget(&check_preempt_label_); SafeCallTarget(&check_preempt_label_);
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), r3);
CallCheckStackGuardState(r2); CallCheckStackGuardState(r2);
__ CmpS64(r2, Operand::Zero()); __ CmpS64(r2, Operand::Zero());
// If returning non-zero, we should end execution with the given // If returning non-zero, we should end execution with the given
// result as return value. // result as return value.
__ bne(&return_r2); __ bne(&return_r2);
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
// String might have moved: Reload end of string from frame. // String might have moved: Reload end of string from frame.
__ LoadU64(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); __ LoadU64(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
SafeReturn(); SafeReturn();
...@@ -936,16 +986,17 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) { ...@@ -936,16 +986,17 @@ Handle<HeapObject> RegExpMacroAssemblerS390::GetCode(Handle<String> source) {
SafeCallTarget(&stack_overflow_label_); SafeCallTarget(&stack_overflow_label_);
// Reached if the backtrack-stack limit has been hit. // Reached if the backtrack-stack limit has been hit.
// Call GrowStack(backtrack_stackpointer(), &stack_base) // Call GrowStack(isolate).
static const int num_arguments = 3;
__ PrepareCallCFunction(num_arguments, r2); StoreRegExpStackPointerToMemory(backtrack_stackpointer(), r3);
__ mov(r2, backtrack_stackpointer());
__ AddS64(r3, frame_pointer(), Operand(kStackHighEnd)); static constexpr int kNumArguments = 1;
__ mov(r4, Operand(ExternalReference::isolate_address(isolate()))); __ PrepareCallCFunction(kNumArguments, r2);
__ mov(r2, Operand(ExternalReference::isolate_address(isolate())));
ExternalReference grow_stack = ExternalReference::re_grow_stack(isolate()); ExternalReference grow_stack = ExternalReference::re_grow_stack(isolate());
__ CallCFunction(grow_stack, num_arguments); __ CallCFunction(grow_stack, kNumArguments);
// If return nullptr, we have failed to grow the stack, and // If nullptr is returned, we have failed to grow the stack, and must exit
// must exit with a stack-overflow exception. // with a stack-overflow exception.
__ CmpS64(r2, Operand::Zero()); __ CmpS64(r2, Operand::Zero());
__ beq(&exit_with_exception); __ beq(&exit_with_exception);
// Otherwise use return value as new stack pointer. // Otherwise use return value as new stack pointer.
...@@ -1041,10 +1092,22 @@ void RegExpMacroAssemblerS390::ReadCurrentPositionFromRegister(int reg) { ...@@ -1041,10 +1092,22 @@ void RegExpMacroAssemblerS390::ReadCurrentPositionFromRegister(int reg) {
__ LoadU64(current_input_offset(), register_location(reg), r0); __ LoadU64(current_input_offset(), register_location(reg), r0);
} }
void RegExpMacroAssemblerS390::WriteStackPointerToRegister(int reg) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ mov(r3, Operand(ref));
__ LoadU64(r3, MemOperand(r3));
__ SubS64(r2, backtrack_stackpointer(), r3);
__ StoreU64(r2, register_location(reg));
}
void RegExpMacroAssemblerS390::ReadStackPointerFromRegister(int reg) { void RegExpMacroAssemblerS390::ReadStackPointerFromRegister(int reg) {
__ LoadU64(backtrack_stackpointer(), register_location(reg), r0); ExternalReference ref =
__ LoadU64(r2, MemOperand(frame_pointer(), kStackHighEnd)); ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ AddS64(backtrack_stackpointer(), r2); __ mov(r2, Operand(ref));
__ LoadU64(r2, MemOperand(r2));
__ LoadU64(backtrack_stackpointer(), register_location(reg));
__ AddS64(backtrack_stackpointer(), backtrack_stackpointer(), r2);
} }
void RegExpMacroAssemblerS390::SetCurrentPositionFromEnd(int by) { void RegExpMacroAssemblerS390::SetCurrentPositionFromEnd(int by) {
...@@ -1088,12 +1151,6 @@ void RegExpMacroAssemblerS390::ClearRegisters(int reg_from, int reg_to) { ...@@ -1088,12 +1151,6 @@ void RegExpMacroAssemblerS390::ClearRegisters(int reg_from, int reg_to) {
} }
} }
void RegExpMacroAssemblerS390::WriteStackPointerToRegister(int reg) {
__ LoadU64(r3, MemOperand(frame_pointer(), kStackHighEnd));
__ SubS64(r2, backtrack_stackpointer(), r3);
__ StoreU64(r2, register_location(reg));
}
// Private methods: // Private methods:
void RegExpMacroAssemblerS390::CallCheckStackGuardState(Register scratch) { void RegExpMacroAssemblerS390::CallCheckStackGuardState(Register scratch) {
......
...@@ -5,9 +5,7 @@ ...@@ -5,9 +5,7 @@
#ifndef V8_REGEXP_S390_REGEXP_MACRO_ASSEMBLER_S390_H_ #ifndef V8_REGEXP_S390_REGEXP_MACRO_ASSEMBLER_S390_H_
#define V8_REGEXP_S390_REGEXP_MACRO_ASSEMBLER_S390_H_ #define V8_REGEXP_S390_REGEXP_MACRO_ASSEMBLER_S390_H_
#include "src/base/strings.h"
#include "src/codegen/macro-assembler.h" #include "src/codegen/macro-assembler.h"
#include "src/codegen/s390/assembler-s390.h"
#include "src/regexp/regexp-macro-assembler.h" #include "src/regexp/regexp-macro-assembler.h"
namespace v8 { namespace v8 {
...@@ -116,8 +114,14 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerS390 ...@@ -116,8 +114,14 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerS390
static const int kStringStartMinusOne = static const int kStringStartMinusOne =
kSuccessfulCaptures - kSystemPointerSize; kSuccessfulCaptures - kSystemPointerSize;
static const int kBacktrackCount = kStringStartMinusOne - kSystemPointerSize; static const int kBacktrackCount = kStringStartMinusOne - kSystemPointerSize;
// Stores the initial value of the regexp stack pointer in a
// position-independent representation (in case the regexp stack grows and
// thus moves).
static const int kRegExpStackBasePointer =
kBacktrackCount - kSystemPointerSize;
// First register address. Following registers are below it on the stack. // First register address. Following registers are below it on the stack.
static const int kRegisterZero = kBacktrackCount - kSystemPointerSize; static const int kRegisterZero = kRegExpStackBasePointer - kSystemPointerSize;
// Initial size of code buffer. // Initial size of code buffer.
static const int kRegExpCodeSize = 1024; static const int kRegExpCodeSize = 1024;
...@@ -137,27 +141,27 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerS390 ...@@ -137,27 +141,27 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerS390
// Register holding the current input position as negative offset from // Register holding the current input position as negative offset from
// the end of the string. // the end of the string.
inline Register current_input_offset() { return r8; } static constexpr Register current_input_offset() { return r8; }
// The register containing the current character after LoadCurrentCharacter. // The register containing the current character after LoadCurrentCharacter.
inline Register current_character() { return r9; } static constexpr Register current_character() { return r9; }
// Register holding address of the end of the input string. // Register holding address of the end of the input string.
inline Register end_of_input_address() { return r10; } static constexpr Register end_of_input_address() { return r10; }
// Register holding the frame address. Local variables, parameters and // Register holding the frame address. Local variables, parameters and
// regexp registers are addressed relative to this. // regexp registers are addressed relative to this.
inline Register frame_pointer() { return fp; } static constexpr Register frame_pointer() { return fp; }
// The register containing the backtrack stack top. Provides a meaningful // The register containing the backtrack stack top. Provides a meaningful
// name to the register. // name to the register.
inline Register backtrack_stackpointer() { return r13; } static constexpr Register backtrack_stackpointer() { return r13; }
// Register holding pointer to the current code object. // Register holding pointer to the current code object.
inline Register code_pointer() { return r7; } static constexpr Register code_pointer() { return r7; }
// Byte size of chars in the string to match (decided by the Mode argument) // Byte size of chars in the string to match (decided by the Mode argument)
inline int char_size() { return static_cast<int>(mode_); } inline int char_size() const { return static_cast<int>(mode_); }
// Equivalent to a conditional branch to the label, unless the label // Equivalent to a conditional branch to the label, unless the label
// is nullptr, in which case it is a conditional Backtrack. // is nullptr, in which case it is a conditional Backtrack.
...@@ -177,19 +181,25 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerS390 ...@@ -177,19 +181,25 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerS390
// and increments it by a word size. // and increments it by a word size.
inline void Pop(Register target); inline void Pop(Register target);
void LoadRegExpStackPointerFromMemory(Register dst);
void StoreRegExpStackPointerToMemory(Register src, Register scratch);
void PushRegExpBasePointer(Register scratch1, Register scratch2);
void PopRegExpBasePointer(Register scratch1, Register scratch2);
Isolate* isolate() const { return masm_->isolate(); } Isolate* isolate() const { return masm_->isolate(); }
MacroAssembler* masm_; MacroAssembler* const masm_;
const 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_; const Mode mode_;
// One greater than maximal register index actually used. // One greater than maximal register index actually used.
int num_registers_; int num_registers_;
// Number of registers to output at the end (the saved registers // Number of registers to output at the end (the saved registers
// are always 0..num_saved_registers_-1) // are always 0..num_saved_registers_-1)
int num_saved_registers_; const int num_saved_registers_;
// Labels used internally. // Labels used internally.
Label entry_label_; Label entry_label_;
......
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