summaryrefslogtreecommitdiff
path: root/deps/v8/src/x64/regexp-macro-assembler-x64.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/x64/regexp-macro-assembler-x64.cc')
-rw-r--r--deps/v8/src/x64/regexp-macro-assembler-x64.cc142
1 files changed, 54 insertions, 88 deletions
diff --git a/deps/v8/src/x64/regexp-macro-assembler-x64.cc b/deps/v8/src/x64/regexp-macro-assembler-x64.cc
index 09cb9177a..026301b2a 100644
--- a/deps/v8/src/x64/regexp-macro-assembler-x64.cc
+++ b/deps/v8/src/x64/regexp-macro-assembler-x64.cc
@@ -71,8 +71,6 @@ namespace internal {
* through the runtime system)
* - stack_area_base (High end of the memory area to use as
* backtracking stack)
- * - at_start (if 1, we are starting at the start of the
- * string, otherwise 0)
* - int* capture_array (int[num_saved_registers_], for output).
* - end of input (Address of end of string)
* - start of input (Address of first character in string)
@@ -82,6 +80,8 @@ namespace internal {
* - backup of callee save registers (rbx, possibly rsi and rdi).
* - Offset of location before start of input (effectively character
* position -1). Used to initialize capture registers to a non-position.
+ * - At start of string (if 1, we are starting at the start of the
+ * string, otherwise 0)
* - register 0 rbp[-n] (Only positions must be stored in the first
* - register 1 rbp[-n-8] num_saved_registers_ registers)
* - ...
@@ -329,14 +329,14 @@ void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase(
ASSERT(mode_ == UC16);
// Save important/volatile registers before calling C function.
#ifndef _WIN64
- // Callee save on Win64
+ // Caller save on Linux and callee save in Windows.
__ push(rsi);
__ push(rdi);
#endif
__ push(backtrack_stackpointer());
int num_arguments = 3;
- FrameAlign(num_arguments);
+ __ PrepareCallCFunction(num_arguments);
// Put arguments into parameter registers. Parameters are
// Address byte_offset1 - Address captured substring's start.
@@ -361,7 +361,7 @@ void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase(
#endif
ExternalReference compare =
ExternalReference::re_case_insensitive_compare_uc16();
- CallCFunction(compare, num_arguments);
+ __ CallCFunction(compare, num_arguments);
// Restore original values before reacting on result value.
__ Move(code_object_pointer(), masm_->CodeObject());
@@ -582,49 +582,38 @@ bool RegExpMacroAssemblerX64::CheckSpecialCharacterClass(uc16 type,
return true;
}
case 'w': {
- Label done, check_digits;
- __ cmpl(current_character(), Immediate('9'));
- __ j(less_equal, &check_digits);
- __ cmpl(current_character(), Immediate('_'));
- __ j(equal, &done);
- // Convert to lower case if letter.
- __ movl(rax, current_character());
- __ orl(rax, Immediate(0x20));
- // check rax in range ['a'..'z'].
- __ subl(rax, Immediate('a'));
- __ cmpl(rax, Immediate('z' - 'a'));
- BranchOrBacktrack(above, on_no_match);
- __ jmp(&done);
- __ bind(&check_digits);
- // Check current character in range ['0'..'9'].
- __ cmpl(current_character(), Immediate('0'));
- BranchOrBacktrack(below, on_no_match);
- __ bind(&done);
-
+ if (mode_ != ASCII) {
+ // Table is 128 entries, so all ASCII characters can be tested.
+ __ cmpl(current_character(), Immediate('z'));
+ BranchOrBacktrack(above, on_no_match);
+ }
+ __ movq(rbx, ExternalReference::re_word_character_map());
+ ASSERT_EQ(0, word_character_map[0]); // Character '\0' is not a word char.
+ ExternalReference word_map = ExternalReference::re_word_character_map();
+ __ testb(Operand(rbx, current_character(), times_1, 0),
+ current_character());
+ BranchOrBacktrack(zero, on_no_match);
return true;
}
case 'W': {
- Label done, check_digits;
- __ cmpl(current_character(), Immediate('9'));
- __ j(less_equal, &check_digits);
- __ cmpl(current_character(), Immediate('_'));
- BranchOrBacktrack(equal, on_no_match);
- // Convert to lower case if letter.
- __ movl(rax, current_character());
- __ orl(rax, Immediate(0x20));
- // check current character in range ['a'..'z'], nondestructively.
- __ subl(rax, Immediate('a'));
- __ cmpl(rax, Immediate('z' - 'a'));
- BranchOrBacktrack(below_equal, on_no_match);
- __ jmp(&done);
- __ bind(&check_digits);
- // Check current character in range ['0'..'9'].
- __ cmpl(current_character(), Immediate('0'));
- BranchOrBacktrack(above_equal, on_no_match);
- __ bind(&done);
-
+ Label done;
+ if (mode_ != ASCII) {
+ // Table is 128 entries, so all ASCII characters can be tested.
+ __ cmpl(current_character(), Immediate('z'));
+ __ j(above, &done);
+ }
+ __ movq(rbx, ExternalReference::re_word_character_map());
+ ASSERT_EQ(0, word_character_map[0]); // Character '\0' is not a word char.
+ ExternalReference word_map = ExternalReference::re_word_character_map();
+ __ testb(Operand(rbx, current_character(), times_1, 0),
+ current_character());
+ BranchOrBacktrack(not_zero, on_no_match);
+ if (mode_ != ASCII) {
+ __ bind(&done);
+ }
return true;
}
+
case '*':
// Match any character.
return true;
@@ -645,7 +634,6 @@ void RegExpMacroAssemblerX64::Fail() {
Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
// Finalize code - write the entry point code now we know how many
// registers we need.
-
// Entry code:
__ bind(&entry_label_);
// Start new stack frame.
@@ -672,7 +660,7 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
ASSERT_EQ(kInputStart, -3 * kPointerSize);
ASSERT_EQ(kInputEnd, -4 * kPointerSize);
ASSERT_EQ(kRegisterOutput, -5 * kPointerSize);
- ASSERT_EQ(kAtStart, -6 * kPointerSize);
+ ASSERT_EQ(kStackHighEnd, -6 * kPointerSize);
__ push(rdi);
__ push(rsi);
__ push(rdx);
@@ -682,7 +670,9 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
__ push(rbx); // Callee-save
#endif
+
__ push(Immediate(0)); // Make room for "input start - 1" constant.
+ __ push(Immediate(0)); // Make room for "at start" constant.
// Check if we have space on the stack for registers.
Label stack_limit_hit;
@@ -727,6 +717,15 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
// Store this value in a local variable, for use when clearing
// position registers.
__ movq(Operand(rbp, kInputStartMinusOne), rax);
+
+ // Determine whether the start index is zero, that is at the start of the
+ // string, and store that value in a local variable.
+ __ movq(rbx, Operand(rbp, kStartIndex));
+ __ xor_(rcx, rcx); // setcc only operates on cl (lower byte of rcx).
+ __ testq(rbx, rbx);
+ __ setcc(zero, rcx); // 1 if 0 (start of string), 0 if positive.
+ __ movq(Operand(rbp, kAtStart), rcx);
+
if (num_saved_registers_ > 0) {
// Fill saved registers with initial value = start offset - 1
// Fill in stack push order, to avoid accessing across an unwritten
@@ -851,7 +850,7 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
// Call GrowStack(backtrack_stackpointer())
int num_arguments = 2;
- FrameAlign(num_arguments);
+ __ PrepareCallCFunction(num_arguments);
#ifdef _WIN64
// Microsoft passes parameters in rcx, rdx.
// First argument, backtrack stackpointer, is already in rcx.
@@ -862,7 +861,7 @@ Handle<Object> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
__ lea(rsi, Operand(rbp, kStackHighEnd)); // Second argument.
#endif
ExternalReference grow_stack = ExternalReference::re_grow_stack();
- CallCFunction(grow_stack, num_arguments);
+ __ CallCFunction(grow_stack, num_arguments);
// If return NULL, we have failed to grow the stack, and
// must exit with a stack-overflow exception.
__ testq(rax, rax);
@@ -1031,7 +1030,7 @@ void RegExpMacroAssemblerX64::CallCheckStackGuardState() {
// This function call preserves no register values. Caller should
// store anything volatile in a C call or overwritten by this function.
int num_arguments = 3;
- FrameAlign(num_arguments);
+ __ PrepareCallCFunction(num_arguments);
#ifdef _WIN64
// Second argument: Code* of self. (Do this before overwriting r8).
__ movq(rdx, code_object_pointer());
@@ -1051,7 +1050,7 @@ void RegExpMacroAssemblerX64::CallCheckStackGuardState() {
#endif
ExternalReference stack_check =
ExternalReference::re_check_stack_guard_state();
- CallCFunction(stack_check, num_arguments);
+ __ CallCFunction(stack_check, num_arguments);
}
@@ -1073,6 +1072,12 @@ int RegExpMacroAssemblerX64::CheckStackGuardState(Address* return_address,
// If not real stack overflow the stack guard was used to interrupt
// execution for another purpose.
+ // If this is a direct call from JavaScript retry the RegExp forcing the call
+ // through the runtime system. Currently the direct call cannot handle a GC.
+ if (frame_entry<int>(re_frame, kDirectCall) == 1) {
+ return RETRY;
+ }
+
// Prepare for possible GC.
HandleScope handles;
Handle<Code> code_handle(re_code);
@@ -1267,45 +1272,6 @@ void RegExpMacroAssemblerX64::CheckStackLimit() {
}
-void RegExpMacroAssemblerX64::FrameAlign(int num_arguments) {
- // TODO(lrn): Since we no longer use the system stack arbitrarily (but we do
- // use it, e.g., for SafeCall), we know the number of elements on the stack
- // since the last frame alignment. We might be able to do this simpler then.
- int frameAlignment = OS::ActivationFrameAlignment();
- ASSERT(frameAlignment != 0);
- // Make stack end at alignment and make room for num_arguments pointers
- // (on Win64 only) and the original value of rsp.
- __ movq(kScratchRegister, rsp);
- ASSERT(IsPowerOf2(frameAlignment));
-#ifdef _WIN64
- // Allocate space for parameters and old rsp.
- __ subq(rsp, Immediate((num_arguments + 1) * kPointerSize));
- __ and_(rsp, Immediate(-frameAlignment));
- __ movq(Operand(rsp, num_arguments * kPointerSize), kScratchRegister);
-#else
- // Allocate space for old rsp.
- __ subq(rsp, Immediate(kPointerSize));
- __ and_(rsp, Immediate(-frameAlignment));
- __ movq(Operand(rsp, 0), kScratchRegister);
-#endif
-}
-
-
-void RegExpMacroAssemblerX64::CallCFunction(ExternalReference function,
- int num_arguments) {
- __ movq(rax, function);
- __ call(rax);
- ASSERT(OS::ActivationFrameAlignment() != 0);
-#ifdef _WIN64
- __ movq(rsp, Operand(rsp, num_arguments * kPointerSize));
-#else
- // All arguments passed in registers.
- ASSERT(num_arguments <= 6);
- __ pop(rsp);
-#endif
-}
-
-
void RegExpMacroAssemblerX64::LoadCurrentCharacterUnchecked(int cp_offset,
int characters) {
if (mode_ == ASCII) {