Commit 5ee6b7a7 authored by Liu Yu's avatar Liu Yu Committed by V8 LUCI CQ

[loong][mips][regexp] Fix stack growth for global regexps

Port commit 3e3a027d

Beside, some registers are changed to callee-saved, and the previous
related save and restore operations are removed.

Bug: v8:11382

Change-Id: Ic3161f8173771c1b7c190c77cbaf2534f52ec422
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3281673Reviewed-by: 's avatarZhao Jiazhong <zhaojiazhong-hf@loongson.cn>
Commit-Queue: Zhao Jiazhong <zhaojiazhong-hf@loongson.cn>
Auto-Submit: Liu yu <liuyu@loongson.cn>
Cr-Commit-Position: refs/heads/main@{#77902}
parent 5f201563
...@@ -19,18 +19,16 @@ namespace internal { ...@@ -19,18 +19,16 @@ namespace internal {
/* clang-format off /* clang-format off
* *
* This assembler uses the following register assignment convention * This assembler uses the following register assignment convention
* - t3 : Temporarily stores the index of capture start after a matching pass * - s0 : Unused.
* for a global regexp. * - s1 : Pointer to current Code object including heap object tag.
* - a5 : Pointer to current Code object including heap object tag. * - s2 : Current position in input, as negative offset from end of string.
* - a6 : Current position in input, as negative offset from end of string.
* Please notice that this is the byte offset, not the character offset! * Please notice that this is the byte offset, not the character offset!
* - a7 : Currently loaded character. Must be loaded using * - s5 : Currently loaded character. Must be loaded using
* LoadCurrentCharacter before using any of the dispatch methods. * LoadCurrentCharacter before using any of the dispatch methods.
* - t0 : Points to tip of backtrack stack * - s6 : Points to tip of backtrack stack
* - t1 : Unused. * - s7 : End of input (points to byte after last character in input).
* - t2 : End of input (points to byte after last character in input).
* - fp : Frame pointer. Used to access arguments, local variables and * - fp : Frame pointer. Used to access arguments, local variables and
* RegExp registers. * RegExp registers.
* - sp : Points to tip of C stack. * - sp : Points to tip of C stack.
* *
* The remaining registers are free for computations. * The remaining registers are free for computations.
...@@ -216,21 +214,6 @@ void RegExpMacroAssemblerLOONG64::CheckGreedyLoop(Label* on_equal) { ...@@ -216,21 +214,6 @@ void RegExpMacroAssemblerLOONG64::CheckGreedyLoop(Label* on_equal) {
BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0)); BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0));
} }
// Push (pop) caller-saved registers used by irregexp.
void RegExpMacroAssemblerLOONG64::PushCallerSavedRegisters() {
RegList caller_saved_regexp =
current_input_offset().bit() | current_character().bit() |
end_of_input_address().bit() | backtrack_stackpointer().bit();
__ MultiPush(caller_saved_regexp);
}
void RegExpMacroAssemblerLOONG64::PopCallerSavedRegisters() {
RegList caller_saved_regexp =
current_input_offset().bit() | current_character().bit() |
end_of_input_address().bit() | backtrack_stackpointer().bit();
__ MultiPop(caller_saved_regexp);
}
void RegExpMacroAssemblerLOONG64::CheckNotBackReferenceIgnoreCase( void RegExpMacroAssemblerLOONG64::CheckNotBackReferenceIgnoreCase(
int start_reg, bool read_backward, bool unicode, Label* on_no_match) { int start_reg, bool read_backward, bool unicode, Label* on_no_match) {
Label fallthrough; Label fallthrough;
...@@ -312,7 +295,6 @@ void RegExpMacroAssemblerLOONG64::CheckNotBackReferenceIgnoreCase( ...@@ -312,7 +295,6 @@ void RegExpMacroAssemblerLOONG64::CheckNotBackReferenceIgnoreCase(
} }
} else { } else {
DCHECK(mode_ == UC16); DCHECK(mode_ == UC16);
PushCallerSavedRegisters();
int argument_count = 4; int argument_count = 4;
__ PrepareCallCFunction(argument_count, a2); __ PrepareCallCFunction(argument_count, a2);
...@@ -350,10 +332,6 @@ void RegExpMacroAssemblerLOONG64::CheckNotBackReferenceIgnoreCase( ...@@ -350,10 +332,6 @@ void RegExpMacroAssemblerLOONG64::CheckNotBackReferenceIgnoreCase(
__ CallCFunction(function, argument_count); __ CallCFunction(function, argument_count);
} }
PopCallerSavedRegisters();
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
__ Ld_d(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
// Check if function returned non-zero for success or zero for failure. // Check if function returned non-zero for success or zero for failure.
BranchOrBacktrack(on_no_match, eq, a0, Operand(zero_reg)); BranchOrBacktrack(on_no_match, eq, a0, Operand(zero_reg));
// On success, increment position by length of capture. // On success, increment position by length of capture.
...@@ -474,7 +452,6 @@ void RegExpMacroAssemblerLOONG64::CheckCharacterNotInRange( ...@@ -474,7 +452,6 @@ void RegExpMacroAssemblerLOONG64::CheckCharacterNotInRange(
void RegExpMacroAssemblerLOONG64::CallIsCharacterInRangeArray( void RegExpMacroAssemblerLOONG64::CallIsCharacterInRangeArray(
const ZoneList<CharacterRange>* ranges) { const ZoneList<CharacterRange>* ranges) {
static const int kNumArguments = 3; static const int kNumArguments = 3;
PushCallerSavedRegisters();
__ PrepareCallCFunction(kNumArguments, a0); __ PrepareCallCFunction(kNumArguments, a0);
__ mov(a0, current_character()); __ mov(a0, current_character());
...@@ -488,7 +465,6 @@ void RegExpMacroAssemblerLOONG64::CallIsCharacterInRangeArray( ...@@ -488,7 +465,6 @@ void RegExpMacroAssemblerLOONG64::CallIsCharacterInRangeArray(
kNumArguments); kNumArguments);
} }
PopCallerSavedRegisters();
__ li(code_pointer(), Operand(masm_->CodeObject())); __ li(code_pointer(), Operand(masm_->CodeObject()));
} }
...@@ -643,26 +619,26 @@ void RegExpMacroAssemblerLOONG64::StoreRegExpStackPointerToMemory( ...@@ -643,26 +619,26 @@ void RegExpMacroAssemblerLOONG64::StoreRegExpStackPointerToMemory(
__ St_d(src, MemOperand(scratch, 0)); __ St_d(src, MemOperand(scratch, 0));
} }
void RegExpMacroAssemblerLOONG64::PushRegExpBasePointer(Register scratch1, void RegExpMacroAssemblerLOONG64::PushRegExpBasePointer(Register stack_pointer,
Register scratch2) { Register scratch) {
LoadRegExpStackPointerFromMemory(scratch1);
ExternalReference ref = ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate()); ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(scratch2, ref); __ li(scratch, ref);
__ Ld_d(scratch2, MemOperand(scratch2, 0)); __ Ld_d(scratch, MemOperand(scratch, 0));
__ Sub_d(scratch2, scratch1, scratch2); __ Sub_d(scratch, stack_pointer, scratch);
__ St_d(scratch2, MemOperand(frame_pointer(), kRegExpStackBasePointer)); __ St_d(scratch, MemOperand(frame_pointer(), kRegExpStackBasePointer));
} }
void RegExpMacroAssemblerLOONG64::PopRegExpBasePointer(Register scratch1, void RegExpMacroAssemblerLOONG64::PopRegExpBasePointer(
Register scratch2) { Register stack_pointer_out, Register scratch) {
ExternalReference ref = ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate()); ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ Ld_d(scratch1, MemOperand(frame_pointer(), kRegExpStackBasePointer)); __ Ld_d(stack_pointer_out,
__ li(scratch2, ref); MemOperand(frame_pointer(), kRegExpStackBasePointer));
__ Ld_d(scratch2, MemOperand(scratch2, 0)); __ li(scratch, ref);
__ Add_d(scratch1, scratch1, scratch2); __ Ld_d(scratch, MemOperand(scratch, 0));
StoreRegExpStackPointerToMemory(scratch1, scratch2); __ Add_d(stack_pointer_out, stack_pointer_out, scratch);
StoreRegExpStackPointerToMemory(stack_pointer_out, scratch);
} }
Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
...@@ -714,35 +690,43 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { ...@@ -714,35 +690,43 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
kBacktrackCount - kSystemPointerSize); kBacktrackCount - kSystemPointerSize);
__ Push(a0); // The regexp stack base ptr. __ Push(a0); // The regexp stack base ptr.
// Initialize backtrack stack pointer. It must not be clobbered from here
// on. Note the backtrack_stackpointer is callee-saved.
STATIC_ASSERT(backtrack_stackpointer() == s7);
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
// Store the regexp base pointer - we'll later restore it / write it to // Store the regexp base pointer - we'll later restore it / write it to
// memory when returning from this irregexp code object. // memory when returning from this irregexp code object.
PushRegExpBasePointer(a0, a1); PushRegExpBasePointer(backtrack_stackpointer(), a1);
// Check if we have space on the stack for registers. {
Label stack_limit_hit; // Check if we have space on the stack for registers.
Label stack_ok; Label stack_limit_hit, stack_ok;
ExternalReference stack_limit = ExternalReference stack_limit =
ExternalReference::address_of_jslimit(masm_->isolate()); ExternalReference::address_of_jslimit(masm_->isolate());
__ li(a0, Operand(stack_limit)); __ li(a0, Operand(stack_limit));
__ Ld_d(a0, MemOperand(a0, 0)); __ Ld_d(a0, MemOperand(a0, 0));
__ Sub_d(a0, sp, a0); __ Sub_d(a0, sp, a0);
// Handle it if the stack pointer is already below the stack limit. // Handle it if the stack pointer is already below the stack limit.
__ Branch(&stack_limit_hit, le, a0, Operand(zero_reg)); __ Branch(&stack_limit_hit, le, a0, Operand(zero_reg));
// Check if there is room for the variable number of registers above // Check if there is room for the variable number of registers above
// the stack limit. // the stack limit.
__ Branch(&stack_ok, hs, a0, Operand(num_registers_ * kPointerSize)); __ Branch(&stack_ok, hs, a0, Operand(num_registers_ * kPointerSize));
// Exit with OutOfMemory exception. There is not enough space on the stack // Exit with OutOfMemory exception. There is not enough space on the stack
// for our working registers. // for our working registers.
__ li(a0, Operand(EXCEPTION)); __ li(a0, Operand(EXCEPTION));
__ jmp(&return_v0); __ jmp(&return_v0);
__ bind(&stack_limit_hit); __ bind(&stack_limit_hit);
CallCheckStackGuardState(a0); CallCheckStackGuardState(a0);
// If returned value is non-zero, we exit with the returned value as result. // If returned value is non-zero, we exit with the returned value as
__ Branch(&return_v0, ne, a0, Operand(zero_reg)); // result.
__ Branch(&return_v0, ne, a0, Operand(zero_reg));
__ bind(&stack_ok);
__ bind(&stack_ok);
}
// Allocate space on stack for registers. // Allocate space on stack for registers.
__ Sub_d(sp, sp, Operand(num_registers_ * kPointerSize)); __ Sub_d(sp, sp, Operand(num_registers_ * kPointerSize));
// Load string end. // Load string end.
...@@ -764,17 +748,20 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { ...@@ -764,17 +748,20 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
// Initialize code pointer register // Initialize code pointer register
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
Label load_char_start_regexp, start_regexp; Label load_char_start_regexp;
// Load newline if index is at start, previous character otherwise. {
__ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg)); Label start_regexp;
__ li(current_character(), Operand('\n')); // Load newline if index is at start, previous character otherwise.
__ jmp(&start_regexp); __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg));
__ li(current_character(), Operand('\n'));
// Global regexp restarts matching here. __ jmp(&start_regexp);
__ bind(&load_char_start_regexp);
// Load previous char as initial value of current character register. // Global regexp restarts matching here.
LoadCurrentCharacterUnchecked(-1, 1); __ bind(&load_char_start_regexp);
__ bind(&start_regexp); // Load previous char as initial value of current character register.
LoadCurrentCharacterUnchecked(-1, 1);
__ bind(&start_regexp);
}
// Initialize on-stack registers. // Initialize on-stack registers.
if (num_saved_registers_ > 0) { // Always is, if generated from a regexp. if (num_saved_registers_ > 0) { // Always is, if generated from a regexp.
...@@ -796,9 +783,6 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { ...@@ -796,9 +783,6 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
} }
} }
// Initialize backtrack stack pointer.
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
__ jmp(&start_label_); __ jmp(&start_label_);
// Exit code: // Exit code:
...@@ -870,6 +854,10 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { ...@@ -870,6 +854,10 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
// Prepare a0 to initialize registers with its value in the next run. // Prepare a0 to initialize registers with its value in the next run.
__ Ld_d(a0, MemOperand(frame_pointer(), kStringStartMinusOne)); __ Ld_d(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), a2);
if (global_with_zero_length_check()) { if (global_with_zero_length_check()) {
// Special case for zero-length matches. // Special case for zero-length matches.
// t3: capture start index // t3: capture start index
...@@ -901,7 +889,7 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { ...@@ -901,7 +889,7 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
__ bind(&return_v0); __ bind(&return_v0);
// Restore the original regexp stack pointer value (effectively, pop the // Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer). // stored base pointer).
PopRegExpBasePointer(a1, a2); PopRegExpBasePointer(backtrack_stackpointer(), a2);
// Skip sp past regexp registers and local variables.. // Skip sp past regexp registers and local variables..
__ mov(sp, frame_pointer()); __ mov(sp, frame_pointer());
...@@ -923,9 +911,7 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { ...@@ -923,9 +911,7 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
// Put regexp engine registers on stack. // Put regexp engine registers on stack.
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1); StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1);
PushCallerSavedRegisters();
CallCheckStackGuardState(a0); CallCheckStackGuardState(a0);
PopCallerSavedRegisters();
// 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.
__ Branch(&return_v0, ne, a0, Operand(zero_reg)); __ Branch(&return_v0, ne, a0, Operand(zero_reg));
...@@ -934,7 +920,6 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { ...@@ -934,7 +920,6 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
// String might have moved: Reload end of string from frame. // String might have moved: Reload end of string from frame.
__ Ld_d(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); __ Ld_d(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
SafeReturn(); SafeReturn();
} }
...@@ -944,10 +929,6 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { ...@@ -944,10 +929,6 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
SafeCallTarget(&stack_overflow_label_); SafeCallTarget(&stack_overflow_label_);
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1); StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1);
// Reached if the backtrack-stack limit has been hit. // Reached if the backtrack-stack limit has been hit.
// Put regexp engine registers on stack first.
RegList regexp_registers =
current_input_offset().bit() | current_character().bit();
__ MultiPush(regexp_registers);
// Call GrowStack(isolate). // Call GrowStack(isolate).
static const int kNumArguments = 1; static const int kNumArguments = 1;
...@@ -955,16 +936,11 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { ...@@ -955,16 +936,11 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
__ li(a0, Operand(ExternalReference::isolate_address(masm_->isolate()))); __ li(a0, Operand(ExternalReference::isolate_address(masm_->isolate())));
ExternalReference grow_stack = ExternalReference::re_grow_stack(); ExternalReference grow_stack = ExternalReference::re_grow_stack();
__ CallCFunction(grow_stack, kNumArguments); __ CallCFunction(grow_stack, kNumArguments);
// Restore regexp registers.
__ MultiPop(regexp_registers);
// If nullptr is returned, we have failed to grow the stack, and must exit // If nullptr is returned, we have failed to grow the stack, and must exit
// with a stack-overflow exception. // with a stack-overflow exception.
__ Branch(&exit_with_exception, eq, a0, Operand(zero_reg)); __ Branch(&exit_with_exception, eq, a0, Operand(zero_reg));
// Otherwise use return value as new stack pointer. // Otherwise use return value as new stack pointer.
__ mov(backtrack_stackpointer(), a0); __ mov(backtrack_stackpointer(), a0);
// Restore saved registers and continue.
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
__ Ld_d(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
SafeReturn(); SafeReturn();
} }
......
...@@ -151,13 +151,13 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerLOONG64 ...@@ -151,13 +151,13 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerLOONG64
// 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.
static constexpr Register current_input_offset() { return a6; } static constexpr Register current_input_offset() { return s2; }
// The register containing the current character after LoadCurrentCharacter. // The register containing the current character after LoadCurrentCharacter.
static constexpr Register current_character() { return a7; } static constexpr Register current_character() { return s5; }
// Register holding address of the end of the input string. // Register holding address of the end of the input string.
static constexpr Register end_of_input_address() { return t2; } static constexpr Register end_of_input_address() { return s6; }
// 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.
...@@ -165,10 +165,10 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerLOONG64 ...@@ -165,10 +165,10 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerLOONG64
// 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.
static constexpr Register backtrack_stackpointer() { return t0; } static constexpr Register backtrack_stackpointer() { return s7; }
// Register holding pointer to the current code object. // Register holding pointer to the current code object.
static constexpr Register code_pointer() { return a5; } static constexpr Register code_pointer() { return s1; }
// 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() { return static_cast<int>(mode_); }
...@@ -195,8 +195,8 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerLOONG64 ...@@ -195,8 +195,8 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerLOONG64
void LoadRegExpStackPointerFromMemory(Register dst); void LoadRegExpStackPointerFromMemory(Register dst);
void StoreRegExpStackPointerToMemory(Register src, Register scratch); void StoreRegExpStackPointerToMemory(Register src, Register scratch);
void PushRegExpBasePointer(Register scratch1, Register scratch2); void PushRegExpBasePointer(Register stack_pointer, Register scratch);
void PopRegExpBasePointer(Register scratch1, Register scratch2); void PopRegExpBasePointer(Register stack_pointer_out, Register scratch);
Isolate* isolate() const { return masm_->isolate(); } Isolate* isolate() const { return masm_->isolate(); }
......
...@@ -18,18 +18,16 @@ namespace internal { ...@@ -18,18 +18,16 @@ namespace internal {
/* /*
* This assembler uses the following register assignment convention * This assembler uses the following register assignment convention
* - t7 : Temporarily stores the index of capture start after a matching pass * - s0 : Unused.
* for a global regexp. * - s1 : Pointer to current Code object including heap object tag.
* - t1 : Pointer to current Code object including heap object tag. * - s2 : Current position in input, as negative offset from end of string.
* - t2 : Current position in input, as negative offset from end of string.
* Please notice that this is the byte offset, not the character offset! * Please notice that this is the byte offset, not the character offset!
* - t3 : Currently loaded character. Must be loaded using * - s5 : Currently loaded character. Must be loaded using
* LoadCurrentCharacter before using any of the dispatch methods. * LoadCurrentCharacter before using any of the dispatch methods.
* - t4 : Points to tip of backtrack stack * - s6 : Points to tip of backtrack stack
* - t5 : Unused. * - s7 : End of input (points to byte after last character in input).
* - t6 : End of input (points to byte after last character in input).
* - fp : Frame pointer. Used to access arguments, local variables and * - fp : Frame pointer. Used to access arguments, local variables and
* RegExp registers. * RegExp registers.
* - sp : Points to tip of C stack. * - sp : Points to tip of C stack.
* *
* The remaining registers are free for computations. * The remaining registers are free for computations.
...@@ -223,21 +221,6 @@ void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) { ...@@ -223,21 +221,6 @@ void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) {
BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0)); BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0));
} }
// Push (pop) caller-saved registers used by irregexp.
void RegExpMacroAssemblerMIPS::PushCallerSavedRegisters() {
RegList caller_saved_regexp =
current_input_offset().bit() | current_character().bit() |
end_of_input_address().bit() | backtrack_stackpointer().bit();
__ MultiPush(caller_saved_regexp);
}
void RegExpMacroAssemblerMIPS::PopCallerSavedRegisters() {
RegList caller_saved_regexp =
current_input_offset().bit() | current_character().bit() |
end_of_input_address().bit() | backtrack_stackpointer().bit();
__ MultiPop(caller_saved_regexp);
}
void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase(
int start_reg, bool read_backward, bool unicode, Label* on_no_match) { int start_reg, bool read_backward, bool unicode, Label* on_no_match) {
Label fallthrough; Label fallthrough;
...@@ -318,7 +301,6 @@ void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( ...@@ -318,7 +301,6 @@ void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase(
} }
} else { } else {
DCHECK_EQ(UC16, mode_); DCHECK_EQ(UC16, mode_);
PushCallerSavedRegisters();
int argument_count = 4; int argument_count = 4;
__ PrepareCallCFunction(argument_count, a2); __ PrepareCallCFunction(argument_count, a2);
...@@ -356,11 +338,6 @@ void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( ...@@ -356,11 +338,6 @@ void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase(
__ CallCFunction(function, argument_count); __ CallCFunction(function, argument_count);
} }
// Restore regexp engine registers.
PopCallerSavedRegisters();
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
__ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
// Check if function returned non-zero for success or zero for failure. // Check if function returned non-zero for success or zero for failure.
BranchOrBacktrack(on_no_match, eq, v0, Operand(zero_reg)); BranchOrBacktrack(on_no_match, eq, v0, Operand(zero_reg));
// On success, advance position by length of capture. // On success, advance position by length of capture.
...@@ -491,7 +468,6 @@ void RegExpMacroAssemblerMIPS::CheckCharacterNotInRange( ...@@ -491,7 +468,6 @@ void RegExpMacroAssemblerMIPS::CheckCharacterNotInRange(
void RegExpMacroAssemblerMIPS::CallIsCharacterInRangeArray( void RegExpMacroAssemblerMIPS::CallIsCharacterInRangeArray(
const ZoneList<CharacterRange>* ranges) { const ZoneList<CharacterRange>* ranges) {
static const int kNumArguments = 3; static const int kNumArguments = 3;
PushCallerSavedRegisters();
__ PrepareCallCFunction(kNumArguments, a0); __ PrepareCallCFunction(kNumArguments, a0);
__ mov(a0, current_character()); __ mov(a0, current_character());
...@@ -505,7 +481,6 @@ void RegExpMacroAssemblerMIPS::CallIsCharacterInRangeArray( ...@@ -505,7 +481,6 @@ void RegExpMacroAssemblerMIPS::CallIsCharacterInRangeArray(
kNumArguments); kNumArguments);
} }
PopCallerSavedRegisters();
__ li(code_pointer(), Operand(masm_->CodeObject())); __ li(code_pointer(), Operand(masm_->CodeObject()));
} }
...@@ -660,26 +635,26 @@ void RegExpMacroAssemblerMIPS::StoreRegExpStackPointerToMemory( ...@@ -660,26 +635,26 @@ void RegExpMacroAssemblerMIPS::StoreRegExpStackPointerToMemory(
__ Sw(src, MemOperand(scratch)); __ Sw(src, MemOperand(scratch));
} }
void RegExpMacroAssemblerMIPS::PushRegExpBasePointer(Register scratch1, void RegExpMacroAssemblerMIPS::PushRegExpBasePointer(Register stack_pointer,
Register scratch2) { Register scratch) {
LoadRegExpStackPointerFromMemory(scratch1);
ExternalReference ref = ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate()); ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(scratch2, Operand(ref)); __ li(scratch, Operand(ref));
__ Lw(scratch2, MemOperand(scratch2)); __ Lw(scratch, MemOperand(scratch));
__ Subu(scratch2, scratch1, scratch2); __ Subu(scratch, stack_pointer, scratch);
__ Sw(scratch2, MemOperand(frame_pointer(), kRegExpStackBasePointer)); __ Sw(scratch, MemOperand(frame_pointer(), kRegExpStackBasePointer));
} }
void RegExpMacroAssemblerMIPS::PopRegExpBasePointer(Register scratch1, void RegExpMacroAssemblerMIPS::PopRegExpBasePointer(Register stack_pointer_out,
Register scratch2) { Register scratch) {
ExternalReference ref = ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate()); ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ Lw(scratch1, MemOperand(frame_pointer(), kRegExpStackBasePointer)); __ Lw(stack_pointer_out,
__ li(scratch2, Operand(ref)); MemOperand(frame_pointer(), kRegExpStackBasePointer));
__ Lw(scratch2, MemOperand(scratch2)); __ li(scratch, Operand(ref));
__ Addu(scratch1, scratch1, scratch2); __ Lw(scratch, MemOperand(scratch));
StoreRegExpStackPointerToMemory(scratch1, scratch2); __ Addu(stack_pointer_out, stack_pointer_out, scratch);
StoreRegExpStackPointerToMemory(stack_pointer_out, scratch);
} }
Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
...@@ -726,35 +701,43 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -726,35 +701,43 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
kBacktrackCount - kSystemPointerSize); kBacktrackCount - kSystemPointerSize);
__ push(a0); // The regexp stack base ptr. __ push(a0); // The regexp stack base ptr.
// Initialize backtrack stack pointer. It must not be clobbered from here
// on. Note the backtrack_stackpointer is callee-saved.
STATIC_ASSERT(backtrack_stackpointer() == s7);
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
// Store the regexp base pointer - we'll later restore it / write it to // Store the regexp base pointer - we'll later restore it / write it to
// memory when returning from this irregexp code object. // memory when returning from this irregexp code object.
PushRegExpBasePointer(a0, a1); PushRegExpBasePointer(backtrack_stackpointer(), a1);
// Check if we have space on the stack for registers. {
Label stack_limit_hit; // Check if we have space on the stack for registers.
Label stack_ok; Label stack_limit_hit, stack_ok;
ExternalReference stack_limit = ExternalReference stack_limit =
ExternalReference::address_of_jslimit(masm_->isolate()); ExternalReference::address_of_jslimit(masm_->isolate());
__ li(a0, Operand(stack_limit)); __ li(a0, Operand(stack_limit));
__ lw(a0, MemOperand(a0)); __ lw(a0, MemOperand(a0));
__ Subu(a0, sp, a0); __ Subu(a0, sp, a0);
// Handle it if the stack pointer is already below the stack limit. // Handle it if the stack pointer is already below the stack limit.
__ Branch(&stack_limit_hit, le, a0, Operand(zero_reg)); __ Branch(&stack_limit_hit, le, a0, Operand(zero_reg));
// Check if there is room for the variable number of registers above // Check if there is room for the variable number of registers above
// the stack limit. // the stack limit.
__ Branch(&stack_ok, hs, a0, Operand(num_registers_ * kPointerSize)); __ Branch(&stack_ok, hs, a0, Operand(num_registers_ * kPointerSize));
// Exit with OutOfMemory exception. There is not enough space on the stack // Exit with OutOfMemory exception. There is not enough space on the stack
// for our working registers. // for our working registers.
__ li(v0, Operand(EXCEPTION)); __ li(v0, Operand(EXCEPTION));
__ jmp(&return_v0); __ jmp(&return_v0);
__ bind(&stack_limit_hit); __ bind(&stack_limit_hit);
CallCheckStackGuardState(a0); CallCheckStackGuardState(a0);
// If returned value is non-zero, we exit with the returned value as result. // If returned value is non-zero, we exit with the returned value as
__ Branch(&return_v0, ne, v0, Operand(zero_reg)); // result.
__ Branch(&return_v0, ne, v0, Operand(zero_reg));
__ bind(&stack_ok);
__ bind(&stack_ok);
}
// Allocate space on stack for registers. // Allocate space on stack for registers.
__ Subu(sp, sp, Operand(num_registers_ * kPointerSize)); __ Subu(sp, sp, Operand(num_registers_ * kPointerSize));
// Load string end. // Load string end.
...@@ -776,17 +759,20 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -776,17 +759,20 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Initialize code pointer register // Initialize code pointer register
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
Label load_char_start_regexp, start_regexp; Label load_char_start_regexp;
// Load newline if index is at start, previous character otherwise. {
__ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg)); Label start_regexp;
__ li(current_character(), Operand('\n')); // Load newline if index is at start, previous character otherwise.
__ jmp(&start_regexp); __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg));
__ li(current_character(), Operand('\n'));
// Global regexp restarts matching here. __ jmp(&start_regexp);
__ bind(&load_char_start_regexp);
// Load previous char as initial value of current character register. // Global regexp restarts matching here.
LoadCurrentCharacterUnchecked(-1, 1); __ bind(&load_char_start_regexp);
__ bind(&start_regexp); // Load previous char as initial value of current character register.
LoadCurrentCharacterUnchecked(-1, 1);
__ bind(&start_regexp);
}
// Initialize on-stack registers. // Initialize on-stack registers.
if (num_saved_registers_ > 0) { // Always is, if generated from a regexp. if (num_saved_registers_ > 0) { // Always is, if generated from a regexp.
...@@ -808,9 +794,6 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -808,9 +794,6 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
} }
} }
// Initialize backtrack stack pointer.
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
__ jmp(&start_label_); __ jmp(&start_label_);
...@@ -882,6 +865,10 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -882,6 +865,10 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Prepare a0 to initialize registers with its value in the next run. // Prepare a0 to initialize registers with its value in the next run.
__ lw(a0, MemOperand(frame_pointer(), kStringStartMinusOne)); __ lw(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), a2);
if (global_with_zero_length_check()) { if (global_with_zero_length_check()) {
// Special case for zero-length matches. // Special case for zero-length matches.
// t7: capture start index // t7: capture start index
...@@ -913,7 +900,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -913,7 +900,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
__ bind(&return_v0); __ bind(&return_v0);
// Restore the original regexp stack pointer value (effectively, pop the // Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer). // stored base pointer).
PopRegExpBasePointer(a0, a1); PopRegExpBasePointer(backtrack_stackpointer(), a1);
// Skip sp past regexp registers and local variables.. // Skip sp past regexp registers and local variables..
__ mov(sp, frame_pointer()); __ mov(sp, frame_pointer());
...@@ -933,9 +920,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -933,9 +920,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::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(), a0); StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a0);
PushCallerSavedRegisters();
CallCheckStackGuardState(a0); CallCheckStackGuardState(a0);
PopCallerSavedRegisters();
// 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.
__ Branch(&return_v0, ne, v0, Operand(zero_reg)); __ Branch(&return_v0, ne, v0, Operand(zero_reg));
...@@ -944,7 +929,6 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -944,7 +929,6 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// String might have moved: Reload end of string from frame. // String might have moved: Reload end of string from frame.
__ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); __ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
SafeReturn(); SafeReturn();
} }
...@@ -953,10 +937,6 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -953,10 +937,6 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
SafeCallTarget(&stack_overflow_label_); SafeCallTarget(&stack_overflow_label_);
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a0); StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a0);
// Reached if the backtrack-stack limit has been hit. // Reached if the backtrack-stack limit has been hit.
// Put regexp engine registers on stack first.
RegList regexp_registers = current_input_offset().bit() |
current_character().bit();
__ MultiPush(regexp_registers);
// Call GrowStack(isolate). // Call GrowStack(isolate).
static constexpr int kNumArguments = 1; static constexpr int kNumArguments = 1;
...@@ -964,16 +944,11 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -964,16 +944,11 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
__ li(a0, Operand(ExternalReference::isolate_address(masm_->isolate()))); __ li(a0, Operand(ExternalReference::isolate_address(masm_->isolate())));
ExternalReference grow_stack = ExternalReference::re_grow_stack(); ExternalReference grow_stack = ExternalReference::re_grow_stack();
__ CallCFunction(grow_stack, kNumArguments); __ CallCFunction(grow_stack, kNumArguments);
// Restore regexp registers.
__ MultiPop(regexp_registers);
// If nullptr is returned, we have failed to grow the stack, and must exit // If nullptr is returned, we have failed to grow the stack, and must exit
// with a stack-overflow exception. // with a stack-overflow exception.
__ Branch(&exit_with_exception, eq, v0, Operand(zero_reg)); __ Branch(&exit_with_exception, eq, v0, Operand(zero_reg));
// Otherwise use return value as new stack pointer. // Otherwise use return value as new stack pointer.
__ mov(backtrack_stackpointer(), v0); __ mov(backtrack_stackpointer(), v0);
// Restore saved registers and continue.
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
__ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
SafeReturn(); SafeReturn();
} }
......
...@@ -147,13 +147,13 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS ...@@ -147,13 +147,13 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
// 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.
static constexpr Register current_input_offset() { return t2; } static constexpr Register current_input_offset() { return s2; }
// The register containing the current character after LoadCurrentCharacter. // The register containing the current character after LoadCurrentCharacter.
static constexpr Register current_character() { return t3; } static constexpr Register current_character() { return s5; }
// Register holding address of the end of the input string. // Register holding address of the end of the input string.
static constexpr Register end_of_input_address() { return t6; } static constexpr Register end_of_input_address() { return s6; }
// 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.
...@@ -161,10 +161,10 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS ...@@ -161,10 +161,10 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
// 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.
static constexpr Register backtrack_stackpointer() { return t4; } static constexpr Register backtrack_stackpointer() { return s7; }
// Register holding pointer to the current code object. // Register holding pointer to the current code object.
static constexpr Register code_pointer() { return t1; } static constexpr Register code_pointer() { return s1; }
// 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() const { return static_cast<int>(mode_); } inline int char_size() const { return static_cast<int>(mode_); }
...@@ -195,8 +195,8 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS ...@@ -195,8 +195,8 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
void LoadRegExpStackPointerFromMemory(Register dst); void LoadRegExpStackPointerFromMemory(Register dst);
void StoreRegExpStackPointerToMemory(Register src, Register scratch); void StoreRegExpStackPointerToMemory(Register src, Register scratch);
void PushRegExpBasePointer(Register scratch1, Register scratch2); void PushRegExpBasePointer(Register stack_pointer, Register scratch);
void PopRegExpBasePointer(Register scratch1, Register scratch2); void PopRegExpBasePointer(Register stack_pointer_out, Register scratch);
Isolate* isolate() const { return masm_->isolate(); } Isolate* isolate() const { return masm_->isolate(); }
......
...@@ -20,18 +20,16 @@ namespace internal { ...@@ -20,18 +20,16 @@ namespace internal {
/* clang-format off /* clang-format off
* *
* This assembler uses the following register assignment convention * This assembler uses the following register assignment convention
* - t3 : Temporarily stores the index of capture start after a matching pass * - s0 : Unused.
* for a global regexp. * - s1 : Pointer to current Code object including heap object tag.
* - a5 : Pointer to current Code object including heap object tag. * - s2 : Current position in input, as negative offset from end of string.
* - a6 : Current position in input, as negative offset from end of string.
* Please notice that this is the byte offset, not the character offset! * Please notice that this is the byte offset, not the character offset!
* - a7 : Currently loaded character. Must be loaded using * - s5 : Currently loaded character. Must be loaded using
* LoadCurrentCharacter before using any of the dispatch methods. * LoadCurrentCharacter before using any of the dispatch methods.
* - t0 : Points to tip of backtrack stack * - s6 : Points to tip of backtrack stack
* - t1 : Unused. * - s7 : End of input (points to byte after last character in input).
* - t2 : End of input (points to byte after last character in input).
* - fp : Frame pointer. Used to access arguments, local variables and * - fp : Frame pointer. Used to access arguments, local variables and
* RegExp registers. * RegExp registers.
* - sp : Points to tip of C stack. * - sp : Points to tip of C stack.
* *
* The remaining registers are free for computations. * The remaining registers are free for computations.
...@@ -261,21 +259,6 @@ void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) { ...@@ -261,21 +259,6 @@ void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) {
BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0)); BranchOrBacktrack(on_equal, eq, current_input_offset(), Operand(a0));
} }
// Push (pop) caller-saved registers used by irregexp.
void RegExpMacroAssemblerMIPS::PushCallerSavedRegisters() {
RegList caller_saved_regexp =
current_input_offset().bit() | current_character().bit() |
end_of_input_address().bit() | backtrack_stackpointer().bit();
__ MultiPush(caller_saved_regexp);
}
void RegExpMacroAssemblerMIPS::PopCallerSavedRegisters() {
RegList caller_saved_regexp =
current_input_offset().bit() | current_character().bit() |
end_of_input_address().bit() | backtrack_stackpointer().bit();
__ MultiPop(caller_saved_regexp);
}
void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase(
int start_reg, bool read_backward, bool unicode, Label* on_no_match) { int start_reg, bool read_backward, bool unicode, Label* on_no_match) {
Label fallthrough; Label fallthrough;
...@@ -356,7 +339,6 @@ void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( ...@@ -356,7 +339,6 @@ void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase(
} }
} else { } else {
DCHECK(mode_ == UC16); DCHECK(mode_ == UC16);
PushCallerSavedRegisters();
int argument_count = 4; int argument_count = 4;
__ PrepareCallCFunction(argument_count, a2); __ PrepareCallCFunction(argument_count, a2);
...@@ -394,10 +376,6 @@ void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( ...@@ -394,10 +376,6 @@ void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase(
__ CallCFunction(function, argument_count); __ CallCFunction(function, argument_count);
} }
PopCallerSavedRegisters();
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
__ Ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
// Check if function returned non-zero for success or zero for failure. // Check if function returned non-zero for success or zero for failure.
BranchOrBacktrack(on_no_match, eq, v0, Operand(zero_reg)); BranchOrBacktrack(on_no_match, eq, v0, Operand(zero_reg));
// On success, increment position by length of capture. // On success, increment position by length of capture.
...@@ -522,7 +500,6 @@ void RegExpMacroAssemblerMIPS::CheckCharacterNotInRange( ...@@ -522,7 +500,6 @@ void RegExpMacroAssemblerMIPS::CheckCharacterNotInRange(
void RegExpMacroAssemblerMIPS::CallIsCharacterInRangeArray( void RegExpMacroAssemblerMIPS::CallIsCharacterInRangeArray(
const ZoneList<CharacterRange>* ranges) { const ZoneList<CharacterRange>* ranges) {
static const int kNumArguments = 3; static const int kNumArguments = 3;
PushCallerSavedRegisters();
__ PrepareCallCFunction(kNumArguments, a0); __ PrepareCallCFunction(kNumArguments, a0);
__ mov(a0, current_character()); __ mov(a0, current_character());
...@@ -536,7 +513,6 @@ void RegExpMacroAssemblerMIPS::CallIsCharacterInRangeArray( ...@@ -536,7 +513,6 @@ void RegExpMacroAssemblerMIPS::CallIsCharacterInRangeArray(
kNumArguments); kNumArguments);
} }
PopCallerSavedRegisters();
__ li(code_pointer(), Operand(masm_->CodeObject())); __ li(code_pointer(), Operand(masm_->CodeObject()));
} }
...@@ -691,26 +667,26 @@ void RegExpMacroAssemblerMIPS::StoreRegExpStackPointerToMemory( ...@@ -691,26 +667,26 @@ void RegExpMacroAssemblerMIPS::StoreRegExpStackPointerToMemory(
__ Sd(src, MemOperand(scratch)); __ Sd(src, MemOperand(scratch));
} }
void RegExpMacroAssemblerMIPS::PushRegExpBasePointer(Register scratch1, void RegExpMacroAssemblerMIPS::PushRegExpBasePointer(Register stack_pointer,
Register scratch2) { Register scratch) {
LoadRegExpStackPointerFromMemory(scratch1);
ExternalReference ref = ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate()); ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(scratch2, Operand(ref)); __ li(scratch, Operand(ref));
__ Ld(scratch2, MemOperand(scratch2)); __ Ld(scratch, MemOperand(scratch));
__ Dsubu(scratch2, scratch1, scratch2); __ Dsubu(scratch, stack_pointer, scratch);
__ Sd(scratch2, MemOperand(frame_pointer(), kRegExpStackBasePointer)); __ Sd(scratch, MemOperand(frame_pointer(), kRegExpStackBasePointer));
} }
void RegExpMacroAssemblerMIPS::PopRegExpBasePointer(Register scratch1, void RegExpMacroAssemblerMIPS::PopRegExpBasePointer(Register stack_pointer_out,
Register scratch2) { Register scratch) {
ExternalReference ref = ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate()); ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ Ld(scratch1, MemOperand(frame_pointer(), kRegExpStackBasePointer)); __ Ld(stack_pointer_out,
__ li(scratch2, Operand(ref)); MemOperand(frame_pointer(), kRegExpStackBasePointer));
__ Ld(scratch2, MemOperand(scratch2)); __ li(scratch, Operand(ref));
__ Daddu(scratch1, scratch1, scratch2); __ Ld(scratch, MemOperand(scratch));
StoreRegExpStackPointerToMemory(scratch1, scratch2); __ Daddu(stack_pointer_out, stack_pointer_out, scratch);
StoreRegExpStackPointerToMemory(stack_pointer_out, scratch);
} }
Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
...@@ -762,35 +738,43 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -762,35 +738,43 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
kBacktrackCount - kSystemPointerSize); kBacktrackCount - kSystemPointerSize);
__ push(a0); // The regexp stack base ptr. __ push(a0); // The regexp stack base ptr.
// Initialize backtrack stack pointer. It must not be clobbered from here
// on. Note the backtrack_stackpointer is callee-saved.
STATIC_ASSERT(backtrack_stackpointer() == s7);
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
// Store the regexp base pointer - we'll later restore it / write it to // Store the regexp base pointer - we'll later restore it / write it to
// memory when returning from this irregexp code object. // memory when returning from this irregexp code object.
PushRegExpBasePointer(a0, a1); PushRegExpBasePointer(backtrack_stackpointer(), a1);
// Check if we have space on the stack for registers. {
Label stack_limit_hit; // Check if we have space on the stack for registers.
Label stack_ok; Label stack_limit_hit, stack_ok;
ExternalReference stack_limit = ExternalReference stack_limit =
ExternalReference::address_of_jslimit(masm_->isolate()); ExternalReference::address_of_jslimit(masm_->isolate());
__ li(a0, Operand(stack_limit)); __ li(a0, Operand(stack_limit));
__ Ld(a0, MemOperand(a0)); __ Ld(a0, MemOperand(a0));
__ Dsubu(a0, sp, a0); __ Dsubu(a0, sp, a0);
// Handle it if the stack pointer is already below the stack limit. // Handle it if the stack pointer is already below the stack limit.
__ Branch(&stack_limit_hit, le, a0, Operand(zero_reg)); __ Branch(&stack_limit_hit, le, a0, Operand(zero_reg));
// Check if there is room for the variable number of registers above // Check if there is room for the variable number of registers above
// the stack limit. // the stack limit.
__ Branch(&stack_ok, hs, a0, Operand(num_registers_ * kPointerSize)); __ Branch(&stack_ok, hs, a0, Operand(num_registers_ * kPointerSize));
// Exit with OutOfMemory exception. There is not enough space on the stack // Exit with OutOfMemory exception. There is not enough space on the stack
// for our working registers. // for our working registers.
__ li(v0, Operand(EXCEPTION)); __ li(v0, Operand(EXCEPTION));
__ jmp(&return_v0); __ jmp(&return_v0);
__ bind(&stack_limit_hit); __ bind(&stack_limit_hit);
CallCheckStackGuardState(a0); CallCheckStackGuardState(a0);
// If returned value is non-zero, we exit with the returned value as result. // If returned value is non-zero, we exit with the returned value as
__ Branch(&return_v0, ne, v0, Operand(zero_reg)); // result.
__ Branch(&return_v0, ne, v0, Operand(zero_reg));
__ bind(&stack_ok);
__ bind(&stack_ok);
}
// Allocate space on stack for registers. // Allocate space on stack for registers.
__ Dsubu(sp, sp, Operand(num_registers_ * kPointerSize)); __ Dsubu(sp, sp, Operand(num_registers_ * kPointerSize));
// Load string end. // Load string end.
...@@ -812,17 +796,20 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -812,17 +796,20 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Initialize code pointer register // Initialize code pointer register
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE); __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
Label load_char_start_regexp, start_regexp; Label load_char_start_regexp;
// Load newline if index is at start, previous character otherwise. {
__ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg)); Label start_regexp;
__ li(current_character(), Operand('\n')); // Load newline if index is at start, previous character otherwise.
__ jmp(&start_regexp); __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg));
__ li(current_character(), Operand('\n'));
// Global regexp restarts matching here. __ jmp(&start_regexp);
__ bind(&load_char_start_regexp);
// Load previous char as initial value of current character register. // Global regexp restarts matching here.
LoadCurrentCharacterUnchecked(-1, 1); __ bind(&load_char_start_regexp);
__ bind(&start_regexp); // Load previous char as initial value of current character register.
LoadCurrentCharacterUnchecked(-1, 1);
__ bind(&start_regexp);
}
// Initialize on-stack registers. // Initialize on-stack registers.
if (num_saved_registers_ > 0) { // Always is, if generated from a regexp. if (num_saved_registers_ > 0) { // Always is, if generated from a regexp.
...@@ -844,12 +831,8 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -844,12 +831,8 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
} }
} }
// Initialize backtrack stack pointer.
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
__ jmp(&start_label_); __ jmp(&start_label_);
// Exit code: // Exit code:
if (success_label_.is_linked()) { if (success_label_.is_linked()) {
// Save captures when successful. // Save captures when successful.
...@@ -919,6 +902,10 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -919,6 +902,10 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Prepare a0 to initialize registers with its value in the next run. // Prepare a0 to initialize registers with its value in the next run.
__ Ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne)); __ Ld(a0, MemOperand(frame_pointer(), kStringStartMinusOne));
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(backtrack_stackpointer(), a2);
if (global_with_zero_length_check()) { if (global_with_zero_length_check()) {
// Special case for zero-length matches. // Special case for zero-length matches.
// t3: capture start index // t3: capture start index
...@@ -950,7 +937,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -950,7 +937,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
__ bind(&return_v0); __ bind(&return_v0);
// Restore the original regexp stack pointer value (effectively, pop the // Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer). // stored base pointer).
PopRegExpBasePointer(a0, a1); PopRegExpBasePointer(backtrack_stackpointer(), a1);
// Skip sp past regexp registers and local variables.. // Skip sp past regexp registers and local variables..
__ mov(sp, frame_pointer()); __ mov(sp, frame_pointer());
...@@ -971,9 +958,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -971,9 +958,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
SafeCallTarget(&check_preempt_label_); SafeCallTarget(&check_preempt_label_);
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a0); StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a0);
PushCallerSavedRegisters();
CallCheckStackGuardState(a0); CallCheckStackGuardState(a0);
PopCallerSavedRegisters();
// 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.
__ Branch(&return_v0, ne, v0, Operand(zero_reg)); __ Branch(&return_v0, ne, v0, Operand(zero_reg));
...@@ -982,7 +967,6 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -982,7 +967,6 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// String might have moved: Reload end of string from frame. // String might have moved: Reload end of string from frame.
__ Ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); __ Ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
SafeReturn(); SafeReturn();
} }
...@@ -991,10 +975,6 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -991,10 +975,6 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
SafeCallTarget(&stack_overflow_label_); SafeCallTarget(&stack_overflow_label_);
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a0); StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a0);
// Reached if the backtrack-stack limit has been hit. // Reached if the backtrack-stack limit has been hit.
// Put regexp engine registers on stack first.
RegList regexp_registers = current_input_offset().bit() |
current_character().bit();
__ MultiPush(regexp_registers);
// Call GrowStack(isolate) // Call GrowStack(isolate)
static constexpr int kNumArguments = 1; static constexpr int kNumArguments = 1;
...@@ -1002,16 +982,11 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -1002,16 +982,11 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
__ li(a0, Operand(ExternalReference::isolate_address(masm_->isolate()))); __ li(a0, Operand(ExternalReference::isolate_address(masm_->isolate())));
ExternalReference grow_stack = ExternalReference::re_grow_stack(); ExternalReference grow_stack = ExternalReference::re_grow_stack();
__ CallCFunction(grow_stack, kNumArguments); __ CallCFunction(grow_stack, kNumArguments);
// Restore regexp registers.
__ MultiPop(regexp_registers);
// If nullptr is returned, we have failed to grow the stack, and must exit // If nullptr is returned, we have failed to grow the stack, and must exit
// with a stack-overflow exception. // with a stack-overflow exception.
__ Branch(&exit_with_exception, eq, v0, Operand(zero_reg)); __ Branch(&exit_with_exception, eq, v0, Operand(zero_reg));
// Otherwise use return value as new stack pointer. // Otherwise use return value as new stack pointer.
__ mov(backtrack_stackpointer(), v0); __ mov(backtrack_stackpointer(), v0);
// Restore saved registers and continue.
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
__ Ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
SafeReturn(); SafeReturn();
} }
......
...@@ -153,13 +153,13 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS ...@@ -153,13 +153,13 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
// 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.
static constexpr Register current_input_offset() { return a6; } static constexpr Register current_input_offset() { return s2; }
// The register containing the current character after LoadCurrentCharacter. // The register containing the current character after LoadCurrentCharacter.
static constexpr Register current_character() { return a7; } static constexpr Register current_character() { return s5; }
// Register holding address of the end of the input string. // Register holding address of the end of the input string.
static constexpr Register end_of_input_address() { return t2; } static constexpr Register end_of_input_address() { return s6; }
// 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.
...@@ -167,10 +167,10 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS ...@@ -167,10 +167,10 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
// 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.
static constexpr Register backtrack_stackpointer() { return t0; } static constexpr Register backtrack_stackpointer() { return s7; }
// Register holding pointer to the current code object. // Register holding pointer to the current code object.
static constexpr Register code_pointer() { return a5; } static constexpr Register code_pointer() { return s1; }
// 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() const { return static_cast<int>(mode_); } inline int char_size() const { return static_cast<int>(mode_); }
...@@ -201,8 +201,8 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS ...@@ -201,8 +201,8 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
void LoadRegExpStackPointerFromMemory(Register dst); void LoadRegExpStackPointerFromMemory(Register dst);
void StoreRegExpStackPointerToMemory(Register src, Register scratch); void StoreRegExpStackPointerToMemory(Register src, Register scratch);
void PushRegExpBasePointer(Register scratch1, Register scratch2); void PushRegExpBasePointer(Register stack_pointer, Register scratch);
void PopRegExpBasePointer(Register scratch1, Register scratch2); void PopRegExpBasePointer(Register stack_pointer_out, Register scratch);
Isolate* isolate() const { return masm_->isolate(); } Isolate* isolate() const { return masm_->isolate(); }
......
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