Author: [email protected]
Date: Tue Dec 16 06:21:00 2008
New Revision: 984

Modified:
    branches/bleeding_edge/src/assembler-ia32.cc
    branches/bleeding_edge/src/assembler-ia32.h
    branches/bleeding_edge/src/regexp-macro-assembler-ia32.cc
    branches/bleeding_edge/src/regexp-macro-assembler-ia32.h
    branches/bleeding_edge/test/cctest/test-regexp.cc

Log:
Removed rep-cmps{w,b} from CheckCharacters to improve performance.


Modified: branches/bleeding_edge/src/assembler-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/assembler-ia32.cc        (original)
+++ branches/bleeding_edge/src/assembler-ia32.cc        Tue Dec 16 06:21:00 2008
@@ -866,21 +866,20 @@
  }


-void Assembler::rep_cmpsb() {
+void Assembler::cmpb_al(const Operand& op) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
-  EMIT(0xFC);  // CLD to ensure forward operation
-  EMIT(0xF3);  // REP
-  EMIT(0xA6);  // CMPSB
+  EMIT(0x38);  // CMP r/m8, r8
+  emit_operand(eax, op);  // eax has same code as register al.
  }

-void Assembler::rep_cmpsw() {
+
+void Assembler::cmpw_ax(const Operand& op) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
-  EMIT(0xFC);  // CLD to ensure forward operation
-  EMIT(0xF3);  // REP
-  EMIT(0x66);  // Operand size overide.
-  EMIT(0xA7);  // CMPS
+  EMIT(0x66);
+  EMIT(0x39);  // CMP r/m16, r16
+  emit_operand(eax, op);  // eax has same code as register ax.
  }



Modified: branches/bleeding_edge/src/assembler-ia32.h
==============================================================================
--- branches/bleeding_edge/src/assembler-ia32.h (original)
+++ branches/bleeding_edge/src/assembler-ia32.h Tue Dec 16 06:21:00 2008
@@ -503,14 +503,13 @@
    void and_(const Operand& dst, const Immediate& x);

    void cmpb(const Operand& op, int8_t imm8);
+  void cmpb_al(const Operand& op);
+  void cmpw_ax(const Operand& op);
    void cmpw(const Operand& op, Immediate imm16);
    void cmp(Register reg, int32_t imm32);
    void cmp(Register reg, Handle<Object> handle);
    void cmp(Register reg, const Operand& op);
    void cmp(const Operand& op, const Immediate& imm);
-
-  void rep_cmpsb();
-  void rep_cmpsw();

    void dec_b(Register dst);


Modified: branches/bleeding_edge/src/regexp-macro-assembler-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/regexp-macro-assembler-ia32.cc   (original)
+++ branches/bleeding_edge/src/regexp-macro-assembler-ia32.cc   Tue Dec 16  
06:21:00 2008
@@ -193,47 +193,28 @@
      BranchOrBacktrack(greater, on_failure);
    }

-  if (str.length() <= kMaxInlineStringTests) {
-    for (int i = 0; i < str.length(); i++) {
-      if (mode_ == ASCII) {
-        __ cmpb(Operand(esi, edi, times_1, byte_offset + i),
-                static_cast<int8_t>(str[i]));
-      } else {
-        ASSERT(mode_ == UC16);
-        __ cmpw(Operand(esi, edi, times_1, byte_offset + i * sizeof(uc16)),
-                Immediate(str[i]));
-      }
-      BranchOrBacktrack(not_equal, on_failure);
-    }
-    return;
+  Label backtrack;
+  if (on_failure == NULL) {
+    // Avoid inlining the Backtrack macro for each test.
+    Label skip_backtrack;
+    __ jmp(&skip_backtrack);
+    __ bind(&backtrack);
+    Backtrack();
+    __ bind(&skip_backtrack);
+    on_failure = &backtrack;
    }

-  ArraySlice constant_buffer = constants_.GetBuffer(str.length(),  
char_size());
-  if (mode_ == ASCII) {
-    for (int i = 0; i < str.length(); i++) {
-      constant_buffer.at<char>(i) = static_cast<char>(str[i]);
+  for (int i = 0; i < str.length(); i++) {
+    if (mode_ == ASCII) {
+      __ cmpb(Operand(esi, edi, times_1, byte_offset + i),
+              static_cast<int8_t>(str[i]));
+    } else {
+      ASSERT(mode_ == UC16);
+      __ cmpw(Operand(esi, edi, times_1, byte_offset + i * sizeof(uc16)),
+              Immediate(str[i]));
      }
-  } else {
-    ASSERT(mode_ == UC16);
-    memcpy(constant_buffer.location(),
-           str.start(),
-           str.length() * sizeof(uc16));
-  }
-
-  __ mov(eax, edi);
-  __ mov(ebx, esi);
-  __ lea(edi, Operand(esi, edi, times_1, byte_offset));
-  LoadConstantBufferAddress(esi, &constant_buffer);
-  __ mov(ecx, str.length());
-  if (char_size() == 1) {
-    __ rep_cmpsb();
-  } else {
-    ASSERT(char_size() == 2);
-    __ rep_cmpsw();
+    BranchOrBacktrack(not_equal, on_failure);
    }
-  __ mov(esi, ebx);
-  __ mov(edi, eax);
-  BranchOrBacktrack(not_equal, on_failure);
  }


@@ -251,45 +232,50 @@
      int start_reg,
      Label* on_no_match) {
    Label fallthrough;
-  __ mov(eax, register_location(start_reg));
+  __ mov(edx, register_location(start_reg));
    __ mov(ecx, register_location(start_reg + 1));
-  __ sub(ecx, Operand(eax));  // Length to check.
+  __ sub(ecx, Operand(edx));  // Length to check.
    BranchOrBacktrack(less, on_no_match);
    __ j(equal, &fallthrough);

    if (mode_ == ASCII) {
      Label success;
      Label fail;
-    __ push(esi);
+    Label loop_increment;
      __ push(edi);
+    __ add(edx, Operand(esi));
      __ add(edi, Operand(esi));
-    __ add(esi, Operand(eax));
+    __ add(ecx, Operand(edi));
+
      Label loop;
      __ bind(&loop);
-    __ rep_cmpsb();
-    __ j(equal, &success);
+    __ movzx_b(eax, Operand(edi, 0));
+    __ cmpb_al(Operand(edx, 0));
+    __ j(equal, &loop_increment);
+
      // Compare lower-case if letters.
-    __ movzx_b(eax, Operand(edi, -1));
-    __ or_(eax, 0x20);  // To-lower-case
+    __ or_(eax, 0x20);  // To lower-case.
      __ lea(ebx, Operand(eax, -'a'));
      __ cmp(ebx, static_cast<int32_t>('z' - 'a'));
      __ j(above, &fail);
-    __ movzx_b(ebx, Operand(esi, -1));
+    __ movzx_b(ebx, Operand(edx, 0));
      __ or_(ebx, 0x20);  // To-lower-case
      __ cmp(eax, Operand(ebx));
      __ j(not_equal, &fail);
-    __ or_(ecx, Operand(ecx));
-    __ j(not_equal, &loop);
+
+    __ bind(&loop_increment);
+    __ add(Operand(edx), Immediate(1));
+    __ add(Operand(edi), Immediate(1));
+    __ cmp(edi, Operand(ecx));
+    __ j(below, &loop, taken);
      __ jmp(&success);

      __ bind(&fail);
      __ pop(edi);
-    __ pop(esi);
      BranchOrBacktrack(no_condition, on_no_match);

      __ bind(&success);
      __ pop(eax);  // discard original value of edi
-    __ pop(esi);
      __ sub(edi, Operand(esi));
    } else {
      ASSERT(mode_ == UC16);
@@ -325,30 +311,47 @@
      int start_reg,
      Label* on_no_match) {
    Label fallthrough;
-  __ mov(eax, register_location(start_reg));
+  Label success;
+  Label fail;
+  __ mov(edx, register_location(start_reg));
    __ mov(ecx, register_location(start_reg + 1));
-  __ sub(ecx, Operand(eax));  // Length to check.
+  __ sub(ecx, Operand(edx));  // Length to check.
    BranchOrBacktrack(less, on_no_match);
    __ j(equal, &fallthrough);
    // Check that there are sufficient characters left in the input.
+
    __ mov(ebx, edi);
    __ add(ebx, Operand(ecx));
    BranchOrBacktrack(greater, on_no_match);

    __ mov(ebx, edi);
-  __ mov(edx, esi);
    __ add(edi, Operand(esi));
-  __ add(esi, Operand(eax));
-  __ rep_cmpsb();
-  __ mov(esi, edx);
-  Label success;
-  __ j(equal, &success);
+  __ add(edx, Operand(esi));
+  __ add(ecx, Operand(edi));
+
+  Label loop;
+  __ bind(&loop);
+  if (mode_ == ASCII) {
+    __ movzx_b(eax, Operand(edx, 0));
+    __ cmpb_al(Operand(edi, 0));
+  } else {
+    ASSERT(mode_ == UC16);
+    __ movzx_w(eax, Operand(edx, 0));
+    __ cmpw_ax(Operand(edi, 0));
+  }
+  __ j(not_equal, &fail);
+  __ add(Operand(edx), Immediate(char_size()));
+  __ add(Operand(edi), Immediate(char_size()));
+  __ cmp(edi, Operand(ecx));
+  __ j(below, &loop);
+  __ jmp(&success);
+
+  __ bind(&fail);
    __ mov(edi, ebx);
    BranchOrBacktrack(no_condition, on_no_match);

    __ bind(&success);
    __ sub(edi, Operand(esi));
-
    __ bind(&fallthrough);
  }


Modified: branches/bleeding_edge/src/regexp-macro-assembler-ia32.h
==============================================================================
--- branches/bleeding_edge/src/regexp-macro-assembler-ia32.h    (original)
+++ branches/bleeding_edge/src/regexp-macro-assembler-ia32.h    Tue Dec 16  
06:21:00 2008
@@ -126,10 +126,10 @@
    static const size_t kRegExpCodeSize = 1024;
    // Initial size of constant buffers allocated during compilation.
    static const int kRegExpConstantsSize = 256;
-  // Only unroll loops up to this length.
-  static const int kMaxInlineStringTests = 8;
+  // Only unroll loops up to this length. TODO(lrn): Actually use this.
+  static const int kMaxInlineStringTests = 32;

-  // Compares two-byte strings case insenstively.
+  // Compares two-byte strings case insensitively.
    static int CaseInsensitiveCompareUC16(uc16** buffer,
                                          int byte_offset1,
                                          int byte_offset2,

Modified: branches/bleeding_edge/test/cctest/test-regexp.cc
==============================================================================
--- branches/bleeding_edge/test/cctest/test-regexp.cc   (original)
+++ branches/bleeding_edge/test/cctest/test-regexp.cc   Tue Dec 16 06:21:00  
2008
@@ -788,7 +788,7 @@
  }


-TEST(MacroAssemblerIA32BackReference) {
+TEST(MacroAssemblerIA32BackReferenceASCII) {
    v8::V8::Initialize();
    ContextInitializer initializer;

@@ -833,6 +833,57 @@
    CHECK_EQ(2, output[1]);
    CHECK_EQ(6, output[2]);
  }
+
+
+TEST(MacroAssemblerIA32BackReferenceUC16) {
+  v8::V8::Initialize();
+  ContextInitializer initializer;
+
+  RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::UC16, 3);
+
+  m.WriteCurrentPositionToRegister(0, 0);
+  m.AdvanceCurrentPosition(2);
+  m.WriteCurrentPositionToRegister(1, 0);
+  Label nomatch;
+  m.CheckNotBackReference(0, &nomatch);
+  m.Fail();
+  m.Bind(&nomatch);
+  m.AdvanceCurrentPosition(2);
+  Label missing_match;
+  m.CheckNotBackReference(0, &missing_match);
+  m.WriteCurrentPositionToRegister(2, 0);
+  m.Succeed();
+  m.Bind(&missing_match);
+  m.Fail();
+
+  Handle<String> source =  
Factory::NewStringFromAscii(CStrVector("^(..)..\1"));
+  Handle<Object> code_object = m.GetCode(source);
+  Handle<Code> code = Handle<Code>::cast(code_object);
+
+  const uc16 input_data[6] = {'f', 0x2028, 'o', 'o', 'f', 0x2028};
+  Handle<String> input =
+      Factory::NewStringFromTwoByte(Vector<const uc16>(input_data, 6));
+  Handle<SeqTwoByteString> seq_input =  
Handle<SeqTwoByteString>::cast(input);
+  Address start_adr = seq_input->GetCharsAddress();
+
+  int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
+  int end_offset = start_offset + seq_input->length() *  
sizeof(input_data[0]);
+
+  int output[3];
+  RegExpMacroAssemblerIA32::Result result =
+      RegExpMacroAssemblerIA32::Execute(*code,
+                                        seq_input.location(),
+                                        start_offset,
+                                        end_offset,
+                                        output,
+                                        true);
+
+  CHECK_EQ(RegExpMacroAssemblerIA32::SUCCESS, result);
+  CHECK_EQ(0, output[0]);
+  CHECK_EQ(2, output[1]);
+  CHECK_EQ(6, output[2]);
+}
+


  TEST(MacroAssemblerIA32AtStart) {

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to