зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1644590: Add fast path for atom regexps r=jandem
We fill in the match pairs for atom regexps using an ABI call, then use the normal jit path for everything else (checking for errors, allocating results, etc...). I also made a drive-by fix to remove the cx argument from RegExpShared::executeAtom, since we don't need it. Differential Revision: https://phabricator.services.mozilla.com/D79001
This commit is contained in:
Родитель
2756eea4aa
Коммит
5c8dcb2c0a
|
@ -2182,7 +2182,8 @@ static bool PrepareAndExecuteRegExp(JSContext* cx, MacroAssembler& masm,
|
|||
// execution finished successfully.
|
||||
|
||||
// Initialize MatchPairs::pairCount to 1. The correct value can only
|
||||
// be determined after loading the RegExpShared.
|
||||
// be determined after loading the RegExpShared. If the RegExpShared
|
||||
// has Kind::Atom, this is the correct pairCount.
|
||||
masm.store32(Imm32(1), pairCountAddress);
|
||||
|
||||
// Initialize MatchPairs::pairs pointer
|
||||
|
@ -2202,6 +2203,33 @@ static bool PrepareAndExecuteRegExp(JSContext* cx, MacroAssembler& masm,
|
|||
regexpReg);
|
||||
masm.branchPtr(Assembler::Equal, regexpReg, ImmWord(0), failure);
|
||||
|
||||
// Handle Atom matches
|
||||
Label notAtom, checkSuccess;
|
||||
masm.branchPtr(Assembler::Equal,
|
||||
Address(regexpReg, RegExpShared::offsetOfPatternAtom()),
|
||||
ImmWord(0), ¬Atom);
|
||||
{
|
||||
LiveGeneralRegisterSet regsToSave(GeneralRegisterSet::Volatile());
|
||||
regsToSave.takeUnchecked(temp1);
|
||||
regsToSave.takeUnchecked(temp2);
|
||||
regsToSave.takeUnchecked(temp3);
|
||||
|
||||
masm.computeEffectiveAddress(matchPairsAddress, temp3);
|
||||
|
||||
masm.PushRegsInMask(regsToSave);
|
||||
masm.setupUnalignedABICall(temp2);
|
||||
masm.passABIArg(regexpReg);
|
||||
masm.passABIArg(input);
|
||||
masm.passABIArg(lastIndex);
|
||||
masm.passABIArg(temp3);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, ExecuteRegExpAtomRaw));
|
||||
masm.storeCallInt32Result(temp1);
|
||||
masm.PopRegsInMask(regsToSave);
|
||||
|
||||
masm.jump(&checkSuccess);
|
||||
}
|
||||
masm.bind(¬Atom);
|
||||
|
||||
// Don't handle regexps with too many capture pairs.
|
||||
masm.load32(Address(regexpReg, RegExpShared::offsetOfPairCount()), temp2);
|
||||
masm.branch32(Assembler::Above, temp2, Imm32(RegExpObject::MaxPairCount),
|
||||
|
@ -2296,6 +2324,7 @@ static bool PrepareAndExecuteRegExp(JSContext* cx, MacroAssembler& masm,
|
|||
#endif
|
||||
|
||||
Label success;
|
||||
masm.bind(&checkSuccess);
|
||||
masm.branch32(Assembler::Equal, temp1,
|
||||
Imm32(RegExpRunStatus_Success_NotFound), notFound);
|
||||
masm.branch32(Assembler::Equal, temp1, Imm32(RegExpRunStatus_Error), failure);
|
||||
|
|
|
@ -66,6 +66,7 @@ class MatchPairs {
|
|||
|
||||
void forgetArray() { pairs_ = nullptr; }
|
||||
|
||||
public:
|
||||
void checkAgainst(size_t inputLength) {
|
||||
#ifdef DEBUG
|
||||
for (size_t i = 0; i < pairCount_; i++) {
|
||||
|
@ -79,7 +80,6 @@ class MatchPairs {
|
|||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
/* Querying functions in the style of RegExpStatics. */
|
||||
bool empty() const { return pairCount_ == 0; }
|
||||
size_t pairCount() const {
|
||||
|
|
|
@ -712,7 +712,7 @@ RegExpRunStatus RegExpShared::execute(JSContext* cx,
|
|||
}
|
||||
|
||||
if (re->kind() == RegExpShared::Kind::Atom) {
|
||||
return RegExpShared::executeAtom(cx, re, input, start, matches);
|
||||
return RegExpShared::executeAtom(re, input, start, matches);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -854,14 +854,9 @@ bool RegExpShared::markedForTierUp() const {
|
|||
return ticks_ == 0;
|
||||
}
|
||||
|
||||
/* static */
|
||||
RegExpRunStatus RegExpShared::executeAtom(JSContext* cx,
|
||||
MutableHandleRegExpShared re,
|
||||
HandleLinearString input,
|
||||
size_t start,
|
||||
VectorMatchPairs* matches) {
|
||||
static RegExpRunStatus ExecuteAtomImpl(RegExpShared* re, JSLinearString* input,
|
||||
size_t start, MatchPairs* matches) {
|
||||
MOZ_ASSERT(re->pairCount() == 1);
|
||||
|
||||
size_t length = input->length();
|
||||
size_t searchLength = re->patternAtom()->length();
|
||||
|
||||
|
@ -876,8 +871,7 @@ RegExpRunStatus RegExpShared::executeAtom(JSContext* cx,
|
|||
|
||||
(*matches)[0].start = start;
|
||||
(*matches)[0].limit = start + searchLength;
|
||||
matches->checkAgainst(length);
|
||||
|
||||
matches->checkAgainst(input->length());
|
||||
return RegExpRunStatus_Success;
|
||||
}
|
||||
|
||||
|
@ -888,11 +882,25 @@ RegExpRunStatus RegExpShared::executeAtom(JSContext* cx,
|
|||
|
||||
(*matches)[0].start = res;
|
||||
(*matches)[0].limit = res + searchLength;
|
||||
matches->checkAgainst(length);
|
||||
|
||||
matches->checkAgainst(input->length());
|
||||
return RegExpRunStatus_Success;
|
||||
}
|
||||
|
||||
RegExpRunStatus js::ExecuteRegExpAtomRaw(RegExpShared* re,
|
||||
JSLinearString* input, size_t start,
|
||||
MatchPairs* matchPairs) {
|
||||
AutoUnsafeCallWithABI unsafe;
|
||||
return ExecuteAtomImpl(re, input, start, matchPairs);
|
||||
}
|
||||
|
||||
/* static */
|
||||
RegExpRunStatus RegExpShared::executeAtom(MutableHandleRegExpShared re,
|
||||
HandleLinearString input,
|
||||
size_t start,
|
||||
VectorMatchPairs* matches) {
|
||||
return ExecuteAtomImpl(re, input, start, matches);
|
||||
}
|
||||
|
||||
size_t RegExpShared::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) {
|
||||
size_t n = 0;
|
||||
|
||||
|
|
|
@ -152,8 +152,7 @@ class RegExpShared : public gc::TenuredCell {
|
|||
static bool compileIfNecessary(JSContext* cx, MutableHandleRegExpShared res,
|
||||
HandleLinearString input, CodeKind code);
|
||||
|
||||
static RegExpRunStatus executeAtom(JSContext* cx,
|
||||
MutableHandleRegExpShared re,
|
||||
static RegExpRunStatus executeAtom(MutableHandleRegExpShared re,
|
||||
HandleLinearString input, size_t start,
|
||||
VectorMatchPairs* matches);
|
||||
|
||||
|
@ -238,6 +237,10 @@ class RegExpShared : public gc::TenuredCell {
|
|||
HeaderWithAtom::offsetOfPtr();
|
||||
}
|
||||
|
||||
static size_t offsetOfPatternAtom() {
|
||||
return offsetof(RegExpShared, patternAtom_);
|
||||
}
|
||||
|
||||
static size_t offsetOfFlags() { return offsetof(RegExpShared, flags); }
|
||||
|
||||
static size_t offsetOfPairCount() {
|
||||
|
@ -396,6 +399,9 @@ class RegExpRealm {
|
|||
}
|
||||
};
|
||||
|
||||
RegExpRunStatus ExecuteRegExpAtomRaw(RegExpShared* re, JSLinearString* input,
|
||||
size_t start, MatchPairs* matchPairs);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
namespace JS {
|
||||
|
|
Загрузка…
Ссылка в новой задаче