зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1387968 - Part 2: Optimize array accesses and allocations in RegExpGetSubstitution. r=till
--HG-- extra : rebase_source : 06bba8286960b5f805b152aeaceb52c62b275913
This commit is contained in:
Родитель
1618ce2e73
Коммит
c70f65a1f9
|
@ -22,6 +22,7 @@
|
|||
#include "jsobjinlines.h"
|
||||
|
||||
#include "vm/NativeObject-inl.h"
|
||||
#include "vm/UnboxedObject-inl.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::unicode;
|
||||
|
@ -1203,6 +1204,8 @@ js::regexp_test_no_statics(JSContext* cx, unsigned argc, Value* vp)
|
|||
return status != RegExpRunStatus_Error;
|
||||
}
|
||||
|
||||
using CapturesVector = GCVector<Value, 4>;
|
||||
|
||||
static void
|
||||
GetParen(JSLinearString* matched, const JS::Value& capture, JSSubString* out)
|
||||
{
|
||||
|
@ -1217,7 +1220,7 @@ GetParen(JSLinearString* matched, const JS::Value& capture, JSSubString* out)
|
|||
template <typename CharT>
|
||||
static bool
|
||||
InterpretDollar(JSLinearString* matched, JSLinearString* string, size_t position, size_t tailPos,
|
||||
MutableHandle<GCVector<Value>> captures, JSLinearString* replacement,
|
||||
Handle<CapturesVector> captures, JSLinearString* replacement,
|
||||
const CharT* replacementBegin, const CharT* currentDollar,
|
||||
const CharT* replacementEnd,
|
||||
JSSubString* out, size_t* skip)
|
||||
|
@ -1229,7 +1232,7 @@ InterpretDollar(JSLinearString* matched, JSLinearString* string, size_t position
|
|||
return false;
|
||||
|
||||
/* ES 2016 draft Mar 25, 2016 Table 46. */
|
||||
char16_t c = currentDollar[1];
|
||||
CharT c = currentDollar[1];
|
||||
if (JS7_ISDEC(c)) {
|
||||
/* $n, $nn */
|
||||
unsigned num = JS7_UNDEC(c);
|
||||
|
@ -1296,7 +1299,7 @@ InterpretDollar(JSLinearString* matched, JSLinearString* string, size_t position
|
|||
template <typename CharT>
|
||||
static bool
|
||||
FindReplaceLengthString(JSContext* cx, HandleLinearString matched, HandleLinearString string,
|
||||
size_t position, size_t tailPos, MutableHandle<GCVector<Value>> captures,
|
||||
size_t position, size_t tailPos, Handle<CapturesVector> captures,
|
||||
HandleLinearString replacement, size_t firstDollarIndex, size_t* sizep)
|
||||
{
|
||||
CheckedInt<uint32_t> replen = replacement->length();
|
||||
|
@ -1335,7 +1338,7 @@ FindReplaceLengthString(JSContext* cx, HandleLinearString matched, HandleLinearS
|
|||
|
||||
static bool
|
||||
FindReplaceLength(JSContext* cx, HandleLinearString matched, HandleLinearString string,
|
||||
size_t position, size_t tailPos, MutableHandle<GCVector<Value>> captures,
|
||||
size_t position, size_t tailPos, Handle<CapturesVector> captures,
|
||||
HandleLinearString replacement, size_t firstDollarIndex, size_t* sizep)
|
||||
{
|
||||
return replacement->hasLatin1Chars()
|
||||
|
@ -1353,7 +1356,7 @@ FindReplaceLength(JSContext* cx, HandleLinearString matched, HandleLinearString
|
|||
template <typename CharT>
|
||||
static void
|
||||
DoReplace(HandleLinearString matched, HandleLinearString string,
|
||||
size_t position, size_t tailPos, MutableHandle<GCVector<Value>> captures,
|
||||
size_t position, size_t tailPos, Handle<CapturesVector> captures,
|
||||
HandleLinearString replacement, size_t firstDollarIndex, StringBuffer &sb)
|
||||
{
|
||||
JS::AutoCheckCannotGC nogc;
|
||||
|
@ -1388,7 +1391,7 @@ DoReplace(HandleLinearString matched, HandleLinearString string,
|
|||
|
||||
static bool
|
||||
NeedTwoBytes(HandleLinearString string, HandleLinearString replacement,
|
||||
HandleLinearString matched, Handle<GCVector<Value>> captures)
|
||||
HandleLinearString matched, Handle<CapturesVector> captures)
|
||||
{
|
||||
if (string->hasTwoByteChars())
|
||||
return true;
|
||||
|
@ -1398,7 +1401,7 @@ NeedTwoBytes(HandleLinearString string, HandleLinearString replacement,
|
|||
return true;
|
||||
|
||||
for (size_t i = 0, len = captures.length(); i < len; i++) {
|
||||
Value capture = captures[i];
|
||||
const Value& capture = captures[i];
|
||||
if (capture.isUndefined())
|
||||
continue;
|
||||
if (capture.toString()->hasTwoByteChars())
|
||||
|
@ -1415,19 +1418,16 @@ js::RegExpGetSubstitution(JSContext* cx, HandleObject matchResult, HandleLinearS
|
|||
size_t firstDollarIndex, MutableHandleValue rval)
|
||||
{
|
||||
MOZ_ASSERT(firstDollarIndex < replacement->length());
|
||||
MOZ_ASSERT(matchResult->is<ArrayObject>() || matchResult->is<UnboxedArrayObject>());
|
||||
|
||||
// Step 1 (skipped).
|
||||
|
||||
// Step 10 (reordered).
|
||||
uint32_t matchResultLength;
|
||||
if (!GetLengthProperty(cx, matchResult, &matchResultLength))
|
||||
return false;
|
||||
uint32_t matchResultLength = GetAnyBoxedOrUnboxedArrayLength(matchResult);
|
||||
MOZ_ASSERT(matchResultLength > 0);
|
||||
MOZ_ASSERT(matchResultLength == GetAnyBoxedOrUnboxedInitializedLength(matchResult));
|
||||
|
||||
RootedValue matchedValue(cx);
|
||||
if (!GetElement(cx, matchResult, matchResult, 0, &matchedValue))
|
||||
return false;
|
||||
|
||||
const Value& matchedValue = GetAnyBoxedOrUnboxedDenseElement(matchResult, 0);
|
||||
RootedLinearString matched(cx, matchedValue.toString()->ensureLinear(cx));
|
||||
if (!matched)
|
||||
return false;
|
||||
|
@ -1441,23 +1441,20 @@ js::RegExpGetSubstitution(JSContext* cx, HandleObject matchResult, HandleLinearS
|
|||
MOZ_ASSERT(position <= string->length());
|
||||
|
||||
uint32_t nCaptures = matchResultLength - 1;
|
||||
Rooted<GCVector<Value>> captures(cx, GCVector<Value>(cx));
|
||||
Rooted<CapturesVector> captures(cx, CapturesVector(cx));
|
||||
if (!captures.reserve(nCaptures))
|
||||
return false;
|
||||
|
||||
// Step 7.
|
||||
RootedValue capture(cx);
|
||||
for (uint32_t i = 1; i <= nCaptures; i++) {
|
||||
if (!GetElement(cx, matchResult, matchResult, i, &capture))
|
||||
return false;
|
||||
const Value& capture = GetAnyBoxedOrUnboxedDenseElement(matchResult, i);
|
||||
|
||||
if (capture.isUndefined()) {
|
||||
captures.infallibleAppend(capture);
|
||||
continue;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(capture.isString());
|
||||
RootedLinearString captureLinear(cx, capture.toString()->ensureLinear(cx));
|
||||
JSLinearString* captureLinear = capture.toString()->ensureLinear(cx);
|
||||
if (!captureLinear)
|
||||
return false;
|
||||
captures.infallibleAppend(StringValue(captureLinear));
|
||||
|
@ -1477,7 +1474,7 @@ js::RegExpGetSubstitution(JSContext* cx, HandleObject matchResult, HandleLinearS
|
|||
|
||||
// Step 11.
|
||||
size_t reserveLength;
|
||||
if (!FindReplaceLength(cx, matched, string, position, tailPos, &captures, replacement,
|
||||
if (!FindReplaceLength(cx, matched, string, position, tailPos, captures, replacement,
|
||||
firstDollarIndex, &reserveLength))
|
||||
{
|
||||
return false;
|
||||
|
@ -1493,10 +1490,10 @@ js::RegExpGetSubstitution(JSContext* cx, HandleObject matchResult, HandleLinearS
|
|||
return false;
|
||||
|
||||
if (replacement->hasLatin1Chars()) {
|
||||
DoReplace<Latin1Char>(matched, string, position, tailPos, &captures,
|
||||
DoReplace<Latin1Char>(matched, string, position, tailPos, captures,
|
||||
replacement, firstDollarIndex, result);
|
||||
} else {
|
||||
DoReplace<char16_t>(matched, string, position, tailPos, &captures,
|
||||
DoReplace<char16_t>(matched, string, position, tailPos, captures,
|
||||
replacement, firstDollarIndex, result);
|
||||
}
|
||||
|
||||
|
|
|
@ -1533,31 +1533,23 @@ intrinsic_RegExpGetSubstitution(JSContext* cx, unsigned argc, Value* vp)
|
|||
MOZ_ASSERT(args.length() == 5);
|
||||
|
||||
RootedObject matchResult(cx, &args[0].toObject());
|
||||
#ifdef DEBUG
|
||||
bool isArray = false;
|
||||
MOZ_ALWAYS_TRUE(IsArray(cx, matchResult, &isArray));
|
||||
MOZ_ASSERT(isArray);
|
||||
#endif
|
||||
|
||||
RootedString string(cx, args[1].toString());
|
||||
RootedLinearString string(cx, args[1].toString()->ensureLinear(cx));
|
||||
if (!string)
|
||||
return false;
|
||||
|
||||
int32_t position = int32_t(args[2].toNumber());
|
||||
MOZ_ASSERT(position >= 0);
|
||||
|
||||
RootedString replacement(cx, args[3].toString());
|
||||
RootedLinearString replacement(cx, args[3].toString()->ensureLinear(cx));
|
||||
if (!replacement)
|
||||
return false;
|
||||
|
||||
int32_t firstDollarIndex = int32_t(args[4].toNumber());
|
||||
MOZ_ASSERT(firstDollarIndex >= 0);
|
||||
|
||||
RootedLinearString stringLinear(cx, string->ensureLinear(cx));
|
||||
if (!stringLinear)
|
||||
return false;
|
||||
RootedLinearString replacementLinear(cx, replacement->ensureLinear(cx));
|
||||
if (!replacementLinear)
|
||||
return false;
|
||||
|
||||
return RegExpGetSubstitution(cx, matchResult, stringLinear, size_t(position),
|
||||
replacementLinear, size_t(firstDollarIndex), args.rval());
|
||||
return RegExpGetSubstitution(cx, matchResult, string, size_t(position), replacement,
|
||||
size_t(firstDollarIndex), args.rval());
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
Загрузка…
Ссылка в новой задаче