[regexp] Move the tier-up check into C++

The tier-up check is only needed for instances that currently go
through the interpreter. It is simpler to move the check into the
interpreter's C++ entry point. At that point, when we see a JSRegExp
that should tier-up, we simply return RETRY which will automatically
send us back into runtime where the actual recompilation happens.

Bug: v8:9566
Change-Id: Ib7bb5d21a30bae45d6e14846edd2a47469989b35
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1852125
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Peter Marshall <petermarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64210}
This commit is contained in:
Jakob Gruber 2019-10-10 09:58:21 +02:00 committed by Commit Bot
parent 6f8381958c
commit d0aed76451
3 changed files with 13 additions and 14 deletions

View File

@ -518,27 +518,18 @@ TNode<HeapObject> RegExpBuiltinsAssembler::RegExpExecInternal(
GotoIf(TaggedIsSmi(var_code.value()), &runtime);
TNode<Code> code = CAST(var_code.value());
// Tier-up in runtime if ticks are zero and tier-up hasn't happened yet
// and ensure that a RegExp stack is allocated when using compiled Irregexp.
// Ensure that a RegExp stack is allocated when using compiled Irregexp.
// TODO(jgruber): Guarantee an allocated stack and remove this check.
{
Label next(this), check_tier_up(this);
GotoIfNot(TaggedIsSmi(var_bytecode.value()), &check_tier_up);
Label next(this);
GotoIfNot(TaggedIsSmi(var_bytecode.value()), &next);
CSA_ASSERT(this, SmiEqual(CAST(var_bytecode.value()),
SmiConstant(JSRegExp::kUninitializedValue)));
// Ensure RegExp stack is allocated.
TNode<IntPtrT> stack_size = UncheckedCast<IntPtrT>(
Load(MachineType::IntPtr(), regexp_stack_memory_size_address));
GotoIf(IntPtrEqual(stack_size, IntPtrZero()), &runtime);
Goto(&next);
Branch(IntPtrEqual(stack_size, IntPtrZero()), &runtime, &next);
// Check if tier-up is requested.
BIND(&check_tier_up);
TNode<Smi> ticks = CAST(UnsafeLoadFixedArrayElement(
data, JSRegExp::kIrregexpTicksUntilTierUpIndex));
GotoIfNot(SmiToInt32(ticks), &runtime);
Goto(&next);
BIND(&next);
}

View File

@ -1018,6 +1018,12 @@ IrregexpInterpreter::Result IrregexpInterpreter::MatchForCallFromJs(
String subject_string = String::cast(Object(subject));
JSRegExp regexp_obj = JSRegExp::cast(Object(regexp));
if (regexp_obj.MarkedForTierUp()) {
// Returning RETRY will re-enter through runtime, where actual recompilation
// for tier-up takes place.
return IrregexpInterpreter::RETRY;
}
return Match(isolate, regexp_obj, subject_string, registers, registers_length,
start_position, call_origin);
}

View File

@ -31,6 +31,8 @@ class V8_EXPORT_PRIVATE IrregexpInterpreter : public AllStatic {
// In case a StackOverflow occurs, EXCEPTION is returned. The caller is
// responsible for creating the exception.
// RETRY is returned if a retry through the runtime is needed (e.g. when
// interrupts have been scheduled or the regexp is marked for tier-up).
// Arguments input_start, input_end and backtrack_stack are
// unused. They are only passed to match the signature of the native irregex
// code.