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(&macro_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

Reply via email to