Commit 4db15f12 authored by lrn@chromium.org's avatar lrn@chromium.org

Refactoring of RegExp interface to better support calling several times in a row.

Review URL: http://codereview.chromium.org/1114001

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4190 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 9582645a
...@@ -648,16 +648,17 @@ Handle<Object> RegExpMacroAssemblerARM::GetCode(Handle<String> source) { ...@@ -648,16 +648,17 @@ Handle<Object> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
__ ldr(r0, MemOperand(frame_pointer(), kInputStart)); __ ldr(r0, MemOperand(frame_pointer(), kInputStart));
// Find negative length (offset of start relative to end). // Find negative length (offset of start relative to end).
__ sub(current_input_offset(), r0, end_of_input_address()); __ sub(current_input_offset(), r0, end_of_input_address());
// Set r0 to address of char before start of input // Set r0 to address of char before start of the input string
// (effectively string position -1). // (effectively string position -1).
__ ldr(r1, MemOperand(frame_pointer(), kStartIndex));
__ sub(r0, current_input_offset(), Operand(char_size())); __ sub(r0, current_input_offset(), Operand(char_size()));
__ sub(r0, r0, Operand(r1, LSL, (mode_ == UC16) ? 1 : 0));
// Store this value in a local variable, for use when clearing // Store this value in a local variable, for use when clearing
// position registers. // position registers.
__ str(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); __ str(r0, MemOperand(frame_pointer(), kInputStartMinusOne));
// Determine whether the start index is zero, that is at the start of the // Determine whether the start index is zero, that is at the start of the
// string, and store that value in a local variable. // string, and store that value in a local variable.
__ ldr(r1, MemOperand(frame_pointer(), kStartIndex));
__ tst(r1, Operand(r1)); __ tst(r1, Operand(r1));
__ mov(r1, Operand(1), LeaveCC, eq); __ mov(r1, Operand(1), LeaveCC, eq);
__ mov(r1, Operand(0), LeaveCC, ne); __ mov(r1, Operand(0), LeaveCC, ne);
...@@ -700,12 +701,15 @@ Handle<Object> RegExpMacroAssemblerARM::GetCode(Handle<String> source) { ...@@ -700,12 +701,15 @@ Handle<Object> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
// copy captures to output // copy captures to output
__ ldr(r1, MemOperand(frame_pointer(), kInputStart)); __ ldr(r1, MemOperand(frame_pointer(), kInputStart));
__ ldr(r0, MemOperand(frame_pointer(), kRegisterOutput)); __ ldr(r0, MemOperand(frame_pointer(), kRegisterOutput));
__ ldr(r2, MemOperand(frame_pointer(), kStartIndex));
__ sub(r1, end_of_input_address(), r1); __ sub(r1, end_of_input_address(), r1);
// r1 is length of input in bytes. // r1 is length of input in bytes.
if (mode_ == UC16) { if (mode_ == UC16) {
__ mov(r1, Operand(r1, LSR, 1)); __ mov(r1, Operand(r1, LSR, 1));
} }
// r1 is length of input in characters. // r1 is length of input in characters.
__ add(r1, r1, Operand(r2));
// r1 is length of string in characters.
ASSERT_EQ(0, num_saved_registers_ % 2); ASSERT_EQ(0, num_saved_registers_ % 2);
// Always an even number of capture registers. This allows us to // Always an even number of capture registers. This allows us to
......
...@@ -10584,15 +10584,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { ...@@ -10584,15 +10584,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ j(negative, &done); __ j(negative, &done);
// Read the value from the static offsets vector buffer. // Read the value from the static offsets vector buffer.
__ mov(edi, Operand(ecx, edx, times_int_size, 0)); __ mov(edi, Operand(ecx, edx, times_int_size, 0));
// Perform explicit shift __ SmiTag(edi);
ASSERT_EQ(0, kSmiTag);
__ shl(edi, kSmiTagSize);
// Add previous index (from its stack slot) if value is not negative.
Label capture_negative;
// Carry flag set by shift above.
__ j(negative, &capture_negative, not_taken);
__ add(edi, Operand(eax)); // Add previous index (adding smi to smi).
__ bind(&capture_negative);
// Store the smi value in the last match info. // Store the smi value in the last match info.
__ mov(FieldOperand(ebx, __ mov(FieldOperand(ebx,
edx, edx,
......
...@@ -182,7 +182,8 @@ class MacroAssembler: public Assembler { ...@@ -182,7 +182,8 @@ class MacroAssembler: public Assembler {
// Smi tagging support. // Smi tagging support.
void SmiTag(Register reg) { void SmiTag(Register reg) {
ASSERT(kSmiTag == 0); ASSERT(kSmiTag == 0);
shl(reg, kSmiTagSize); ASSERT(kSmiTagSize == 1);
add(reg, Operand(reg));
} }
void SmiUntag(Register reg) { void SmiUntag(Register reg) {
sar(reg, kSmiTagSize); sar(reg, kSmiTagSize);
......
...@@ -653,6 +653,8 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { ...@@ -653,6 +653,8 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
__ j(not_zero, &exit_label_); __ j(not_zero, &exit_label_);
__ bind(&stack_ok); __ bind(&stack_ok);
// Load start index for later use.
__ mov(ebx, Operand(ebp, kStartIndex));
// Allocate space on stack for registers. // Allocate space on stack for registers.
__ sub(Operand(esp), Immediate(num_registers_ * kPointerSize)); __ sub(Operand(esp), Immediate(num_registers_ * kPointerSize));
...@@ -662,17 +664,23 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { ...@@ -662,17 +664,23 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
__ mov(edi, Operand(ebp, kInputStart)); __ mov(edi, Operand(ebp, kInputStart));
// Set up edi to be negative offset from string end. // Set up edi to be negative offset from string end.
__ sub(edi, Operand(esi)); __ sub(edi, Operand(esi));
// Set eax to address of char before start of input
// Set eax to address of char before start of the string.
// (effectively string position -1). // (effectively string position -1).
__ lea(eax, Operand(edi, -char_size())); __ neg(ebx);
if (mode_ == UC16) {
__ lea(eax, Operand(edi, ebx, times_2, -char_size()));
} else {
__ lea(eax, Operand(edi, ebx, times_1, -char_size()));
}
// Store this value in a local variable, for use when clearing // Store this value in a local variable, for use when clearing
// position registers. // position registers.
__ mov(Operand(ebp, kInputStartMinusOne), eax); __ mov(Operand(ebp, kInputStartMinusOne), eax);
// Determine whether the start index is zero, that is at the start of the // Determine whether the start index is zero, that is at the start of the
// string, and store that value in a local variable. // string, and store that value in a local variable.
__ mov(ebx, Operand(ebp, kStartIndex));
__ xor_(Operand(ecx), ecx); // setcc only operates on cl (lower byte of ecx). __ xor_(Operand(ecx), ecx); // setcc only operates on cl (lower byte of ecx).
// Register ebx still holds -stringIndex.
__ test(ebx, Operand(ebx)); __ test(ebx, Operand(ebx));
__ setcc(zero, ecx); // 1 if 0 (start of string), 0 if positive. __ setcc(zero, ecx); // 1 if 0 (start of string), 0 if positive.
__ mov(Operand(ebp, kAtStart), ecx); __ mov(Operand(ebp, kAtStart), ecx);
...@@ -721,10 +729,17 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { ...@@ -721,10 +729,17 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
// copy captures to output // copy captures to output
__ mov(ebx, Operand(ebp, kRegisterOutput)); __ mov(ebx, Operand(ebp, kRegisterOutput));
__ mov(ecx, Operand(ebp, kInputEnd)); __ mov(ecx, Operand(ebp, kInputEnd));
__ mov(edx, Operand(ebp, kStartIndex));
__ sub(ecx, Operand(ebp, kInputStart)); __ sub(ecx, Operand(ebp, kInputStart));
if (mode_ == UC16) {
__ lea(ecx, Operand(ecx, edx, times_2, 0));
} else {
__ add(ecx, Operand(edx));
}
for (int i = 0; i < num_saved_registers_; i++) { for (int i = 0; i < num_saved_registers_; i++) {
__ mov(eax, register_location(i)); __ mov(eax, register_location(i));
__ add(eax, Operand(ecx)); // Convert to index from start, not end. // Convert to index from start of string, not end.
__ add(eax, Operand(ecx));
if (mode_ == UC16) { if (mode_ == UC16) {
__ sar(eax, 1); // Convert byte index to character index. __ sar(eax, 1); // Convert byte index to character index.
} }
......
This diff is collapsed.
...@@ -77,10 +77,10 @@ class RegExpImpl { ...@@ -77,10 +77,10 @@ class RegExpImpl {
Handle<JSArray> lastMatchInfo); Handle<JSArray> lastMatchInfo);
// Prepares a JSRegExp object with Irregexp-specific data. // Prepares a JSRegExp object with Irregexp-specific data.
static void IrregexpPrepare(Handle<JSRegExp> re, static void IrregexpInitialize(Handle<JSRegExp> re,
Handle<String> pattern, Handle<String> pattern,
JSRegExp::Flags flags, JSRegExp::Flags flags,
int capture_register_count); int capture_register_count);
static void AtomCompile(Handle<JSRegExp> re, static void AtomCompile(Handle<JSRegExp> re,
...@@ -93,6 +93,29 @@ class RegExpImpl { ...@@ -93,6 +93,29 @@ class RegExpImpl {
int index, int index,
Handle<JSArray> lastMatchInfo); Handle<JSArray> lastMatchInfo);
enum IrregexpResult { RE_FAILURE = 0, RE_SUCCESS = 1, RE_EXCEPTION = -1 };
// Prepare a RegExp for being executed one or more times (using
// IrregexpExecOnce) on the subject.
// This ensures that the regexp is compiled for the subject, and that
// the subject is flat.
// Returns the number of integer spaces required by IrregexpExecOnce
// as its "registers" argument. If the regexp cannot be compiled,
// an exception is set as pending, and this function returns negative.
static int IrregexpPrepare(Handle<JSRegExp> regexp,
Handle<String> subject);
// Execute a regular expression once on the subject, starting from
// character "index".
// If successful, returns RE_SUCCESS and set the capture positions
// in the first registers.
// If matching fails, returns RE_FAILURE.
// If execution fails, sets a pending exception and returns RE_EXCEPTION.
static IrregexpResult IrregexpExecOnce(Handle<JSRegExp> regexp,
Handle<String> subject,
int index,
Vector<int32_t> registers);
// Execute an Irregexp bytecode pattern. // Execute an Irregexp bytecode pattern.
// On a successful match, the result is a JSArray containing // On a successful match, the result is a JSArray containing
// captured positions. On a failure, the result is the null value. // captured positions. On a failure, the result is the null value.
......
...@@ -7182,12 +7182,6 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { ...@@ -7182,12 +7182,6 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// Read the value from the static offsets vector buffer and make it a smi. // Read the value from the static offsets vector buffer and make it a smi.
__ movl(rdi, Operand(rcx, rdx, times_int_size, 0)); __ movl(rdi, Operand(rcx, rdx, times_int_size, 0));
__ Integer32ToSmi(rdi, rdi, &runtime); __ Integer32ToSmi(rdi, rdi, &runtime);
// Add previous index (from its stack slot) if value is not negative.
Label capture_negative;
// Negative flag set by smi convertion above.
__ j(negative, &capture_negative);
__ SmiAdd(rdi, rdi, rax, &runtime); // Add previous index.
__ bind(&capture_negative);
// Store the smi value in the last match info. // Store the smi value in the last match info.
__ movq(FieldOperand(rbx, __ movq(FieldOperand(rbx,
rdx, rdx,
......
...@@ -711,9 +711,15 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { ...@@ -711,9 +711,15 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
__ movq(rdi, Operand(rbp, kInputStart)); __ movq(rdi, Operand(rbp, kInputStart));
// Set up rdi to be negative offset from string end. // Set up rdi to be negative offset from string end.
__ subq(rdi, rsi); __ subq(rdi, rsi);
// Set rax to address of char before start of input // Set rax to address of char before start of the string
// (effectively string position -1). // (effectively string position -1).
__ lea(rax, Operand(rdi, -char_size())); __ movq(rbx, Operand(rbp, kStartIndex));
__ neg(rbx);
if (mode_ == UC16) {
__ lea(rax, Operand(rdi, rbx, times_2, -char_size()));
} else {
__ lea(rax, Operand(rdi, rbx, times_1, -char_size()));
}
// Store this value in a local variable, for use when clearing // Store this value in a local variable, for use when clearing
// position registers. // position registers.
__ movq(Operand(rbp, kInputStartMinusOne), rax); __ movq(Operand(rbp, kInputStartMinusOne), rax);
...@@ -770,9 +776,15 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { ...@@ -770,9 +776,15 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
__ bind(&success_label_); __ bind(&success_label_);
if (num_saved_registers_ > 0) { if (num_saved_registers_ > 0) {
// copy captures to output // copy captures to output
__ movq(rdx, Operand(rbp, kStartIndex));
__ movq(rbx, Operand(rbp, kRegisterOutput)); __ movq(rbx, Operand(rbp, kRegisterOutput));
__ movq(rcx, Operand(rbp, kInputEnd)); __ movq(rcx, Operand(rbp, kInputEnd));
__ subq(rcx, Operand(rbp, kInputStart)); __ subq(rcx, Operand(rbp, kInputStart));
if (mode_ == UC16) {
__ lea(rcx, Operand(rcx, rdx, times_2, 0));
} else {
__ addq(rcx, rdx);
}
for (int i = 0; i < num_saved_registers_; i++) { for (int i = 0; i < num_saved_registers_; i++) {
__ movq(rax, register_location(i)); __ movq(rax, register_location(i));
__ addq(rax, rcx); // Convert to index from start, not end. __ addq(rax, rcx); // Convert to index from start, not end.
......
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