[regexp] Avoid runtime call on OOB lastIndex values
At this point, last_index is definitely a canonicalized non-negative number, which implies that any non-Smi last_index is greater than the maximal string length. That in turn means that the matcher will definitely fail, and we can avoid the expensive runtime call. BUG=v8:6365,v8:6344 Review-Url: https://codereview.chromium.org/2863643004 Cr-Commit-Position: refs/heads/master@{#45143}
This commit is contained in:
parent
3f4536894a
commit
2fd1afc0c8
@ -306,9 +306,16 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
|
||||
|
||||
Node* const smi_string_length = LoadStringLength(string);
|
||||
|
||||
// Bail out to runtime for invalid {last_index} values.
|
||||
GotoIfNot(TaggedIsSmi(last_index), &runtime);
|
||||
GotoIf(SmiAboveOrEqual(last_index, smi_string_length), &runtime);
|
||||
// At this point, last_index is definitely a canonicalized non-negative
|
||||
// number, which implies that any non-Smi last_index is greater than
|
||||
// the maximal string length. If lastIndex > string.length then the matcher
|
||||
// must fail.
|
||||
|
||||
Label if_failure(this);
|
||||
CSA_ASSERT(this, IsNumberNormalized(last_index));
|
||||
CSA_ASSERT(this, IsNumberPositive(last_index));
|
||||
GotoIfNot(TaggedIsSmi(last_index), &if_failure); // Outside Smi range.
|
||||
GotoIf(SmiGreaterThan(last_index, smi_string_length), &if_failure);
|
||||
|
||||
// Load the irregexp code object and offsets into the subject string. Both
|
||||
// depend on whether the string is one- or two-byte.
|
||||
@ -358,8 +365,7 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
|
||||
GotoIf(TaggedIsSmi(code), &runtime);
|
||||
CSA_ASSERT(this, HasInstanceType(code, CODE_TYPE));
|
||||
|
||||
Label if_success(this), if_failure(this),
|
||||
if_exception(this, Label::kDeferred);
|
||||
Label if_success(this), if_exception(this, Label::kDeferred);
|
||||
{
|
||||
IncrementCounter(isolate()->counters()->regexp_entry_native(), 1);
|
||||
|
||||
|
@ -3362,6 +3362,18 @@ Node* CodeStubAssembler::IsNumberNormalized(Node* number) {
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::IsNumberPositive(Node* number) {
|
||||
CSA_ASSERT(this, IsNumber(number));
|
||||
Node* const float_zero = Float64Constant(0.);
|
||||
return Select(TaggedIsSmi(number),
|
||||
[=] { return TaggedIsPositiveSmi(number); },
|
||||
[=] {
|
||||
Node* v = LoadHeapNumberValue(number);
|
||||
return Float64GreaterThanOrEqual(v, float_zero);
|
||||
},
|
||||
MachineRepresentation::kWord32);
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index,
|
||||
ParameterMode parameter_mode) {
|
||||
if (parameter_mode == SMI_PARAMETERS) CSA_ASSERT(this, TaggedIsSmi(index));
|
||||
|
@ -791,6 +791,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
// True iff |number| is either a Smi, or a HeapNumber whose value is not
|
||||
// within Smi range.
|
||||
Node* IsNumberNormalized(Node* number);
|
||||
Node* IsNumberPositive(Node* number);
|
||||
|
||||
// ElementsKind helpers:
|
||||
Node* IsFastElementsKind(Node* elements_kind);
|
||||
|
Loading…
Reference in New Issue
Block a user