Revision: 11704
Author: [email protected]
Date: Mon Jun 4 01:49:17 2012
Log: Remove unnecessary code for non-zero-length global regexps.
Also fixing a bug in the arm implementation.
BUG=
TEST=regexp-global.js
Review URL: https://chromiumcodereview.appspot.com/10383280
http://code.google.com/p/v8/source/detail?r=11704
Modified:
/branches/bleeding_edge/src/arm/regexp-macro-assembler-arm.cc
/branches/bleeding_edge/src/ia32/regexp-macro-assembler-ia32.cc
/branches/bleeding_edge/src/jsregexp.cc
/branches/bleeding_edge/src/regexp-macro-assembler.cc
/branches/bleeding_edge/src/regexp-macro-assembler.h
/branches/bleeding_edge/src/x64/regexp-macro-assembler-x64.cc
/branches/bleeding_edge/test/mjsunit/regexp-global.js
=======================================
--- /branches/bleeding_edge/src/arm/regexp-macro-assembler-arm.cc Tue May
22 07:05:44 2012
+++ /branches/bleeding_edge/src/arm/regexp-macro-assembler-arm.cc Mon Jun
4 01:49:17 2012
@@ -796,7 +796,7 @@
for (int i = 0; i < num_saved_registers_; i += 2) {
__ ldr(r2, register_location(i));
__ ldr(r3, register_location(i + 1));
- if (global()) {
+ if (i == 0 && global_with_zero_length_check()) {
// Keep capture start in r4 for the zero-length check later.
__ mov(r4, r2);
}
@@ -834,18 +834,22 @@
// Prepare r0 to initialize registers with its value in the next run.
__ ldr(r0, MemOperand(frame_pointer(), kInputStartMinusOne));
- // Special case for zero-length matches.
- // r4: capture start index
- __ cmp(current_input_offset(), r4);
- // Not a zero-length match, restart.
- __ b(ne, &load_char_start_regexp);
- // Offset from the end is zero if we already reached the end.
- __ cmp(current_input_offset(), Operand(0));
- __ b(eq, &exit_label_);
- // Advance current position after a zero-length match.
- __ add(current_input_offset(),
- current_input_offset(),
- Operand((mode_ == UC16) ? 2 : 1));
+
+ if (global_with_zero_length_check()) {
+ // Special case for zero-length matches.
+ // r4: capture start index
+ __ cmp(current_input_offset(), r4);
+ // Not a zero-length match, restart.
+ __ b(ne, &load_char_start_regexp);
+ // Offset from the end is zero if we already reached the end.
+ __ cmp(current_input_offset(), Operand(0));
+ __ b(eq, &exit_label_);
+ // Advance current position after a zero-length match.
+ __ add(current_input_offset(),
+ current_input_offset(),
+ Operand((mode_ == UC16) ? 2 : 1));
+ }
+
__ b(&load_char_start_regexp);
} else {
__ mov(r0, Operand(SUCCESS));
=======================================
--- /branches/bleeding_edge/src/ia32/regexp-macro-assembler-ia32.cc Tue May
22 08:30:08 2012
+++ /branches/bleeding_edge/src/ia32/regexp-macro-assembler-ia32.cc Mon
Jun 4 01:49:17 2012
@@ -857,7 +857,7 @@
}
for (int i = 0; i < num_saved_registers_; i++) {
__ mov(eax, register_location(i));
- if (i == 0 && global()) {
+ if (i == 0 && global_with_zero_length_check()) {
// Keep capture start in edx for the zero-length check later.
__ mov(edx, eax);
}
@@ -890,20 +890,23 @@
// Prepare eax to initialize registers with its value in the next
run.
__ mov(eax, Operand(ebp, kInputStartMinusOne));
- // Special case for zero-length matches.
- // edx: capture start index
- __ cmp(edi, edx);
- // Not a zero-length match, restart.
- __ j(not_equal, &load_char_start_regexp);
- // edi (offset from the end) is zero if we already reached the end.
- __ test(edi, edi);
- __ j(zero, &exit_label_, Label::kNear);
- // Advance current position after a zero-length match.
- if (mode_ == UC16) {
- __ add(edi, Immediate(2));
- } else {
- __ inc(edi);
- }
+ if (global_with_zero_length_check()) {
+ // Special case for zero-length matches.
+ // edx: capture start index
+ __ cmp(edi, edx);
+ // Not a zero-length match, restart.
+ __ j(not_equal, &load_char_start_regexp);
+ // edi (offset from the end) is zero if we already reached the end.
+ __ test(edi, edi);
+ __ j(zero, &exit_label_, Label::kNear);
+ // Advance current position after a zero-length match.
+ if (mode_ == UC16) {
+ __ add(edi, Immediate(2));
+ } else {
+ __ inc(edi);
+ }
+ }
+
__ jmp(&load_char_start_regexp);
} else {
__ mov(eax, Immediate(SUCCESS));
=======================================
--- /branches/bleeding_edge/src/jsregexp.cc Fri Jun 1 04:28:52 2012
+++ /branches/bleeding_edge/src/jsregexp.cc Mon Jun 4 01:49:17 2012
@@ -5927,7 +5927,12 @@
macro_assembler.SetCurrentPositionFromEnd(max_length);
}
- macro_assembler.set_global(is_global);
+ if (is_global) {
+ macro_assembler.set_global_mode(
+ (data->tree->min_match() > 0)
+ ? RegExpMacroAssembler::GLOBAL_NO_ZERO_LENGTH_CHECK
+ : RegExpMacroAssembler::GLOBAL);
+ }
return compiler.Assemble(¯o_assembler,
node,
=======================================
--- /branches/bleeding_edge/src/regexp-macro-assembler.cc Tue May 22
07:05:44 2012
+++ /branches/bleeding_edge/src/regexp-macro-assembler.cc Mon Jun 4
01:49:17 2012
@@ -37,7 +37,7 @@
RegExpMacroAssembler::RegExpMacroAssembler()
: slow_safe_compiler_(false),
- global_(false) {
+ global_mode_(NOT_GLOBAL) {
}
=======================================
--- /branches/bleeding_edge/src/regexp-macro-assembler.h Tue May 22
07:05:44 2012
+++ /branches/bleeding_edge/src/regexp-macro-assembler.h Mon Jun 4
01:49:17 2012
@@ -184,14 +184,18 @@
void set_slow_safe(bool ssc) { slow_safe_compiler_ = ssc; }
bool slow_safe() { return slow_safe_compiler_; }
+ enum GlobalMode { NOT_GLOBAL, GLOBAL, GLOBAL_NO_ZERO_LENGTH_CHECK };
// Set whether the regular expression has the global flag. Exiting due
to
// a failure in a global regexp may still mean success overall.
- void set_global(bool global) { global_ = global; }
- bool global() { return global_; }
+ inline void set_global_mode(GlobalMode mode) { global_mode_ = mode; }
+ inline bool global() { return global_mode_ != NOT_GLOBAL; }
+ inline bool global_with_zero_length_check() {
+ return global_mode_ == GLOBAL;
+ }
private:
bool slow_safe_compiler_;
- bool global_;
+ bool global_mode_;
};
=======================================
--- /branches/bleeding_edge/src/x64/regexp-macro-assembler-x64.cc Wed May
23 04:36:54 2012
+++ /branches/bleeding_edge/src/x64/regexp-macro-assembler-x64.cc Mon Jun
4 01:49:17 2012
@@ -926,7 +926,7 @@
}
for (int i = 0; i < num_saved_registers_; i++) {
__ movq(rax, register_location(i));
- if (i == 0 && global()) {
+ if (i == 0 && global_with_zero_length_check()) {
// Keep capture start in rdx for the zero-length check later.
__ movq(rdx, rax);
}
@@ -958,20 +958,23 @@
// Prepare rax to initialize registers with its value in the next
run.
__ movq(rax, Operand(rbp, kInputStartMinusOne));
- // Special case for zero-length matches.
- // rdx: capture start index
- __ cmpq(rdi, rdx);
- // Not a zero-length match, restart.
- __ j(not_equal, &load_char_start_regexp);
- // rdi (offset from the end) is zero if we already reached the end.
- __ testq(rdi, rdi);
- __ j(zero, &exit_label_, Label::kNear);
- // Advance current position after a zero-length match.
- if (mode_ == UC16) {
- __ addq(rdi, Immediate(2));
- } else {
- __ incq(rdi);
- }
+ if (global_with_zero_length_check()) {
+ // Special case for zero-length matches.
+ // rdx: capture start index
+ __ cmpq(rdi, rdx);
+ // Not a zero-length match, restart.
+ __ j(not_equal, &load_char_start_regexp);
+ // rdi (offset from the end) is zero if we already reached the end.
+ __ testq(rdi, rdi);
+ __ j(zero, &exit_label_, Label::kNear);
+ // Advance current position after a zero-length match.
+ if (mode_ == UC16) {
+ __ addq(rdi, Immediate(2));
+ } else {
+ __ incq(rdi);
+ }
+ }
+
__ jmp(&load_char_start_regexp);
} else {
__ movq(rax, Immediate(SUCCESS));
=======================================
--- /branches/bleeding_edge/test/mjsunit/regexp-global.js Fri May 25
04:03:28 2012
+++ /branches/bleeding_edge/test/mjsunit/regexp-global.js Mon Jun 4
01:49:17 2012
@@ -130,3 +130,12 @@
var str = "Beasts of England, beasts of Ireland";
str = str.replace(/(.*)/g, function(match) { return '~'; });
assertEquals("~~", str);
+
+// Test zero-length matches that have non-zero-length sub-captures that do
not
+// start at the match start position.
+str = "up up up up";
+str = str.replace(/\b(?=u(p))/g, function(match, capture) {
+ return capture.length;
+ });
+
+assertEquals("1up 1up 1up 1up", str);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev