MIPS: Implement loop for global regexps in regexp assembler.
Port r11623 (f153116d) BUG= TEST= Review URL: https://chromiumcodereview.appspot.com/10436012 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11639 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
17ec52b6cd
commit
ef7524bd29
@ -5043,7 +5043,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
|
|||||||
1, a0, a2);
|
1, a0, a2);
|
||||||
|
|
||||||
// Isolates: note we add an additional parameter here (isolate pointer).
|
// Isolates: note we add an additional parameter here (isolate pointer).
|
||||||
const int kRegExpExecuteArguments = 8;
|
const int kRegExpExecuteArguments = 9;
|
||||||
const int kParameterRegisters = 4;
|
const int kParameterRegisters = 4;
|
||||||
__ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters);
|
__ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters);
|
||||||
|
|
||||||
@ -5054,27 +5054,33 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
|
|||||||
// allocating space for the c argument slots, we don't need to calculate
|
// allocating space for the c argument slots, we don't need to calculate
|
||||||
// that into the argument positions on the stack. This is how the stack will
|
// that into the argument positions on the stack. This is how the stack will
|
||||||
// look (sp meaning the value of sp at this moment):
|
// look (sp meaning the value of sp at this moment):
|
||||||
|
// [sp + 5] - Argument 9
|
||||||
// [sp + 4] - Argument 8
|
// [sp + 4] - Argument 8
|
||||||
// [sp + 3] - Argument 7
|
// [sp + 3] - Argument 7
|
||||||
// [sp + 2] - Argument 6
|
// [sp + 2] - Argument 6
|
||||||
// [sp + 1] - Argument 5
|
// [sp + 1] - Argument 5
|
||||||
// [sp + 0] - saved ra
|
// [sp + 0] - saved ra
|
||||||
|
|
||||||
// Argument 8: Pass current isolate address.
|
// Argument 9: Pass current isolate address.
|
||||||
// CFunctionArgumentOperand handles MIPS stack argument slots.
|
// CFunctionArgumentOperand handles MIPS stack argument slots.
|
||||||
__ li(a0, Operand(ExternalReference::isolate_address()));
|
__ li(a0, Operand(ExternalReference::isolate_address()));
|
||||||
|
__ sw(a0, MemOperand(sp, 5 * kPointerSize));
|
||||||
|
|
||||||
|
// Argument 8: Indicate that this is a direct call from JavaScript.
|
||||||
|
__ li(a0, Operand(1));
|
||||||
__ sw(a0, MemOperand(sp, 4 * kPointerSize));
|
__ sw(a0, MemOperand(sp, 4 * kPointerSize));
|
||||||
|
|
||||||
// Argument 7: Indicate that this is a direct call from JavaScript.
|
// Argument 7: Start (high end) of backtracking stack memory area.
|
||||||
__ li(a0, Operand(1));
|
|
||||||
__ sw(a0, MemOperand(sp, 3 * kPointerSize));
|
|
||||||
|
|
||||||
// Argument 6: Start (high end) of backtracking stack memory area.
|
|
||||||
__ li(a0, Operand(address_of_regexp_stack_memory_address));
|
__ li(a0, Operand(address_of_regexp_stack_memory_address));
|
||||||
__ lw(a0, MemOperand(a0, 0));
|
__ lw(a0, MemOperand(a0, 0));
|
||||||
__ li(a2, Operand(address_of_regexp_stack_memory_size));
|
__ li(a2, Operand(address_of_regexp_stack_memory_size));
|
||||||
__ lw(a2, MemOperand(a2, 0));
|
__ lw(a2, MemOperand(a2, 0));
|
||||||
__ addu(a0, a0, a2);
|
__ addu(a0, a0, a2);
|
||||||
|
__ sw(a0, MemOperand(sp, 3 * kPointerSize));
|
||||||
|
|
||||||
|
// Argument 6: Set the number of capture registers to zero to force global
|
||||||
|
// regexps to behave as non-global. This does not affect non-global regexps.
|
||||||
|
__ mov(a0, zero_reg);
|
||||||
__ sw(a0, MemOperand(sp, 2 * kPointerSize));
|
__ sw(a0, MemOperand(sp, 2 * kPointerSize));
|
||||||
|
|
||||||
// Argument 5: static offsets vector buffer.
|
// Argument 5: static offsets vector buffer.
|
||||||
@ -5125,7 +5131,9 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
|
|||||||
// Check the result.
|
// Check the result.
|
||||||
|
|
||||||
Label success;
|
Label success;
|
||||||
__ Branch(&success, eq, v0, Operand(NativeRegExpMacroAssembler::SUCCESS));
|
__ Branch(&success, eq, v0, Operand(1));
|
||||||
|
// We expect exactly one result since we force the called regexp to behave
|
||||||
|
// as non-global.
|
||||||
Label failure;
|
Label failure;
|
||||||
__ Branch(&failure, eq, v0, Operand(NativeRegExpMacroAssembler::FAILURE));
|
__ Branch(&failure, eq, v0, Operand(NativeRegExpMacroAssembler::FAILURE));
|
||||||
// If not exception it can only be retry. Handle that in the runtime system.
|
// If not exception it can only be retry. Handle that in the runtime system.
|
||||||
|
@ -43,27 +43,31 @@ namespace internal {
|
|||||||
#ifndef V8_INTERPRETED_REGEXP
|
#ifndef V8_INTERPRETED_REGEXP
|
||||||
/*
|
/*
|
||||||
* This assembler uses the following register assignment convention
|
* This assembler uses the following register assignment convention
|
||||||
|
* - t7 : Temporarily stores the index of capture start after a matching pass
|
||||||
|
* for a global regexp.
|
||||||
* - t1 : Pointer to current code object (Code*) including heap object tag.
|
* - t1 : Pointer to current code object (Code*) including heap object tag.
|
||||||
* - t2 : Current position in input, as negative offset from end of string.
|
* - t2 : Current position in input, as negative offset from end of string.
|
||||||
* Please notice that this is the byte offset, not the character offset!
|
* Please notice that this is the byte offset, not the character offset!
|
||||||
* - t3 : Currently loaded character. Must be loaded using
|
* - t3 : Currently loaded character. Must be loaded using
|
||||||
* LoadCurrentCharacter before using any of the dispatch methods.
|
* LoadCurrentCharacter before using any of the dispatch methods.
|
||||||
* - t4 : points to tip of backtrack stack
|
* - t4 : Points to tip of backtrack stack
|
||||||
* - t5 : Unused.
|
* - t5 : Unused.
|
||||||
* - t6 : End of input (points to byte after last character in input).
|
* - t6 : End of input (points to byte after last character in input).
|
||||||
* - fp : Frame pointer. Used to access arguments, local variables and
|
* - fp : Frame pointer. Used to access arguments, local variables and
|
||||||
* RegExp registers.
|
* RegExp registers.
|
||||||
* - sp : points to tip of C stack.
|
* - sp : Points to tip of C stack.
|
||||||
*
|
*
|
||||||
* The remaining registers are free for computations.
|
* The remaining registers are free for computations.
|
||||||
* Each call to a public method should retain this convention.
|
* Each call to a public method should retain this convention.
|
||||||
*
|
*
|
||||||
* The stack will have the following structure:
|
* The stack will have the following structure:
|
||||||
*
|
*
|
||||||
* - fp[56] direct_call (if 1, direct call from JavaScript code,
|
* - fp[64] Isolate* isolate (address of the current isolate)
|
||||||
|
* - fp[60] 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
|
* - fp[56] stack_area_base (High end of the memory area to use as
|
||||||
* backtracking stack).
|
* backtracking stack).
|
||||||
|
* - fp[52] capture array size (may fit multiple sets of matches)
|
||||||
* - fp[48] int* capture_array (int[num_saved_registers_], for output).
|
* - fp[48] int* capture_array (int[num_saved_registers_], for output).
|
||||||
* - fp[44] secondary link/return address used by native call.
|
* - fp[44] secondary link/return address used by native call.
|
||||||
* --- sp when called ---
|
* --- sp when called ---
|
||||||
@ -71,16 +75,17 @@ namespace internal {
|
|||||||
* - fp[36] old frame pointer (r11).
|
* - fp[36] old frame pointer (r11).
|
||||||
* - fp[0..32] backup of registers s0..s7.
|
* - fp[0..32] backup of registers s0..s7.
|
||||||
* --- frame pointer ----
|
* --- frame pointer ----
|
||||||
* - fp[-4] end of input (Address of end of string).
|
* - fp[-4] end of input (address of end of string).
|
||||||
* - fp[-8] start of input (Address of first character in string).
|
* - fp[-8] start of input (address of first character in string).
|
||||||
* - fp[-12] start index (character index of start).
|
* - fp[-12] start index (character index of start).
|
||||||
* - fp[-16] void* input_string (location of a handle containing the string).
|
* - fp[-16] void* input_string (location of a handle containing the string).
|
||||||
* - fp[-20] Offset of location before start of input (effectively character
|
* - fp[-20] success counter (only for global regexps to count matches).
|
||||||
|
* - fp[-24] Offset of location before start of input (effectively character
|
||||||
* position -1). Used to initialize capture registers to a
|
* position -1). Used to initialize capture registers to a
|
||||||
* non-position.
|
* non-position.
|
||||||
* - fp[-24] At start (if 1, we are starting at the start of the
|
* - fp[-28] At start (if 1, we are starting at the start of the
|
||||||
* string, otherwise 0)
|
* string, otherwise 0)
|
||||||
* - fp[-28] register 0 (Only positions must be stored in the first
|
* - fp[-32] register 0 (Only positions must be stored in the first
|
||||||
* - register 1 num_saved_registers_ registers)
|
* - register 1 num_saved_registers_ registers)
|
||||||
* - ...
|
* - ...
|
||||||
* - register num_registers-1
|
* - register num_registers-1
|
||||||
@ -201,8 +206,8 @@ void RegExpMacroAssemblerMIPS::CheckCharacterGT(uc16 limit, Label* on_greater) {
|
|||||||
void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) {
|
void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) {
|
||||||
Label not_at_start;
|
Label not_at_start;
|
||||||
// Did we start the match at the start of the string at all?
|
// Did we start the match at the start of the string at all?
|
||||||
__ lw(a0, MemOperand(frame_pointer(), kAtStart));
|
__ lw(a0, MemOperand(frame_pointer(), kStartIndex));
|
||||||
BranchOrBacktrack(¬_at_start, eq, a0, Operand(zero_reg));
|
BranchOrBacktrack(¬_at_start, ne, a0, Operand(zero_reg));
|
||||||
|
|
||||||
// If we did, are we still at the start of the input?
|
// If we did, are we still at the start of the input?
|
||||||
__ lw(a1, MemOperand(frame_pointer(), kInputStart));
|
__ lw(a1, MemOperand(frame_pointer(), kInputStart));
|
||||||
@ -214,8 +219,8 @@ void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) {
|
|||||||
|
|
||||||
void RegExpMacroAssemblerMIPS::CheckNotAtStart(Label* on_not_at_start) {
|
void RegExpMacroAssemblerMIPS::CheckNotAtStart(Label* on_not_at_start) {
|
||||||
// Did we start the match at the start of the string at all?
|
// Did we start the match at the start of the string at all?
|
||||||
__ lw(a0, MemOperand(frame_pointer(), kAtStart));
|
__ lw(a0, MemOperand(frame_pointer(), kStartIndex));
|
||||||
BranchOrBacktrack(on_not_at_start, eq, a0, Operand(zero_reg));
|
BranchOrBacktrack(on_not_at_start, ne, a0, Operand(zero_reg));
|
||||||
// If we did, are we still at the start of the input?
|
// If we did, are we still at the start of the input?
|
||||||
__ lw(a1, MemOperand(frame_pointer(), kInputStart));
|
__ lw(a1, MemOperand(frame_pointer(), kInputStart));
|
||||||
__ Addu(a0, end_of_input_address(), Operand(current_input_offset()));
|
__ Addu(a0, end_of_input_address(), Operand(current_input_offset()));
|
||||||
@ -640,6 +645,7 @@ void RegExpMacroAssemblerMIPS::Fail() {
|
|||||||
|
|
||||||
|
|
||||||
Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
||||||
|
Label return_v0;
|
||||||
if (masm_->has_exception()) {
|
if (masm_->has_exception()) {
|
||||||
// If the code gets corrupted due to long regular expressions and lack of
|
// If the code gets corrupted due to long regular expressions and lack of
|
||||||
// space on trampolines, an internal exception flag is set. If this case
|
// space on trampolines, an internal exception flag is set. If this case
|
||||||
@ -669,8 +675,9 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
|||||||
// Set frame pointer in space for it if this is not a direct call
|
// Set frame pointer in space for it if this is not a direct call
|
||||||
// from generated code.
|
// from generated code.
|
||||||
__ Addu(frame_pointer(), sp, Operand(4 * kPointerSize));
|
__ Addu(frame_pointer(), sp, Operand(4 * kPointerSize));
|
||||||
|
__ mov(a0, zero_reg);
|
||||||
|
__ push(a0); // Make room for success counter and initialize it to 0.
|
||||||
__ push(a0); // Make room for "position - 1" constant (value irrelevant).
|
__ push(a0); // Make room for "position - 1" constant (value irrelevant).
|
||||||
__ push(a0); // Make room for "at start" constant (value irrelevant).
|
|
||||||
|
|
||||||
// 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;
|
||||||
@ -689,12 +696,12 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
|||||||
// Exit with OutOfMemory exception. There is not enough space on the stack
|
// Exit with OutOfMemory exception. There is not enough space on the stack
|
||||||
// for our working registers.
|
// for our working registers.
|
||||||
__ li(v0, Operand(EXCEPTION));
|
__ li(v0, Operand(EXCEPTION));
|
||||||
__ jmp(&exit_label_);
|
__ jmp(&return_v0);
|
||||||
|
|
||||||
__ bind(&stack_limit_hit);
|
__ bind(&stack_limit_hit);
|
||||||
CallCheckStackGuardState(a0);
|
CallCheckStackGuardState(a0);
|
||||||
// If returned value is non-zero, we exit with the returned value as result.
|
// If returned value is non-zero, we exit with the returned value as result.
|
||||||
__ Branch(&exit_label_, ne, v0, Operand(zero_reg));
|
__ Branch(&return_v0, ne, v0, Operand(zero_reg));
|
||||||
|
|
||||||
__ bind(&stack_ok);
|
__ bind(&stack_ok);
|
||||||
// Allocate space on stack for registers.
|
// Allocate space on stack for registers.
|
||||||
@ -715,16 +722,25 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
|||||||
// position registers.
|
// position registers.
|
||||||
__ sw(a0, MemOperand(frame_pointer(), kInputStartMinusOne));
|
__ sw(a0, MemOperand(frame_pointer(), kInputStartMinusOne));
|
||||||
|
|
||||||
// Determine whether the start index is zero, that is at the start of the
|
// Initialize code pointer register
|
||||||
// string, and store that value in a local variable.
|
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
|
||||||
__ mov(t5, a1);
|
|
||||||
__ li(a1, Operand(1));
|
|
||||||
__ Movn(a1, zero_reg, t5);
|
|
||||||
__ sw(a1, MemOperand(frame_pointer(), kAtStart));
|
|
||||||
|
|
||||||
|
Label load_char_start_regexp, start_regexp;
|
||||||
|
// Load newline if index is at start, previous character otherwise.
|
||||||
|
__ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg));
|
||||||
|
__ li(current_character(), Operand('\n'));
|
||||||
|
__ jmp(&start_regexp);
|
||||||
|
|
||||||
|
// Global regexp restarts matching here.
|
||||||
|
__ bind(&load_char_start_regexp);
|
||||||
|
// Load previous char as initial value of current character register.
|
||||||
|
LoadCurrentCharacterUnchecked(-1, 1);
|
||||||
|
__ bind(&start_regexp);
|
||||||
|
|
||||||
|
// Initialize on-stack registers.
|
||||||
if (num_saved_registers_ > 0) { // Always is, if generated from a regexp.
|
if (num_saved_registers_ > 0) { // Always is, if generated from a regexp.
|
||||||
// Fill saved registers with initial value = start offset - 1.
|
// Fill saved registers with initial value = start offset - 1.
|
||||||
|
if (num_saved_registers_ > 8) {
|
||||||
// Address of register 0.
|
// Address of register 0.
|
||||||
__ Addu(a1, frame_pointer(), Operand(kRegisterZero));
|
__ Addu(a1, frame_pointer(), Operand(kRegisterZero));
|
||||||
__ li(a2, Operand(num_saved_registers_));
|
__ li(a2, Operand(num_saved_registers_));
|
||||||
@ -734,20 +750,16 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
|||||||
__ Addu(a1, a1, Operand(-kPointerSize));
|
__ Addu(a1, a1, Operand(-kPointerSize));
|
||||||
__ Subu(a2, a2, Operand(1));
|
__ Subu(a2, a2, Operand(1));
|
||||||
__ Branch(&init_loop, ne, a2, Operand(zero_reg));
|
__ Branch(&init_loop, ne, a2, Operand(zero_reg));
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < num_saved_registers_; i++) {
|
||||||
|
__ sw(a0, register_location(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize backtrack stack pointer.
|
// Initialize backtrack stack pointer.
|
||||||
__ lw(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd));
|
__ lw(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd));
|
||||||
// Initialize code pointer register
|
|
||||||
__ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
|
|
||||||
// Load previous char as initial value of current character register.
|
|
||||||
Label at_start;
|
|
||||||
__ lw(a0, MemOperand(frame_pointer(), kAtStart));
|
|
||||||
__ Branch(&at_start, ne, a0, Operand(zero_reg));
|
|
||||||
LoadCurrentCharacterUnchecked(-1, 1); // Load previous char.
|
|
||||||
__ jmp(&start_label_);
|
|
||||||
__ bind(&at_start);
|
|
||||||
__ li(current_character(), Operand('\n'));
|
|
||||||
__ jmp(&start_label_);
|
__ jmp(&start_label_);
|
||||||
|
|
||||||
|
|
||||||
@ -776,6 +788,10 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
|||||||
for (int i = 0; i < num_saved_registers_; i += 2) {
|
for (int i = 0; i < num_saved_registers_; i += 2) {
|
||||||
__ lw(a2, register_location(i));
|
__ lw(a2, register_location(i));
|
||||||
__ lw(a3, register_location(i + 1));
|
__ lw(a3, register_location(i + 1));
|
||||||
|
if (global()) {
|
||||||
|
// Keep capture start in a4 for the zero-length check later.
|
||||||
|
__ mov(t7, a2);
|
||||||
|
}
|
||||||
if (mode_ == UC16) {
|
if (mode_ == UC16) {
|
||||||
__ sra(a2, a2, 1);
|
__ sra(a2, a2, 1);
|
||||||
__ Addu(a2, a2, a1);
|
__ Addu(a2, a2, a1);
|
||||||
@ -791,10 +807,51 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
|||||||
__ Addu(a0, a0, kPointerSize);
|
__ Addu(a0, a0, kPointerSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (global()) {
|
||||||
|
// Restart matching if the regular expression is flagged as global.
|
||||||
|
__ lw(a0, MemOperand(frame_pointer(), kSuccessfulCaptures));
|
||||||
|
__ lw(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
|
||||||
|
__ lw(a2, MemOperand(frame_pointer(), kRegisterOutput));
|
||||||
|
// Increment success counter.
|
||||||
|
__ Addu(a0, a0, 1);
|
||||||
|
__ sw(a0, MemOperand(frame_pointer(), kSuccessfulCaptures));
|
||||||
|
// Capture results have been stored, so the number of remaining global
|
||||||
|
// output registers is reduced by the number of stored captures.
|
||||||
|
__ Subu(a1, a1, num_saved_registers_);
|
||||||
|
// Check whether we have enough room for another set of capture results.
|
||||||
|
__ mov(v0, a0);
|
||||||
|
__ Branch(&return_v0, lt, a1, Operand(num_saved_registers_));
|
||||||
|
|
||||||
|
__ sw(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
|
||||||
|
// Advance the location for output.
|
||||||
|
__ Addu(a2, a2, num_saved_registers_ * kPointerSize);
|
||||||
|
__ sw(a2, MemOperand(frame_pointer(), kRegisterOutput));
|
||||||
|
|
||||||
|
// Prepare a0 to initialize registers with its value in the next run.
|
||||||
|
__ lw(a0, MemOperand(frame_pointer(), kInputStartMinusOne));
|
||||||
|
// Special case for zero-length matches.
|
||||||
|
// t7: capture start index
|
||||||
|
// Not a zero-length match, restart.
|
||||||
|
__ Branch(&load_char_start_regexp, ne, current_input_offset(), Operand(t7));
|
||||||
|
// Offset from the end is zero if we already reached the end.
|
||||||
|
__ Branch(&exit_label_, eq, current_input_offset(), Operand(zero_reg));
|
||||||
|
// Advance current position after a zero-length match.
|
||||||
|
__ Addu(current_input_offset(),
|
||||||
|
current_input_offset(),
|
||||||
|
Operand((mode_ == UC16) ? 2 : 1));
|
||||||
|
__ Branch(&load_char_start_regexp);
|
||||||
|
} else {
|
||||||
__ li(v0, Operand(SUCCESS));
|
__ li(v0, Operand(SUCCESS));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Exit and return v0.
|
// Exit and return v0.
|
||||||
__ bind(&exit_label_);
|
__ bind(&exit_label_);
|
||||||
|
if (global()) {
|
||||||
|
__ lw(v0, MemOperand(frame_pointer(), kSuccessfulCaptures));
|
||||||
|
}
|
||||||
|
|
||||||
|
__ bind(&return_v0);
|
||||||
// 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).
|
||||||
@ -820,7 +877,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
|||||||
__ MultiPop(regexp_registers_to_retain);
|
__ MultiPop(regexp_registers_to_retain);
|
||||||
// If returning non-zero, we should end execution with the given
|
// If returning non-zero, we should end execution with the given
|
||||||
// result as return value.
|
// result as return value.
|
||||||
__ Branch(&exit_label_, ne, v0, Operand(zero_reg));
|
__ Branch(&return_v0, ne, v0, Operand(zero_reg));
|
||||||
|
|
||||||
// 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));
|
||||||
@ -864,7 +921,7 @@ Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
|
|||||||
__ bind(&exit_with_exception);
|
__ bind(&exit_with_exception);
|
||||||
// Exit with Result EXCEPTION(-1) to signal thrown exception.
|
// Exit with Result EXCEPTION(-1) to signal thrown exception.
|
||||||
__ li(v0, Operand(EXCEPTION));
|
__ li(v0, Operand(EXCEPTION));
|
||||||
__ jmp(&exit_label_);
|
__ jmp(&return_v0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1012,8 +1069,9 @@ void RegExpMacroAssemblerMIPS::SetRegister(int register_index, int to) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RegExpMacroAssemblerMIPS::Succeed() {
|
bool RegExpMacroAssemblerMIPS::Succeed() {
|
||||||
__ jmp(&success_label_);
|
__ jmp(&success_label_);
|
||||||
|
return global();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1280,8 +1338,9 @@ void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset,
|
|||||||
int characters) {
|
int characters) {
|
||||||
Register offset = current_input_offset();
|
Register offset = current_input_offset();
|
||||||
if (cp_offset != 0) {
|
if (cp_offset != 0) {
|
||||||
__ Addu(a0, current_input_offset(), Operand(cp_offset * char_size()));
|
// t7 is not being used to store the capture start index at this point.
|
||||||
offset = a0;
|
__ Addu(t7, current_input_offset(), Operand(cp_offset * char_size()));
|
||||||
|
offset = t7;
|
||||||
}
|
}
|
||||||
// We assume that we cannot do unaligned loads on MIPS, so this function
|
// We assume that we cannot do unaligned loads on MIPS, so this function
|
||||||
// must only be used to load a single character at a time.
|
// must only be used to load a single character at a time.
|
||||||
|
@ -115,7 +115,7 @@ class RegExpMacroAssemblerMIPS: public NativeRegExpMacroAssembler {
|
|||||||
virtual void ReadStackPointerFromRegister(int reg);
|
virtual void ReadStackPointerFromRegister(int reg);
|
||||||
virtual void SetCurrentPositionFromEnd(int by);
|
virtual void SetCurrentPositionFromEnd(int by);
|
||||||
virtual void SetRegister(int register_index, int to);
|
virtual void SetRegister(int register_index, int to);
|
||||||
virtual void Succeed();
|
virtual bool Succeed();
|
||||||
virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
|
virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
|
||||||
virtual void ClearRegisters(int reg_from, int reg_to);
|
virtual void ClearRegisters(int reg_from, int reg_to);
|
||||||
virtual void WriteStackPointerToRegister(int reg);
|
virtual void WriteStackPointerToRegister(int reg);
|
||||||
@ -141,7 +141,8 @@ class RegExpMacroAssemblerMIPS: public NativeRegExpMacroAssembler {
|
|||||||
static const int kStackFrameHeader = kReturnAddress + kPointerSize;
|
static const int kStackFrameHeader = kReturnAddress + kPointerSize;
|
||||||
// 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 kStackHighEnd = kRegisterOutput + kPointerSize;
|
static const int kNumOutputRegisters = kRegisterOutput + kPointerSize;
|
||||||
|
static const int kStackHighEnd = kNumOutputRegisters + kPointerSize;
|
||||||
static const int kDirectCall = kStackHighEnd + kPointerSize;
|
static const int kDirectCall = kStackHighEnd + kPointerSize;
|
||||||
static const int kIsolate = kDirectCall + kPointerSize;
|
static const int kIsolate = kDirectCall + kPointerSize;
|
||||||
|
|
||||||
@ -153,10 +154,10 @@ class RegExpMacroAssemblerMIPS: public NativeRegExpMacroAssembler {
|
|||||||
static const int kInputString = kStartIndex - kPointerSize;
|
static const int kInputString = kStartIndex - kPointerSize;
|
||||||
// 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 kInputStartMinusOne = kInputString - kPointerSize;
|
static const int kSuccessfulCaptures = kInputString - kPointerSize;
|
||||||
static const int kAtStart = kInputStartMinusOne - kPointerSize;
|
static const int kInputStartMinusOne = kSuccessfulCaptures - kPointerSize;
|
||||||
// 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 = kAtStart - kPointerSize;
|
static const int kRegisterZero = kInputStartMinusOne - kPointerSize;
|
||||||
|
|
||||||
// Initial size of code buffer.
|
// Initial size of code buffer.
|
||||||
static const size_t kRegExpCodeSize = 1024;
|
static const size_t kRegExpCodeSize = 1024;
|
||||||
|
@ -50,16 +50,16 @@ namespace internal {
|
|||||||
entry(p0, p1, p2, p3, p4)
|
entry(p0, p1, p2, p3, p4)
|
||||||
|
|
||||||
typedef int (*mips_regexp_matcher)(String*, int, const byte*, const byte*,
|
typedef int (*mips_regexp_matcher)(String*, int, const byte*, const byte*,
|
||||||
void*, int*, Address, int, Isolate*);
|
void*, int*, int, Address, int, Isolate*);
|
||||||
|
|
||||||
|
|
||||||
// Call the generated regexp code directly. The code at the entry address
|
// Call the generated regexp code directly. The code at the entry address
|
||||||
// should act as a function matching the type arm_regexp_matcher.
|
// should act as a function matching the type arm_regexp_matcher.
|
||||||
// The fifth argument is a dummy that reserves the space used for
|
// The fifth argument is a dummy that reserves the space used for
|
||||||
// the return address added by the ExitFrame in native calls.
|
// the return address added by the ExitFrame in native calls.
|
||||||
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
|
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \
|
||||||
(FUNCTION_CAST<mips_regexp_matcher>(entry)( \
|
(FUNCTION_CAST<mips_regexp_matcher>(entry)( \
|
||||||
p0, p1, p2, p3, NULL, p4, p5, p6, p7))
|
p0, p1, p2, p3, NULL, p4, p5, p6, p7, p8))
|
||||||
|
|
||||||
#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
|
#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
|
||||||
reinterpret_cast<TryCatch*>(try_catch_address)
|
reinterpret_cast<TryCatch*>(try_catch_address)
|
||||||
@ -403,9 +403,9 @@ class Simulator {
|
|||||||
reinterpret_cast<Object*>(Simulator::current(Isolate::Current())->Call( \
|
reinterpret_cast<Object*>(Simulator::current(Isolate::Current())->Call( \
|
||||||
FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4))
|
FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4))
|
||||||
|
|
||||||
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
|
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \
|
||||||
Simulator::current(Isolate::Current())->Call( \
|
Simulator::current(Isolate::Current())->Call( \
|
||||||
entry, 9, p0, p1, p2, p3, NULL, p4, p5, p6, p7)
|
entry, 10, p0, p1, p2, p3, NULL, p4, p5, p6, p7, p8)
|
||||||
|
|
||||||
#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
|
#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
|
||||||
try_catch_address == NULL ? \
|
try_catch_address == NULL ? \
|
||||||
|
Loading…
Reference in New Issue
Block a user