Commit 74f2497e authored by jgruber's avatar jgruber Committed by Commit bot

[regexp] Remove remainder of native RegExpExecStub

If we avoid throwing a stack overflow exception from Irregexp code during
direct calls, there is no need to construct exit frames before the Irregexp
call anymore. As that was the last remaining blocker, we can now implement the
entire stub in CSA.

BUG=v8:5339

Review-Url: https://codereview.chromium.org/2752143003
Cr-Commit-Position: refs/heads/master@{#44770}
parent 28157965
......@@ -1145,75 +1145,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ ldm(ia_w, sp, kCalleeSaved | pc.bit());
}
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).
const int kRegExpExecuteArguments = 9;
const int kParameterRegisters = 4;
__ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters);
// Stack pointer now points to cell where return address is to be written.
// Arguments are before that on the stack or in registers.
// Argument 9 (sp[20]): Pass current isolate address.
__ mov(r5, Operand(ExternalReference::isolate_address(isolate())));
__ str(r5, MemOperand(sp, 5 * kPointerSize));
// Argument 8 (sp[16]): Indicate that this is a direct call from JavaScript.
__ mov(r5, Operand(1));
__ str(r5, MemOperand(sp, 4 * kPointerSize));
// Argument 7 (sp[12]): 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());
__ mov(r5, Operand(address_of_regexp_stack_memory_address));
__ ldr(r5, MemOperand(r5, 0));
__ mov(r6, Operand(address_of_regexp_stack_memory_size));
__ ldr(r6, MemOperand(r6, 0));
__ add(r5, r5, Operand(r6));
__ str(r5, MemOperand(sp, 3 * kPointerSize));
// 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.
__ mov(r5, Operand::Zero());
__ str(r5, MemOperand(sp, 2 * kPointerSize));
// Argument 5 (sp[4]): static offsets vector buffer.
__ mov(
r5,
Operand(ExternalReference::address_of_static_offsets_vector(isolate())));
__ str(r5, MemOperand(sp, 1 * kPointerSize));
// Argument 4: End of string data
// Argument 3: Start of string data
CHECK(r3.is(RegExpExecDescriptor::StringEndRegister()));
CHECK(r2.is(RegExpExecDescriptor::StringStartRegister()));
// Argument 2 (r1): Previous index.
CHECK(r1.is(RegExpExecDescriptor::LastIndexRegister()));
// Argument 1 (r0): Subject string.
CHECK(r0.is(RegExpExecDescriptor::StringRegister()));
// Locate the code entry and call it.
Register code_reg = RegExpExecDescriptor::CodeRegister();
__ add(code_reg, code_reg, Operand(Code::kHeaderSize - kHeapObjectTag));
DirectCEntryStub stub(isolate());
stub.GenerateCall(masm, code_reg);
__ LeaveExitFrame(false, no_reg, true);
__ SmiTag(r0);
__ Ret();
#endif // V8_INTERPRETED_REGEXP
}
static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) {
// r0 : number of arguments to the construct function
// r1 : the function to call
......
......@@ -58,11 +58,6 @@ const Register MathPowIntegerDescriptor::exponent() {
return MathPowTaggedDescriptor::exponent();
}
const Register RegExpExecDescriptor::StringRegister() { return r0; }
const Register RegExpExecDescriptor::LastIndexRegister() { return r1; }
const Register RegExpExecDescriptor::StringStartRegister() { return r2; }
const Register RegExpExecDescriptor::StringEndRegister() { return r3; }
const Register RegExpExecDescriptor::CodeRegister() { return r4; }
const Register GrowArrayElementsDescriptor::ObjectRegister() { return r0; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return r3; }
......
......@@ -27,18 +27,14 @@ namespace internal {
#define CALL_GENERATED_CODE(isolate, entry, p0, p1, p2, p3, p4) \
(entry(p0, p1, p2, p3, p4))
typedef int (*arm_regexp_matcher)(String*, int, const byte*, const byte*,
void*, int*, int, Address, int, Isolate*);
typedef int (*arm_regexp_matcher)(String*, int, const byte*, const byte*, int*,
int, Address, int, Isolate*);
// Call the generated regexp code directly. The code at the entry address
// should act as a function matching the type arm_regexp_matcher.
// The fifth argument is a dummy that reserves the space used for
// the return address added by the ExitFrame in native calls.
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
(FUNCTION_CAST<arm_regexp_matcher>(entry)(p0, p1, p2, p3, NULL, p4, p5, p6, \
p7, p8))
(FUNCTION_CAST<arm_regexp_matcher>(entry)(p0, p1, p2, p3, p4, p5, p6, p7, p8))
// The stack limit beyond which we will throw stack overflow errors in
// generated code. Because generated code on arm uses the C stack, we
......@@ -549,9 +545,8 @@ class Simulator {
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
Simulator::current(isolate) \
->Call(entry, 10, p0, p1, p2, p3, NULL, p4, p5, p6, p7, p8)
Simulator::current(isolate)->Call(entry, 9, p0, p1, p2, p3, p4, p5, p6, p7, \
p8)
// The simulator has its own stack. Thus it has a different stack limit from
// the C-based native code. The JS-based limit normally points near the end of
......
......@@ -1267,73 +1267,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ Ret();
}
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).
__ EnterExitFrame(false, x10, 1);
DCHECK(csp.Is(__ StackPointer()));
// We have 9 arguments to pass to the regexp code, therefore we have to pass
// one on the stack and the rest as registers.
// Note that the placement of the argument on the stack isn't standard
// AAPCS64:
// csp[0]: Space for the return address placed by DirectCEntryStub.
// csp[8]: Argument 9, the current isolate address.
__ Mov(x10, ExternalReference::isolate_address(isolate()));
__ Poke(x10, kPointerSize);
// Argument 1 (x0): Subject string.
CHECK(x0.is(RegExpExecDescriptor::StringRegister()));
// Argument 2 (x1): Previous index, already there.
CHECK(x1.is(RegExpExecDescriptor::LastIndexRegister()));
// Argument 3 (x2): Input start.
// Argument 4 (x3): Input end.
CHECK(x2.is(RegExpExecDescriptor::StringStartRegister()));
CHECK(x3.is(RegExpExecDescriptor::StringEndRegister()));
// Argument 5 (x4): static offsets vector buffer.
__ Mov(x4, ExternalReference::address_of_static_offsets_vector(isolate()));
// Argument 6 (x5): Set the number of capture registers to zero to force
// global regexps to behave as non-global. This stub is not used for global
// regexps.
__ Mov(x5, 0);
// Argument 7 (x6): 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());
__ Mov(x10, address_of_regexp_stack_memory_address);
__ Ldr(x10, MemOperand(x10));
__ Mov(x11, address_of_regexp_stack_memory_size);
__ Ldr(x11, MemOperand(x11));
__ Add(x6, x10, x11);
// Argument 8 (x7): Indicate that this is a direct call from JavaScript.
__ Mov(x7, 1);
// Locate the code entry and call it.
Register code_object = RegExpExecDescriptor::CodeRegister();
__ Add(code_object, code_object, Code::kHeaderSize - kHeapObjectTag);
DirectCEntryStub stub(isolate());
stub.GenerateCall(masm, code_object);
__ LeaveExitFrame(false, x10, true);
// Return the smi-tagged result.
__ SmiTag(x0);
__ Ret();
#endif
}
static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub,
Register argc, Register function,
......
......@@ -57,11 +57,6 @@ const Register MathPowTaggedDescriptor::exponent() { return x11; }
const Register MathPowIntegerDescriptor::exponent() { return x12; }
const Register RegExpExecDescriptor::StringRegister() { return x0; }
const Register RegExpExecDescriptor::LastIndexRegister() { return x1; }
const Register RegExpExecDescriptor::StringStartRegister() { return x2; }
const Register RegExpExecDescriptor::StringEndRegister() { return x3; }
const Register RegExpExecDescriptor::CodeRegister() { return x8; }
const Register GrowArrayElementsDescriptor::ObjectRegister() { return x0; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return x3; }
......
......@@ -208,7 +208,6 @@ int64_t Simulator::CallRegExp(byte* entry,
int64_t output_size,
Address stack_base,
int64_t direct_call,
void* return_address,
Isolate* isolate) {
CallArgument args[] = {
CallArgument(input),
......@@ -219,7 +218,6 @@ int64_t Simulator::CallRegExp(byte* entry,
CallArgument(output_size),
CallArgument(stack_base),
CallArgument(direct_call),
CallArgument(return_address),
CallArgument(isolate),
CallArgument::End()
};
......
......@@ -41,12 +41,10 @@ typedef int (*arm64_regexp_matcher)(String* input,
// Call the generated regexp code directly. The code at the entry address
// should act as a function matching the type arm64_regexp_matcher.
// The ninth argument is a dummy that reserves the space used for
// the return address added by the ExitFrame in native calls.
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
(FUNCTION_CAST<arm64_regexp_matcher>(entry)(p0, p1, p2, p3, p4, p5, p6, p7, \
NULL, p8))
p8))
// Running without a simulator there is nothing to do.
class SimulatorStack : public v8::internal::AllStatic {
......@@ -201,7 +199,6 @@ class Simulator : public DecoderVisitor {
int64_t output_size,
Address stack_base,
int64_t direct_call,
void* return_address,
Isolate* isolate);
// A wrapper class that stores an argument for one of the above Call
......@@ -973,8 +970,7 @@ class Simulator : public DecoderVisitor {
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
static_cast<int>(Simulator::current(isolate)->CallRegExp( \
entry, p0, p1, p2, p3, p4, p5, p6, p7, NULL, p8))
entry, p0, p1, p2, p3, p4, p5, p6, p7, p8))
// The simulator has its own stack. Thus it has a different stack limit from
// the C-based native code. The JS-based limit normally points near the end of
......
......@@ -234,7 +234,6 @@ namespace internal {
V(kUnexpectedStringType, "Unexpected string type") \
V(kUnexpectedTestTypeofLiteralFlag, \
"Unexpected literal flag for TestTypeof bytecode") \
V(kUnexpectedRegExpExecCall, "Unexpected call to the RegExpExecStub") \
V(kUnexpectedValue, "Unexpected value") \
V(kUnsupportedDoubleImmediate, "Unsupported double immediate") \
V(kUnsupportedLetCompoundAssignment, "Unsupported let compound assignment") \
......
......@@ -231,11 +231,11 @@ void RegExpBuiltinsAssembler::GetStringPointers(
var_string_end->Bind(IntPtrAdd(string_data, to_offset));
}
Node* RegExpBuiltinsAssembler::IrregexpExec(Node* const context,
Node* const regexp,
Node* const string,
Node* const last_index,
Node* const match_info) {
Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
Node* const regexp,
Node* const string,
Node* const last_index,
Node* const match_info) {
// Just jump directly to runtime if native RegExp is not selected at compile
// time or if regexp entry in generated code is turned off runtime switch or
// at compilation.
......@@ -260,12 +260,14 @@ Node* RegExpBuiltinsAssembler::IrregexpExec(Node* const context,
Label out(this), runtime(this, Label::kDeferred);
// External constants.
Node* const isolate_address =
ExternalConstant(ExternalReference::isolate_address(isolate()));
Node* const regexp_stack_memory_address_address = ExternalConstant(
ExternalReference::address_of_regexp_stack_memory_address(isolate()));
Node* const regexp_stack_memory_size_address = ExternalConstant(
ExternalReference::address_of_regexp_stack_memory_size(isolate()));
Node* const static_offsets_vector_address = ExternalConstant(
ExternalReference::address_of_static_offsets_vector(isolate()));
Node* const pending_exception_address = ExternalConstant(
ExternalReference(Isolate::kPendingExceptionAddress, isolate()));
// Ensure that a RegExp stack is allocated.
{
......@@ -361,22 +363,85 @@ Node* RegExpBuiltinsAssembler::IrregexpExec(Node* const context,
{
IncrementCounter(isolate()->counters()->regexp_entry_native(), 1);
Callable exec_callable = CodeFactory::RegExpExec(isolate());
Node* const result = CallStub(
exec_callable, context, string, TruncateWordToWord32(int_last_index),
var_string_start.value(), var_string_end.value(), code);
// Set up args for the final call into generated Irregexp code.
MachineType type_int32 = MachineType::Int32();
MachineType type_tagged = MachineType::AnyTagged();
MachineType type_ptr = MachineType::Pointer();
// Result: A NativeRegExpMacroAssembler::Result return code.
MachineType retval_type = type_int32;
// Argument 0: Original subject string.
MachineType arg0_type = type_tagged;
Node* const arg0 = string;
// Argument 1: Previous index.
MachineType arg1_type = type_int32;
Node* const arg1 = TruncateWordToWord32(int_last_index);
// Argument 2: Start of string data.
MachineType arg2_type = type_ptr;
Node* const arg2 = var_string_start.value();
// Argument 3: End of string data.
MachineType arg3_type = type_ptr;
Node* const arg3 = var_string_end.value();
// Argument 4: static offsets vector buffer.
MachineType arg4_type = type_ptr;
Node* const arg4 = static_offsets_vector_address;
// Argument 5: Set the number of capture registers to zero to force global
// regexps to behave as non-global. This does not affect non-global
// regexps.
MachineType arg5_type = type_int32;
Node* const arg5 = Int32Constant(0);
// Argument 6: Start (high end) of backtracking stack memory area.
Node* const stack_start =
Load(MachineType::Pointer(), regexp_stack_memory_address_address);
Node* const stack_size =
Load(MachineType::IntPtr(), regexp_stack_memory_size_address);
Node* const stack_end = IntPtrAdd(stack_start, stack_size);
MachineType arg6_type = type_ptr;
Node* const arg6 = stack_end;
// Argument 7: Indicate that this is a direct call from JavaScript.
MachineType arg7_type = type_int32;
Node* const arg7 = Int32Constant(1);
// Argument 8: Pass current isolate address.
MachineType arg8_type = type_ptr;
Node* const arg8 = isolate_address;
Node* const code_entry =
IntPtrAdd(BitcastTaggedToWord(code),
IntPtrConstant(Code::kHeaderSize - kHeapObjectTag));
Node* const result = CallCFunction9(
retval_type, arg0_type, arg1_type, arg2_type, arg3_type, arg4_type,
arg5_type, arg6_type, arg7_type, arg8_type, code_entry, arg0, arg1,
arg2, arg3, arg4, arg5, arg6, arg7, arg8);
// Check the result.
// We expect exactly one result since the stub forces the called regexp to
// behave as non-global.
GotoIf(SmiEqual(result, SmiConstant(1)), &if_success);
GotoIf(SmiEqual(result, SmiConstant(NativeRegExpMacroAssembler::FAILURE)),
// We expect exactly one result since we force the called regexp to behave
// as non-global.
Node* const int_result = ChangeInt32ToIntPtr(result);
GotoIf(IntPtrEqual(int_result,
IntPtrConstant(NativeRegExpMacroAssembler::SUCCESS)),
&if_success);
GotoIf(IntPtrEqual(int_result,
IntPtrConstant(NativeRegExpMacroAssembler::FAILURE)),
&if_failure);
GotoIf(SmiEqual(result, SmiConstant(NativeRegExpMacroAssembler::EXCEPTION)),
GotoIf(IntPtrEqual(int_result,
IntPtrConstant(NativeRegExpMacroAssembler::EXCEPTION)),
&if_exception);
CSA_ASSERT(
this, SmiEqual(result, SmiConstant(NativeRegExpMacroAssembler::RETRY)));
CSA_ASSERT(this,
IntPtrEqual(int_result,
IntPtrConstant(NativeRegExpMacroAssembler::RETRY)));
Goto(&runtime);
}
......@@ -440,22 +505,15 @@ Node* RegExpBuiltinsAssembler::IrregexpExec(Node* const context,
BIND(&if_exception);
{
Node* const pending_exception =
Load(MachineType::AnyTagged(), pending_exception_address);
// If there is no pending exception, a
// stack overflow (on the backtrack stack) was detected in RegExp code.
Label stack_overflow(this), rethrow(this);
Branch(IsTheHole(pending_exception), &stack_overflow, &rethrow);
BIND(&stack_overflow);
// A stack overflow was detected in RegExp code.
#ifdef DEBUG
Node* const pending_exception_address = ExternalConstant(
ExternalReference(Isolate::kPendingExceptionAddress, isolate()));
CSA_ASSERT(this, IsTheHole(Load(MachineType::AnyTagged(),
pending_exception_address)));
#endif // DEBUG
CallRuntime(Runtime::kThrowStackOverflow, context);
Unreachable();
BIND(&rethrow);
CallRuntime(Runtime::kRegExpExecReThrow, context);
Unreachable();
}
BIND(&runtime);
......@@ -571,8 +629,8 @@ Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult(
native_context, Context::REGEXP_LAST_MATCH_INFO_INDEX);
// Call the exec stub.
match_indices = IrregexpExec(context, regexp, string, var_lastindex.value(),
last_match_info);
match_indices = RegExpExecInternal(context, regexp, string,
var_lastindex.value(), last_match_info);
var_result.Bind(match_indices);
// {match_indices} is either null or the RegExpMatchInfo array.
......@@ -2104,8 +2162,8 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(Node* const context,
Node* const last_match_info = LoadContextElement(
native_context, Context::REGEXP_LAST_MATCH_INFO_INDEX);
Node* const match_indices =
IrregexpExec(context, regexp, string, smi_zero, last_match_info);
Node* const match_indices = RegExpExecInternal(context, regexp, string,
smi_zero, last_match_info);
Label return_singleton_array(this);
Branch(WordEqual(match_indices, null), &return_singleton_array,
......@@ -2166,8 +2224,8 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(Node* const context,
Node* const last_match_info = LoadContextElement(
native_context, Context::REGEXP_LAST_MATCH_INFO_INDEX);
Node* const match_indices = IrregexpExec(context, regexp, string,
next_search_from, last_match_info);
Node* const match_indices = RegExpExecInternal(
context, regexp, string, next_search_from, last_match_info);
// We're done if no match was found.
{
......@@ -2848,8 +2906,8 @@ TF_BUILTIN(RegExpInternalMatch, RegExpBuiltinsAssembler) {
Node* const internal_match_info = LoadContextElement(
native_context, Context::REGEXP_INTERNAL_MATCH_INFO_INDEX);
Node* const match_indices =
IrregexpExec(context, regexp, string, smi_zero, internal_match_info);
Node* const match_indices = RegExpExecInternal(context, regexp, string,
smi_zero, internal_match_info);
Label if_matched(this), if_didnotmatch(this);
Branch(WordEqual(match_indices, null), &if_didnotmatch, &if_matched);
......
......@@ -36,10 +36,10 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
String::Encoding encoding, Variable* var_string_start,
Variable* var_string_end);
// Low level logic around the actual call into generated Irregexp code.
Node* IrregexpExec(Node* const context, Node* const regexp,
Node* const string, Node* const last_index,
Node* const match_info);
// Low level logic around the actual call into pattern matching code.
Node* RegExpExecInternal(Node* const context, Node* const regexp,
Node* const string, Node* const last_index,
Node* const match_info);
Node* ConstructNewResultFromMatchInfo(Node* const context, Node* const regexp,
Node* const match_info,
......
......@@ -231,12 +231,6 @@ Callable CodeFactory::NumberToString(Isolate* isolate) {
return make_callable(stub);
}
// static
Callable CodeFactory::RegExpExec(Isolate* isolate) {
RegExpExecStub stub(isolate);
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
}
// static
Callable CodeFactory::StringFromCharCode(Isolate* isolate) {
Handle<Code> code(isolate->builtins()->StringFromCharCode());
......
......@@ -91,8 +91,6 @@ class V8_EXPORT_PRIVATE CodeFactory final {
OrdinaryToPrimitiveHint hint);
static Callable NumberToString(Isolate* isolate);
static Callable RegExpExec(Isolate* isolate);
static Callable Add(Isolate* isolate);
static Callable Subtract(Isolate* isolate);
static Callable Multiply(Isolate* isolate);
......
......@@ -45,7 +45,6 @@ class Node;
V(MathPow) \
V(ProfileEntryHook) \
V(RecordWrite) \
V(RegExpExec) \
V(StoreBufferOverflow) \
V(StoreSlowElement) \
V(SubString) \
......@@ -1136,15 +1135,6 @@ class JSEntryStub : public PlatformCodeStub {
DEFINE_PLATFORM_CODE_STUB(JSEntry, PlatformCodeStub);
};
class RegExpExecStub: public PlatformCodeStub {
public:
explicit RegExpExecStub(Isolate* isolate) : PlatformCodeStub(isolate) { }
DEFINE_CALL_INTERFACE_DESCRIPTOR(RegExpExec);
DEFINE_PLATFORM_CODE_STUB(RegExpExec, PlatformCodeStub);
};
// TODO(bmeurer/mvstanton): Turn CallConstructStub into ConstructICStub.
class CallConstructStub final : public PlatformCodeStub {
public:
......
......@@ -743,6 +743,18 @@ Node* CodeAssembler::CallCFunction6(
arg5_type, function, arg0, arg1, arg2, arg3, arg4, arg5);
}
Node* CodeAssembler::CallCFunction9(
MachineType return_type, MachineType arg0_type, MachineType arg1_type,
MachineType arg2_type, MachineType arg3_type, MachineType arg4_type,
MachineType arg5_type, MachineType arg6_type, MachineType arg7_type,
MachineType arg8_type, Node* function, Node* arg0, Node* arg1, Node* arg2,
Node* arg3, Node* arg4, Node* arg5, Node* arg6, Node* arg7, Node* arg8) {
return raw_assembler()->CallCFunction9(
return_type, arg0_type, arg1_type, arg2_type, arg3_type, arg4_type,
arg5_type, arg6_type, arg7_type, arg8_type, function, arg0, arg1, arg2,
arg3, arg4, arg5, arg6, arg7, arg8);
}
void CodeAssembler::Goto(Label* label) {
label->MergeVariables();
raw_assembler()->Goto(label->label_);
......
......@@ -429,6 +429,16 @@ class V8_EXPORT_PRIVATE CodeAssembler {
Node* arg1, Node* arg2, Node* arg3, Node* arg4,
Node* arg5);
// Call to a C function with nine arguments.
Node* CallCFunction9(MachineType return_type, MachineType arg0_type,
MachineType arg1_type, MachineType arg2_type,
MachineType arg3_type, MachineType arg4_type,
MachineType arg5_type, MachineType arg6_type,
MachineType arg7_type, MachineType arg8_type,
Node* function, Node* arg0, Node* arg1, Node* arg2,
Node* arg3, Node* arg4, Node* arg5, Node* arg6,
Node* arg7, Node* arg8);
// Exception handling support.
void GotoIfException(Node* node, Label* if_exception,
Variable* exception_var = nullptr);
......
......@@ -462,69 +462,6 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ 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;
__ EnterApiExitFrame(kRegExpExecuteArguments);
// Argument 9: Pass current isolate address.
__ mov(Operand(esp, 8 * kPointerSize),
Immediate(ExternalReference::isolate_address(isolate())));
// Argument 8: Indicate that this is a direct call from JavaScript.
__ mov(Operand(esp, 7 * kPointerSize), 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());
__ mov(esi, Operand::StaticVariable(address_of_regexp_stack_memory_address));
__ add(esi, Operand::StaticVariable(address_of_regexp_stack_memory_size));
__ mov(Operand(esp, 6 * kPointerSize), esi);
// 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.
__ mov(Operand(esp, 5 * kPointerSize), Immediate(0));
// Argument 5: static offsets vector buffer.
__ mov(Operand(esp, 4 * kPointerSize),
Immediate(ExternalReference::address_of_static_offsets_vector(
isolate())));
// Argument 4: End of string data
// Argument 3: Start of string data
__ mov(Operand(esp, 3 * kPointerSize),
RegExpExecDescriptor::StringEndRegister());
__ mov(Operand(esp, 2 * kPointerSize),
RegExpExecDescriptor::StringStartRegister());
// Argument 2: Previous index.
__ mov(Operand(esp, 1 * kPointerSize),
RegExpExecDescriptor::LastIndexRegister());
// Argument 1: Original subject string.
__ mov(Operand(esp, 0 * kPointerSize),
RegExpExecDescriptor::StringRegister());
// Locate the code entry and call it.
__ add(RegExpExecDescriptor::CodeRegister(),
Immediate(Code::kHeaderSize - kHeapObjectTag));
__ call(RegExpExecDescriptor::CodeRegister());
// Drop arguments and come back to JS mode.
__ LeaveApiExitFrame(true);
// TODO(jgruber): Don't tag return value once this is supported by stubs.
__ SmiTag(eax);
__ ret(0 * kPointerSize);
#endif // V8_INTERPRETED_REGEXP
}
static int NegativeComparisonResult(Condition cc) {
DCHECK(cc != equal);
......
......@@ -56,11 +56,6 @@ const Register MathPowIntegerDescriptor::exponent() {
return MathPowTaggedDescriptor::exponent();
}
const Register RegExpExecDescriptor::StringRegister() { return eax; }
const Register RegExpExecDescriptor::LastIndexRegister() { return ecx; }
const Register RegExpExecDescriptor::StringStartRegister() { return edx; }
const Register RegExpExecDescriptor::StringEndRegister() { return ebx; }
const Register RegExpExecDescriptor::CodeRegister() { return edi; }
const Register GrowArrayElementsDescriptor::ObjectRegister() { return eax; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return ebx; }
......
......@@ -492,24 +492,6 @@ void CallICTrampolineDescriptor::InitializePlatformIndependent(
machine_types);
}
void RegExpExecDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) {
// kString, kLastIndex, kStringStart, kStringEnd, kEntryPoint
MachineType machine_types[] = {MachineType::AnyTagged(), MachineType::Int32(),
MachineType::Pointer(), MachineType::Pointer(),
MachineType::AnyTagged()};
data->InitializePlatformIndependent(arraysize(machine_types), 0,
machine_types);
}
void RegExpExecDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {StringRegister(), LastIndexRegister(),
StringStartRegister(), StringEndRegister(),
CodeRegister()};
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void BuiltinDescriptor::InitializePlatformIndependent(
CallInterfaceDescriptorData* data) {
// kTarget, kNewTarget, kArgumentsCount
......
......@@ -49,7 +49,6 @@ class PlatformInterfaceDescriptor;
V(CallTrampoline) \
V(ConstructStub) \
V(ConstructTrampoline) \
V(RegExpExec) \
V(TransitionElementsKind) \
V(AllocateHeapNumber) \
V(Builtin) \
......@@ -613,19 +612,6 @@ class CallConstructDescriptor : public CallInterfaceDescriptor {
DECLARE_DESCRIPTOR(CallConstructDescriptor, CallInterfaceDescriptor)
};
class RegExpExecDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kString, kLastIndex, kStringStart, kStringEnd, kCode)
DECLARE_DESCRIPTOR_WITH_CUSTOM_FUNCTION_TYPE(RegExpExecDescriptor,
CallInterfaceDescriptor)
static const Register StringRegister();
static const Register LastIndexRegister();
static const Register StringStartRegister();
static const Register StringEndRegister();
static const Register CodeRegister();
};
class TransitionElementsKindDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kObject, kMap)
......
......@@ -1271,87 +1271,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ Jump(ra);
}
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).
const int kRegExpExecuteArguments = 9;
const int kParameterRegisters = 4;
__ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters);
// Stack pointer now points to cell where return address is to be written.
// Arguments are before that on the stack or in registers, meaning we
// treat the return address as argument 5. Thus every argument after that
// needs to be shifted back by 1. Since DirectCEntryStub will handle
// allocating space for the c argument slots, we don't need to calculate
// that into the argument positions on the stack. This is how the stack will
// look (sp meaning the value of sp at this moment):
// [sp + 5] - Argument 9
// [sp + 4] - Argument 8
// [sp + 3] - Argument 7
// [sp + 2] - Argument 6
// [sp + 1] - Argument 5
// [sp + 0] - saved ra
// Argument 9: Pass current isolate address.
// CFunctionArgumentOperand handles MIPS stack argument slots.
__ li(t1, Operand(ExternalReference::isolate_address(isolate())));
__ sw(t1, MemOperand(sp, 5 * kPointerSize));
// Argument 8: Indicate that this is a direct call from JavaScript.
__ li(t1, Operand(1));
__ sw(t1, MemOperand(sp, 4 * kPointerSize));
// 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());
__ li(t1, Operand(address_of_regexp_stack_memory_address));
__ lw(t1, MemOperand(t1, 0));
__ li(t2, Operand(address_of_regexp_stack_memory_size));
__ lw(t2, MemOperand(t2, 0));
__ addu(t1, t1, t2);
__ sw(t1, MemOperand(sp, 3 * kPointerSize));
// 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.
__ mov(t1, zero_reg);
__ sw(t1, MemOperand(sp, 2 * kPointerSize));
// Argument 5: static offsets vector buffer.
__ li(
t1,
Operand(ExternalReference::address_of_static_offsets_vector(isolate())));
__ sw(t1, MemOperand(sp, 1 * kPointerSize));
// Argument 4, a3: End of string data
// Argument 3, a2: Start of string data
CHECK(a3.is(RegExpExecDescriptor::StringEndRegister()));
CHECK(a2.is(RegExpExecDescriptor::StringStartRegister()));
// Argument 2 (a1): Previous index.
CHECK(a1.is(RegExpExecDescriptor::LastIndexRegister()));
// Argument 1 (a0): Subject string.
CHECK(a0.is(RegExpExecDescriptor::StringRegister()));
// Locate the code entry and call it.
Register code_reg = RegExpExecDescriptor::CodeRegister();
__ Addu(code_reg, code_reg, Operand(Code::kHeaderSize - kHeapObjectTag));
DirectCEntryStub stub(isolate());
stub.GenerateCall(masm, code_reg);
__ LeaveExitFrame(false, no_reg, true);
// Return the smi-tagged result.
__ SmiTag(v0);
__ Ret();
#endif // V8_INTERPRETED_REGEXP
}
static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) {
// a0 : number of arguments to the construct function
......
......@@ -56,11 +56,6 @@ const Register MathPowIntegerDescriptor::exponent() {
return MathPowTaggedDescriptor::exponent();
}
const Register RegExpExecDescriptor::StringRegister() { return a0; }
const Register RegExpExecDescriptor::LastIndexRegister() { return a1; }
const Register RegExpExecDescriptor::StringStartRegister() { return a2; }
const Register RegExpExecDescriptor::StringEndRegister() { return a3; }
const Register RegExpExecDescriptor::CodeRegister() { return t0; }
const Register GrowArrayElementsDescriptor::ObjectRegister() { return a0; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return a3; }
......
......@@ -32,12 +32,10 @@ typedef int (*mips_regexp_matcher)(String*, int, const byte*, const byte*,
// Call the generated regexp code directly. The code at the entry address
// should act as a function matching the type arm_regexp_matcher.
// The fifth argument is a dummy that reserves the space used for
// the return address added by the ExitFrame in native calls.
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
(FUNCTION_CAST<mips_regexp_matcher>(entry)(p0, p1, p2, p3, NULL, p4, p5, p6, \
p7, p8))
(FUNCTION_CAST<mips_regexp_matcher>(entry)(p0, p1, p2, p3, p4, p5, p6, p7, \
p8))
// The stack limit beyond which we will throw stack overflow errors in
// generated code. Because generated code on mips uses the C stack, we
......@@ -530,9 +528,8 @@ class Simulator {
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
Simulator::current(isolate) \
->Call(entry, 10, p0, p1, p2, p3, NULL, p4, p5, p6, p7, p8)
Simulator::current(isolate)->Call(entry, 9, p0, p1, p2, p3, p4, p5, p6, p7, \
p8)
// The simulator has its own stack. Thus it has a different stack limit from
// the C-based native code. The JS-based limit normally points near the end of
......
......@@ -1266,86 +1266,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ Jump(ra);
}
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).
const int kRegExpExecuteArguments = 9;
const int kParameterRegisters = 8;
__ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters);
// Stack pointer now points to cell where return address is to be written.
// Arguments are before that on the stack or in registers, meaning we
// treat the return address as argument 5. Thus every argument after that
// needs to be shifted back by 1. Since DirectCEntryStub will handle
// allocating space for the c argument slots, we don't need to calculate
// that into the argument positions on the stack. This is how the stack will
// look (sp meaning the value of sp at this moment):
// Abi n64:
// [sp + 1] - Argument 9
// [sp + 0] - saved ra
// Abi O32:
// [sp + 5] - Argument 9
// [sp + 4] - Argument 8
// [sp + 3] - Argument 7
// [sp + 2] - Argument 6
// [sp + 1] - Argument 5
// [sp + 0] - saved ra
// Argument 9: Pass current isolate address.
__ li(t1, Operand(ExternalReference::isolate_address(isolate())));
__ Sd(t1, MemOperand(sp, 1 * kPointerSize));
// Argument 8: Indicate that this is a direct call from JavaScript.
__ li(a7, Operand(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());
__ li(t1, Operand(address_of_regexp_stack_memory_address));
__ Ld(t1, MemOperand(t1, 0));
__ li(t2, Operand(address_of_regexp_stack_memory_size));
__ Ld(t2, MemOperand(t2, 0));
__ daddu(a6, t1, t2);
// 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.
__ mov(a5, zero_reg);
// Argument 5: static offsets vector buffer.
__ li(
a4,
Operand(ExternalReference::address_of_static_offsets_vector(isolate())));
// Argument 4, a3: End of string data
// Argument 3, a2: Start of string data
CHECK(a3.is(RegExpExecDescriptor::StringEndRegister()));
CHECK(a2.is(RegExpExecDescriptor::StringStartRegister()));
// Argument 2 (a1): Previous index.
CHECK(a1.is(RegExpExecDescriptor::LastIndexRegister()));
// Argument 1 (a0): Subject string.
CHECK(a0.is(RegExpExecDescriptor::StringRegister()));
// Locate the code entry and call it.
Register code_reg = RegExpExecDescriptor::CodeRegister();
__ Daddu(code_reg, code_reg, Operand(Code::kHeaderSize - kHeapObjectTag));
DirectCEntryStub stub(isolate());
stub.GenerateCall(masm, code_reg);
__ LeaveExitFrame(false, no_reg, true);
// Return the smi-tagged result.
__ SmiTag(v0);
__ Ret();
#endif // V8_INTERPRETED_REGEXP
}
static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) {
// a0 : number of arguments to the construct function
......
......@@ -56,11 +56,6 @@ const Register MathPowIntegerDescriptor::exponent() {
return MathPowTaggedDescriptor::exponent();
}
const Register RegExpExecDescriptor::StringRegister() { return a0; }
const Register RegExpExecDescriptor::LastIndexRegister() { return a1; }
const Register RegExpExecDescriptor::StringStartRegister() { return a2; }
const Register RegExpExecDescriptor::StringEndRegister() { return a3; }
const Register RegExpExecDescriptor::CodeRegister() { return t0; }
const Register GrowArrayElementsDescriptor::ObjectRegister() { return a0; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return a3; }
......
......@@ -29,8 +29,6 @@ namespace internal {
// Call the generated regexp code directly. The code at the entry address
// should act as a function matching the type arm_regexp_matcher.
// The fifth (or ninth) argument is a dummy that reserves the space used for
// the return address added by the ExitFrame in native calls.
typedef int (*mips_regexp_matcher)(String* input,
int64_t start_offset,
const byte* input_start,
......@@ -39,14 +37,12 @@ typedef int (*mips_regexp_matcher)(String* input,
int64_t output_size,
Address stack_base,
int64_t direct_call,
void* return_address,
Isolate* isolate);
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
(FUNCTION_CAST<mips_regexp_matcher>(entry)(p0, p1, p2, p3, p4, p5, p6, p7, \
NULL, p8))
p8))
// The stack limit beyond which we will throw stack overflow errors in
// generated code. Because generated code on mips uses the C stack, we
......@@ -560,13 +556,10 @@ class Simulator {
reinterpret_cast<int64_t*>(p1), reinterpret_cast<int64_t*>(p2), \
reinterpret_cast<int64_t*>(p3), reinterpret_cast<int64_t*>(p4)))
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
static_cast<int>(Simulator::current(isolate)->Call( \
entry, 10, p0, p1, p2, p3, p4, reinterpret_cast<int64_t*>(p5), p6, p7, \
NULL, p8))
static_cast<int>(Simulator::current(isolate)->Call(entry, 9, p0, p1, p2, p3, \
p4, p5, p6, p7, p8))
// The simulator has its own stack. Thus it has a different stack limit from
// the C-based native code. The JS-based limit normally points near the end of
......
......@@ -1214,77 +1214,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ blr();
}
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).
const int kRegExpExecuteArguments = 10;
const int kParameterRegisters = 8;
__ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters);
// Stack pointer now points to cell where return address is to be written.
// Arguments are before that on the stack or in registers.
// Argument 10 (in stack parameter area): Pass current isolate address.
__ mov(r11, Operand(ExternalReference::isolate_address(isolate())));
__ StoreP(r11,
MemOperand(sp, (kStackFrameExtraParamSlot + 1) * kPointerSize));
// Argument 9 is a dummy that reserves the space used for
// the return address added by the ExitFrame in native calls.
// Argument 8 (r10): Indicate that this is a direct call from JavaScript.
__ li(r10, Operand(1));
// Argument 7 (r9): 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());
__ mov(r11, Operand(address_of_regexp_stack_memory_address));
__ LoadP(r11, MemOperand(r11, 0));
__ mov(ip, Operand(address_of_regexp_stack_memory_size));
__ LoadP(ip, MemOperand(ip, 0));
__ add(r9, r11, ip);
// Argument 6 (r8): Set the number of capture registers to zero to force
// global egexps to behave as non-global. This does not affect non-global
// regexps.
__ li(r8, Operand::Zero());
// Argument 5 (r7): static offsets vector buffer.
__ mov(
r7,
Operand(ExternalReference::address_of_static_offsets_vector(isolate())));
// Argument 4, r6: End of string data
// Argument 3, r5: Start of string data
CHECK(r6.is(RegExpExecDescriptor::StringEndRegister()));
CHECK(r5.is(RegExpExecDescriptor::StringStartRegister()));
// Argument 2 (r4): Previous index.
CHECK(r4.is(RegExpExecDescriptor::LastIndexRegister()));
// Argument 1 (r3): Subject string.
CHECK(r3.is(RegExpExecDescriptor::StringRegister()));
// Locate the code entry and call it.
Register code_reg = RegExpExecDescriptor::CodeRegister();
__ addi(code_reg, code_reg, Operand(Code::kHeaderSize - kHeapObjectTag));
DirectCEntryStub stub(isolate());
stub.GenerateCall(masm, code_reg);
__ LeaveExitFrame(false, no_reg, true);
// Return the smi-tagged result.
__ SmiTag(r3);
__ Ret();
#endif // V8_INTERPRETED_REGEXP
}
static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) {
// r3 : number of arguments to the construct function
......
......@@ -56,11 +56,6 @@ const Register MathPowIntegerDescriptor::exponent() {
return MathPowTaggedDescriptor::exponent();
}
const Register RegExpExecDescriptor::StringRegister() { return r3; }
const Register RegExpExecDescriptor::LastIndexRegister() { return r4; }
const Register RegExpExecDescriptor::StringStartRegister() { return r5; }
const Register RegExpExecDescriptor::StringEndRegister() { return r6; }
const Register RegExpExecDescriptor::CodeRegister() { return r17; }
const Register GrowArrayElementsDescriptor::ObjectRegister() { return r3; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return r6; }
......
......@@ -26,17 +26,13 @@ namespace internal {
(entry(p0, p1, p2, p3, p4))
typedef int (*ppc_regexp_matcher)(String*, int, const byte*, const byte*, int*,
int, Address, int, void*, Isolate*);
int, Address, int, Isolate*);
// Call the generated regexp code directly. The code at the entry address
// should act as a function matching the type ppc_regexp_matcher.
// The ninth argument is a dummy that reserves the space used for
// the return address added by the ExitFrame in native calls.
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
(FUNCTION_CAST<ppc_regexp_matcher>(entry)(p0, p1, p2, p3, p4, p5, p6, p7, \
NULL, p8))
(FUNCTION_CAST<ppc_regexp_matcher>(entry)(p0, p1, p2, p3, p4, p5, p6, p7, p8))
// The stack limit beyond which we will throw stack overflow errors in
// generated code. Because generated code on ppc uses the C stack, we
......@@ -495,11 +491,9 @@ class Simulator {
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
Simulator::current(isolate)->Call(entry, 10, (intptr_t)p0, (intptr_t)p1, \
(intptr_t)p2, (intptr_t)p3, (intptr_t)p4, \
(intptr_t)p5, (intptr_t)p6, (intptr_t)p7, \
(intptr_t)NULL, (intptr_t)p8)
Simulator::current(isolate)->Call( \
entry, 9, (intptr_t)p0, (intptr_t)p1, (intptr_t)p2, (intptr_t)p3, \
(intptr_t)p4, (intptr_t)p5, (intptr_t)p6, (intptr_t)p7, (intptr_t)p8)
// The simulator has its own stack. Thus it has a different stack limit from
// the C-based native code. The JS-based limit normally points near the end of
......
......@@ -41,14 +41,13 @@ namespace internal {
* Each call to a public method should retain this convention.
*
* The stack will have the following structure:
* - fp[56] Isolate* isolate (address of the current isolate)
* - fp[52] direct_call (if 1, direct call from JavaScript code,
* - fp[52] Isolate* isolate (address of the current isolate)
* - fp[48] direct_call (if 1, direct call from JavaScript code,
* if 0, call through the runtime system).
* - fp[48] stack_area_base (high end of the memory area to use as
* - fp[44] stack_area_base (high end of the memory area to use as
* backtracking stack).
* - fp[44] capture array size (may fit multiple sets of matches)
* - fp[40] int* capture_array (int[num_saved_registers_], for output).
* - fp[36] secondary link/return address used by native call.
* - fp[40] capture array size (may fit multiple sets of matches)
* - fp[36] int* capture_array (int[num_saved_registers_], for output).
* --- sp when called ---
* - fp[32] return address (lr).
* - fp[28] old frame pointer (r11).
......@@ -81,17 +80,14 @@ namespace internal {
* int start_index,
* Address start,
* Address end,
* Address secondary_return_address, // Only used by native call.
* int* capture_output_array,
* int num_capture_registers,
* byte* stack_area_base,
* bool direct_call = false)
* bool direct_call = false,
* Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute()
* (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro
* in arm/simulator-arm.h.
* When calling as a non-direct call (i.e., from C++ code), the return address
* area is overwritten with the LR register by the RegExp code. When doing a
* direct call from generated code, the return address is placed there by
* the calling code, as in a normal exit frame.
*/
#define __ ACCESS_MASM(masm_)
......
......@@ -103,9 +103,8 @@ class RegExpMacroAssemblerARM: public NativeRegExpMacroAssembler {
static const int kStoredRegisters = kFramePointer;
// Return address (stored from link register, read into pc on return).
static const int kReturnAddress = kStoredRegisters + 8 * kPointerSize;
static const int kSecondaryReturnAddress = kReturnAddress + kPointerSize;
// Stack parameters placed by caller.
static const int kRegisterOutput = kSecondaryReturnAddress + kPointerSize;
static const int kRegisterOutput = kReturnAddress + kPointerSize;
static const int kNumOutputRegisters = kRegisterOutput + kPointerSize;
static const int kStackHighEnd = kNumOutputRegisters + kPointerSize;
static const int kDirectCall = kStackHighEnd + kPointerSize;
......
......@@ -56,10 +56,7 @@ namespace internal {
* (as referred to in
* the code)
*
* - fp[104] isolate Address of the current isolate.
* - fp[96] return_address Secondary link/return address
* used by an exit frame if this is a
* native call.
* - fp[96] isolate Address of the current isolate.
* ^^^ csp when called ^^^
* - fp[88] lr Return from the RegExp code.
* - fp[80] r29 Old frame pointer (CalleeSaved).
......@@ -89,23 +86,18 @@ namespace internal {
* The data up to the return address must be placed there by the calling
* code and the remaining arguments are passed in registers, e.g. by calling the
* code entry as cast to a function with the signature:
* int (*match)(String* input,
* int start_offset,
* Address input_start,
* Address input_end,
* int* output,
* int output_size,
* Address stack_base,
* int (*match)(String* input_string,
* int start_index,
* Address start,
* Address end,
* int* capture_output_array,
* int num_capture_registers,
* byte* stack_area_base,
* bool direct_call = false,
* Address secondary_return_address, // Only used by native call.
* Isolate* isolate)
* Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute()
* (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro
* in arm64/simulator-arm64.h.
* When calling as a non-direct call (i.e., from C++ code), the return address
* area is overwritten with the LR register by the RegExp code. When doing a
* direct call from generated code, the return address is placed there by
* the calling code, as in a normal exit frame.
*/
#define __ ACCESS_MASM(masm_)
......
......@@ -109,9 +109,8 @@ class RegExpMacroAssemblerARM64: public NativeRegExpMacroAssembler {
// Return address.
// It is placed above the 11 callee-saved registers.
static const int kReturnAddress = kCalleeSavedRegisters + 11 * kPointerSize;
static const int kSecondaryReturnAddress = kReturnAddress + kPointerSize;
// Stack parameter placed by caller.
static const int kIsolate = kSecondaryReturnAddress + kPointerSize;
static const int kIsolate = kReturnAddress + kPointerSize;
// Below the frame pointer.
// Register parameters stored by setup code.
......
......@@ -69,9 +69,10 @@ namespace internal {
* Address start,
* Address end,
* int* capture_output_array,
* bool at_start,
* int num_capture_registers,
* byte* stack_area_base,
* bool direct_call)
* bool direct_call = false,
* Isolate* isolate);
*/
#define __ ACCESS_MASM(masm_)
......
......@@ -38,14 +38,13 @@ namespace internal {
*
* The stack will have the following structure:
*
* - fp[64] Isolate* isolate (address of the current isolate)
* - fp[60] direct_call (if 1, direct call from JavaScript code,
* - fp[60] Isolate* isolate (address of the current isolate)
* - fp[56] direct_call (if 1, direct call from JavaScript code,
* if 0, call through the runtime system).
* - fp[56] stack_area_base (High end of the memory area to use as
* - fp[52] stack_area_base (High end of the memory area to use as
* backtracking stack).
* - fp[52] capture array size (may fit multiple sets of matches)
* - fp[48] int* capture_array (int[num_saved_registers_], for output).
* - fp[44] secondary link/return address used by native call.
* - fp[48] capture array size (may fit multiple sets of matches)
* - fp[44] int* capture_array (int[num_saved_registers_], for output).
* --- sp when called ---
* - fp[40] return address (lr).
* - fp[36] old frame pointer (r11).
......@@ -78,17 +77,14 @@ namespace internal {
* int start_index,
* Address start,
* Address end,
* Address secondary_return_address, // Only used by native call.
* int* capture_output_array,
* int num_capture_registers,
* byte* stack_area_base,
* bool direct_call = false)
* bool direct_call = false,
* Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute()
* (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro
* in mips/simulator-mips.h.
* When calling as a non-direct call (i.e., from C++ code), the return address
* area is overwritten with the ra register by the RegExp code. When doing a
* direct call from generated code, the return address is placed there by
* the calling code, as in a normal exit frame.
*/
#define __ ACCESS_MASM(masm_)
......
......@@ -103,9 +103,8 @@ class RegExpMacroAssemblerMIPS: public NativeRegExpMacroAssembler {
static const int kStoredRegisters = kFramePointer;
// Return address (stored from link register, read into pc on return).
static const int kReturnAddress = kStoredRegisters + 9 * kPointerSize;
static const int kSecondaryReturnAddress = kReturnAddress + kPointerSize;
// Stack frame header.
static const int kStackFrameHeader = kReturnAddress + kPointerSize;
static const int kStackFrameHeader = kReturnAddress;
// Stack parameters placed by caller.
static const int kRegisterOutput = kStackFrameHeader + 20;
static const int kNumOutputRegisters = kRegisterOutput + kPointerSize;
......
......@@ -17,7 +17,9 @@ namespace v8 {
namespace internal {
#ifndef V8_INTERPRETED_REGEXP
/*
/* clang-format off
*
* This assembler uses the following register assignment convention
* - t3 : Temporarily stores the index of capture start after a matching pass
* for a global regexp.
......@@ -41,15 +43,14 @@ namespace internal {
*
* The O32 stack will have the following structure:
*
* - fp[76] Isolate* isolate (address of the current isolate)
* - fp[72] direct_call (if 1, direct call from JavaScript code,
* - fp[72] Isolate* isolate (address of the current isolate)
* - fp[68] direct_call (if 1, direct call from JavaScript code,
* if 0, call through the runtime system).
* - fp[68] stack_area_base (High end of the memory area to use as
* - fp[64] stack_area_base (High end of the memory area to use as
* backtracking stack).
* - fp[64] capture array size (may fit multiple sets of matches)
* - fp[60] int* capture_array (int[num_saved_registers_], for output).
* - fp[60] capture array size (may fit multiple sets of matches)
* - fp[44..59] MIPS O32 four argument slots
* - fp[40] secondary link/return address used by native call.
* - fp[40] int* capture_array (int[num_saved_registers_], for output).
* --- sp when called ---
* - fp[36] return address (lr).
* - fp[32] old frame pointer (r11).
......@@ -74,9 +75,8 @@ namespace internal {
*
* The N64 stack will have the following structure:
*
* - fp[88] Isolate* isolate (address of the current isolate) kIsolate
* - fp[80] secondary link/return address used by exit frame on native call. kSecondaryReturnAddress
kStackFrameHeader
* - fp[80] Isolate* isolate (address of the current isolate) kIsolate
* kStackFrameHeader
* --- sp when called ---
* - fp[72] ra Return from RegExp code (ra). kReturnAddress
* - fp[64] s9, old-fp Old fp, callee saved(s9).
......@@ -112,19 +112,16 @@ namespace internal {
* int start_index,
* Address start,
* Address end,
* Address secondary_return_address, // Only used by native call.
* int* capture_output_array,
* int num_capture_registers,
* byte* stack_area_base,
* bool direct_call = false,
* void* return_address,
* Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute()
* (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro
* in mips/simulator-mips.h.
* When calling as a non-direct call (i.e., from C++ code), the return address
* area is overwritten with the ra register by the RegExp code. When doing a
* direct call from generated code, the return address is placed there by
* the calling code, as in a normal exit frame.
*
* clang-format on
*/
#define __ ACCESS_MASM(masm_)
......
......@@ -107,9 +107,8 @@ class RegExpMacroAssemblerMIPS: public NativeRegExpMacroAssembler {
// TODO(plind): This 9 - is 8 s-regs (s0..s7) plus fp.
static const int kReturnAddress = kStoredRegisters + 9 * kPointerSize;
static const int kSecondaryReturnAddress = kReturnAddress + kPointerSize;
// Stack frame header.
static const int kStackFrameHeader = kSecondaryReturnAddress;
static const int kStackFrameHeader = kReturnAddress;
// Stack parameters placed by caller.
static const int kIsolate = kStackFrameHeader + kPointerSize;
......
......@@ -38,8 +38,7 @@ namespace internal {
* Each call to a public method should retain this convention.
*
* The stack will have the following structure:
* - fp[44] Isolate* isolate (address of the current isolate)
* - fp[40] secondary link/return address used by native call.
* - fp[40] Isolate* isolate (address of the current isolate)
* - fp[36] lr save area (currently unused)
* - fp[32] backchain (currently unused)
* --- sp when called ---
......@@ -81,16 +80,13 @@ namespace internal {
* Address start,
* Address end,
* int* capture_output_array,
* int num_capture_registers,
* byte* stack_area_base,
* Address secondary_return_address, // Only used by native call.
* bool direct_call = false)
* bool direct_call = false,
* Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute()
* (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro
* in ppc/simulator-ppc.h.
* When calling as a non-direct call (i.e., from C++ code), the return address
* area is overwritten with the LR register by the RegExp code. When doing a
* direct call from generated code, the return address is placed there by
* the calling code, as in a normal exit frame.
*/
#define __ ACCESS_MASM(masm_)
......
......@@ -96,9 +96,8 @@ class RegExpMacroAssemblerPPC : public NativeRegExpMacroAssembler {
static const int kReturnAddress = kStoredRegisters + 7 * kPointerSize;
static const int kCallerFrame = kReturnAddress + kPointerSize;
// Stack parameters placed by caller.
static const int kSecondaryReturnAddress =
static const int kIsolate =
kCallerFrame + kStackFrameExtraParamSlot * kPointerSize;
static const int kIsolate = kSecondaryReturnAddress + kPointerSize;
// Below the frame pointer.
// Register parameters stored by setup code.
......
......@@ -170,15 +170,18 @@ int NativeRegExpMacroAssembler::CheckStackGuardState(
bool is_one_byte = subject_handle->IsOneByteRepresentationUnderneath();
StackLimitCheck check(isolate);
if (check.JsHasOverflowed()) {
bool js_has_overflowed = check.JsHasOverflowed();
if (is_direct_call) {
// Direct calls from JavaScript can be interrupted in two ways:
// 1. A real stack overflow, in which case we let the caller throw the
// exception.
// 2. The stack guard was used to interrupt execution for another purpose,
// forcing the call through the runtime system.
return_value = js_has_overflowed ? EXCEPTION : RETRY;
} else if (js_has_overflowed) {
isolate->StackOverflow();
return_value = EXCEPTION;
} else if (is_direct_call) {
// 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.
return_value = RETRY;
} else {
Object* result = isolate->stack_guard()->HandleInterrupts();
if (result->IsException(isolate)) return_value = EXCEPTION;
......
......@@ -39,8 +39,7 @@ namespace internal {
* Each call to a public method should retain this convention.
*
* The stack will have the following structure:
* - fp[112] Isolate* isolate (address of the current isolate)
* - fp[108] secondary link/return address used by native call.
* - fp[108] Isolate* isolate (address of the current isolate)
* - fp[104] direct_call (if 1, direct call from JavaScript code,
* if 0, call through the runtime system).
* - fp[100] stack_area_base (high end of the memory area to use as
......@@ -83,16 +82,13 @@ namespace internal {
* Address start,
* Address end,
* int* capture_output_array,
* int num_capture_registers,
* byte* stack_area_base,
* Address secondary_return_address, // Only used by native call.
* bool direct_call = false)
* bool direct_call = false,
* Isolate* isolate);
* The call is performed by NativeRegExpMacroAssembler::Execute()
* (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro
* in s390/simulator-s390.h.
* When calling as a non-direct call (i.e., from C++ code), the return address
* area is overwritten with the LR register by the RegExp code. When doing a
* direct call from generated code, the return address is placed there by
* the calling code, as in a normal exit frame.
*/
#define __ ACCESS_MASM(masm_)
......
......@@ -97,8 +97,7 @@ class RegExpMacroAssemblerS390 : public NativeRegExpMacroAssembler {
static const int kCaptureArraySize = kCallerFrame;
static const int kStackAreaBase = kCallerFrame + kPointerSize;
// kDirectCall again
static const int kSecondaryReturnAddress = kStackAreaBase + 2 * kPointerSize;
static const int kIsolate = kSecondaryReturnAddress + kPointerSize;
static const int kIsolate = kStackAreaBase + 2 * kPointerSize;
// Below the frame pointer.
// Register parameters stored by setup code.
......
......@@ -85,9 +85,10 @@ namespace internal {
* Address start,
* Address end,
* int* capture_output_array,
* bool at_start,
* int num_capture_registers,
* byte* stack_area_base,
* bool direct_call)
* bool direct_call = false,
* Isolate* isolate);
*/
#define __ ACCESS_MASM((&masm_))
......
......@@ -69,9 +69,10 @@ namespace internal {
* Address start,
* Address end,
* int* capture_output_array,
* bool at_start,
* int num_capture_registers,
* byte* stack_area_base,
* bool direct_call)
* bool direct_call = false,
* Isolate* isolate);
*/
#define __ ACCESS_MASM(masm_)
......
......@@ -1205,87 +1205,6 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
__ b(r14);
}
void RegExpExecStub::Generate(MacroAssembler* masm) {
#ifdef V8_INTERPRETED_REGEXP
// This case is handled prior to the RegExpExecStub call.
__ Abort(kUnexpectedRegExpExecCall);
#else // V8_INTERPRETED_REGEXP
__ CleanseP(r14);
// Isolates: note we add an additional parameter here (isolate pointer).
const int kRegExpExecuteArguments = 10;
const int kParameterRegisters = 5;
__ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters);
// Stack pointer now points to cell where return address is to be written.
// Arguments are before that on the stack or in registers.
// Argument 10 (in stack parameter area): Pass current isolate address.
__ mov(r6, Operand(ExternalReference::isolate_address(isolate())));
__ StoreP(r6, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize +
4 * kPointerSize));
// Argument 9 is a dummy that reserves the space used for
// the return address added by the ExitFrame in native calls.
__ mov(r6, Operand::Zero());
__ StoreP(r6, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize +
3 * kPointerSize));
// Argument 8: Indicate that this is a direct call from JavaScript.
__ mov(r6, Operand(1));
__ StoreP(r6, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize +
2 * kPointerSize));
// 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());
__ mov(r6, Operand(address_of_regexp_stack_memory_address));
__ LoadP(r6, MemOperand(r6, 0));
__ mov(r1, Operand(address_of_regexp_stack_memory_size));
__ LoadP(r1, MemOperand(r1, 0));
__ AddP(r6, r1);
__ StoreP(r6, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize +
1 * kPointerSize));
// Argument 6: Set the number of capture registers to zero to force
// global egexps to behave as non-global. This does not affect non-global
// regexps.
__ mov(r6, Operand::Zero());
__ StoreP(r6, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize +
0 * kPointerSize));
// Argument 5 (r6): static offsets vector buffer.
__ mov(
r6,
Operand(ExternalReference::address_of_static_offsets_vector(isolate())));
// Argument 4, r5: End of string data
// Argument 3, r4: Start of string data
CHECK(r5.is(RegExpExecDescriptor::StringEndRegister()));
CHECK(r4.is(RegExpExecDescriptor::StringStartRegister()));
// Argument 2 (r3): Previous index.
CHECK(r3.is(RegExpExecDescriptor::LastIndexRegister()));
// Argument 1 (r2): Subject string.
CHECK(r2.is(RegExpExecDescriptor::StringRegister()));
// Locate the code entry and call it.
Register code_reg = RegExpExecDescriptor::CodeRegister();
__ AddP(code_reg, Operand(Code::kHeaderSize - kHeapObjectTag));
DirectCEntryStub stub(isolate());
stub.GenerateCall(masm, code_reg);
__ LeaveExitFrame(false, no_reg, true);
// Return the smi-tagged result.
__ SmiTag(r2);
__ Ret();
#endif // V8_INTERPRETED_REGEXP
}
static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) {
// r2 : number of arguments to the construct function
......
......@@ -56,12 +56,6 @@ const Register MathPowIntegerDescriptor::exponent() {
return MathPowTaggedDescriptor::exponent();
}
const Register RegExpExecDescriptor::StringRegister() { return r2; }
const Register RegExpExecDescriptor::LastIndexRegister() { return r3; }
const Register RegExpExecDescriptor::StringStartRegister() { return r4; }
const Register RegExpExecDescriptor::StringEndRegister() { return r5; }
const Register RegExpExecDescriptor::CodeRegister() { return r9; }
const Register GrowArrayElementsDescriptor::ObjectRegister() { return r2; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return r5; }
......
......@@ -25,16 +25,14 @@ namespace internal {
(entry(p0, p1, p2, p3, p4))
typedef int (*s390_regexp_matcher)(String*, int, const byte*, const byte*, int*,
int, Address, int, void*, Isolate*);
int, Address, int, Isolate*);
// Call the generated regexp code directly. The code at the entry address
// should act as a function matching the type ppc_regexp_matcher.
// The ninth argument is a dummy that reserves the space used for
// the return address added by the ExitFrame in native calls.
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
(FUNCTION_CAST<s390_regexp_matcher>(entry)(p0, p1, p2, p3, p4, p5, p6, p7, \
NULL, p8))
p8))
// The stack limit beyond which we will throw stack overflow errors in
// generated code. Because generated code on s390 uses the C stack, we
......@@ -1259,10 +1257,9 @@ class Simulator {
#define CALL_GENERATED_REGEXP_CODE(isolate, entry, p0, p1, p2, p3, p4, p5, p6, \
p7, p8) \
Simulator::current(isolate)->Call(entry, 10, (intptr_t)p0, (intptr_t)p1, \
(intptr_t)p2, (intptr_t)p3, (intptr_t)p4, \
(intptr_t)p5, (intptr_t)p6, (intptr_t)p7, \
(intptr_t)NULL, (intptr_t)p8)
Simulator::current(isolate)->Call( \
entry, 9, (intptr_t)p0, (intptr_t)p1, (intptr_t)p2, (intptr_t)p3, \
(intptr_t)p4, (intptr_t)p5, (intptr_t)p6, (intptr_t)p7, (intptr_t)p8)
// The simulator has its own stack. Thus it has a different stack limit from
// the C-based native code. The JS-based limit normally points near the end of
......
......@@ -350,85 +350,6 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ 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)
......
......@@ -56,11 +56,6 @@ const Register MathPowIntegerDescriptor::exponent() {
return MathPowTaggedDescriptor::exponent();
}
const Register RegExpExecDescriptor::StringRegister() { return arg_reg_1; }
const Register RegExpExecDescriptor::LastIndexRegister() { return r11; }
const Register RegExpExecDescriptor::StringStartRegister() { return arg_reg_3; }
const Register RegExpExecDescriptor::StringEndRegister() { return arg_reg_4; }
const Register RegExpExecDescriptor::CodeRegister() { return rax; }
const Register GrowArrayElementsDescriptor::ObjectRegister() { return rax; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return rbx; }
......
......@@ -281,69 +281,6 @@ void MathPowStub::Generate(MacroAssembler* masm) {
__ 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;
__ EnterApiExitFrame(kRegExpExecuteArguments);
// Argument 9: Pass current isolate address.
__ mov(Operand(esp, 8 * kPointerSize),
Immediate(ExternalReference::isolate_address(isolate())));
// Argument 8: Indicate that this is a direct call from JavaScript.
__ mov(Operand(esp, 7 * kPointerSize), 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());
__ mov(esi, Operand::StaticVariable(address_of_regexp_stack_memory_address));
__ add(esi, Operand::StaticVariable(address_of_regexp_stack_memory_size));
__ mov(Operand(esp, 6 * kPointerSize), esi);
// 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.
__ mov(Operand(esp, 5 * kPointerSize), Immediate(0));
// Argument 5: static offsets vector buffer.
__ mov(Operand(esp, 4 * kPointerSize),
Immediate(ExternalReference::address_of_static_offsets_vector(
isolate())));
// Argument 4: End of string data
// Argument 3: Start of string data
__ mov(Operand(esp, 3 * kPointerSize),
RegExpExecDescriptor::StringEndRegister());
__ mov(Operand(esp, 2 * kPointerSize),
RegExpExecDescriptor::StringStartRegister());
// Argument 2: Previous index.
__ mov(Operand(esp, 1 * kPointerSize),
RegExpExecDescriptor::LastIndexRegister());
// Argument 1: Original subject string.
__ mov(Operand(esp, 0 * kPointerSize),
RegExpExecDescriptor::StringRegister());
// Locate the code entry and call it.
__ add(RegExpExecDescriptor::CodeRegister(),
Immediate(Code::kHeaderSize - kHeapObjectTag));
__ call(RegExpExecDescriptor::CodeRegister());
// Drop arguments and come back to JS mode.
__ LeaveApiExitFrame(true);
// TODO(jgruber): Don't tag return value once this is supported by stubs.
__ SmiTag(eax);
__ ret(0 * kPointerSize);
#endif // V8_INTERPRETED_REGEXP
}
static int NegativeComparisonResult(Condition cc) {
DCHECK(cc != equal);
......
......@@ -56,11 +56,6 @@ const Register MathPowIntegerDescriptor::exponent() {
return MathPowTaggedDescriptor::exponent();
}
const Register RegExpExecDescriptor::StringRegister() { return eax; }
const Register RegExpExecDescriptor::LastIndexRegister() { return ecx; }
const Register RegExpExecDescriptor::StringStartRegister() { return edx; }
const Register RegExpExecDescriptor::StringEndRegister() { return ebx; }
const Register RegExpExecDescriptor::CodeRegister() { return edi; }
const Register GrowArrayElementsDescriptor::ObjectRegister() { return eax; }
const Register GrowArrayElementsDescriptor::KeyRegister() { return ebx; }
......
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