Index: src/ia32/regexp-macro-assembler-ia32.cc |
diff --git a/src/ia32/regexp-macro-assembler-ia32.cc b/src/ia32/regexp-macro-assembler-ia32.cc |
index a49c1f510efe48304450ff1f50f9f538184b24ff..27a66bc2d89a76d841cfef0338b29fdffde72c5a 100644 |
--- a/src/ia32/regexp-macro-assembler-ia32.cc |
+++ b/src/ia32/regexp-macro-assembler-ia32.cc |
@@ -54,7 +54,7 @@ namespace internal { |
* |
* Each call to a public method should retain this convention. |
* The stack will have the following structure: |
- * - stack_area_top (High end of the memory area to use as |
+ * - stack_area_base (High end of the memory area to use as |
* backtracking stack) |
* - at_start (if 1, start at start of string, if 0, don't) |
* - int* capture_array (int[num_saved_registers_], for output). |
@@ -78,13 +78,13 @@ namespace internal { |
* character of the string). The remaining registers starts out as garbage. |
* |
* The data up to the return address must be placed there by the calling |
- * code, e.g., by calling the code entry as cast to: |
+ * code, by calling the code entry as cast to a function with the signature: |
* int (*match)(String* input_string, |
* Address start, |
* Address end, |
* int* capture_output_array, |
* bool at_start, |
- * byte* stack_area_top) |
+ * byte* stack_area_base) |
*/ |
#define __ ACCESS_MASM(masm_) |
@@ -93,7 +93,6 @@ RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32( |
Mode mode, |
int registers_to_save) |
: masm_(new MacroAssembler(NULL, kRegExpCodeSize)), |
- constants_(kRegExpConstantsSize), |
mode_(mode), |
num_registers_(registers_to_save), |
num_saved_registers_(registers_to_save), |
@@ -156,13 +155,6 @@ void RegExpMacroAssemblerIA32::Bind(Label* label) { |
} |
-void RegExpMacroAssemblerIA32::CheckBitmap(uc16 start, |
- Label* bitmap, |
- Label* on_zero) { |
- UNIMPLEMENTED(); |
-} |
- |
- |
void RegExpMacroAssemblerIA32::CheckCharacter(uint32_t c, Label* on_equal) { |
__ cmp(current_character(), c); |
BranchOrBacktrack(equal, on_equal); |
@@ -217,15 +209,9 @@ void RegExpMacroAssemblerIA32::CheckCharacters(Vector<const uc16> str, |
BranchOrBacktrack(greater, on_failure); |
} |
- 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; |
+ // Instead of inlining a backtrack, (re)use the global backtrack target. |
+ on_failure = &backtrack_label_; |
} |
for (int i = 0; i < str.length(); i++) { |
@@ -581,34 +567,6 @@ bool RegExpMacroAssemblerIA32::CheckSpecialCharacterClass(uc16 type, |
} |
} |
-void RegExpMacroAssemblerIA32::DispatchHalfNibbleMap( |
- uc16 start, |
- Label* half_nibble_map, |
- const Vector<Label*>& destinations) { |
- UNIMPLEMENTED(); |
-} |
- |
- |
-void RegExpMacroAssemblerIA32::DispatchByteMap( |
- uc16 start, |
- Label* byte_map, |
- const Vector<Label*>& destinations) { |
- UNIMPLEMENTED(); |
-} |
- |
- |
-void RegExpMacroAssemblerIA32::DispatchHighByteMap( |
- byte start, |
- Label* byte_map, |
- const Vector<Label*>& destinations) { |
- UNIMPLEMENTED(); |
-} |
- |
- |
-void RegExpMacroAssemblerIA32::EmitOrLink(Label* label) { |
- UNIMPLEMENTED(); // Has no use. |
-} |
- |
void RegExpMacroAssemblerIA32::Fail() { |
ASSERT(FAILURE == 0); // Return value for failure is zero. |
@@ -668,17 +626,17 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { |
__ mov(edi, Operand(ebp, kInputStart)); |
// Set up edi to be negative offset from string end. |
__ sub(edi, Operand(esi)); |
- if (num_saved_registers_ > 0) { |
+ // Set eax to address of char before start of input |
+ // (effectively string position -1). |
+ __ lea(eax, Operand(edi, -char_size())); |
+ // Store this value in a local variable, for use when clearing |
+ // position registers. |
+ __ mov(Operand(ebp, kInputStartMinusOne), eax); |
+ if (num_saved_registers_ > 0) { // Always is, if generated from a regexp. |
// Fill saved registers with initial value = start offset - 1 |
// Fill in stack push order, to avoid accessing across an unwritten |
// page (a problem on Windows). |
__ mov(ecx, kRegisterZero); |
- // Set eax to address of char before start of input |
- // (effectively string position -1). |
- __ lea(eax, Operand(edi, -char_size())); |
- // Store this value in a local variable, for use when clearing |
- // position registers. |
- __ mov(Operand(ebp, kInputStartMinusOne), eax); |
Label init_loop; |
__ bind(&init_loop); |
__ mov(Operand(ebp, ecx, times_1, +0), eax); |
@@ -942,139 +900,8 @@ void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) { |
} |
-RegExpMacroAssemblerIA32::Result RegExpMacroAssemblerIA32::Match( |
- Handle<Code> regexp_code, |
- Handle<String> subject, |
- int* offsets_vector, |
- int offsets_vector_length, |
- int previous_index) { |
- |
- ASSERT(subject->IsFlat()); |
- ASSERT(previous_index >= 0); |
- ASSERT(previous_index <= subject->length()); |
- |
- // No allocations before calling the regexp, but we can't use |
- // AssertNoAllocation, since regexps might be preempted, and another thread |
- // might do allocation anyway. |
- |
- String* subject_ptr = *subject; |
- // Character offsets into string. |
- int start_offset = previous_index; |
- int end_offset = subject_ptr->length(); |
- |
- bool is_ascii = subject->IsAsciiRepresentation(); |
- |
- if (StringShape(subject_ptr).IsCons()) { |
- subject_ptr = ConsString::cast(subject_ptr)->first(); |
- } else if (StringShape(subject_ptr).IsSliced()) { |
- SlicedString* slice = SlicedString::cast(subject_ptr); |
- start_offset += slice->start(); |
- end_offset += slice->start(); |
- subject_ptr = slice->buffer(); |
- } |
- // Ensure that an underlying string has the same ascii-ness. |
- ASSERT(subject_ptr->IsAsciiRepresentation() == is_ascii); |
- ASSERT(subject_ptr->IsExternalString() || subject_ptr->IsSeqString()); |
- // String is now either Sequential or External |
- int char_size_shift = is_ascii ? 0 : 1; |
- int char_length = end_offset - start_offset; |
- |
- const byte* input_start = |
- StringCharacterPosition(subject_ptr, start_offset); |
- int byte_length = char_length << char_size_shift; |
- const byte* input_end = input_start + byte_length; |
- RegExpMacroAssemblerIA32::Result res = Execute(*regexp_code, |
- subject_ptr, |
- start_offset, |
- input_start, |
- input_end, |
- offsets_vector, |
- previous_index == 0); |
- |
- if (res == SUCCESS) { |
- // Capture values are relative to start_offset only. |
- // Convert them to be relative to start of string. |
- for (int i = 0; i < offsets_vector_length; i++) { |
- if (offsets_vector[i] >= 0) { |
- offsets_vector[i] += previous_index; |
- } |
- } |
- } |
- |
- return res; |
-} |
- |
// Private methods: |
-static unibrow::Mapping<unibrow::Ecma262Canonicalize> canonicalize; |
- |
-RegExpMacroAssemblerIA32::Result RegExpMacroAssemblerIA32::Execute( |
- Code* code, |
- String* input, |
- int start_offset, |
- const byte* input_start, |
- const byte* input_end, |
- int* output, |
- bool at_start) { |
- typedef int (*matcher)(String*, int, const byte*, |
- const byte*, int*, int, Address); |
- matcher matcher_func = FUNCTION_CAST<matcher>(code->entry()); |
- |
- int at_start_val = at_start ? 1 : 0; |
- |
- // Ensure that the minimum stack has been allocated. |
- RegExpStack stack; |
- Address stack_top = RegExpStack::stack_top(); |
- |
- int result = matcher_func(input, |
- start_offset, |
- input_start, |
- input_end, |
- output, |
- at_start_val, |
- stack_top); |
- ASSERT(result <= SUCCESS); |
- ASSERT(result >= RETRY); |
- |
- if (result == EXCEPTION && !Top::has_pending_exception()) { |
- // We detected a stack overflow (on the backtrack stack) in RegExp code, |
- // but haven't created the exception yet. |
- Top::StackOverflow(); |
- } |
- return static_cast<Result>(result); |
-} |
- |
- |
-int RegExpMacroAssemblerIA32::CaseInsensitiveCompareUC16(Address byte_offset1, |
- Address byte_offset2, |
- size_t byte_length) { |
- // This function is not allowed to cause a garbage collection. |
- // A GC might move the calling generated code and invalidate the |
- // return address on the stack. |
- ASSERT(byte_length % 2 == 0); |
- uc16* substring1 = reinterpret_cast<uc16*>(byte_offset1); |
- uc16* substring2 = reinterpret_cast<uc16*>(byte_offset2); |
- size_t length = byte_length >> 1; |
- |
- for (size_t i = 0; i < length; i++) { |
- unibrow::uchar c1 = substring1[i]; |
- unibrow::uchar c2 = substring2[i]; |
- if (c1 != c2) { |
- unibrow::uchar s1[1] = { c1 }; |
- canonicalize.get(c1, '\0', s1); |
- if (s1[0] != c2) { |
- unibrow::uchar s2[1] = { c2 }; |
- canonicalize.get(c2, '\0', s2); |
- if (s1[0] != s2[0]) { |
- return 0; |
- } |
- } |
- } |
- } |
- return 1; |
-} |
- |
- |
void RegExpMacroAssemblerIA32::CallCheckStackGuardState(Register scratch) { |
int num_arguments = 3; |
FrameAlign(num_arguments, scratch); |
@@ -1096,35 +923,6 @@ static T& frame_entry(Address re_frame, int frame_offset) { |
} |
-const byte* RegExpMacroAssemblerIA32::StringCharacterPosition(String* subject, |
- int start_index) { |
- // Not just flat, but ultra flat. |
- ASSERT(subject->IsExternalString() || subject->IsSeqString()); |
- ASSERT(start_index >= 0); |
- ASSERT(start_index <= subject->length()); |
- if (subject->IsAsciiRepresentation()) { |
- const byte* address; |
- if (StringShape(subject).IsExternal()) { |
- const char* data = ExternalAsciiString::cast(subject)->resource()->data(); |
- address = reinterpret_cast<const byte*>(data); |
- } else { |
- ASSERT(subject->IsSeqAsciiString()); |
- char* data = SeqAsciiString::cast(subject)->GetChars(); |
- address = reinterpret_cast<const byte*>(data); |
- } |
- return address + start_index; |
- } |
- const uc16* data; |
- if (StringShape(subject).IsExternal()) { |
- data = ExternalTwoByteString::cast(subject)->resource()->data(); |
- } else { |
- ASSERT(subject->IsSeqTwoByteString()); |
- data = SeqTwoByteString::cast(subject)->GetChars(); |
- } |
- return reinterpret_cast<const byte*>(data + start_index); |
-} |
- |
- |
int RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address, |
Code* re_code, |
Address re_frame) { |
@@ -1198,18 +996,18 @@ int RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address, |
Address RegExpMacroAssemblerIA32::GrowStack(Address stack_pointer, |
- Address* stack_top) { |
+ Address* stack_base) { |
size_t size = RegExpStack::stack_capacity(); |
- Address old_stack_top = RegExpStack::stack_top(); |
- ASSERT(old_stack_top == *stack_top); |
- ASSERT(stack_pointer <= old_stack_top); |
- ASSERT(static_cast<size_t>(old_stack_top - stack_pointer) <= size); |
- Address new_stack_top = RegExpStack::EnsureCapacity(size * 2); |
- if (new_stack_top == NULL) { |
+ Address old_stack_base = RegExpStack::stack_base(); |
+ ASSERT(old_stack_base == *stack_base); |
+ ASSERT(stack_pointer <= old_stack_base); |
+ ASSERT(static_cast<size_t>(old_stack_base - stack_pointer) <= size); |
+ Address new_stack_base = RegExpStack::EnsureCapacity(size * 2); |
+ if (new_stack_base == NULL) { |
return NULL; |
} |
- *stack_top = new_stack_top; |
- return new_stack_top - (old_stack_top - stack_pointer); |
+ *stack_base = new_stack_base; |
+ return new_stack_base - (old_stack_base - stack_pointer); |
} |
@@ -1373,11 +1171,5 @@ void RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(int cp_offset, |
} |
-void RegExpMacroAssemblerIA32::LoadConstantBufferAddress(Register reg, |
- ArraySlice* buffer) { |
- __ mov(reg, buffer->array()); |
- __ add(Operand(reg), Immediate(buffer->base_offset())); |
-} |
- |
#undef __ |
}} // namespace v8::internal |