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 @@
#include "src/regexp/loong64/regexp-macro-assembler-loong64.h"
#include "src/codegen/assembler-inl.h"
#include "src/codegen/macro-assembler.h"
#include "src/heap/factory.h"
#include "src/logging/log.h"
#include "src/objects/objects-inl.h"
#include "src/regexp/regexp-macro-assembler.h"
#include "src/objects/code-inl.h"
#include "src/regexp/regexp-stack.h"
#include "src/snapshot/embedded/embedded-data.h"
#include "src/strings/unicode.h"
namespace v8 {
namespace internal {
......@@ -48,19 +46,18 @@ namespace internal {
* - fp[0..63] s0..s7 Callee-saved registers s0..s7.
* --- frame pointer ----
* - fp[-8] direct_call (1 = direct call from JS, 0 = from runtime) kDirectCall
* - fp[-16] stack_base (Top of backtracking stack). kStackHighEnd
* - fp[-24] capture array size (may fit multiple sets of matches) kNumOutputRegisters
* - fp[-32] int* capture_array (int[num_saved_registers_], for output). kRegisterOutput
* - fp[-40] end of input (address of end of string). kInputEnd
* - fp[-48] start of input (address of first character in string). kInputStart
* - fp[-56] start index (character index of start). kStartIndex
* - fp[-64] void* input_string (location of a handle containing the string). kInputString
* - fp[-72] success counter (only for global regexps to count matches). kSuccessfulCaptures
* - fp[-80] Offset of location before start of input (effectively character kStringStartMinusOne
* - fp[-16] capture array size (may fit multiple sets of matches) kNumOutputRegisters
* - fp[-24] int* capture_array (int[num_saved_registers_], for output). kRegisterOutput
* - fp[-32] end of input (address of end of string). kInputEnd
* - fp[-40] start of input (address of first character in string). kInputStart
* - fp[-48] start index (character index of start). kStartIndex
* - fp[-56] 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] Offset of location before start of input (effectively character kStringStartMinusOne
* position -1). Used to initialize capture registers to a
* non-position.
* --------- 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 num_registers-1
......@@ -79,7 +76,6 @@ namespace internal {
* Address end,
* int* capture_output_array,
* int num_capture_registers,
* byte* stack_area_base,
* bool direct_call = false,
* Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute()
......@@ -96,8 +92,10 @@ RegExpMacroAssemblerLOONG64::RegExpMacroAssemblerLOONG64(Isolate* isolate,
Zone* zone, Mode mode,
int registers_to_save)
: NativeRegExpMacroAssembler(isolate, zone),
masm_(new MacroAssembler(isolate, CodeObjectRequired::kYes,
NewAssemblerBuffer(kRegExpCodeSize))),
masm_(std::make_unique<MacroAssembler>(
isolate, CodeObjectRequired::kYes,
NewAssemblerBuffer(kRegExpCodeSize))),
no_root_array_scope_(masm_.get()),
mode_(mode),
num_registers_(registers_to_save),
num_saved_registers_(registers_to_save),
......@@ -107,8 +105,6 @@ RegExpMacroAssemblerLOONG64::RegExpMacroAssemblerLOONG64(Isolate* isolate,
backtrack_label_(),
exit_label_(),
internal_failure_label_() {
masm_->set_root_array_available(false);
DCHECK_EQ(0, registers_to_save % 2);
__ jmp(&entry_label_); // We'll write the entry code later.
// If the code gets too big or corrupted, an internal exception will be
......@@ -120,7 +116,6 @@ RegExpMacroAssemblerLOONG64::RegExpMacroAssemblerLOONG64(Isolate* isolate,
}
RegExpMacroAssemblerLOONG64::~RegExpMacroAssemblerLOONG64() {
delete masm_;
// Unuse labels in case we throw away the assembler without calling GetCode.
entry_label_.Unuse();
start_label_.Unuse();
......@@ -336,7 +331,7 @@ void RegExpMacroAssemblerLOONG64::CheckNotBackReferenceIgnoreCase(
__ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate())));
{
AllowExternalCallThatCantCauseGC scope(masm_);
AllowExternalCallThatCantCauseGC scope(masm_.get());
ExternalReference function =
unicode ? ExternalReference::re_case_insensitive_compare_unicode(
isolate())
......@@ -592,6 +587,44 @@ void RegExpMacroAssemblerLOONG64::Fail() {
__ 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) {
Label return_v0;
if (0 /* todo masm_->has_exception()*/) {
......@@ -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,
// no is generated.
FrameScope scope(masm_, StackFrame::MANUAL);
FrameScope scope(masm_.get(), StackFrame::MANUAL);
// Actually emit code to start a new stack frame.
// Push arguments
......@@ -637,6 +670,13 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
__ Push(a0); // Make room for "string start - 1" constant.
STATIC_ASSERT(kBacktrackCount == kStringStartMinusOne - kSystemPointerSize);
__ 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.
Label stack_limit_hit;
......@@ -717,8 +757,7 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
}
// Initialize backtrack stack pointer.
__ Ld_d(backtrack_stackpointer(),
MemOperand(frame_pointer(), kStackHighEnd));
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
__ jmp(&start_label_);
......@@ -820,6 +859,10 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
}
__ 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..
__ mov(sp, frame_pointer());
// Restore registers s0..s7 and return (restoring ra to pc).
......@@ -838,6 +881,8 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
if (check_preempt_label_.is_linked()) {
SafeCallTarget(&check_preempt_label_);
// Put regexp engine registers on stack.
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1);
RegList regexp_registers_to_retain = current_input_offset().bit() |
current_character().bit() |
backtrack_stackpointer().bit();
......@@ -848,34 +893,36 @@ Handle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(Handle<String> source) {
// result as return value.
__ Branch(&return_v0, ne, a0, Operand(zero_reg));
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
// String might have moved: Reload end of string from frame.
__ Ld_d(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
SafeReturn();
}
// Backtrack stack overflow code.
if (stack_overflow_label_.is_linked()) {
SafeCallTarget(&stack_overflow_label_);
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1);
// 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(backtrack_stackpointer(), &stack_base)
static const int num_arguments = 3;
__ PrepareCallCFunction(num_arguments, a0);
__ mov(a0, backtrack_stackpointer());
__ Add_d(a1, frame_pointer(), Operand(kStackHighEnd));
__ li(a2, Operand(ExternalReference::isolate_address(masm_->isolate())));
// Call GrowStack(isolate).
static const int kNumArguments = 1;
__ PrepareCallCFunction(kNumArguments, a0);
__ li(a0, Operand(ExternalReference::isolate_address(masm_->isolate())));
ExternalReference grow_stack =
ExternalReference::re_grow_stack(masm_->isolate());
__ CallCFunction(grow_stack, num_arguments);
__ CallCFunction(grow_stack, kNumArguments);
// Restore regexp registers.
__ MultiPop(regexp_registers);
// If return nullptr, we have failed to grow the stack, and
// must exit with a stack-overflow exception.
// If nullptr is returned, we have failed to grow the stack, and must exit
// with a stack-overflow exception.
__ Branch(&exit_with_exception, eq, a0, Operand(zero_reg));
// Otherwise use return value as new stack pointer.
__ mov(backtrack_stackpointer(), a0);
......@@ -956,7 +1003,7 @@ void RegExpMacroAssemblerLOONG64::PushBacktrack(Label* label) {
int target = label->pos();
__ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag));
} else {
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_.get());
Label after_constant;
__ Branch(&after_constant);
int offset = masm_->pc_offset();
......@@ -991,9 +1038,21 @@ void RegExpMacroAssemblerLOONG64::ReadCurrentPositionFromRegister(int 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) {
__ Ld_d(backtrack_stackpointer(), register_location(reg));
__ Ld_d(a0, MemOperand(frame_pointer(), kStackHighEnd));
ExternalReference stack_top_address =
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));
}
......@@ -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:
void RegExpMacroAssemblerLOONG64::CallCheckStackGuardState(Register scratch) {
......
......@@ -5,8 +5,6 @@
#ifndef 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/regexp/regexp-macro-assembler.h"
......@@ -93,35 +91,39 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerLOONG64
static const int kFramePointer = 0;
// Above the frame pointer - Stored registers and stack passed parameters.
// Registers s0 to s7, fp, and ra.
static const int kStoredRegisters = kFramePointer;
// Return address (stored from link register, read into pc on return).
// 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.
static const int kStackFrameHeader = kReturnAddress;
// Stack parameters placed by caller.
static const int kIsolate = kStackFrameHeader + kPointerSize;
// Below the frame pointer.
// Register parameters stored by setup code.
static const int kDirectCall = kFramePointer - kPointerSize;
static const int kStackHighEnd = kDirectCall - kPointerSize;
static const int kNumOutputRegisters = kStackHighEnd - kPointerSize;
static const int kRegisterOutput = kNumOutputRegisters - kPointerSize;
static const int kInputEnd = kRegisterOutput - kPointerSize;
static const int kInputStart = kInputEnd - kPointerSize;
static const int kStartIndex = kInputStart - kPointerSize;
static const int kInputString = kStartIndex - kPointerSize;
static const int kIsolate = kFramePointer - kSystemPointerSize;
static const int kDirectCall = kIsolate - kSystemPointerSize;
static const int kNumOutputRegisters = kDirectCall - kSystemPointerSize;
static const int kRegisterOutput = kNumOutputRegisters - kSystemPointerSize;
static const int kInputEnd = kRegisterOutput - kSystemPointerSize;
static const int kInputStart = kInputEnd - kSystemPointerSize;
static const int kStartIndex = kInputStart - kSystemPointerSize;
static const int kInputString = kStartIndex - kSystemPointerSize;
// When adding local variables remember to push space for them in
// the frame in GetCode.
static const int kSuccessfulCaptures = kInputString - kPointerSize;
static const int kStringStartMinusOne = kSuccessfulCaptures - kPointerSize;
static const int kSuccessfulCaptures = kInputString - kSystemPointerSize;
static const int kStringStartMinusOne =
kSuccessfulCaptures - 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.
static const int kRegisterZero = kBacktrackCount - kSystemPointerSize;
static const int kRegisterZero = kRegExpStackBasePointer - kSystemPointerSize;
// Initial size of code buffer.
static const int kRegExpCodeSize = 1024;
......@@ -140,24 +142,24 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerLOONG64
// Register holding the current input position as negative offset from
// 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.
inline Register current_character() { return a7; }
static constexpr Register current_character() { return a7; }
// 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
// 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
// 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.
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).
inline int char_size() { return static_cast<int>(mode_); }
......@@ -182,19 +184,26 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerLOONG64
// and increments it by a word size.
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(); }
MacroAssembler* masm_;
const std::unique_ptr<MacroAssembler> masm_;
const NoRootArrayScope no_root_array_scope_;
// Which mode to generate code for (Latin1 or UC16).
Mode mode_;
const Mode mode_;
// One greater than maximal register index actually used.
int num_registers_;
// Number of registers to output at the end (the saved registers
// are always 0..num_saved_registers_-1).
int num_saved_registers_;
const int num_saved_registers_;
// Labels used internally.
Label entry_label_;
......
......@@ -6,14 +6,12 @@
#include "src/regexp/mips/regexp-macro-assembler-mips.h"
#include "src/codegen/assembler-inl.h"
#include "src/codegen/macro-assembler.h"
#include "src/codegen/mips/assembler-mips-inl.h"
#include "src/logging/log.h"
#include "src/objects/objects-inl.h"
#include "src/regexp/regexp-macro-assembler.h"
#include "src/objects/code-inl.h"
#include "src/regexp/regexp-stack.h"
#include "src/snapshot/embedded/embedded-data.h"
#include "src/strings/unicode.h"
namespace v8 {
namespace internal {
......@@ -39,11 +37,9 @@ namespace internal {
*
* The stack will have the following structure:
*
* - fp[60] Isolate* isolate (address of the current isolate)
* - fp[56] direct_call (if 1, direct call from JavaScript code,
* - fp[56] Isolate* isolate (address of the current isolate)
* - fp[52] direct_call (if 1, direct call from JavaScript code,
* 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[44] int* capture_array (int[num_saved_registers_], for output).
* --- sp when called ---
......@@ -80,7 +76,6 @@ namespace internal {
* Address end,
* int* capture_output_array,
* int num_capture_registers,
* byte* stack_area_base,
* bool direct_call = false,
* Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute()
......@@ -95,8 +90,10 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone,
Mode mode,
int registers_to_save)
: NativeRegExpMacroAssembler(isolate, zone),
masm_(new MacroAssembler(isolate, CodeObjectRequired::kYes,
NewAssemblerBuffer(kRegExpCodeSize))),
masm_(std::make_unique<MacroAssembler>(
isolate, CodeObjectRequired::kYes,
NewAssemblerBuffer(kRegExpCodeSize))),
no_root_array_scope_(masm_.get()),
mode_(mode),
num_registers_(registers_to_save),
num_saved_registers_(registers_to_save),
......@@ -106,8 +103,6 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone,
backtrack_label_(),
exit_label_(),
internal_failure_label_() {
masm_->set_root_array_available(false);
DCHECK_EQ(0, registers_to_save % 2);
__ jmp(&entry_label_); // We'll write the entry code later.
// If the code gets too big or corrupted, an internal exception will be
......@@ -119,7 +114,6 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone,
}
RegExpMacroAssemblerMIPS::~RegExpMacroAssemblerMIPS() {
delete masm_;
// Unuse labels in case we throw away the assembler without calling GetCode.
entry_label_.Unuse();
start_label_.Unuse();
......@@ -342,7 +336,7 @@ void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase(
__ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate())));
{
AllowExternalCallThatCantCauseGC scope(masm_);
AllowExternalCallThatCantCauseGC scope(masm_.get());
ExternalReference function =
unicode ? ExternalReference::re_case_insensitive_compare_unicode(
isolate())
......@@ -607,6 +601,42 @@ void RegExpMacroAssemblerMIPS::Fail() {
__ 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) {
Label return_v0;
......@@ -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,
// no is generated.
FrameScope scope(masm_, StackFrame::MANUAL);
FrameScope scope(masm_.get(), StackFrame::MANUAL);
// Actually emit code to start a new stack frame.
// Push arguments
......@@ -648,6 +678,13 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
__ push(a0); // Make room for "string start - 1" constant.
STATIC_ASSERT(kBacktrackCount == kStringStartMinusOne - kSystemPointerSize);
__ 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.
Label stack_limit_hit;
......@@ -728,7 +765,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
}
// Initialize backtrack stack pointer.
__ lw(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd));
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
__ jmp(&start_label_);
......@@ -830,6 +867,10 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
}
__ 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..
__ mov(sp, frame_pointer());
// Restore registers s0..s7 and return (restoring ra to pc).
......@@ -847,6 +888,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Preempt-code.
if (check_preempt_label_.is_linked()) {
SafeCallTarget(&check_preempt_label_);
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a0);
// Put regexp engine registers on stack.
RegList regexp_registers_to_retain = current_input_offset().bit() |
current_character().bit() | backtrack_stackpointer().bit();
......@@ -857,6 +899,8 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// result as return value.
__ Branch(&return_v0, ne, v0, Operand(zero_reg));
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
// String might have moved: Reload end of string from frame.
__ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
......@@ -866,25 +910,24 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Backtrack stack overflow code.
if (stack_overflow_label_.is_linked()) {
SafeCallTarget(&stack_overflow_label_);
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a0);
// 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(backtrack_stackpointer(), &stack_base)
static const int num_arguments = 3;
__ PrepareCallCFunction(num_arguments, a0);
__ mov(a0, backtrack_stackpointer());
__ Addu(a1, frame_pointer(), Operand(kStackHighEnd));
__ li(a2, Operand(ExternalReference::isolate_address(masm_->isolate())));
// Call GrowStack(isolate).
static constexpr int kNumArguments = 1;
__ PrepareCallCFunction(kNumArguments, a0);
__ li(a0, Operand(ExternalReference::isolate_address(masm_->isolate())));
ExternalReference grow_stack =
ExternalReference::re_grow_stack(masm_->isolate());
__ CallCFunction(grow_stack, num_arguments);
__ CallCFunction(grow_stack, kNumArguments);
// Restore regexp registers.
__ MultiPop(regexp_registers);
// If return nullptr, we have failed to grow the stack, and
// must exit with a stack-overflow exception.
// If nullptr is returned, we have failed to grow the stack, and must exit
// with a stack-overflow exception.
__ Branch(&exit_with_exception, eq, v0, Operand(zero_reg));
// Otherwise use return value as new stack pointer.
__ mov(backtrack_stackpointer(), v0);
......@@ -976,7 +1019,7 @@ void RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) {
int target = label->pos();
__ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag));
} else {
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_.get());
Label after_constant;
__ Branch(&after_constant);
int offset = masm_->pc_offset();
......@@ -1013,10 +1056,21 @@ void RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(int 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) {
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(a0, MemOperand(frame_pointer(), kStackHighEnd));
__ Addu(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0));
}
......@@ -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() {
return false;
}
......
......@@ -5,9 +5,7 @@
#ifndef 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/mips/assembler-mips.h"
#include "src/regexp/regexp-macro-assembler.h"
namespace v8 {
......@@ -94,7 +92,6 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
static const int kFramePointer = 0;
// Above the frame pointer - Stored registers and stack passed parameters.
// Registers s0 to s7, fp, and ra.
static const int kStoredRegisters = kFramePointer;
// Return address (stored from link register, read into pc on return).
static const int kReturnAddress = kStoredRegisters + 9 * kPointerSize;
......@@ -103,8 +100,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
// Stack parameters placed by caller.
static const int kRegisterOutput = kStackFrameHeader + 20;
static const int kNumOutputRegisters = kRegisterOutput + kPointerSize;
static const int kStackHighEnd = kNumOutputRegisters + kPointerSize;
static const int kDirectCall = kStackHighEnd + kPointerSize;
static const int kDirectCall = kNumOutputRegisters + kPointerSize;
static const int kIsolate = kDirectCall + kPointerSize;
// Below the frame pointer.
......@@ -118,8 +114,14 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
static const int kSuccessfulCaptures = kInputString - kPointerSize;
static const int kStringStartMinusOne = kSuccessfulCaptures - kPointerSize;
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.
static const int kRegisterZero = kBacktrackCount - kSystemPointerSize;
static const int kRegisterZero = kRegExpStackBasePointer - kSystemPointerSize;
// Initial size of code buffer.
static const int kRegExpCodeSize = 1024;
......@@ -130,7 +132,6 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
// Check whether we are exceeding the stack limit on the backtrack stack.
void CheckStackLimit();
// Generate a call to CheckStackGuardState.
void CallCheckStackGuardState(Register scratch);
......@@ -139,27 +140,27 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
// Register holding the current input position as negative offset from
// 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.
inline Register current_character() { return t3; }
static constexpr Register current_character() { return t3; }
// 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
// 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
// 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.
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).
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
// is nullptr, in which case it is a conditional Backtrack.
......@@ -185,19 +186,25 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
// and increments it by a word size.
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(); }
MacroAssembler* masm_;
const std::unique_ptr<MacroAssembler> masm_;
const NoRootArrayScope no_root_array_scope_;
// Which mode to generate code for (Latin1 or UC16).
Mode mode_;
const Mode mode_;
// One greater than maximal register index actually used.
int num_registers_;
// Number of registers to output at the end (the saved registers
// are always 0..num_saved_registers_-1).
int num_saved_registers_;
const int num_saved_registers_;
// Labels used internally.
Label entry_label_;
......
......@@ -6,14 +6,13 @@
#include "src/regexp/mips64/regexp-macro-assembler-mips64.h"
#include "src/codegen/assembler-inl.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/objects/objects-inl.h"
#include "src/regexp/regexp-macro-assembler.h"
#include "src/objects/code-inl.h"
#include "src/regexp/regexp-stack.h"
#include "src/snapshot/embedded/embedded-data.h"
#include "src/strings/unicode.h"
namespace v8 {
namespace internal {
......@@ -83,19 +82,18 @@ namespace internal {
* - fp[0..63] s0..s7 Callee-saved registers s0..s7.
* --- frame pointer ----
* - fp[-8] direct_call (1 = direct call from JS, 0 = from runtime) kDirectCall
* - fp[-16] stack_base (Top of backtracking stack). kStackHighEnd
* - fp[-24] capture array size (may fit multiple sets of matches) kNumOutputRegisters
* - fp[-32] int* capture_array (int[num_saved_registers_], for output). kRegisterOutput
* - fp[-40] end of input (address of end of string). kInputEnd
* - fp[-48] start of input (address of first character in string). kInputStart
* - fp[-56] start index (character index of start). kStartIndex
* - fp[-64] void* input_string (location of a handle containing the string). kInputString
* - fp[-72] success counter (only for global regexps to count matches). kSuccessfulCaptures
* - fp[-80] Offset of location before start of input (effectively character kStringStartMinusOne
* - fp[-16] capture array size (may fit multiple sets of matches) kNumOutputRegisters
* - fp[-24] int* capture_array (int[num_saved_registers_], for output). kRegisterOutput
* - fp[-32] end of input (address of end of string). kInputEnd
* - fp[-40] start of input (address of first character in string). kInputStart
* - fp[-48] start index (character index of start). kStartIndex
* - fp[-56] 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] Offset of location before start of input (effectively character kStringStartMinusOne
* position -1). Used to initialize capture registers to a
* non-position.
* --------- 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 num_registers-1
......@@ -114,7 +112,6 @@ namespace internal {
* Address end,
* int* capture_output_array,
* int num_capture_registers,
* byte* stack_area_base,
* bool direct_call = false,
* Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute()
......@@ -131,8 +128,10 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone,
Mode mode,
int registers_to_save)
: NativeRegExpMacroAssembler(isolate, zone),
masm_(new MacroAssembler(isolate, CodeObjectRequired::kYes,
NewAssemblerBuffer(kRegExpCodeSize))),
masm_(std::make_unique<MacroAssembler>(
isolate, CodeObjectRequired::kYes,
NewAssemblerBuffer(kRegExpCodeSize))),
no_root_array_scope_(masm_.get()),
mode_(mode),
num_registers_(registers_to_save),
num_saved_registers_(registers_to_save),
......@@ -142,8 +141,6 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone,
backtrack_label_(),
exit_label_(),
internal_failure_label_() {
masm_->set_root_array_available(false);
DCHECK_EQ(0, registers_to_save % 2);
__ jmp(&entry_label_); // We'll write the entry code later.
// If the code gets too big or corrupted, an internal exception will be
......@@ -155,7 +152,6 @@ RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(Isolate* isolate, Zone* zone,
}
RegExpMacroAssemblerMIPS::~RegExpMacroAssemblerMIPS() {
delete masm_;
// Unuse labels in case we throw away the assembler without calling GetCode.
entry_label_.Unuse();
start_label_.Unuse();
......@@ -378,7 +374,7 @@ void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase(
__ li(a3, Operand(ExternalReference::isolate_address(masm_->isolate())));
{
AllowExternalCallThatCantCauseGC scope(masm_);
AllowExternalCallThatCantCauseGC scope(masm_.get());
ExternalReference function =
unicode ? ExternalReference::re_case_insensitive_compare_unicode(
isolate())
......@@ -637,6 +633,42 @@ void RegExpMacroAssemblerMIPS::Fail() {
__ 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) {
Label return_v0;
......@@ -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,
// no is generated.
FrameScope scope(masm_, StackFrame::MANUAL);
FrameScope scope(masm_.get(), StackFrame::MANUAL);
// Actually emit code to start a new stack frame.
// Push arguments
......@@ -683,6 +715,13 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
__ push(a0); // Make room for "string start - 1" constant.
STATIC_ASSERT(kBacktrackCount == kStringStartMinusOne - kSystemPointerSize);
__ 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.
Label stack_limit_hit;
......@@ -763,7 +802,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
}
// Initialize backtrack stack pointer.
__ Ld(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd));
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
__ jmp(&start_label_);
......@@ -866,6 +905,10 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
}
__ 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..
__ mov(sp, frame_pointer());
// Restore registers s0..s7 and return (restoring ra to pc).
......@@ -883,6 +926,8 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Preempt-code.
if (check_preempt_label_.is_linked()) {
SafeCallTarget(&check_preempt_label_);
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a0);
// Put regexp engine registers on stack.
RegList regexp_registers_to_retain = current_input_offset().bit() |
current_character().bit() | backtrack_stackpointer().bit();
......@@ -893,6 +938,8 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// result as return value.
__ Branch(&return_v0, ne, v0, Operand(zero_reg));
LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
// String might have moved: Reload end of string from frame.
__ Ld(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
......@@ -902,25 +949,24 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
// Backtrack stack overflow code.
if (stack_overflow_label_.is_linked()) {
SafeCallTarget(&stack_overflow_label_);
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a0);
// 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(backtrack_stackpointer(), &stack_base)
static const int num_arguments = 3;
__ PrepareCallCFunction(num_arguments, a0);
__ mov(a0, backtrack_stackpointer());
__ Daddu(a1, frame_pointer(), Operand(kStackHighEnd));
__ li(a2, Operand(ExternalReference::isolate_address(masm_->isolate())));
// Call GrowStack(isolate)
static constexpr int kNumArguments = 1;
__ PrepareCallCFunction(kNumArguments, a0);
__ li(a0, Operand(ExternalReference::isolate_address(masm_->isolate())));
ExternalReference grow_stack =
ExternalReference::re_grow_stack(masm_->isolate());
__ CallCFunction(grow_stack, num_arguments);
__ CallCFunction(grow_stack, kNumArguments);
// Restore regexp registers.
__ MultiPop(regexp_registers);
// If return nullptr, we have failed to grow the stack, and
// must exit with a stack-overflow exception.
// If nullptr is returned, we have failed to grow the stack, and must exit
// with a stack-overflow exception.
__ Branch(&exit_with_exception, eq, v0, Operand(zero_reg));
// Otherwise use return value as new stack pointer.
__ mov(backtrack_stackpointer(), v0);
......@@ -1012,7 +1058,7 @@ void RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) {
int target = label->pos();
__ li(a0, Operand(target + Code::kHeaderSize - kHeapObjectTag));
} else {
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_.get());
Label after_constant;
__ Branch(&after_constant);
int offset = masm_->pc_offset();
......@@ -1049,14 +1095,24 @@ void RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(int 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) {
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(a0, MemOperand(frame_pointer(), kStackHighEnd));
__ Daddu(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0));
}
void RegExpMacroAssemblerMIPS::SetCurrentPositionFromEnd(int by) {
Label after_position;
__ Branch(&after_position,
......@@ -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() {
return false;
}
......
......@@ -5,9 +5,7 @@
#ifndef 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/mips64/assembler-mips64.h"
#include "src/regexp/regexp-macro-assembler.h"
namespace v8 {
......@@ -96,35 +94,39 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
static const int kFramePointer = 0;
// Above the frame pointer - Stored registers and stack passed parameters.
// Registers s0 to s7, fp, and ra.
static const int kStoredRegisters = kFramePointer;
// Return address (stored from link register, read into pc on return).
// 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.
static const int kStackFrameHeader = kReturnAddress;
// Stack parameters placed by caller.
static const int kIsolate = kStackFrameHeader + kPointerSize;
// Below the frame pointer.
// Register parameters stored by setup code.
static const int kDirectCall = kFramePointer - kPointerSize;
static const int kStackHighEnd = kDirectCall - kPointerSize;
static const int kNumOutputRegisters = kStackHighEnd - kPointerSize;
static const int kRegisterOutput = kNumOutputRegisters - kPointerSize;
static const int kInputEnd = kRegisterOutput - kPointerSize;
static const int kInputStart = kInputEnd - kPointerSize;
static const int kStartIndex = kInputStart - kPointerSize;
static const int kInputString = kStartIndex - kPointerSize;
static const int kIsolate = kFramePointer - kSystemPointerSize;
static const int kDirectCall = kIsolate - kSystemPointerSize;
static const int kNumOutputRegisters = kDirectCall - kSystemPointerSize;
static const int kRegisterOutput = kNumOutputRegisters - kSystemPointerSize;
static const int kInputEnd = kRegisterOutput - kSystemPointerSize;
static const int kInputStart = kInputEnd - kSystemPointerSize;
static const int kStartIndex = kInputStart - kSystemPointerSize;
static const int kInputString = kStartIndex - kSystemPointerSize;
// When adding local variables remember to push space for them in
// the frame in GetCode.
static const int kSuccessfulCaptures = kInputString - kPointerSize;
static const int kStringStartMinusOne = kSuccessfulCaptures - kPointerSize;
static const int kSuccessfulCaptures = kInputString - kSystemPointerSize;
static const int kStringStartMinusOne =
kSuccessfulCaptures - 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.
static const int kRegisterZero = kBacktrackCount - kSystemPointerSize;
static const int kRegisterZero = kRegExpStackBasePointer - kSystemPointerSize;
// Initial size of code buffer.
static const int kRegExpCodeSize = 1024;
......@@ -144,27 +146,27 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
// Register holding the current input position as negative offset from
// 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.
inline Register current_character() { return a7; }
static constexpr Register current_character() { return a7; }
// 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
// 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
// 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.
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).
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
// is nullptr, in which case it is a conditional Backtrack.
......@@ -190,19 +192,25 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
// and increments it by a word size.
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(); }
MacroAssembler* masm_;
const std::unique_ptr<MacroAssembler> masm_;
const NoRootArrayScope no_root_array_scope_;
// Which mode to generate code for (Latin1 or UC16).
Mode mode_;
const Mode mode_;
// One greater than maximal register index actually used.
int num_registers_;
// Number of registers to output at the end (the saved registers
// are always 0..num_saved_registers_-1).
int num_saved_registers_;
const int num_saved_registers_;
// Labels used internally.
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