ae4529f9e1
Add fast paths when RegExp and RegExp result are fast wherever possible. As shown below, this CL improves the performance of calling S.p.matchAll and iterating over matches. Before: StringMatchAllBuiltinRegExpIteratorCreation-Strings(Score): 5002 StringMatchAllBuiltinStringIteratorCreation-Strings(Score): 13798 StringMatchAllBuiltinString-Strings(Score): 197 StringMatchAllManualString-Strings(Score): 454 StringMatchAllBuiltinRegExp-Strings(Score): 193 StringMatchAllManualRegExp-Strings(Score): 453 StringMatchAllBuiltinZeroWidth-Strings(Score): 97.2 StringMatchAllBuiltinZeroWidthUnicode-Strings(Score): 95.9 After: StringMatchAllBuiltinRegExpIteratorCreation-Strings(Score): 15437 StringMatchAllBuiltinStringIteratorCreation-Strings(Score): 16708 StringMatchAllBuiltinString-Strings(Score): 392 StringMatchAllManualString-Strings(Score): 452 StringMatchAllBuiltinRegExp-Strings(Score): 394 StringMatchAllManualRegExp-Strings(Score): 484 StringMatchAllBuiltinZeroWidth-Strings(Score): 409 StringMatchAllBuiltinZeroWidthUnicode-Strings(Score): 413 Bug: v8:6890 Change-Id: I6fcc1003a471314cf412aac456d42286b2926810 Reviewed-on: https://chromium-review.googlesource.com/1005400 Commit-Queue: Peter Wong <peter.wm.wong@gmail.com> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#52581}
144 lines
6.5 KiB
C++
144 lines
6.5 KiB
C++
// Copyright 2017 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef V8_BUILTINS_BUILTINS_REGEXP_GEN_H_
|
|
#define V8_BUILTINS_BUILTINS_REGEXP_GEN_H_
|
|
|
|
#include "src/code-stub-assembler.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
|
|
class RegExpBuiltinsAssembler : public CodeStubAssembler {
|
|
public:
|
|
explicit RegExpBuiltinsAssembler(compiler::CodeAssemblerState* state)
|
|
: CodeStubAssembler(state) {}
|
|
|
|
void BranchIfFastRegExp(Node* const context, Node* const object,
|
|
Node* const map, Label* const if_isunmodified,
|
|
Label* const if_ismodified);
|
|
|
|
// Create and initialize a RegExp object.
|
|
TNode<Object> RegExpCreate(TNode<Context> context,
|
|
TNode<Context> native_context,
|
|
TNode<Object> regexp_string, TNode<String> flags);
|
|
|
|
TNode<Object> RegExpCreate(TNode<Context> context, TNode<Map> initial_map,
|
|
TNode<Object> regexp_string, TNode<String> flags);
|
|
|
|
TNode<Object> MatchAllIterator(TNode<Context> context,
|
|
TNode<Context> native_context,
|
|
TNode<Object> regexp, TNode<String> string,
|
|
TNode<BoolT> is_fast_regexp,
|
|
char const* method_name);
|
|
|
|
protected:
|
|
// Allocate a RegExpResult with the given length (the number of captures,
|
|
// including the match itself), index (the index where the match starts),
|
|
// and input string. |length| and |index| are expected to be tagged, and
|
|
// |input| must be a string.
|
|
Node* AllocateRegExpResult(Node* context, Node* length, Node* index,
|
|
Node* input);
|
|
|
|
Node* FastLoadLastIndex(Node* regexp);
|
|
Node* SlowLoadLastIndex(Node* context, Node* regexp);
|
|
Node* LoadLastIndex(Node* context, Node* regexp, bool is_fastpath);
|
|
|
|
void FastStoreLastIndex(Node* regexp, Node* value);
|
|
void SlowStoreLastIndex(Node* context, Node* regexp, Node* value);
|
|
void StoreLastIndex(Node* context, Node* regexp, Node* value,
|
|
bool is_fastpath);
|
|
|
|
// Loads {var_string_start} and {var_string_end} with the corresponding
|
|
// offsets into the given {string_data}.
|
|
void GetStringPointers(Node* const string_data, Node* const offset,
|
|
Node* const last_index, Node* const string_length,
|
|
String::Encoding encoding, Variable* var_string_start,
|
|
Variable* var_string_end);
|
|
|
|
// 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,
|
|
TNode<String> const string);
|
|
|
|
Node* RegExpPrototypeExecBodyWithoutResult(Node* const context,
|
|
Node* const regexp,
|
|
Node* const string,
|
|
Label* if_didnotmatch,
|
|
const bool is_fastpath);
|
|
Node* RegExpPrototypeExecBody(Node* const context, Node* const regexp,
|
|
TNode<String> string, const bool is_fastpath);
|
|
|
|
Node* ThrowIfNotJSReceiver(Node* context, Node* maybe_receiver,
|
|
MessageTemplate::Template msg_template,
|
|
char const* method_name);
|
|
|
|
// Analogous to BranchIfFastRegExp, for use in asserts.
|
|
TNode<BoolT> IsFastRegExp(SloppyTNode<Context> context,
|
|
SloppyTNode<Object> object);
|
|
|
|
void BranchIfFastRegExp(Node* const context, Node* const object,
|
|
Label* const if_isunmodified,
|
|
Label* const if_ismodified);
|
|
|
|
// Performs fast path checks on the given object itself, but omits prototype
|
|
// checks.
|
|
Node* IsFastRegExpNoPrototype(Node* const context, Node* const object);
|
|
Node* IsFastRegExpNoPrototype(Node* const context, Node* const object,
|
|
Node* const map);
|
|
|
|
void BranchIfFastRegExpResult(Node* const context, Node* const object,
|
|
Label* if_isunmodified, Label* if_ismodified);
|
|
|
|
Node* FlagsGetter(Node* const context, Node* const regexp, bool is_fastpath);
|
|
|
|
Node* FastFlagGetter(Node* const regexp, JSRegExp::Flag flag);
|
|
Node* SlowFlagGetter(Node* const context, Node* const regexp,
|
|
JSRegExp::Flag flag);
|
|
Node* FlagGetter(Node* const context, Node* const regexp, JSRegExp::Flag flag,
|
|
bool is_fastpath);
|
|
void FlagGetter(Node* context, Node* receiver, JSRegExp::Flag flag,
|
|
int counter, const char* method_name);
|
|
|
|
Node* IsRegExp(Node* const context, Node* const maybe_receiver);
|
|
|
|
TNode<Object> LoadRegExpResultFirstMatch(SloppyTNode<Context> context,
|
|
SloppyTNode<JSObject> maybe_array);
|
|
|
|
Node* RegExpInitialize(Node* const context, Node* const regexp,
|
|
Node* const maybe_pattern, Node* const maybe_flags);
|
|
|
|
Node* RegExpExec(Node* context, Node* regexp, Node* string);
|
|
|
|
Node* AdvanceStringIndex(Node* const string, Node* const index,
|
|
Node* const is_unicode, bool is_fastpath);
|
|
|
|
void RegExpPrototypeMatchBody(Node* const context, Node* const regexp,
|
|
TNode<String> const string,
|
|
const bool is_fastpath);
|
|
|
|
void RegExpPrototypeSearchBodyFast(Node* const context, Node* const regexp,
|
|
Node* const string);
|
|
void RegExpPrototypeSearchBodySlow(Node* const context, Node* const regexp,
|
|
Node* const string);
|
|
|
|
void RegExpPrototypeSplitBody(Node* const context, Node* const regexp,
|
|
TNode<String> const string, Node* const limit);
|
|
|
|
Node* ReplaceGlobalCallableFastPath(Node* context, Node* regexp, Node* string,
|
|
Node* replace_callable);
|
|
Node* ReplaceSimpleStringFastPath(Node* context, Node* regexp,
|
|
TNode<String> string,
|
|
TNode<String> replace_string);
|
|
};
|
|
|
|
} // namespace internal
|
|
} // namespace v8
|
|
|
|
#endif // V8_BUILTINS_BUILTINS_REGEXP_GEN_H_
|