Commit cf78ed05 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

Don't pass the "at start" parameter to native RegExp

As the start index is already passed it is easy to calculate the "at start" boolean in generated code. Also as direct entry has been implemented this needs to be done in generated code anyway, and therefore might as well be moved to the generated code for RegExp. The "at start" value is now calcualted as a local variable on the native RegExp frame based on the value of the start index argument.

The x64 version have been tested on both Linux and 64-bit Windows Vista.

For ARM I have tested cctest/test-regexp on ARM hardware, but the rest of the tests have only been run on the ARM simulator.
Review URL: http://codereview.chromium.org/554078

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3709 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c33dfa5a
......@@ -63,8 +63,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).
* --- sp when called ---
* - link address
......@@ -76,6 +74,8 @@ namespace internal {
* - void* input_string (location of a handle containing the string)
* - Offset of location before start of input (effectively character
* position -1). Used to initialize capture registers to a non-position.
* - At start (if 1, we are starting at the start of the
* string, otherwise 0)
* - register 0 (Only positions must be stored in the first
* - register 1 num_saved_registers_ registers)
* - ...
......@@ -610,6 +610,7 @@ Handle<Object> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
// Set frame pointer just above the arguments.
__ add(frame_pointer(), sp, Operand(4 * kPointerSize));
__ push(r0); // Make room for "position - 1" constant (value is irrelevant).
__ push(r0); // Make room for "at start" constant (value is irrelevant).
// Check if we have space on the stack for registers.
Label stack_limit_hit;
......@@ -653,6 +654,15 @@ Handle<Object> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
// Store this value in a local variable, for use when clearing
// position registers.
__ str(r0, MemOperand(frame_pointer(), kInputStartMinusOne));
// Determine whether the start index is zero, that is at the start of the
// string, and store that value in a local variable.
__ ldr(r1, MemOperand(frame_pointer(), kStartIndex));
__ tst(r1, Operand(r1));
__ mov(r1, Operand(1), LeaveCC, eq);
__ mov(r1, Operand(0), LeaveCC, ne);
__ str(r1, MemOperand(frame_pointer(), kAtStart));
if (num_saved_registers_ > 0) { // Always is, if generated from a regexp.
// Fill saved registers with initial value = start offset - 1
......
......@@ -123,8 +123,7 @@ class RegExpMacroAssemblerARM: public NativeRegExpMacroAssembler {
static const int kReturnAddress = kStoredRegisters + 8 * kPointerSize;
// Stack parameters placed by caller.
static const int kRegisterOutput = kReturnAddress + kPointerSize;
static const int kAtStart = kRegisterOutput + kPointerSize;
static const int kStackHighEnd = kAtStart + kPointerSize;
static const int kStackHighEnd = kRegisterOutput + kPointerSize;
static const int kDirectCall = kStackHighEnd + kPointerSize;
// Below the frame pointer.
......@@ -136,8 +135,9 @@ class RegExpMacroAssemblerARM: public NativeRegExpMacroAssembler {
// When adding local variables remember to push space for them in
// the frame in GetCode.
static const int kInputStartMinusOne = kInputString - kPointerSize;
static const int kAtStart = kInputStartMinusOne - kPointerSize;
// First register address. Following registers are below it on the stack.
static const int kRegisterZero = kInputStartMinusOne - kPointerSize;
static const int kRegisterZero = kAtStart - kPointerSize;
// Initial size of code buffer.
static const size_t kRegExpCodeSize = 1024;
......
......@@ -63,8 +63,8 @@ class SimulatorStack : public v8::internal::AllStatic {
// Call the generated regexp code directly. The entry function pointer should
// expect eight int/pointer sized arguments and return an int.
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
entry(p0, p1, p2, p3, p4, p5, p6, p7)
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \
entry(p0, p1, p2, p3, p4, p5, p6)
#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
reinterpret_cast<TryCatch*>(try_catch_address)
......@@ -79,9 +79,9 @@ class SimulatorStack : public v8::internal::AllStatic {
assembler::arm::Simulator::current()->Call(FUNCTION_ADDR(entry), 5, \
p0, p1, p2, p3, p4))
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \
assembler::arm::Simulator::current()->Call( \
FUNCTION_ADDR(entry), 8, p0, p1, p2, p3, p4, p5, p6, p7)
FUNCTION_ADDR(entry), 7, p0, p1, p2, p3, p4, p5, p6)
#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
try_catch_address == NULL ? \
......
......@@ -8453,20 +8453,14 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// All checks done. Now push arguments for native regexp code.
__ IncrementCounter(&Counters::regexp_entry_native, 1);
// Argument 8: Indicate that this is a direct call from JavaScript.
// Argument 7: Indicate that this is a direct call from JavaScript.
__ push(Immediate(1));
// Argument 7: Start (high end) of backtracking stack memory area.
// Argument 6: Start (high end) of backtracking stack memory area.
__ mov(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_address));
__ add(ecx, Operand::StaticVariable(address_of_regexp_stack_memory_size));
__ push(ecx);
// Argument 6: At start of string?
__ xor_(Operand(ecx), ecx); // setcc only operated on cl (lower byte of ecx).
__ test(ebx, Operand(ebx));
__ setcc(zero, ecx); // 1 if 0 (start of string), 0 if positive.
__ push(ecx);
// Argument 5: static offsets vector buffer.
__ push(Immediate(ExternalReference::address_of_static_offsets_vector()));
......@@ -8501,7 +8495,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag));
__ call(Operand(edx));
// Remove arguments.
__ add(Operand(esp), Immediate(8 * kPointerSize));
__ add(Operand(esp), Immediate(7 * kPointerSize));
// Check the result.
Label success;
......
......@@ -59,8 +59,6 @@ namespace internal {
* call 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)
......@@ -74,6 +72,8 @@ namespace internal {
* - backup of caller ebx
* - Offset of location before start of input (effectively character
* position -1). Used to initialize capture registers to a non-position.
* - Boolean at start (if 1, we are starting at the start of the string,
* otherwise 0)
* - register 0 ebp[-4] (Only positions must be stored in the first
* - register 1 ebp[-8] num_saved_registers_ registers)
* - ...
......@@ -625,6 +625,7 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
__ push(edi);
__ push(ebx); // Callee-save on MacOS.
__ 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;
......@@ -667,6 +668,15 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
// Store this value in a local variable, for use when clearing
// position registers.
__ mov(Operand(ebp, kInputStartMinusOne), eax);
// Determine whether the start index is zero, that is at the start of the
// string, and store that value in a local variable.
__ mov(ebx, Operand(ebp, kStartIndex));
__ xor_(Operand(ecx), ecx); // setcc only operates on cl (lower byte of ecx).
__ test(ebx, Operand(ebx));
__ setcc(zero, ecx); // 1 if 0 (start of string), 0 if positive.
__ mov(Operand(ebp, kAtStart), ecx);
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
......
......@@ -123,8 +123,7 @@ class RegExpMacroAssemblerIA32: public NativeRegExpMacroAssembler {
static const int kInputStart = kStartIndex + kPointerSize;
static const int kInputEnd = kInputStart + kPointerSize;
static const int kRegisterOutput = kInputEnd + kPointerSize;
static const int kAtStart = kRegisterOutput + kPointerSize;
static const int kStackHighEnd = kAtStart + kPointerSize;
static const int kStackHighEnd = kRegisterOutput + kPointerSize;
static const int kDirectCall = kStackHighEnd + kPointerSize;
// Below the frame pointer - local stack variables.
// When adding local variables remember to push space for them in
......@@ -133,8 +132,9 @@ class RegExpMacroAssemblerIA32: public NativeRegExpMacroAssembler {
static const int kBackup_edi = kBackup_esi - kPointerSize;
static const int kBackup_ebx = kBackup_edi - kPointerSize;
static const int kInputStartMinusOne = kBackup_ebx - kPointerSize;
static const int kAtStart = kInputStartMinusOne - kPointerSize;
// First register address. Following registers are below it on the stack.
static const int kRegisterZero = kInputStartMinusOne - kPointerSize;
static const int kRegisterZero = kAtStart - kPointerSize;
// Initial size of code buffer.
static const size_t kRegExpCodeSize = 1024;
......
......@@ -53,8 +53,8 @@ class SimulatorStack : public v8::internal::AllStatic {
// Call the generated regexp code directly. The entry function pointer should
// expect eight int/pointer sized arguments and return an int.
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
entry(p0, p1, p2, p3, p4, p5, p6, p7)
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \
entry(p0, p1, p2, p3, p4, p5, p6)
#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
reinterpret_cast<TryCatch*>(try_catch_address)
......
......@@ -144,8 +144,7 @@ NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Match(
start_offset,
input_start,
input_end,
offsets_vector,
previous_index == 0);
offsets_vector);
return res;
}
......@@ -156,14 +155,11 @@ NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Execute(
int start_offset,
const byte* input_start,
const byte* input_end,
int* output,
bool at_start) {
int* output) {
typedef int (*matcher)(String*, int, const byte*,
const byte*, int*, int, Address, int);
const byte*, int*, Address, int);
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_base = RegExpStack::stack_base();
......@@ -175,7 +171,6 @@ NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Execute(
input_start,
input_end,
output,
at_start_val,
stack_base,
direct_call);
ASSERT(result <= SUCCESS);
......
......@@ -218,8 +218,7 @@ class NativeRegExpMacroAssembler: public RegExpMacroAssembler {
int start_offset,
const byte* input_start,
const byte* input_end,
int* output,
bool at_start);
int* output);
};
#endif // V8_NATIVE_REGEXP
......
......@@ -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)
* - ...
......@@ -661,7 +661,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);
......@@ -672,6 +672,7 @@ 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;
......@@ -716,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
......
......@@ -138,9 +138,7 @@ class RegExpMacroAssemblerX64: public NativeRegExpMacroAssembler {
static const int kInputStart = kStartIndex + kPointerSize;
static const int kInputEnd = kInputStart + kPointerSize;
static const int kRegisterOutput = kInputEnd + kPointerSize;
// AtStart is passed as 32 bit int (values 0 or 1).
static const int kAtStart = kRegisterOutput + kPointerSize;
static const int kStackHighEnd = kAtStart + kPointerSize;
static const int kStackHighEnd = kRegisterOutput + kPointerSize;
// DirectCall is passed as 32 bit int (values 0 or 1).
static const int kDirectCall = kStackHighEnd + kPointerSize;
#else
......@@ -152,9 +150,8 @@ class RegExpMacroAssemblerX64: public NativeRegExpMacroAssembler {
static const int kInputStart = kStartIndex - kPointerSize;
static const int kInputEnd = kInputStart - kPointerSize;
static const int kRegisterOutput = kInputEnd - kPointerSize;
static const int kAtStart = kRegisterOutput - kPointerSize;
static const int kStackHighEnd = kFrameAlign;
static const int kDirectCall = kStackHighEnd + kPointerSize;
static const int kStackHighEnd = kRegisterOutput - kPointerSize;
static const int kDirectCall = kFrameAlign;
#endif
#ifdef _WIN64
......@@ -168,7 +165,7 @@ class RegExpMacroAssemblerX64: public NativeRegExpMacroAssembler {
// AMD64 Calling Convention has only one callee-save register that
// we use. We push this after the frame pointer (and after the
// parameters).
static const int kBackup_rbx = kAtStart - kPointerSize;
static const int kBackup_rbx = kStackHighEnd - kPointerSize;
static const int kLastCalleeSaveRegister = kBackup_rbx;
#endif
......@@ -176,9 +173,10 @@ class RegExpMacroAssemblerX64: public NativeRegExpMacroAssembler {
// the frame in GetCode.
static const int kInputStartMinusOne =
kLastCalleeSaveRegister - kPointerSize;
static const int kAtStart = kInputStartMinusOne - kPointerSize;
// First register address. Following registers are below it on the stack.
static const int kRegisterZero = kInputStartMinusOne - kPointerSize;
static const int kRegisterZero = kAtStart - kPointerSize;
// Initial size of code buffer.
static const size_t kRegExpCodeSize = 1024;
......
......@@ -54,8 +54,8 @@ class SimulatorStack : public v8::internal::AllStatic {
// Call the generated regexp code directly. The entry function pointer should
// expect eight int/pointer sized arguments and return an int.
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
entry(p0, p1, p2, p3, p4, p5, p6, p7)
#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6) \
entry(p0, p1, p2, p3, p4, p5, p6)
#define TRY_CATCH_FROM_ADDRESS(try_catch_address) \
reinterpret_cast<TryCatch*>(try_catch_address)
......
......@@ -679,16 +679,14 @@ static ArchRegExpMacroAssembler::Result Execute(Code* code,
int start_offset,
const byte* input_start,
const byte* input_end,
int* captures,
bool at_start) {
int* captures) {
return NativeRegExpMacroAssembler::Execute(
code,
input,
start_offset,
input_start,
input_end,
captures,
at_start);
captures);
}
......@@ -716,8 +714,7 @@ TEST(MacroAssemblerNativeSuccess) {
0,
start_adr,
start_adr + seq_input->length(),
captures,
true);
captures);
CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
CHECK_EQ(-1, captures[0]);
......@@ -760,8 +757,7 @@ TEST(MacroAssemblerNativeSimple) {
0,
start_adr,
start_adr + input->length(),
captures,
true);
captures);
CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
CHECK_EQ(0, captures[0]);
......@@ -778,8 +774,7 @@ TEST(MacroAssemblerNativeSimple) {
0,
start_adr,
start_adr + input->length(),
captures,
true);
captures);
CHECK_EQ(NativeRegExpMacroAssembler::FAILURE, result);
}
......@@ -820,8 +815,7 @@ TEST(MacroAssemblerNativeSimpleUC16) {
0,
start_adr,
start_adr + input->length(),
captures,
true);
captures);
CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
CHECK_EQ(0, captures[0]);
......@@ -839,8 +833,7 @@ TEST(MacroAssemblerNativeSimpleUC16) {
0,
start_adr,
start_adr + input->length() * 2,
captures,
true);
captures);
CHECK_EQ(NativeRegExpMacroAssembler::FAILURE, result);
}
......@@ -877,8 +870,7 @@ TEST(MacroAssemblerNativeBacktrack) {
0,
start_adr,
start_adr + input->length(),
NULL,
true);
NULL);
CHECK_EQ(NativeRegExpMacroAssembler::FAILURE, result);
}
......@@ -920,8 +912,7 @@ TEST(MacroAssemblerNativeBackReferenceASCII) {
0,
start_adr,
start_adr + input->length(),
output,
true);
output);
CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
CHECK_EQ(0, output[0]);
......@@ -969,8 +960,7 @@ TEST(MacroAssemblerNativeBackReferenceUC16) {
0,
start_adr,
start_adr + input->length() * 2,
output,
true);
output);
CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
CHECK_EQ(0, output[0]);
......@@ -1022,8 +1012,7 @@ TEST(MacroAssemblernativeAtStart) {
0,
start_adr,
start_adr + input->length(),
NULL,
true);
NULL);
CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
......@@ -1032,8 +1021,7 @@ TEST(MacroAssemblernativeAtStart) {
3,
start_adr + 3,
start_adr + input->length(),
NULL,
false);
NULL);
CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
}
......@@ -1084,8 +1072,7 @@ TEST(MacroAssemblerNativeBackRefNoCase) {
0,
start_adr,
start_adr + input->length(),
output,
true);
output);
CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
CHECK_EQ(0, output[0]);
......@@ -1184,8 +1171,7 @@ TEST(MacroAssemblerNativeRegisters) {
0,
start_adr,
start_adr + input->length(),
output,
true);
output);
CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
CHECK_EQ(0, output[0]);
......@@ -1225,8 +1211,7 @@ TEST(MacroAssemblerStackOverflow) {
0,
start_adr,
start_adr + input->length(),
NULL,
true);
NULL);
CHECK_EQ(NativeRegExpMacroAssembler::EXCEPTION, result);
CHECK(Top::has_pending_exception());
......@@ -1271,8 +1256,7 @@ TEST(MacroAssemblerNativeLotsOfRegisters) {
0,
start_adr,
start_adr + input->length(),
captures,
true);
captures);
CHECK_EQ(NativeRegExpMacroAssembler::SUCCESS, result);
CHECK_EQ(0, captures[0]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment