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
-~----------~----~----~----~------~----~------~--~---