| Index: src/x64/code-stubs-x64.cc
|
| diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
|
| index 3a1edf4c5e848df960b974bf7df26e70122ad131..fc080f4c4cc2fc63abbf122d7d4f4e23b903892d 100644
|
| --- a/src/x64/code-stubs-x64.cc
|
| +++ b/src/x64/code-stubs-x64.cc
|
| @@ -350,6 +350,85 @@
|
| __ ret(0);
|
| }
|
|
|
| +void RegExpExecStub::Generate(MacroAssembler* masm) {
|
| +#ifdef V8_INTERPRETED_REGEXP
|
| + // This case is handled prior to the RegExpExecStub call.
|
| + __ Abort(kUnexpectedRegExpExecCall);
|
| +#else // V8_INTERPRETED_REGEXP
|
| + // Isolates: note we add an additional parameter here (isolate pointer).
|
| + static const int kRegExpExecuteArguments = 9;
|
| + int argument_slots_on_stack =
|
| + masm->ArgumentStackSlotsForCFunctionCall(kRegExpExecuteArguments);
|
| + __ EnterApiExitFrame(argument_slots_on_stack);
|
| +
|
| + // Argument 9: Pass current isolate address.
|
| + __ LoadAddress(kScratchRegister,
|
| + ExternalReference::isolate_address(isolate()));
|
| + __ movq(Operand(rsp, (argument_slots_on_stack - 1) * kRegisterSize),
|
| + kScratchRegister);
|
| +
|
| + // Argument 8: Indicate that this is a direct call from JavaScript.
|
| + __ movq(Operand(rsp, (argument_slots_on_stack - 2) * kRegisterSize),
|
| + Immediate(1));
|
| +
|
| + // Argument 7: Start (high end) of backtracking stack memory area.
|
| + ExternalReference address_of_regexp_stack_memory_address =
|
| + ExternalReference::address_of_regexp_stack_memory_address(isolate());
|
| + ExternalReference address_of_regexp_stack_memory_size =
|
| + ExternalReference::address_of_regexp_stack_memory_size(isolate());
|
| + __ Move(kScratchRegister, address_of_regexp_stack_memory_address);
|
| + __ movp(r12, Operand(kScratchRegister, 0));
|
| + __ Move(kScratchRegister, address_of_regexp_stack_memory_size);
|
| + __ addp(r12, Operand(kScratchRegister, 0));
|
| + __ movq(Operand(rsp, (argument_slots_on_stack - 3) * kRegisterSize), r12);
|
| +
|
| + // Argument 6: Set the number of capture registers to zero to force global
|
| + // regexps to behave as non-global. This does not affect non-global regexps.
|
| + // Argument 6 is passed in r9 on Linux and on the stack on Windows.
|
| +#ifdef _WIN64
|
| + __ movq(Operand(rsp, (argument_slots_on_stack - 4) * kRegisterSize),
|
| + Immediate(0));
|
| +#else
|
| + __ Set(r9, 0);
|
| +#endif
|
| +
|
| + // Argument 5: static offsets vector buffer.
|
| + // Argument 5 passed in r8 on Linux and on the stack on Windows.
|
| +#ifdef _WIN64
|
| + __ LoadAddress(
|
| + r12, ExternalReference::address_of_static_offsets_vector(isolate()));
|
| + __ movq(Operand(rsp, (argument_slots_on_stack - 5) * kRegisterSize), r12);
|
| +#else // _WIN64
|
| + __ LoadAddress(
|
| + r8, ExternalReference::address_of_static_offsets_vector(isolate()));
|
| +#endif
|
| +
|
| + // Argument 2: Previous index.
|
| + // TODO(jgruber): Ideally, LastIndexRegister would already equal arg_reg_2,
|
| + // but that makes register allocation fail.
|
| + __ movp(arg_reg_2, RegExpExecDescriptor::LastIndexRegister());
|
| +
|
| + // Argument 4: End of string data
|
| + // Argument 3: Start of string data
|
| + CHECK(arg_reg_4.is(RegExpExecDescriptor::StringEndRegister()));
|
| + CHECK(arg_reg_3.is(RegExpExecDescriptor::StringStartRegister()));
|
| +
|
| + // Argument 1: Original subject string.
|
| + CHECK(arg_reg_1.is(RegExpExecDescriptor::StringRegister()));
|
| +
|
| + __ addp(RegExpExecDescriptor::CodeRegister(),
|
| + Immediate(Code::kHeaderSize - kHeapObjectTag));
|
| + __ call(RegExpExecDescriptor::CodeRegister());
|
| +
|
| + __ LeaveApiExitFrame(true);
|
| +
|
| + // TODO(jgruber): Don't tag return value once this is supported by stubs.
|
| + __ Integer32ToSmi(rax, rax);
|
| + __ ret(0 * kPointerSize);
|
| +#endif // V8_INTERPRETED_REGEXP
|
| +}
|
| +
|
| +
|
| static int NegativeComparisonResult(Condition cc) {
|
| DCHECK(cc != equal);
|
| DCHECK((cc == less) || (cc == less_equal)
|
|
|