Author: [EMAIL PROTECTED]
Date: Fri Nov 14 02:58:30 2008
New Revision: 752

Added:
    branches/experimental/regexp2000/src/regexp-macro-assembler-ia32.cc
    branches/experimental/regexp2000/src/regexp-macro-assembler-ia32.h
       - copied, changed from r750,  
/branches/experimental/regexp2000/src/regexp-macro-assembler.h
    branches/experimental/regexp2000/src/regexp-macro-assembler.cc    
(contents, props changed)
Modified:
    branches/experimental/regexp2000/src/assembler-ia32-inl.h
    branches/experimental/regexp2000/src/assembler-ia32.cc
    branches/experimental/regexp2000/src/assembler-ia32.h
    branches/experimental/regexp2000/src/heap.cc
    branches/experimental/regexp2000/src/heap.h
    branches/experimental/regexp2000/src/jsregexp.cc
    branches/experimental/regexp2000/src/regexp-macro-assembler.h

Log:
* Create ByteArray to hold constants outside of the code.
Can reuse the same ByteArray for several bytes.

* Start on regexp-macro-assembler-ia32.

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

Modified: branches/experimental/regexp2000/src/assembler-ia32-inl.h
==============================================================================
--- branches/experimental/regexp2000/src/assembler-ia32-inl.h   (original)
+++ branches/experimental/regexp2000/src/assembler-ia32-inl.h   Fri Nov 14  
02:58:30 2008
@@ -205,6 +205,14 @@
  }


+void Assembler::emit_w(const Immediate& x) {
+  ASSERT(x.rmode_ == RelocInfo::NONE);
+  uint16_t value = static_cast<uint16_t>(x.x_);
+  reinterpret_cast<uint16_t*>(pc_)[0] = value;
+  pc_ += sizeof(uint16_t);
+}
+
+
  Address Assembler::target_address_at(Address pc) {
    return pc + sizeof(int32_t) + *reinterpret_cast<int32_t*>(pc);
  }

Modified: branches/experimental/regexp2000/src/assembler-ia32.cc
==============================================================================
--- branches/experimental/regexp2000/src/assembler-ia32.cc      (original)
+++ branches/experimental/regexp2000/src/assembler-ia32.cc      Fri Nov 14  
02:58:30 2008
@@ -545,6 +545,22 @@
  }


+void Assembler::enter(const Immediate& size) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0xC8);
+  emit_w(size);
+  EMIT(0);
+}
+
+
+void Assembler::leave() {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0xC9);
+}
+
+
  void Assembler::mov_b(Register dst, const Operand& src) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
@@ -829,6 +845,23 @@
  }


+void Assembler::rep_cmpsb() {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0xFC);  // CLD to ensure forward operation
+  EMIT(0xF3);  // REP
+  EMIT(0xA6);  // CMPSB
+}
+
+void Assembler::rep_cmpsw() {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0xFC);  // CLD to ensure forward operation
+  EMIT(0xF3);  // REP
+  EMIT(0xA7);  // CMPSW
+}
+
+
  void Assembler::dec_b(Register dst) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
@@ -1170,6 +1203,15 @@
  }


+void Assembler::bt(const Operand& dst, Register src) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0x0F);
+  EMIT(0xA3);
+  emit_operand(src, dst);
+}
+
+
  void Assembler::bts(const Operand& dst, Register src) {
    EnsureSpace ensure_space(this);
    last_pc_ = pc_;
@@ -1220,13 +1262,6 @@
      EMIT(imm16 & 0xFF);
      EMIT((imm16 >> 8) & 0xFF);
    }
-}
-
-
-void Assembler::leave() {
-  EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
-  EMIT(0xC9);
  }



Modified: branches/experimental/regexp2000/src/assembler-ia32.h
==============================================================================
--- branches/experimental/regexp2000/src/assembler-ia32.h       (original)
+++ branches/experimental/regexp2000/src/assembler-ia32.h       Fri Nov 14  
02:58:30 2008
@@ -444,6 +444,9 @@
    void pop(Register dst);
    void pop(const Operand& dst);

+  void enter(const Immediate& size);
+  void leave();
+
    // Moves
    void mov_b(Register dst, const Operand& src);
    void mov_b(const Operand& dst, int8_t imm8);
@@ -491,6 +494,9 @@
    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);

    void dec(Register dst);
@@ -550,6 +556,7 @@
    void xor_(const Operand& dst, const Immediate& x);

    // Bit operations.
+  void bt(const Operand& dst, Register src);
    void bts(const Operand& dst, Register src);

    // Miscellaneous
@@ -558,7 +565,6 @@
    void nop();
    void rdtsc();
    void ret(int imm16);
-  void leave();

    // Label operations & relative jumps (PPUM Appendix D)
    //
@@ -748,6 +754,7 @@
    inline void emit(Handle<Object> handle);
    inline void emit(uint32_t x, RelocInfo::Mode rmode);
    inline void emit(const Immediate& x);
+  inline void emit_w(const Immediate& x);

    // instruction generation
    void emit_arith_b(int op1, int op2, Register dst, int imm8);

Modified: branches/experimental/regexp2000/src/heap.cc
==============================================================================
--- branches/experimental/regexp2000/src/heap.cc        (original)
+++ branches/experimental/regexp2000/src/heap.cc        Fri Nov 14 02:58:30 2008
@@ -1557,6 +1557,24 @@
  }


+Object* Heap::AllocateByteArray(int length, PretenureFlag pretenure) {
+  if (pretenure == NOT_TENURED) {
+    return AllocateByteArray(length);
+  }
+  int size = ByteArray::SizeFor(length);
+  AllocationSpace space =
+      size > MaxHeapObjectSize() ? LO_SPACE : OLD_DATA_SPACE;
+
+  Object* result = AllocateRaw(size, space, OLD_DATA_SPACE);
+
+  if (result->IsFailure()) return result;
+
+  reinterpret_cast<Array*>(result)->set_map(byte_array_map());
+  reinterpret_cast<Array*>(result)->set_length(length);
+  return result;
+}
+
+
  Object* Heap::AllocateByteArray(int length) {
    int size = ByteArray::SizeFor(length);
    AllocationSpace space =

Modified: branches/experimental/regexp2000/src/heap.h
==============================================================================
--- branches/experimental/regexp2000/src/heap.h (original)
+++ branches/experimental/regexp2000/src/heap.h Fri Nov 14 02:58:30 2008
@@ -383,7 +383,13 @@
    // Allocate a byte array of the specified length
    // Returns Failure::RetryAfterGC(requested_bytes, space) if the  
allocation
    // failed.
-  // Please not this does not perform a garbage collection.
+  // Please note this does not perform a garbage collection.
+  static Object* AllocateByteArray(int length, PretenureFlag pretenure);
+
+  // Allocate a non-tenured byte array of the specified length
+  // Returns Failure::RetryAfterGC(requested_bytes, space) if the  
allocation
+  // failed.
+  // Please note this does not perform a garbage collection.
    static Object* AllocateByteArray(int length);

    // Allocates a fixed array initialized with undefined values

Modified: branches/experimental/regexp2000/src/jsregexp.cc
==============================================================================
--- branches/experimental/regexp2000/src/jsregexp.cc    (original)
+++ branches/experimental/regexp2000/src/jsregexp.cc    Fri Nov 14 02:58:30  
2008
@@ -1635,8 +1635,12 @@
    return node;
  }

+RegExpMacroAssembler::RegExpMacroAssembler() {
+
+}

  RegExpMacroAssembler::~RegExpMacroAssembler() {
+
  }



Added: branches/experimental/regexp2000/src/regexp-macro-assembler-ia32.cc
==============================================================================
--- (empty file)
+++ branches/experimental/regexp2000/src/regexp-macro-assembler-ia32.cc Fri  
Nov 14 02:58:30 2008
@@ -0,0 +1,437 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+#include "regexp-macro-assembler-ia32.h"
+
+namespace v8 { namespace internal {
+
+/*
+ * This assembler uses the following register assignment convention
+ * - edx : current character, or kEndOfInput if current position is not
+ *         inside string. The kEndOfInput value is greater than 0xffff,
+ *         so any tests that don't check whether the current position
+ *         is inside the correct range should retain bits above the
+ *         15th in their computations, and fail if the value is too
+ *         great.
+ * - edi : current position in input.
+ * - esi : end of input (points to byte after last character in input).
+ * - ebp : points to the location above the registers on the stack,
+ *         as if by the "enter <register_count>" opcode.
+ * - esp : points to tip of backtracking stack.
+ *
+ * The registers eax, ebx and eax are free to use for computations.
+ *
+ * Each call to a public method should retain this convention.
+ * The stack is expected to have the following structure (tentative):
+ *
+ *       - pointer to array where captures can be stored
+ *       - end of input
+ *       - start of input
+ *       - return address
+ * ebp-> - old ebp
+ *       - register 0  ebp[-4]
+ *       - register 1  ebp[-8]
+ *       - ...
+ *
+ * The data before ebp must be placed there by the calling code.
+ */
+
+RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32()
+ : masm_(new MacroAssembler(NULL, kRegExpCodeSize)),
+   constants_(kRegExpConstantsSize),
+   num_registers_(0),
+   ignore_case(false) {}
+
+
+RegExpMacroAssemblerIA32::~RegExpMacroAssemblerIA32() {
+  delete masm_;
+}
+
+
+#define __ masm_->
+
+void RegExpMacroAssemblerIA32::AdvanceCurrentPosition(int by) {
+  __ add(edi, by * sizeof(SubjectChar));
+  __ cmp(edi, esi);
+  Label inside_string;
+  Backtrack();
+
+  __ bind(&inside_string);
+  ReadChar(edx, 0);
+}
+
+
+void RegExpMacroAssemblerIA32::AdvanceRegister(int reg, int by) {
+  ASSERT(reg >= 0);
+  ASSERT(reg < num_registers);
+  __ add(register_location(reg), by);
+}
+
+
+void RegExpMacroAssemblerIA32::Backtrack() {
+  __ ret();
+}
+
+
+void RegExpMacroAssemblerIA32::Bind(Label* label) {
+  __ bind(label);
+}
+
+
+void RegExpMacroAssemblerIA32::CheckBitmap(uc16 start,
+                                           Label* bitmap,
+                                           Label* on_zero) {
+  ReadCurrentChar(eax);
+  __ sub(eax, start);
+  __ cmp(eax, 64); // FIXME: 64 = length_of_bitmap_in_bits.
+  BranchOrBacktrack(greater_equal, on_zero);
+  __ mov(ebx, eax);
+  __ shr(ebx, 3);
+  // TODO: Where is the bitmap stored? Pass the bitmap as argument instead.
+  // __ mov(ecx, position_of_bitmap);
+  __ movzx_b(ebx, Operand(ecx, ebx, times_1, 0));
+  __ and_(eax, (1<<3)-1);
+  __ bt(ebx, eax);
+  __ j(greater_equal, on_zero);  // Aka. jump on carry set.
+}
+
+
+void RegExpMacroAssemblerIA32::CheckCharacterClass(RegExpCharacterClass  
*cclass,
+                                                   Label* on_failure) {
+  UNREACHABLE();  // Not implemented.
+}
+
+
+void RegExpMacroAssemblerIA32::CheckCharacters(Vector<uc16> str,
+                                               Label* on_failure) {
+  if (sizeof(SubjectChar) == 1) {
+    for (int i = 0; i < str.length(); i++) {
+      if (str[i] > String::kMaxAsciiCharCode) {
+        __ jmp(on_failure);
+        return;
+      }
+    }
+  }
+  int byte_length = str.length() * sizeof(SubjectChar);
+  __ mov(ebx, edi);
+  __ add(ebx, byte_length);
+  __ cmp(ebx, esi);
+  BranchOrBacktrack(greater_equal, on_failure);
+
+  if (str.length() <= kMaxInlineStringTests || ignore_case()) {
+    // TODO: make proper loop if str.length is large but ignore_case is  
true;
+    for(int i = 0; i < str.length(); i++) {
+      ReadChar(eax, i);
+      if (ignore_case()) {
+        Canonicalize(eax);
+      }
+      __ cmp(eax, str[i]);
+      BranchOrBacktrack(not_equal, on_failure);
+    }
+    add(edi, byte_length);
+  } else {
+    int offset;
+    ArraySlice<SubjectChar> constant_buffer =
+        constants_.GetBuffer<SubjectChar>(str.length());
+    for (int i = 0; i < str.length(); i++) {
+      constant_buffer[i] = str[i];
+    }
+    __ mov(ebx, esi);
+    LoadConstantBufferAddress(esi, constant_buffer);
+    __ mov(ecx, str.length());
+    if (sizeof(SubjectChar) == 1) {
+      __ rep_cmpsb();
+    } else {
+      ASSERT(sizeof(SubjectChar)==2);
+      __ rep_cmpsw();
+    }
+    __ mov(esi, ebx);
+    BranchOrBacktrack(not_equal, on_failure);
+  }
+};
+
+
+void RegExpMacroAssemblerIA32::CheckCurrentPosition(int register_index,
+                                                    Label* on_equal) {
+  __ cmp(register_location(register_index), edi);
+  BranchOrBacktrack(equal, on_equal);
+}
+
+
+void RegExpMacroAssemblerIA32::DispatchHalfNibbleMap(
+    uc16 start,
+    Label* half_nibble_map,
+    const Vector<Label*>& destinations) {
+
+  if (sizeof(SubjectChar) == 1 && start > String::kMaxAsciiCharCode) {
+    return;
+  }
+
+  Label fallthrough;
+
+  ReadCurrentChar(eax);
+  __ sub(eax, start);
+  __ cmp(eax, 64);  // FIXME: 64 = size of map in bytes. Found somehow??
+  __ j(greater_equal, &fallthrough);
+
+  __ mov(ebx, eax);
+  __ shr(eax, 2);
+  __ movzx_b(eax, Operand(ecx, eax)); // FIXME: ecx holds address of map
+  Label got_nybble;
+  Label high_bits;
+  __ and_(ebx, 0x03);
+  __ shr(eax, ebx);
+
+  Label second_bit_set, case_3, case_1;
+  __ test(eax, 2);
+  __ j(not_equal, &second_bit_set);
+  __ test(eax, 1);
+  __ j(not_equal, &case_1);
+  // Case 0:
+  __ jmp(&destinations[0]);
+  __ bind(&case_1);
+  // Case 1:
+  __ jmp(&destinations[1]);
+  __ bind(&second_bit_set);
+  __ test(eax, 1);
+  __ j(not_equal, &case_3);
+  // Case 2
+  __ jmp(&destinations[2]);
+  __ bind(&case_3);
+  // Case 3:
+  __ jmp(&destinations[3]);
+
+  __ bind(&fallthrough);
+}
+
+
+void RegExpMacroAssemblerIA32::DispatchByteMap(
+    uc16 start,
+    Label* byte_map,
+    const Vector<Label*>& destinations) {
+
+  if (sizeof(SubjectChar) == 1 && start > String::kMaxAsciiCharCode) {
+    return;
+  }
+
+  Label fallthrough;
+
+  ReadCurrentChar(eax);
+  __ sub(eax, start);
+  __ cmp(eax, 64);  // FIXME: 64 = size of map. Found somehow??
+  __ j(greater_equal, &fallthrough);
+
+  __ movzx_b(eax, Operand(ecx, eax));  // FIXME: ecx must hold address of  
map
+  // jump table: jump to destinations[eax];
+
+  __ bind(&fallthrough);
+}
+
+void RegExpMacroAssemblerIA32::DispatchHighByteMap(
+    byte start,
+    Label* byte_map,
+    const Vector<Label*>& destinations) {
+  Label fallthrough;
+  ReadCurrentChar(eax);
+  __ shr(eax, 8);
+  __ sub(eax, start);
+  __ cmp(eax, destinations.length() - start);
+  __ j(greater_equal, &fallthrough);
+
+  // TODO jumptable: jump to destinations[eax]
+  __ bind(&fallthrough);
+}
+
+
+void RegExpMacroAssemblerIA32::EmitOrLink(Label* label) {
+  UNREACHABLE();  // Has no use.
+}
+
+
+void RegExpMacroAssemblerIA32::Fail() {
+  Exit(false);
+}
+
+Handle<Object> RegExpMacroAssemblerIA32::GetCode() {
+  // something
+  return Handle();
+}
+
+
+void RegExpMacroAssemblerIA32::GoTo(Label &to) {
+  __ jmp(to);
+}
+
+
+void RegExpMacroAssemblerIA32::IfRegisterGE(int reg,
+                                            int comparand,
+                                            Label* if_ge) {
+  __ cmp(register_location(reg), comparand);
+  BranchOrBacktrack(greater_equal, if_ge);
+}
+
+
+void RegExpMacroAssemblerIA32::IfRegisterLT(int reg,
+                                            int comparand,
+                                            Label* if_lt) {
+  __ cmp(register_location(reg), comparand);
+  BranchOrBacktrack(less, if_lt);
+}
+
+
+Re2kImplementation RegExpMacroAssemblerIA32::Implementation() {
+  return kIA32Implementation;
+}
+
+
+void RegExpMacroAssemblerIA32::PopCurrentPosition() {
+  __ pop(edi);
+  ReadChar(edx, 0);
+}
+
+
+void RegExpMacroAssemblerIA32::PopRegister(int register_index) {
+  __ pop(register_location(register_index));
+}
+
+
+void RegExpMacroAssemblerIA32::PushBacktrack(Label* label) {
+  Label cont;
+  __ call(&cont);
+  __ jmp(label);
+  __ bind(&cont);
+}
+
+
+void RegExpMacroAssemblerIA32::PushCurrentPosition() {
+  __ push(edi);
+}
+
+
+void RegExpMacroAssemblerIA32::PushRegister(int register_index) {
+  __ push(register_location(register_index));
+}
+
+
+void RegExpMacroAssemblerIA32::SetRegister(int register_index, int to) {
+  __ mov(register_location(register_index), to);
+}
+
+
+void RegExpMacroAssemblerIA32::Succeed() {
+  Exit(true);
+}
+
+void RegExpMacroAssemblerIA32::WriteCurrentPositionToRegister() {
+  __ mov(register_location(register_index), edi);
+}
+
+// Custom :
+
+void RegExpMacroAssemblerIA32::Initialize(int num_registers, bool  
ignore_case) {
+  num_registers_ = num_registers;
+  ignore_case_ = ignore_case;
+  __ enter(num_registers * sizeof(uint32_t));
+}
+
+
+Operand RegExpMacroAssemblerIA32::register_location(int register_index) {
+  ASSERT(register_index < (1<<30));
+  return Operand(ebp, -((register_index + 1) * sizeof(uint32_t)));
+}
+
+
+void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition,
+                                                 Label* to) {
+  if (condition < 0) {  // No condition
+    if (to == NULL) {
+      Backtrack();
+      return;
+    }
+    __ jmp(to);
+    return;
+  } else if (to == NULL) {
+    Label skip;
+    __ j(NegateCondition(condition), &skip);
+    Backtrack();
+    __ bind(&skip);
+    return;
+  }
+  __ j(condition, to);
+}
+
+
+void RegExpMacroAssemblerIA32::Canonicalize(Register reg) {
+  if (sizeof(SubjectChar) == 1) {
+    Label end;
+    __ cmp(reg, 'a');
+    __ j(below, &end);
+    __ cmp(reg, 'z');
+    __ j(above, &end);
+    __ sub(reg, 'a' - 'A');
+    __ bind(&end);
+    return;
+  }
+  ASSERT(sizeof(SubjectChar) == 2);
+  // TODO: Use some tables.
+}
+
+
+void RegExpMacroAssemblerIA32::Exit(bool success) {
+  if (success) {
+    // Copy captures to output capture array.
+  }
+  __ leave();
+  __ mov(eax, success ? 1 : 0);
+  __ ret();
+}
+
+
+void RegExpMacroAssemblerIA32::ReadChar(Register destination, int offset) {
+  if (sizeof(SubjectChar) == 1) {
+    __ movzx_b(destination, Operand(edi, offset));
+    return;
+  }
+  ASSERT(sizeof(SubjectChar) == 2);
+  __ movzx_w(destination, Operand(edi, offset * 2));
+}
+
+
+void RegExpMacroAssemblerIA32::ReadCurrentChar(Register destination) {
+  mov(destination, edx);
+}
+
+
+template <typename T>
+void LoadConstantBufferAddress(Register reg, ArraySlice<T>& buffer) {
+  __ mov(reg, buffer.array());
+  __ add(reg, buffer.base_offset());
+}
+
+#undef __
+}}

Copied: branches/experimental/regexp2000/src/regexp-macro-assembler-ia32.h  
(from r750, /branches/experimental/regexp2000/src/regexp-macro-assembler.h)
==============================================================================
--- /branches/experimental/regexp2000/src/regexp-macro-assembler.h       
(original)
+++ branches/experimental/regexp2000/src/regexp-macro-assembler-ia32.h  Fri  
Nov 14 02:58:30 2008
@@ -25,101 +25,127 @@
  // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-#ifndef V8_REGEXP_MACRO_ASSEMBLER_H_
-#define V8_REGEXP_MACRO_ASSEMBLER_H_
+#ifndef REGEXP_MACRO_ASSEMBLER_IA32_H_
+#define REGEXP_MACRO_ASSEMBLER_IA32_H_
+
+#include "regexp-macro-assembler.h"
+#include "macro-assembler-ia32.h"

  namespace v8 { namespace internal {

+template <typename SubjectChar>
+class RegExpMacroAssemblerIA32: public RegExpMacroAssembler<SubjectChar> {
+ public:
+  RegExpMacroAssemblerIA32() { }
+  virtual ~RegExpMacroAssembler();
+  void Initialize(int num_registers, bool ignore_case);
+  virtual void AdvanceCurrentPosition(int by);  // Signed cp change.
+  virtual void AdvanceRegister(int reg, int by);  // r[reg] += by.
+  virtual void Backtrack();
+  virtual void Bind(Label* label);

-struct DisjunctDecisionRow {
-  RegExpCharacterClass cc;
-  Label* on_match;
-};
+  // Check the current character against a bitmap.  The range of the  
current
+  // character must be from start to start + length_of_bitmap_in_bits.
+  // Where to go if the bit is 0.  Fall through on 1.
+  virtual void CheckBitmap(
+      uc16 start,           // The bitmap is indexed from this character.
+      Label* bitmap,        // Where the bitmap is emitted.
+      Label* on_zero);


-class RegExpMacroAssembler {
- public:
-  RegExpMacroAssembler() { }
-  virtual ~RegExpMacroAssembler();
-  virtual void Bind(Label* label) = 0;
-  virtual void EmitOrLink(Label* label) = 0;
-  virtual void AdvanceCurrentPosition(int by) = 0;  // Signed cp change.
-  virtual void PopCurrentPosition() = 0;
-  virtual void PushCurrentPosition() = 0;
-  virtual void Backtrack() = 0;
-  virtual void GoTo(Label* label) = 0;
-  virtual void PushBacktrack(Label* label) = 0;
-  virtual void Succeed() = 0;
-  virtual void Fail() = 0;
-  virtual void PopRegister(int register_index) = 0;
-  virtual void PushRegister(int register_index) = 0;
-  virtual void AdvanceRegister(int reg, int by) = 0;  // r[reg] += by.
-  virtual void WriteCurrentPositionToRegister(int reg) = 0;
-  virtual void SetRegister(int register_index, int to) = 0;
    // Looks at the next character from the subject and if it doesn't match
    // then goto the on_failure label.  End of input never matches.  If the
    // label is NULL then we should pop a backtrack address off the stack and
    // go to that.
    virtual void CheckCharacterClass(
        RegExpCharacterClass* cclass,
-      int cp_offset,
-      Label* on_failure) = 0;
+      Label* on_failure);
+
    // Check the current character for a match with a literal string.  If we
    // fail to match then goto the on_failure label.  End of input always
    // matches.  If the label is NULL then we should pop a backtrack address  
off
-  // the stack abnd go to that.
+  // the stack and go to that.
    virtual void CheckCharacters(
-      Vector<const uc16> str,
-      int cp_offset,
-      Label* on_failure) = 0;
+      Vector<uc16> str,
+      Label* on_failure);
+
    // Check the current input position against a register.  If the register  
is
    // equal to the current position then go to the label.  If the label is  
NULL
    // then backtrack instead.
    virtual void CheckCurrentPosition(
        int register_index,
-      Label* on_equal) = 0;
-  // Check the current character against a bitmap.  The range of the  
current
-  // character must be from start to start + length_of_bitmap_in_bits.
-  virtual void CheckBitmap(
-      uc16 start,           // The bitmap is indexed from this character.
-      Label* bitmap,        // Where the bitmap is emitted.
-      Label* on_zero) = 0;  // Where to go if the bit is 0.  Fall through  
on 1.
-  // Dispatch after looking the current character up in a 2-bits-per-entry
-  // map.  The destinations vector has up to 4 labels.
-  virtual void DispatchHalfNibbleMap(
-      uc16 start,
-      Label* half_nibble_map,
-      const Vector<Label*>& destinations) = 0;
+      Label* on_equal);
+
    // Dispatch after looking the current character up in a byte map.  The
    // destinations vector has up to 256 labels.
    virtual void DispatchByteMap(
        uc16 start,
        Label* byte_map,
-      const Vector<Label*>& destinations) = 0;
+      Vector<Label*>& destinations);
+
+  // Dispatch after looking the current character up in a 2-bits-per-entry
+  // map.  The destinations vector has up to 4 labels.
+  virtual void DispatchHalfNibbleMap(
+      uc16 start,
+      Label* half_nibble_map,
+      Vector<Label*>& destinations);
+
    // Dispatch after looking the high byte of the current character up in a  
byte
    // map.  The destinations vector has up to 256 labels.
    virtual void DispatchHighByteMap(
        byte start,
        Label* byte_map,
-      const Vector<Label*>& destinations) = 0;
-  // Check whether a register is < a given constant and go to a label if  
it is.
-  // Backtracks instead if the label is NULL.
-  virtual void IfRegisterLT(int reg, int comparand, Label* if_lt) = 0;
+      Vector<Label*>& destinations);
+
+  virtual void EmitOrLink(Label* label);
+
+  virtual void Fail();
+
+  virtual Handle<Object> GetCode();
+
+  virtual void GoTo(Label* label);
+
    // Check whether a register is >= a given constant and go to a label if  
it
    // is.  Backtracks instead if the label is NULL.
-  virtual void IfRegisterGE(int reg, int comparand, Label* if_ge) = 0;
+  virtual void IfRegisterGE(int reg, int comparand, Label* if_ge);

-  enum Re2kImplementation {
-    kIA32Implementation,
-    kARMImplementation,
-    kBytecodeImplementation};
+  // Check whether a register is < a given constant and go to a label if  
it is.
+  // Backtracks instead if the label is NULL.
+  virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);

-  virtual Re2kImplementation Implementation() = 0;
-  virtual Handle<Object> GetCode() = 0;
+  virtual Re2kImplementation Implementation();
+
+  virtual void PopCurrentPosition();
+  virtual void PopRegister(int register_index);
+  virtual void PushBacktrack(Label* label);
+  virtual void PushCurrentPosition();
+  virtual void PushRegister(int register_index);
+  virtual void SetRegister(int register_index, int to);
+  virtual void Succeed();
+  virtual void WriteCurrentPositionToRegister(int reg);
   private:
+  Operand register_location(int register_index);
+  bool ignore_case();
+  // Generate code to perform case-canonicalization on the register.
+  void BranchOrBacktrack(Condition condition, Label* to);
+  void Canonicalize(Register register);
+  void Exit(bool success);
+  // Read a character from input at the given offset from the current
+  // position.
+  void ReadChar(Register destination, int offset);
+  // Read the current character into the destination register.
+  void ReadCurrentChar(Register destination);
+
+  static const int kRegExpConstantsSize = 256;
+  static const int kMaxInlineStringTests = 8;
+  static const uint32_t kEndOfInput = ~0;
+
+  MacroAssembler* masm_;
+  ByteArrayProvider constants_;
+  int num_registers_;
+  bool ignore_case_;
  };

+}}

-} }  // namespace v8::internal
-
-#endif  // V8_REGEXP_MACRO_ASSEMBLER_H_
+#endif /* REGEXP_MACRO_ASSEMBLER_IA32_H_ */

Added: branches/experimental/regexp2000/src/regexp-macro-assembler.cc
==============================================================================
--- (empty file)
+++ branches/experimental/regexp2000/src/regexp-macro-assembler.cc      Fri Nov 
 
14 02:58:30 2008
@@ -0,0 +1,62 @@
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "v8.h"
+#include "regexp-macro-assembler.h"
+
+namespace v8 { namespace internal {
+
+
+ByteArrayProvider::ByteArrayProvider(int initial_size)
+ : byte_array_size_(initial_size),
+   current_byte_array_(NULL),
+   current_byte_array_free_offset_(initial_size) {}
+
+
+template <typename T>
+ArraySlice<T> ByteArrayProvider::GetBuffer(int size) {
+  ASSERT(sze > 0);
+  size_t elem_size = sizeof(T);
+  size_t byte_size = size * elem_size;
+  int free_offset = current_byte_array_free_offset_;
+  // align elements
+  free_offset += elem_size - 1;
+  free_offset = free_offset - (free_offset % elem_size);
+
+  if (free_offset + byte_size > byte_array_size_) {
+    if (byte_size > (byte_array_size_ / 2)) {
+      Handle<ByteArray> solo_buffer = Factory::NewByteArray(byte_size,  
TENURED);
+      return ArraySlice<T>(solo_buffer, 0);
+    }
+    current_byte_array_ = Factory::NewByteArray(byte_array_size_, TENURED);
+    free_offset = 0;
+  }
+  current_byte_array_free_offset_ = free_offset + size;
+  return ArraySlice<T>(current_byte_array_, free_offset);
+}
+
+}}

Modified: branches/experimental/regexp2000/src/regexp-macro-assembler.h
==============================================================================
--- branches/experimental/regexp2000/src/regexp-macro-assembler.h       
(original)
+++ branches/experimental/regexp2000/src/regexp-macro-assembler.h       Fri Nov 
 
14 02:58:30 2008
@@ -39,7 +39,7 @@

  class RegExpMacroAssembler {
   public:
-  RegExpMacroAssembler() { }
+  RegExpMacroAssembler();
    virtual ~RegExpMacroAssembler();
    virtual void Bind(Label* label) = 0;
    virtual void EmitOrLink(Label* label) = 0;
@@ -116,9 +116,48 @@

    virtual Re2kImplementation Implementation() = 0;
    virtual Handle<Object> GetCode() = 0;
+
   private:
  };

+
+template <typename T>
+struct ArraySlice {
+public:
+  ArraySlice(Handle<ByteArray> array, size_t offset)
+    : array_(array), offset_(offset) {}
+  Handle<ByteArray> array() { return array_; }
+  // Offset in the byte array data.
+  size_t offset() { return offset_; }
+  // Offset from the ByteArray pointer.
+  size_t base_offset() {
+    return kHeaderSize - kHeapObjectTag + offset;
+  }
+  T* operator*() {
+    return reinterpret_cast<T*>(array_->GetDataStartAddress() + offset);
+  }
+  T& operator[](int idx) {
+    return reinterpret_cast<T*>(array_->getDataStartAddress() +  
offset)[idx];
+  }
+private:
+  const Handle<ByteArray> array_;
+  const size_t offset_;
+};
+
+
+class ByteArrayProvider {
+ public:
+  ByteArrayProvider(int initial_size);
+  // Provides a place to put "size" elements of type T. The information
+  // can be stored in the provided ByteArray at the "offset". The offset is
+  // aligned to an "align"-boundary
+  template <typename T>
+  ArraySlice<T> GetBuffer(int size, int align);
+ private:
+  const int byte_array_size_;
+  Handle<ByteArray> current_byte_array_;
+  int current_byte_array_free_offset_;
+};

  } }  // namespace v8::internal


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

Reply via email to