| Index: src/builtins/builtins-regexp-gen.cc
|
| diff --git a/src/builtins/builtins-regexp-gen.cc b/src/builtins/builtins-regexp-gen.cc
|
| index f1169c0b94cc66e8c09adb633c7748e83858fc9b..7752efccfd1f53f4f1728afa070020752b012144 100644
|
| --- a/src/builtins/builtins-regexp-gen.cc
|
| +++ b/src/builtins/builtins-regexp-gen.cc
|
| @@ -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,83 @@ 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.
|
| + // Argument 3: End of string data.
|
| + MachineType arg2_type = type_ptr;
|
| + Node* const arg2 = var_string_start.value();
|
| +
|
| + 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(1)), &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 +503,14 @@ 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.
|
| + Node* const pending_exception_address = ExternalConstant(
|
| + ExternalReference(Isolate::kPendingExceptionAddress, isolate()));
|
| + CSA_ASSERT(this, IsTheHole(Load(MachineType::AnyTagged(),
|
| + pending_exception_address)));
|
| + USE(pending_exception_address);
|
| CallRuntime(Runtime::kThrowStackOverflow, context);
|
| Unreachable();
|
| -
|
| - BIND(&rethrow);
|
| - CallRuntime(Runtime::kRegExpExecReThrow, context);
|
| - Unreachable();
|
| }
|
|
|
| BIND(&runtime);
|
| @@ -571,8 +626,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 +2159,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 +2221,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 +2903,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);
|
|
|