Commit f5e48df1 authored by Zhao Jiazhong's avatar Zhao Jiazhong Committed by V8 LUCI CQ

[mips][loong64][regexp] Fix regexp test failures

Port commit bba7c09a
  [regexp] Allow reentrant irregexp execution

Port commit 4bbfc4b7
  [regexp] Remove the `stack` parameter from regexp matchers

Port commit c1700c56
  [regexp] Fix UAF in RegExpMacroAssembler

Bug: v8:11382
Change-Id: Ie2e95d7b19ecbd740e8d8a4130c725416abc114a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3185562Reviewed-by: 's avatarLiu yu <liuyu@loongson.cn>
Commit-Queue: Zhao Jiazhong <zhaojiazhong-hf@loongson.cn>
Cr-Commit-Position: refs/heads/main@{#77090}
parent ea6dd0f4
...@@ -6,14 +6,12 @@ ...@@ -6,14 +6,12 @@
#include "src/regexp/loong64/regexp-macro-assembler-loong64.h" #include "src/regexp/loong64/regexp-macro-assembler-loong64.h"
#include "src/codegen/assembler-inl.h"
#include "src/codegen/macro-assembler.h" #include "src/codegen/macro-assembler.h"
#include "src/heap/factory.h"
#include "src/logging/log.h" #include "src/logging/log.h"
#include "src/objects/objects-inl.h" #include "src/objects/code-inl.h"
#include "src/regexp/regexp-macro-assembler.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 {
...@@ -48,19 +46,18 @@ namespace internal { ...@@ -48,19 +46,18 @@ namespace internal {
* - fp[0..63] s0..s7 Callee-saved registers s0..s7. * - fp[0..63] s0..s7 Callee-saved registers s0..s7.
* --- frame pointer ---- * --- frame pointer ----
* - fp[-8] direct_call (1 = direct call from JS, 0 = from runtime) kDirectCall * - fp[-8] direct_call (1 = direct call from JS, 0 = from runtime) kDirectCall
* - fp[-16] stack_base (Top of backtracking stack). kStackHighEnd * - fp[-16] capture array size (may fit multiple sets of matches) kNumOutputRegisters
* - fp[-24] capture array size (may fit multiple sets of matches) kNumOutputRegisters * - fp[-24] int* capture_array (int[num_saved_registers_], for output). kRegisterOutput
* - fp[-32] int* capture_array (int[num_saved_registers_], for output). kRegisterOutput * - fp[-32] end of input (address of end of string). kInputEnd
* - fp[-40] end of input (address of end of string). kInputEnd * - fp[-40] start of input (address of first character in string). kInputStart
* - fp[-48] start of input (address of first character in string). kInputStart * - fp[-48] start index (character index of start). kStartIndex
* - fp[-56] start index (character index of start). kStartIndex * - fp[-56] void* input_string (location of a handle containing the string). kInputString
* - fp[-64] void* input_string (location of a handle containing the string). kInputString * - fp[-64] success counter (only for global regexps to count matches). kSuccessfulCaptures
* - fp[-72] success counter (only for global regexps to count matches). kSuccessfulCaptures * - fp[-72] Offset of location before start of input (effectively character kStringStartMinusOne
* - fp[-80] Offset of location before start of input (effectively character kStringStartMinusOne
* position -1). Used to initialize capture registers to a * position -1). Used to initialize capture registers to a
* non-position. * non-position.
* --------- The following output registers are 32-bit values. --------- * --------- The following output registers are 32-bit values. ---------
* - fp[-88] register 0 (Only positions must be stored in the first kRegisterZero * - fp[-80] register 0 (Only positions must be stored in the first kRegisterZero
* - register 1 num_saved_registers_ registers) * - register 1 num_saved_registers_ registers)
* - ... * - ...
* - register num_registers-1 * - register num_registers-1
...@@ -79,7 +76,6 @@ namespace internal { ...@@ -79,7 +76,6 @@ namespace internal {
* Address end, * Address end,
* int* capture_output_array, * int* capture_output_array,
* int num_capture_registers, * int num_capture_registers,
* byte* stack_area_base,
* bool direct_call = false, * bool direct_call = false,
* Isolate* isolate); * Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute() * The call is performed by NativeRegExpMacroAssembler::Execute()
...@@ -96,8 +92,10 @@ RegExpMacroAssemblerLOONG64::RegExpMacroAssemblerLOONG64(Isolate* isolate, ...@@ -96,8 +92,10 @@ RegExpMacroAssemblerLOONG64::RegExpMacroAssemblerLOONG64(Isolate* isolate,
Zone* zone, Mode mode, Zone* zone, Mode mode,
int registers_to_save) int registers_to_save)
: NativeRegExpMacroAssembler(isolate, zone), : NativeRegExpMacroAssembler(isolate, zone),
masm_(new MacroAssembler(isolate, CodeObjectRequired::kYes, masm_(std::make_unique<MacroAssembler>(
NewAssemblerBuffer(kRegExpCodeSize))), isolate, CodeObjectRequired::kYes,
NewAssemblerBuffer(kRegExpCodeSize))),
no_root_array_scope_(masm_.get()),
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),
...@@ -107,8 +105,6 @@ RegExpMacroAssemblerLOONG64::RegExpMacroAssemblerLOONG64(Isolate* isolate, ...@@ -107,8 +105,6 @@ RegExpMacroAssemblerLOONG64::RegExpMacroAssemblerLOONG64(Isolate* isolate,
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);
__ jmp(&entry_label_); // We'll write the entry code later. __ jmp(&entry_label_); // We'll write the entry code later.
// If the code gets too big or corrupted, an internal exception will be // If the code gets too big or corrupted, an internal exception will be
...@@ -120,7 +116,6 @@ RegExpMacroAssemblerLOONG64::RegExpMacroAssemblerLOONG64(Isolate* isolate, ...@@ -120,7 +116,6 @@ RegExpMacroAssemblerLOONG64::RegExpMacroAssemblerLOONG64(Isolate* isolate,
} }
RegExpMacroAssemblerLOONG64::~RegExpMacroAssemblerLOONG64() { RegExpMacroAssemblerLOONG64::~RegExpMacroAssemblerLOONG64() {
delete masm_;
// Unuse labels in case we throw away the assembler without calling GetCode. // Unuse labels in case we throw away the assembler without calling GetCode.
entry_label_.Unuse(); entry_label_.Unuse();
start_label_.Unuse(); start_label_.Unuse();
...@@ -336,7 +331,7 @@ void RegExpMacroAssemblerLOONG64::CheckNotBackReferenceIgnoreCase( ...@@ -336,7 +331,7 @@ void RegExpMacroAssemblerLOONG64::CheckNotBackReferenceIgnoreCase(
__ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate()))); __ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate())));
{ {
AllowExternalCallThatCantCauseGC scope(masm_); AllowExternalCallThatCantCauseGC scope(masm_.get());
ExternalReference function = ExternalReference function =
unicode ? ExternalReference::re_case_insensitive_compare_unicode( unicode ? ExternalReference::re_case_insensitive_compare_unicode(
isolate()) isolate())
...@@ -592,6 +587,44 @@ void RegExpMacroAssemblerLOONG64::Fail() { ...@@ -592,6 +587,44 @@ void RegExpMacroAssemblerLOONG64::Fail() {
__ jmp(&exit_label_); __ jmp(&exit_label_);
} }
void RegExpMacroAssemblerLOONG64::LoadRegExpStackPointerFromMemory(
Register dst) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_stack_pointer(isolate());
__ li(dst, ref);
__ Ld_d(dst, MemOperand(dst, 0));
}
void RegExpMacroAssemblerLOONG64::StoreRegExpStackPointerToMemory(
Register src, Register scratch) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_stack_pointer(isolate());
__ li(scratch, ref);
__ St_d(src, MemOperand(scratch, 0));
}
void RegExpMacroAssemblerLOONG64::PushRegExpBasePointer(Register scratch1,
Register scratch2) {
LoadRegExpStackPointerFromMemory(scratch1);
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(scratch2, ref);
__ Ld_d(scratch2, MemOperand(scratch2, 0));
__ Sub_d(scratch2, scratch1, scratch2);
__ St_d(scratch2, MemOperand(frame_pointer(), kRegExpStackBasePointer));
}
void RegExpMacroAssemblerLOONG64::PopRegExpBasePointer(Register scratch1,
Register scratch2) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ Ld_d(scratch1, MemOperand(frame_pointer(), kRegExpStackBasePointer));
__ li(scratch2, ref);
__ Ld_d(scratch2, MemOperand(scratch2, 0));
__ Add_d(scratch1, scratch1, scratch2);
StoreRegExpStackPointerToMemory(scratch1, scratch2);
}
Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
Label return_v0; Label return_v0;
if (0 /* todo masm_->has_exception()*/) { if (0 /* todo masm_->has_exception()*/) {
...@@ -608,7 +641,7 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { ...@@ -608,7 +641,7 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
// Tell the system that we have a stack frame. Because the type is MANUAL, // Tell the system that we have a stack frame. Because the type is MANUAL,
// no is generated. // no is generated.
FrameScope scope(masm_, StackFrame::MANUAL); FrameScope scope(masm_.get(), StackFrame::MANUAL);
// Actually emit code to start a new stack frame. // Actually emit code to start a new stack frame.
// Push arguments // Push arguments
...@@ -637,6 +670,13 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { ...@@ -637,6 +670,13 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
__ Push(a0); // Make room for "string start - 1" constant. __ Push(a0); // Make room for "string start - 1" constant.
STATIC_ASSERT(kBacktrackCount == kStringStartMinusOne - kSystemPointerSize); STATIC_ASSERT(kBacktrackCount == kStringStartMinusOne - kSystemPointerSize);
__ Push(a0); // The backtrack counter __ Push(a0); // The backtrack counter
STATIC_ASSERT(kRegExpStackBasePointer ==
kBacktrackCount - kSystemPointerSize);
__ Push(a0); // 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(a0, a1);
// 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;
...@@ -717,8 +757,7 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { ...@@ -717,8 +757,7 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
} }
// Initialize backtrack stack pointer. // Initialize backtrack stack pointer.
__ Ld_d(backtrack_stackpointer(), LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
MemOperand(frame_pointer(), kStackHighEnd));
__ jmp(&start_label_); __ jmp(&start_label_);
...@@ -820,6 +859,10 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { ...@@ -820,6 +859,10 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
} }
__ bind(&return_v0); __ bind(&return_v0);
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(a1, 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());
// Restore registers s0..s7 and return (restoring ra to pc). // Restore registers s0..s7 and return (restoring ra to pc).
...@@ -838,6 +881,8 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { ...@@ -838,6 +881,8 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
if (check_preempt_label_.is_linked()) { if (check_preempt_label_.is_linked()) {
SafeCallTarget(&check_preempt_label_); SafeCallTarget(&check_preempt_label_);
// Put regexp engine registers on stack. // Put regexp engine registers on stack.
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1);
RegList regexp_registers_to_retain = current_input_offset().bit() | RegList regexp_registers_to_retain = current_input_offset().bit() |
current_character().bit() | current_character().bit() |
backtrack_stackpointer().bit(); backtrack_stackpointer().bit();
...@@ -848,34 +893,36 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) { ...@@ -848,34 +893,36 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
// result as return value. // result as return value.
__ Branch(&return_v0, ne, a0, Operand(zero_reg)); __ Branch(&return_v0, ne, a0, Operand(zero_reg));
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
// 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); __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
SafeReturn(); SafeReturn();
} }
// Backtrack stack overflow code. // Backtrack stack overflow code.
if (stack_overflow_label_.is_linked()) { if (stack_overflow_label_.is_linked()) {
SafeCallTarget(&stack_overflow_label_); SafeCallTarget(&stack_overflow_label_);
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. // Put regexp engine registers on stack first.
RegList regexp_registers = RegList regexp_registers =
current_input_offset().bit() | current_character().bit(); current_input_offset().bit() | current_character().bit();
__ MultiPush(regexp_registers); __ MultiPush(regexp_registers);
// Call GrowStack(backtrack_stackpointer(), &stack_base) // Call GrowStack(isolate).
static const int num_arguments = 3; static const int kNumArguments = 1;
__ PrepareCallCFunction(num_arguments, a0); __ PrepareCallCFunction(kNumArguments, a0);
__ mov(a0, backtrack_stackpointer()); __ li(a0, Operand(ExternalReference::isolate_address(masm_->isolate())));
__ Add_d(a1, frame_pointer(), Operand(kStackHighEnd));
__ li(a2, Operand(ExternalReference::isolate_address(masm_->isolate())));
ExternalReference grow_stack = ExternalReference grow_stack =
ExternalReference::re_grow_stack(masm_->isolate()); ExternalReference::re_grow_stack(masm_->isolate());
__ CallCFunction(grow_stack, num_arguments); __ CallCFunction(grow_stack, kNumArguments);
// Restore regexp registers. // Restore regexp registers.
__ MultiPop(regexp_registers); __ MultiPop(regexp_registers);
// 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.
__ 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);
...@@ -956,7 +1003,7 @@ void RegExpMacroAssemblerLOONG64::PushBacktrack(Label* label) { ...@@ -956,7 +1003,7 @@ void RegExpMacroAssemblerLOONG64::PushBacktrack(Label* label) {
int target = label->pos(); int target = label->pos();
__ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag)); __ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag));
} else { } else {
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_.get());
Label after_constant; Label after_constant;
__ Branch(&after_constant); __ Branch(&after_constant);
int offset = masm_->pc_offset(); int offset = masm_->pc_offset();
...@@ -991,9 +1038,21 @@ void RegExpMacroAssemblerLOONG64::ReadCurrentPositionFromRegister(int reg) { ...@@ -991,9 +1038,21 @@ void RegExpMacroAssemblerLOONG64::ReadCurrentPositionFromRegister(int reg) {
__ Ld_d(current_input_offset(), register_location(reg)); __ Ld_d(current_input_offset(), register_location(reg));
} }
void RegExpMacroAssemblerLOONG64::WriteStackPointerToRegister(int reg) {
ExternalReference stack_top_address =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(a0, stack_top_address);
__ Ld_d(a0, MemOperand(a0, 0));
__ Sub_d(a0, backtrack_stackpointer(), a0);
__ St_d(a0, register_location(reg));
}
void RegExpMacroAssemblerLOONG64::ReadStackPointerFromRegister(int reg) { void RegExpMacroAssemblerLOONG64::ReadStackPointerFromRegister(int reg) {
__ Ld_d(backtrack_stackpointer(), register_location(reg)); ExternalReference stack_top_address =
__ Ld_d(a0, MemOperand(frame_pointer(), kStackHighEnd)); ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(backtrack_stackpointer(), stack_top_address);
__ Ld_d(backtrack_stackpointer(), MemOperand(backtrack_stackpointer(), 0));
__ Ld_d(a0, register_location(reg));
__ Add_d(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0)); __ Add_d(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0));
} }
...@@ -1038,12 +1097,6 @@ void RegExpMacroAssemblerLOONG64::ClearRegisters(int reg_from, int reg_to) { ...@@ -1038,12 +1097,6 @@ void RegExpMacroAssemblerLOONG64::ClearRegisters(int reg_from, int reg_to) {
} }
} }
void RegExpMacroAssemblerLOONG64::WriteStackPointerToRegister(int reg) {
__ Ld_d(a1, MemOperand(frame_pointer(), kStackHighEnd));
__ Sub_d(a0, backtrack_stackpointer(), a1);
__ St_d(a0, register_location(reg));
}
// Private methods: // Private methods:
void RegExpMacroAssemblerLOONG64::CallCheckStackGuardState(Register scratch) { void RegExpMacroAssemblerLOONG64::CallCheckStackGuardState(Register scratch) {
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
#ifndef V8_REGEXP_LOONG64_REGEXP_MACRO_ASSEMBLER_LOONG64_H_ #ifndef V8_REGEXP_LOONG64_REGEXP_MACRO_ASSEMBLER_LOONG64_H_
#define V8_REGEXP_LOONG64_REGEXP_MACRO_ASSEMBLER_LOONG64_H_ #define V8_REGEXP_LOONG64_REGEXP_MACRO_ASSEMBLER_LOONG64_H_
#include "src/base/strings.h"
#include "src/codegen/loong64/assembler-loong64.h"
#include "src/codegen/macro-assembler.h" #include "src/codegen/macro-assembler.h"
#include "src/regexp/regexp-macro-assembler.h" #include "src/regexp/regexp-macro-assembler.h"
...@@ -93,35 +91,39 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerLOONG64 ...@@ -93,35 +91,39 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerLOONG64
static const int kFramePointer = 0; static const int kFramePointer = 0;
// Above the frame pointer - Stored registers and stack passed parameters. // Above the frame pointer - Stored registers and stack passed parameters.
// Registers s0 to s7, fp, and ra.
static const int kStoredRegisters = kFramePointer; static const int kStoredRegisters = kFramePointer;
// Return address (stored from link register, read into pc on return). // Return address (stored from link register, read into pc on return).
// TODO(plind): This 9 - is 8 s-regs (s0..s7) plus fp. // TODO(plind): This 9 - is 8 s-regs (s0..s7) plus fp.
static const int kReturnAddress = kStoredRegisters + 9 * kPointerSize; static const int kReturnAddress = kStoredRegisters + 9 * kSystemPointerSize;
// Stack frame header. // Stack frame header.
static const int kStackFrameHeader = kReturnAddress; static const int kStackFrameHeader = kReturnAddress;
// Stack parameters placed by caller.
static const int kIsolate = kStackFrameHeader + kPointerSize;
// Below the frame pointer. // Below the frame pointer.
// Register parameters stored by setup code. // Register parameters stored by setup code.
static const int kDirectCall = kFramePointer - kPointerSize; static const int kIsolate = kFramePointer - kSystemPointerSize;
static const int kStackHighEnd = kDirectCall - kPointerSize; static const int kDirectCall = kIsolate - kSystemPointerSize;
static const int kNumOutputRegisters = kStackHighEnd - kPointerSize; static const int kNumOutputRegisters = kDirectCall - kSystemPointerSize;
static const int kRegisterOutput = kNumOutputRegisters - kPointerSize; static const int kRegisterOutput = kNumOutputRegisters - kSystemPointerSize;
static const int kInputEnd = kRegisterOutput - kPointerSize; static const int kInputEnd = kRegisterOutput - kSystemPointerSize;
static const int kInputStart = kInputEnd - kPointerSize; static const int kInputStart = kInputEnd - kSystemPointerSize;
static const int kStartIndex = kInputStart - kPointerSize; static const int kStartIndex = kInputStart - kSystemPointerSize;
static const int kInputString = kStartIndex - kPointerSize; static const int kInputString = kStartIndex - kSystemPointerSize;
// When adding local variables remember to push space for them in // When adding local variables remember to push space for them in
// the frame in GetCode. // the frame in GetCode.
static const int kSuccessfulCaptures = kInputString - kPointerSize; static const int kSuccessfulCaptures = kInputString - kSystemPointerSize;
static const int kStringStartMinusOne = kSuccessfulCaptures - kPointerSize; static const int kStringStartMinusOne =
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;
...@@ -140,24 +142,24 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerLOONG64 ...@@ -140,24 +142,24 @@ 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.
inline Register current_input_offset() { return a6; } static constexpr Register current_input_offset() { return a6; }
// The register containing the current character after LoadCurrentCharacter. // The register containing the current character after LoadCurrentCharacter.
inline Register current_character() { return a7; } static constexpr Register current_character() { return a7; }
// 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 t2; } static constexpr Register end_of_input_address() { return t2; }
// 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 t0; } static constexpr Register backtrack_stackpointer() { return t0; }
// Register holding pointer to the current code object. // Register holding pointer to the current code object.
inline Register code_pointer() { return a5; } static constexpr Register code_pointer() { return a5; }
// 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_); }
...@@ -182,19 +184,26 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerLOONG64 ...@@ -182,19 +184,26 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerLOONG64
// 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_; const std::unique_ptr<MacroAssembler> 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,14 +6,12 @@ ...@@ -6,14 +6,12 @@
#include "src/regexp/mips/regexp-macro-assembler-mips.h" #include "src/regexp/mips/regexp-macro-assembler-mips.h"
#include "src/codegen/assembler-inl.h"
#include "src/codegen/macro-assembler.h" #include "src/codegen/macro-assembler.h"
#include "src/codegen/mips/assembler-mips-inl.h"
#include "src/logging/log.h" #include "src/logging/log.h"
#include "src/objects/objects-inl.h" #include "src/objects/code-inl.h"
#include "src/regexp/regexp-macro-assembler.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 {
...@@ -39,11 +37,9 @@ namespace internal { ...@@ -39,11 +37,9 @@ namespace internal {
* *
* The stack will have the following structure: * The stack will have the following structure:
* *
* - fp[60] Isolate* isolate (address of the current isolate) * - fp[56] Isolate* isolate (address of the current isolate)
* - fp[56] direct_call (if 1, direct call from JavaScript code, * - fp[52] direct_call (if 1, direct call from JavaScript code,
* if 0, call through the runtime system). * if 0, call through the runtime system).
* - fp[52] stack_area_base (High end of the memory area to use as
* backtracking stack).
* - fp[48] capture array size (may fit multiple sets of matches) * - fp[48] capture array size (may fit multiple sets of matches)
* - fp[44] int* capture_array (int[num_saved_registers_], for output). * - fp[44] int* capture_array (int[num_saved_registers_], for output).
* --- sp when called --- * --- sp when called ---
...@@ -80,7 +76,6 @@ namespace internal { ...@@ -80,7 +76,6 @@ namespace internal {
* Address end, * Address end,
* int* capture_output_array, * int* capture_output_array,
* int num_capture_registers, * int num_capture_registers,
* byte* stack_area_base,
* bool direct_call = false, * bool direct_call = false,
* Isolate* isolate); * Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute() * The call is performed by NativeRegExpMacroAssembler::Execute()
...@@ -95,8 +90,10 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone, ...@@ -95,8 +90,10 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone,
Mode mode, Mode mode,
int registers_to_save) int registers_to_save)
: NativeRegExpMacroAssembler(isolate, zone), : NativeRegExpMacroAssembler(isolate, zone),
masm_(new MacroAssembler(isolate, CodeObjectRequired::kYes, masm_(std::make_unique<MacroAssembler>(
NewAssemblerBuffer(kRegExpCodeSize))), isolate, CodeObjectRequired::kYes,
NewAssemblerBuffer(kRegExpCodeSize))),
no_root_array_scope_(masm_.get()),
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),
...@@ -106,8 +103,6 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone, ...@@ -106,8 +103,6 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(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);
__ jmp(&entry_label_); // We'll write the entry code later. __ jmp(&entry_label_); // We'll write the entry code later.
// If the code gets too big or corrupted, an internal exception will be // If the code gets too big or corrupted, an internal exception will be
...@@ -119,7 +114,6 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone, ...@@ -119,7 +114,6 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone,
} }
RegExpMacroAssemblerMIPS::~RegExpMacroAssemblerMIPS() { RegExpMacroAssemblerMIPS::~RegExpMacroAssemblerMIPS() {
delete masm_;
// Unuse labels in case we throw away the assembler without calling GetCode. // Unuse labels in case we throw away the assembler without calling GetCode.
entry_label_.Unuse(); entry_label_.Unuse();
start_label_.Unuse(); start_label_.Unuse();
...@@ -342,7 +336,7 @@ void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( ...@@ -342,7 +336,7 @@ void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase(
__ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate()))); __ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate())));
{ {
AllowExternalCallThatCantCauseGC scope(masm_); AllowExternalCallThatCantCauseGC scope(masm_.get());
ExternalReference function = ExternalReference function =
unicode ? ExternalReference::re_case_insensitive_compare_unicode( unicode ? ExternalReference::re_case_insensitive_compare_unicode(
isolate()) isolate())
...@@ -607,6 +601,42 @@ void RegExpMacroAssemblerMIPS::Fail() { ...@@ -607,6 +601,42 @@ void RegExpMacroAssemblerMIPS::Fail() {
__ jmp(&exit_label_); __ jmp(&exit_label_);
} }
void RegExpMacroAssemblerMIPS::LoadRegExpStackPointerFromMemory(Register dst) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_stack_pointer(isolate());
__ li(dst, Operand(ref));
__ Lw(dst, MemOperand(dst));
}
void RegExpMacroAssemblerMIPS::StoreRegExpStackPointerToMemory(
Register src, Register scratch) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_stack_pointer(isolate());
__ li(scratch, Operand(ref));
__ Sw(src, MemOperand(scratch));
}
void RegExpMacroAssemblerMIPS::PushRegExpBasePointer(Register scratch1,
Register scratch2) {
LoadRegExpStackPointerFromMemory(scratch1);
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(scratch2, Operand(ref));
__ Lw(scratch2, MemOperand(scratch2));
__ Subu(scratch2, scratch1, scratch2);
__ Sw(scratch2, MemOperand(frame_pointer(), kRegExpStackBasePointer));
}
void RegExpMacroAssemblerMIPS::PopRegExpBasePointer(Register scratch1,
Register scratch2) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ Lw(scratch1, MemOperand(frame_pointer(), kRegExpStackBasePointer));
__ li(scratch2, Operand(ref));
__ Lw(scratch2, MemOperand(scratch2));
__ Addu(scratch1, scratch1, scratch2);
StoreRegExpStackPointerToMemory(scratch1, scratch2);
}
Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
Label return_v0; Label return_v0;
...@@ -624,7 +654,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -624,7 +654,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Tell the system that we have a stack frame. Because the type is MANUAL, // Tell the system that we have a stack frame. Because the type is MANUAL,
// no is generated. // no is generated.
FrameScope scope(masm_, StackFrame::MANUAL); FrameScope scope(masm_.get(), StackFrame::MANUAL);
// Actually emit code to start a new stack frame. // Actually emit code to start a new stack frame.
// Push arguments // Push arguments
...@@ -648,6 +678,13 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -648,6 +678,13 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
__ push(a0); // Make room for "string start - 1" constant. __ push(a0); // Make room for "string start - 1" constant.
STATIC_ASSERT(kBacktrackCount == kStringStartMinusOne - kSystemPointerSize); STATIC_ASSERT(kBacktrackCount == kStringStartMinusOne - kSystemPointerSize);
__ push(a0); __ push(a0);
STATIC_ASSERT(kRegExpStackBasePointer ==
kBacktrackCount - kSystemPointerSize);
__ push(a0); // 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(a0, a1);
// 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;
...@@ -728,7 +765,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -728,7 +765,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
} }
// Initialize backtrack stack pointer. // Initialize backtrack stack pointer.
__ lw(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd)); LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
__ jmp(&start_label_); __ jmp(&start_label_);
...@@ -830,6 +867,10 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -830,6 +867,10 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
} }
__ bind(&return_v0); __ bind(&return_v0);
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(a0, 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());
// Restore registers s0..s7 and return (restoring ra to pc). // Restore registers s0..s7 and return (restoring ra to pc).
...@@ -847,6 +888,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -847,6 +888,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Preempt-code. // Preempt-code.
if (check_preempt_label_.is_linked()) { if (check_preempt_label_.is_linked()) {
SafeCallTarget(&check_preempt_label_); SafeCallTarget(&check_preempt_label_);
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a0);
// Put regexp engine registers on stack. // Put regexp engine registers on stack.
RegList regexp_registers_to_retain = current_input_offset().bit() | RegList regexp_registers_to_retain = current_input_offset().bit() |
current_character().bit() | backtrack_stackpointer().bit(); current_character().bit() | backtrack_stackpointer().bit();
...@@ -857,6 +899,8 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -857,6 +899,8 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// result as return value. // result as return value.
__ Branch(&return_v0, ne, v0, Operand(zero_reg)); __ Branch(&return_v0, ne, v0, Operand(zero_reg));
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
// 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); __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
...@@ -866,25 +910,24 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -866,25 +910,24 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Backtrack stack overflow code. // Backtrack stack overflow code.
if (stack_overflow_label_.is_linked()) { if (stack_overflow_label_.is_linked()) {
SafeCallTarget(&stack_overflow_label_); SafeCallTarget(&stack_overflow_label_);
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. // Put regexp engine registers on stack first.
RegList regexp_registers = current_input_offset().bit() | RegList regexp_registers = current_input_offset().bit() |
current_character().bit(); current_character().bit();
__ MultiPush(regexp_registers); __ MultiPush(regexp_registers);
// Call GrowStack(backtrack_stackpointer(), &stack_base) // Call GrowStack(isolate).
static const int num_arguments = 3; static constexpr int kNumArguments = 1;
__ PrepareCallCFunction(num_arguments, a0); __ PrepareCallCFunction(kNumArguments, a0);
__ mov(a0, backtrack_stackpointer()); __ li(a0, Operand(ExternalReference::isolate_address(masm_->isolate())));
__ Addu(a1, frame_pointer(), Operand(kStackHighEnd));
__ li(a2, Operand(ExternalReference::isolate_address(masm_->isolate())));
ExternalReference grow_stack = ExternalReference grow_stack =
ExternalReference::re_grow_stack(masm_->isolate()); ExternalReference::re_grow_stack(masm_->isolate());
__ CallCFunction(grow_stack, num_arguments); __ CallCFunction(grow_stack, kNumArguments);
// Restore regexp registers. // Restore regexp registers.
__ MultiPop(regexp_registers); __ MultiPop(regexp_registers);
// 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.
__ 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);
...@@ -976,7 +1019,7 @@ void RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) { ...@@ -976,7 +1019,7 @@ void RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) {
int target = label->pos(); int target = label->pos();
__ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag)); __ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag));
} else { } else {
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_.get());
Label after_constant; Label after_constant;
__ Branch(&after_constant); __ Branch(&after_constant);
int offset = masm_->pc_offset(); int offset = masm_->pc_offset();
...@@ -1013,10 +1056,21 @@ void RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(int reg) { ...@@ -1013,10 +1056,21 @@ void RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(int reg) {
__ lw(current_input_offset(), register_location(reg)); __ lw(current_input_offset(), register_location(reg));
} }
void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(a0, Operand(ref));
__ Lw(a0, MemOperand(a0));
__ Subu(a0, backtrack_stackpointer(), a0);
__ Sw(a0, register_location(reg));
}
void RegExpMacroAssemblerMIPS::ReadStackPointerFromRegister(int reg) { void RegExpMacroAssemblerMIPS::ReadStackPointerFromRegister(int reg) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(a0, Operand(ref));
__ Lw(a0, MemOperand(a0));
__ lw(backtrack_stackpointer(), register_location(reg)); __ lw(backtrack_stackpointer(), register_location(reg));
__ lw(a0, MemOperand(frame_pointer(), kStackHighEnd));
__ Addu(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0)); __ Addu(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0));
} }
...@@ -1068,14 +1122,6 @@ void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) { ...@@ -1068,14 +1122,6 @@ void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) {
} }
} }
void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) {
__ lw(a1, MemOperand(frame_pointer(), kStackHighEnd));
__ Subu(a0, backtrack_stackpointer(), a1);
__ sw(a0, register_location(reg));
}
bool RegExpMacroAssemblerMIPS::CanReadUnaligned() { bool RegExpMacroAssemblerMIPS::CanReadUnaligned() {
return false; return false;
} }
......
...@@ -5,9 +5,7 @@ ...@@ -5,9 +5,7 @@
#ifndef V8_REGEXP_MIPS_REGEXP_MACRO_ASSEMBLER_MIPS_H_ #ifndef V8_REGEXP_MIPS_REGEXP_MACRO_ASSEMBLER_MIPS_H_
#define V8_REGEXP_MIPS_REGEXP_MACRO_ASSEMBLER_MIPS_H_ #define V8_REGEXP_MIPS_REGEXP_MACRO_ASSEMBLER_MIPS_H_
#include "src/base/strings.h"
#include "src/codegen/macro-assembler.h" #include "src/codegen/macro-assembler.h"
#include "src/codegen/mips/assembler-mips.h"
#include "src/regexp/regexp-macro-assembler.h" #include "src/regexp/regexp-macro-assembler.h"
namespace v8 { namespace v8 {
...@@ -94,7 +92,6 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS ...@@ -94,7 +92,6 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
static const int kFramePointer = 0; static const int kFramePointer = 0;
// Above the frame pointer - Stored registers and stack passed parameters. // Above the frame pointer - Stored registers and stack passed parameters.
// Registers s0 to s7, fp, and ra.
static const int kStoredRegisters = kFramePointer; static const int kStoredRegisters = kFramePointer;
// Return address (stored from link register, read into pc on return). // Return address (stored from link register, read into pc on return).
static const int kReturnAddress = kStoredRegisters + 9 * kPointerSize; static const int kReturnAddress = kStoredRegisters + 9 * kPointerSize;
...@@ -103,8 +100,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS ...@@ -103,8 +100,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
// Stack parameters placed by caller. // Stack parameters placed by caller.
static const int kRegisterOutput = kStackFrameHeader + 20; static const int kRegisterOutput = kStackFrameHeader + 20;
static const int kNumOutputRegisters = kRegisterOutput + kPointerSize; static const int kNumOutputRegisters = kRegisterOutput + kPointerSize;
static const int kStackHighEnd = kNumOutputRegisters + kPointerSize; static const int kDirectCall = kNumOutputRegisters + kPointerSize;
static const int kDirectCall = kStackHighEnd + kPointerSize;
static const int kIsolate = kDirectCall + kPointerSize; static const int kIsolate = kDirectCall + kPointerSize;
// Below the frame pointer. // Below the frame pointer.
...@@ -118,8 +114,14 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS ...@@ -118,8 +114,14 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
static const int kSuccessfulCaptures = kInputString - kPointerSize; static const int kSuccessfulCaptures = kInputString - kPointerSize;
static const int kStringStartMinusOne = kSuccessfulCaptures - kPointerSize; static const int kStringStartMinusOne = kSuccessfulCaptures - kPointerSize;
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;
...@@ -130,7 +132,6 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS ...@@ -130,7 +132,6 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
// Check whether we are exceeding the stack limit on the backtrack stack. // Check whether we are exceeding the stack limit on the backtrack stack.
void CheckStackLimit(); void CheckStackLimit();
// Generate a call to CheckStackGuardState. // Generate a call to CheckStackGuardState.
void CallCheckStackGuardState(Register scratch); void CallCheckStackGuardState(Register scratch);
...@@ -139,27 +140,27 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS ...@@ -139,27 +140,27 @@ 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.
inline Register current_input_offset() { return t2; } static constexpr Register current_input_offset() { return t2; }
// The register containing the current character after LoadCurrentCharacter. // The register containing the current character after LoadCurrentCharacter.
inline Register current_character() { return t3; } static constexpr Register current_character() { return t3; }
// 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 t6; } static constexpr Register end_of_input_address() { return t6; }
// 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 t4; } static constexpr Register backtrack_stackpointer() { return t4; }
// Register holding pointer to the current code object. // Register holding pointer to the current code object.
inline Register code_pointer() { return t1; } static constexpr Register code_pointer() { return t1; }
// 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.
...@@ -185,19 +186,25 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS ...@@ -185,19 +186,25 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
// 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_; const std::unique_ptr<MacroAssembler> 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,14 +6,13 @@ ...@@ -6,14 +6,13 @@
#include "src/regexp/mips64/regexp-macro-assembler-mips64.h" #include "src/regexp/mips64/regexp-macro-assembler-mips64.h"
#include "src/codegen/assembler-inl.h"
#include "src/codegen/macro-assembler.h" #include "src/codegen/macro-assembler.h"
#include "src/codegen/mips64/assembler-mips64-inl.h"
#include "src/heap/factory.h"
#include "src/logging/log.h" #include "src/logging/log.h"
#include "src/objects/objects-inl.h" #include "src/objects/code-inl.h"
#include "src/regexp/regexp-macro-assembler.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 {
...@@ -83,19 +82,18 @@ namespace internal { ...@@ -83,19 +82,18 @@ namespace internal {
* - fp[0..63] s0..s7 Callee-saved registers s0..s7. * - fp[0..63] s0..s7 Callee-saved registers s0..s7.
* --- frame pointer ---- * --- frame pointer ----
* - fp[-8] direct_call (1 = direct call from JS, 0 = from runtime) kDirectCall * - fp[-8] direct_call (1 = direct call from JS, 0 = from runtime) kDirectCall
* - fp[-16] stack_base (Top of backtracking stack). kStackHighEnd * - fp[-16] capture array size (may fit multiple sets of matches) kNumOutputRegisters
* - fp[-24] capture array size (may fit multiple sets of matches) kNumOutputRegisters * - fp[-24] int* capture_array (int[num_saved_registers_], for output). kRegisterOutput
* - fp[-32] int* capture_array (int[num_saved_registers_], for output). kRegisterOutput * - fp[-32] end of input (address of end of string). kInputEnd
* - fp[-40] end of input (address of end of string). kInputEnd * - fp[-40] start of input (address of first character in string). kInputStart
* - fp[-48] start of input (address of first character in string). kInputStart * - fp[-48] start index (character index of start). kStartIndex
* - fp[-56] start index (character index of start). kStartIndex * - fp[-56] void* input_string (location of a handle containing the string). kInputString
* - fp[-64] void* input_string (location of a handle containing the string). kInputString * - fp[-64] success counter (only for global regexps to count matches). kSuccessfulCaptures
* - fp[-72] success counter (only for global regexps to count matches). kSuccessfulCaptures * - fp[-72] Offset of location before start of input (effectively character kStringStartMinusOne
* - fp[-80] Offset of location before start of input (effectively character kStringStartMinusOne
* position -1). Used to initialize capture registers to a * position -1). Used to initialize capture registers to a
* non-position. * non-position.
* --------- The following output registers are 32-bit values. --------- * --------- The following output registers are 32-bit values. ---------
* - fp[-88] register 0 (Only positions must be stored in the first kRegisterZero * - fp[-80] register 0 (Only positions must be stored in the first kRegisterZero
* - register 1 num_saved_registers_ registers) * - register 1 num_saved_registers_ registers)
* - ... * - ...
* - register num_registers-1 * - register num_registers-1
...@@ -114,7 +112,6 @@ namespace internal { ...@@ -114,7 +112,6 @@ namespace internal {
* Address end, * Address end,
* int* capture_output_array, * int* capture_output_array,
* int num_capture_registers, * int num_capture_registers,
* byte* stack_area_base,
* bool direct_call = false, * bool direct_call = false,
* Isolate* isolate); * Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute() * The call is performed by NativeRegExpMacroAssembler::Execute()
...@@ -131,8 +128,10 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone, ...@@ -131,8 +128,10 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone,
Mode mode, Mode mode,
int registers_to_save) int registers_to_save)
: NativeRegExpMacroAssembler(isolate, zone), : NativeRegExpMacroAssembler(isolate, zone),
masm_(new MacroAssembler(isolate, CodeObjectRequired::kYes, masm_(std::make_unique<MacroAssembler>(
NewAssemblerBuffer(kRegExpCodeSize))), isolate, CodeObjectRequired::kYes,
NewAssemblerBuffer(kRegExpCodeSize))),
no_root_array_scope_(masm_.get()),
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),
...@@ -142,8 +141,6 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone, ...@@ -142,8 +141,6 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(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);
__ jmp(&entry_label_); // We'll write the entry code later. __ jmp(&entry_label_); // We'll write the entry code later.
// If the code gets too big or corrupted, an internal exception will be // If the code gets too big or corrupted, an internal exception will be
...@@ -155,7 +152,6 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone, ...@@ -155,7 +152,6 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone,
} }
RegExpMacroAssemblerMIPS::~RegExpMacroAssemblerMIPS() { RegExpMacroAssemblerMIPS::~RegExpMacroAssemblerMIPS() {
delete masm_;
// Unuse labels in case we throw away the assembler without calling GetCode. // Unuse labels in case we throw away the assembler without calling GetCode.
entry_label_.Unuse(); entry_label_.Unuse();
start_label_.Unuse(); start_label_.Unuse();
...@@ -378,7 +374,7 @@ void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase( ...@@ -378,7 +374,7 @@ void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase(
__ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate()))); __ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate())));
{ {
AllowExternalCallThatCantCauseGC scope(masm_); AllowExternalCallThatCantCauseGC scope(masm_.get());
ExternalReference function = ExternalReference function =
unicode ? ExternalReference::re_case_insensitive_compare_unicode( unicode ? ExternalReference::re_case_insensitive_compare_unicode(
isolate()) isolate())
...@@ -637,6 +633,42 @@ void RegExpMacroAssemblerMIPS::Fail() { ...@@ -637,6 +633,42 @@ void RegExpMacroAssemblerMIPS::Fail() {
__ jmp(&exit_label_); __ jmp(&exit_label_);
} }
void RegExpMacroAssemblerMIPS::LoadRegExpStackPointerFromMemory(Register dst) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_stack_pointer(isolate());
__ li(dst, Operand(ref));
__ Ld(dst, MemOperand(dst));
}
void RegExpMacroAssemblerMIPS::StoreRegExpStackPointerToMemory(
Register src, Register scratch) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_stack_pointer(isolate());
__ li(scratch, Operand(ref));
__ Sd(src, MemOperand(scratch));
}
void RegExpMacroAssemblerMIPS::PushRegExpBasePointer(Register scratch1,
Register scratch2) {
LoadRegExpStackPointerFromMemory(scratch1);
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(scratch2, Operand(ref));
__ Ld(scratch2, MemOperand(scratch2));
__ Dsubu(scratch2, scratch1, scratch2);
__ Sd(scratch2, MemOperand(frame_pointer(), kRegExpStackBasePointer));
}
void RegExpMacroAssemblerMIPS::PopRegExpBasePointer(Register scratch1,
Register scratch2) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ Ld(scratch1, MemOperand(frame_pointer(), kRegExpStackBasePointer));
__ li(scratch2, Operand(ref));
__ Ld(scratch2, MemOperand(scratch2));
__ Daddu(scratch1, scratch1, scratch2);
StoreRegExpStackPointerToMemory(scratch1, scratch2);
}
Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
Label return_v0; Label return_v0;
...@@ -654,7 +686,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -654,7 +686,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Tell the system that we have a stack frame. Because the type is MANUAL, // Tell the system that we have a stack frame. Because the type is MANUAL,
// no is generated. // no is generated.
FrameScope scope(masm_, StackFrame::MANUAL); FrameScope scope(masm_.get(), StackFrame::MANUAL);
// Actually emit code to start a new stack frame. // Actually emit code to start a new stack frame.
// Push arguments // Push arguments
...@@ -683,6 +715,13 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -683,6 +715,13 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
__ push(a0); // Make room for "string start - 1" constant. __ push(a0); // Make room for "string start - 1" constant.
STATIC_ASSERT(kBacktrackCount == kStringStartMinusOne - kSystemPointerSize); STATIC_ASSERT(kBacktrackCount == kStringStartMinusOne - kSystemPointerSize);
__ push(a0); // The backtrack counter __ push(a0); // The backtrack counter
STATIC_ASSERT(kRegExpStackBasePointer ==
kBacktrackCount - kSystemPointerSize);
__ push(a0); // 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(a0, a1);
// 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;
...@@ -763,7 +802,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -763,7 +802,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
} }
// Initialize backtrack stack pointer. // Initialize backtrack stack pointer.
__ Ld(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd)); LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
__ jmp(&start_label_); __ jmp(&start_label_);
...@@ -866,6 +905,10 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -866,6 +905,10 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
} }
__ bind(&return_v0); __ bind(&return_v0);
// Restore the original regexp stack pointer value (effectively, pop the
// stored base pointer).
PopRegExpBasePointer(a0, 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());
// Restore registers s0..s7 and return (restoring ra to pc). // Restore registers s0..s7 and return (restoring ra to pc).
...@@ -883,6 +926,8 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -883,6 +926,8 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Preempt-code. // Preempt-code.
if (check_preempt_label_.is_linked()) { if (check_preempt_label_.is_linked()) {
SafeCallTarget(&check_preempt_label_); SafeCallTarget(&check_preempt_label_);
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a0);
// Put regexp engine registers on stack. // Put regexp engine registers on stack.
RegList regexp_registers_to_retain = current_input_offset().bit() | RegList regexp_registers_to_retain = current_input_offset().bit() |
current_character().bit() | backtrack_stackpointer().bit(); current_character().bit() | backtrack_stackpointer().bit();
...@@ -893,6 +938,8 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -893,6 +938,8 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// result as return value. // result as return value.
__ Branch(&return_v0, ne, v0, Operand(zero_reg)); __ Branch(&return_v0, ne, v0, Operand(zero_reg));
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
// 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); __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
...@@ -902,25 +949,24 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) { ...@@ -902,25 +949,24 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Backtrack stack overflow code. // Backtrack stack overflow code.
if (stack_overflow_label_.is_linked()) { if (stack_overflow_label_.is_linked()) {
SafeCallTarget(&stack_overflow_label_); SafeCallTarget(&stack_overflow_label_);
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. // Put regexp engine registers on stack first.
RegList regexp_registers = current_input_offset().bit() | RegList regexp_registers = current_input_offset().bit() |
current_character().bit(); current_character().bit();
__ MultiPush(regexp_registers); __ MultiPush(regexp_registers);
// Call GrowStack(backtrack_stackpointer(), &stack_base) // Call GrowStack(isolate)
static const int num_arguments = 3; static constexpr int kNumArguments = 1;
__ PrepareCallCFunction(num_arguments, a0); __ PrepareCallCFunction(kNumArguments, a0);
__ mov(a0, backtrack_stackpointer()); __ li(a0, Operand(ExternalReference::isolate_address(masm_->isolate())));
__ Daddu(a1, frame_pointer(), Operand(kStackHighEnd));
__ li(a2, Operand(ExternalReference::isolate_address(masm_->isolate())));
ExternalReference grow_stack = ExternalReference grow_stack =
ExternalReference::re_grow_stack(masm_->isolate()); ExternalReference::re_grow_stack(masm_->isolate());
__ CallCFunction(grow_stack, num_arguments); __ CallCFunction(grow_stack, kNumArguments);
// Restore regexp registers. // Restore regexp registers.
__ MultiPop(regexp_registers); __ MultiPop(regexp_registers);
// 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.
__ 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);
...@@ -1012,7 +1058,7 @@ void RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) { ...@@ -1012,7 +1058,7 @@ void RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) {
int target = label->pos(); int target = label->pos();
__ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag)); __ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag));
} else { } else {
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_.get());
Label after_constant; Label after_constant;
__ Branch(&after_constant); __ Branch(&after_constant);
int offset = masm_->pc_offset(); int offset = masm_->pc_offset();
...@@ -1049,14 +1095,24 @@ void RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(int reg) { ...@@ -1049,14 +1095,24 @@ void RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(int reg) {
__ Ld(current_input_offset(), register_location(reg)); __ Ld(current_input_offset(), register_location(reg));
} }
void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(a0, Operand(ref));
__ Ld(a0, MemOperand(a0));
__ Dsubu(a0, backtrack_stackpointer(), a0);
__ Sd(a0, register_location(reg));
}
void RegExpMacroAssemblerMIPS::ReadStackPointerFromRegister(int reg) { void RegExpMacroAssemblerMIPS::ReadStackPointerFromRegister(int reg) {
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(a0, Operand(ref));
__ Ld(a0, MemOperand(a0));
__ Ld(backtrack_stackpointer(), register_location(reg)); __ Ld(backtrack_stackpointer(), register_location(reg));
__ Ld(a0, MemOperand(frame_pointer(), kStackHighEnd));
__ Daddu(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0)); __ Daddu(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0));
} }
void RegExpMacroAssemblerMIPS::SetCurrentPositionFromEnd(int by) { void RegExpMacroAssemblerMIPS::SetCurrentPositionFromEnd(int by) {
Label after_position; Label after_position;
__ Branch(&after_position, __ Branch(&after_position,
...@@ -1104,14 +1160,6 @@ void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) { ...@@ -1104,14 +1160,6 @@ void RegExpMacroAssemblerMIPS::ClearRegisters(int reg_from, int reg_to) {
} }
} }
void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) {
__ Ld(a1, MemOperand(frame_pointer(), kStackHighEnd));
__ Dsubu(a0, backtrack_stackpointer(), a1);
__ Sd(a0, register_location(reg));
}
bool RegExpMacroAssemblerMIPS::CanReadUnaligned() { bool RegExpMacroAssemblerMIPS::CanReadUnaligned() {
return false; return false;
} }
......
...@@ -5,9 +5,7 @@ ...@@ -5,9 +5,7 @@
#ifndef V8_REGEXP_MIPS64_REGEXP_MACRO_ASSEMBLER_MIPS64_H_ #ifndef V8_REGEXP_MIPS64_REGEXP_MACRO_ASSEMBLER_MIPS64_H_
#define V8_REGEXP_MIPS64_REGEXP_MACRO_ASSEMBLER_MIPS64_H_ #define V8_REGEXP_MIPS64_REGEXP_MACRO_ASSEMBLER_MIPS64_H_
#include "src/base/strings.h"
#include "src/codegen/macro-assembler.h" #include "src/codegen/macro-assembler.h"
#include "src/codegen/mips64/assembler-mips64.h"
#include "src/regexp/regexp-macro-assembler.h" #include "src/regexp/regexp-macro-assembler.h"
namespace v8 { namespace v8 {
...@@ -96,35 +94,39 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS ...@@ -96,35 +94,39 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
static const int kFramePointer = 0; static const int kFramePointer = 0;
// Above the frame pointer - Stored registers and stack passed parameters. // Above the frame pointer - Stored registers and stack passed parameters.
// Registers s0 to s7, fp, and ra.
static const int kStoredRegisters = kFramePointer; static const int kStoredRegisters = kFramePointer;
// Return address (stored from link register, read into pc on return). // Return address (stored from link register, read into pc on return).
// TODO(plind): This 9 - is 8 s-regs (s0..s7) plus fp. // TODO(plind): This 9 - is 8 s-regs (s0..s7) plus fp.
static const int kReturnAddress = kStoredRegisters + 9 * kPointerSize; static const int kReturnAddress = kStoredRegisters + 9 * kSystemPointerSize;
// Stack frame header. // Stack frame header.
static const int kStackFrameHeader = kReturnAddress; static const int kStackFrameHeader = kReturnAddress;
// Stack parameters placed by caller.
static const int kIsolate = kStackFrameHeader + kPointerSize;
// Below the frame pointer. // Below the frame pointer.
// Register parameters stored by setup code. // Register parameters stored by setup code.
static const int kDirectCall = kFramePointer - kPointerSize; static const int kIsolate = kFramePointer - kSystemPointerSize;
static const int kStackHighEnd = kDirectCall - kPointerSize; static const int kDirectCall = kIsolate - kSystemPointerSize;
static const int kNumOutputRegisters = kStackHighEnd - kPointerSize; static const int kNumOutputRegisters = kDirectCall - kSystemPointerSize;
static const int kRegisterOutput = kNumOutputRegisters - kPointerSize; static const int kRegisterOutput = kNumOutputRegisters - kSystemPointerSize;
static const int kInputEnd = kRegisterOutput - kPointerSize; static const int kInputEnd = kRegisterOutput - kSystemPointerSize;
static const int kInputStart = kInputEnd - kPointerSize; static const int kInputStart = kInputEnd - kSystemPointerSize;
static const int kStartIndex = kInputStart - kPointerSize; static const int kStartIndex = kInputStart - kSystemPointerSize;
static const int kInputString = kStartIndex - kPointerSize; static const int kInputString = kStartIndex - kSystemPointerSize;
// When adding local variables remember to push space for them in // When adding local variables remember to push space for them in
// the frame in GetCode. // the frame in GetCode.
static const int kSuccessfulCaptures = kInputString - kPointerSize; static const int kSuccessfulCaptures = kInputString - kSystemPointerSize;
static const int kStringStartMinusOne = kSuccessfulCaptures - kPointerSize; static const int kStringStartMinusOne =
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;
...@@ -144,27 +146,27 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS ...@@ -144,27 +146,27 @@ 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.
inline Register current_input_offset() { return a6; } static constexpr Register current_input_offset() { return a6; }
// The register containing the current character after LoadCurrentCharacter. // The register containing the current character after LoadCurrentCharacter.
inline Register current_character() { return a7; } static constexpr Register current_character() { return a7; }
// 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 t2; } static constexpr Register end_of_input_address() { return t2; }
// 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 t0; } static constexpr Register backtrack_stackpointer() { return t0; }
// Register holding pointer to the current code object. // Register holding pointer to the current code object.
inline Register code_pointer() { return a5; } static constexpr Register code_pointer() { return a5; }
// 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.
...@@ -190,19 +192,25 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS ...@@ -190,19 +192,25 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
// 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_; const std::unique_ptr<MacroAssembler> 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