Commit 166a52ff authored by jgruber's avatar jgruber Committed by Commit Bot

[regexp] Micro-optimize block ordering in RegExp.p.exec

Minor differences in how we dispatch on the regexp type
(IRREGEXP,ATOM,NOT_COMPILED) make significant differences in benchmark
performance. A simple switch turns out to be the best alternative.

BUG=chromium:734035, v8:6462

Change-Id: I09c613658e828b9fd1e3082624ef692b8b4a0c5f
Reviewed-on: https://chromium-review.googlesource.com/539295Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45998}
parent 24b7026d
...@@ -291,15 +291,23 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ...@@ -291,15 +291,23 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
CSA_ASSERT(this, TaggedIsNotSmi(data)); CSA_ASSERT(this, TaggedIsNotSmi(data));
CSA_ASSERT(this, HasInstanceType(data, FIXED_ARRAY_TYPE)); CSA_ASSERT(this, HasInstanceType(data, FIXED_ARRAY_TYPE));
// Dispatch on the type of the RegExp. The common case (IRREGEXP) is first. // Dispatch on the type of the RegExp.
// NOT_COMPILED is last as it requires a slow runtime call anyway.
{ {
Label next(this); Label next(this), unreachable(this, Label::kDeferred);
Node* const tag = LoadFixedArrayElement(data, JSRegExp::kTagIndex); Node* const tag = LoadAndUntagToWord32FixedArrayElement(
GotoIf(SmiEqual(tag, SmiConstant(JSRegExp::IRREGEXP)), &next); data, IntPtrConstant(JSRegExp::kTagIndex));
GotoIf(SmiEqual(tag, SmiConstant(JSRegExp::ATOM)), &atom);
CSA_ASSERT(this, SmiEqual(tag, SmiConstant(JSRegExp::NOT_COMPILED))); int32_t values[] = {
Goto(&runtime); JSRegExp::IRREGEXP, JSRegExp::ATOM, JSRegExp::NOT_COMPILED,
};
Label* labels[] = {&next, &atom, &runtime};
STATIC_ASSERT(arraysize(values) == arraysize(labels));
Switch(tag, &unreachable, values, labels, arraysize(values));
BIND(&unreachable);
Unreachable();
BIND(&next); BIND(&next);
} }
...@@ -543,6 +551,8 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ...@@ -543,6 +551,8 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
BIND(&atom); BIND(&atom);
{ {
// TODO(jgruber): A call with 4 args stresses register allocation, this
// should probably just be inlined.
Node* const result = CallBuiltin(Builtins::kRegExpExecAtom, context, regexp, Node* const result = CallBuiltin(Builtins::kRegExpExecAtom, context, regexp,
string, last_index, match_info); string, last_index, match_info);
var_result.Bind(result); var_result.Bind(result);
......
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