зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1226936 - Remove PreserveRegExpStatics and telemetry for it. r=till
--HG-- extra : rebase_source : 5d74966072564ce60f971afde6de351a72550b0e
This commit is contained in:
Родитель
84b12d8d2c
Коммит
61a51b2b78
|
@ -598,8 +598,6 @@ const JSFunctionSpec js::regexp_methods[] = {
|
|||
RegExpStatics* res = cx->global()->getRegExpStatics(cx); \
|
||||
if (!res) \
|
||||
return false; \
|
||||
if (!res->checkRestoredFromModifiedMatch(cx)) \
|
||||
return false; \
|
||||
code; \
|
||||
}
|
||||
|
||||
|
|
|
@ -5,5 +5,4 @@
|
|||
});
|
||||
assertEq(RegExp.lastMatch, '123');
|
||||
});
|
||||
assertEq(RegExp.lastMatch, 'abc');
|
||||
|
||||
assertEq(RegExp.lastMatch, '123');
|
||||
|
|
|
@ -1126,9 +1126,6 @@ PrepareAndExecuteRegExp(JSContext* cx, MacroAssembler& masm, Register regexp, Re
|
|||
masm.branchPtr(Assembler::Equal, codePointer, ImmWord(0), failure);
|
||||
masm.loadPtr(Address(codePointer, JitCode::offsetOfCode()), codePointer);
|
||||
|
||||
// Don't handle execution inside a PreserveRegExpStatics instance.
|
||||
masm.branchPtr(Assembler::NotEqual, AbsoluteAddress(res->addressOfBufferLink()), ImmWord(0), failure);
|
||||
|
||||
// Finish filling in the InputOutputData instance on the stack.
|
||||
if (mode == RegExpShared::Normal) {
|
||||
masm.computeEffectiveAddress(Address(masm.getStackPointer(), matchPairsStartOffset), temp2);
|
||||
|
|
|
@ -750,7 +750,7 @@ struct JSCompartment
|
|||
// NO LONGER USING 6
|
||||
DeprecatedFlagsArgument = 7, // JS 1.3 or older
|
||||
// NO LONGER USING 8
|
||||
DeprecatedRestoredRegExpStatics = 9,// Unknown
|
||||
// NO LONGER USING 9
|
||||
DeprecatedLanguageExtensionCount
|
||||
};
|
||||
|
||||
|
|
|
@ -2591,7 +2591,7 @@ ReplaceRegExp(JSContext* cx, RegExpStatics* res, ReplaceData& rdata);
|
|||
|
||||
static bool
|
||||
DoMatchForReplaceLocal(JSContext* cx, RegExpStatics* res, HandleLinearString linearStr,
|
||||
RegExpShared& re, ReplaceData& rdata)
|
||||
RegExpShared& re, ReplaceData& rdata, size_t* rightContextOffset)
|
||||
{
|
||||
ScopedMatchPairs matches(&cx->tempLifoAlloc());
|
||||
RegExpRunStatus status = re.execute(cx, linearStr, 0, &matches);
|
||||
|
@ -2601,6 +2601,9 @@ DoMatchForReplaceLocal(JSContext* cx, RegExpStatics* res, HandleLinearString lin
|
|||
if (status == RegExpRunStatus_Success_NotFound)
|
||||
return true;
|
||||
|
||||
MatchPair& match = matches[0];
|
||||
*rightContextOffset = match.limit;
|
||||
|
||||
if (!res->updateFromMatchPairs(cx, linearStr, matches))
|
||||
return false;
|
||||
|
||||
|
@ -2609,7 +2612,7 @@ DoMatchForReplaceLocal(JSContext* cx, RegExpStatics* res, HandleLinearString lin
|
|||
|
||||
static bool
|
||||
DoMatchForReplaceGlobal(JSContext* cx, RegExpStatics* res, HandleLinearString linearStr,
|
||||
RegExpShared& re, ReplaceData& rdata)
|
||||
RegExpShared& re, ReplaceData& rdata, size_t* rightContextOffset)
|
||||
{
|
||||
size_t charsLen = linearStr->length();
|
||||
ScopedMatchPairs matches(&cx->tempLifoAlloc());
|
||||
|
@ -2626,6 +2629,7 @@ DoMatchForReplaceGlobal(JSContext* cx, RegExpStatics* res, HandleLinearString li
|
|||
|
||||
MatchPair& match = matches[0];
|
||||
searchIndex = match.isEmpty() ? match.limit + 1 : match.limit;
|
||||
*rightContextOffset = match.limit;
|
||||
|
||||
if (!res->updateFromMatchPairs(cx, linearStr, matches))
|
||||
return false;
|
||||
|
@ -2778,9 +2782,6 @@ FindReplaceLength(JSContext* cx, RegExpStatics* res, ReplaceData& rdata, size_t*
|
|||
|
||||
if (rdata.lambda) {
|
||||
RootedObject lambda(cx, rdata.lambda);
|
||||
PreserveRegExpStatics staticsGuard(cx, res);
|
||||
if (!staticsGuard.init(cx))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* In the lambda case, not only do we find the replacement string's
|
||||
|
@ -3319,11 +3320,12 @@ StrReplaceRegExp(JSContext* cx, ReplaceData& rdata)
|
|||
if (!linearStr)
|
||||
return nullptr;
|
||||
|
||||
size_t rightContextOffset = 0;
|
||||
if (re.global()) {
|
||||
if (!DoMatchForReplaceGlobal(cx, res, linearStr, re, rdata))
|
||||
if (!DoMatchForReplaceGlobal(cx, res, linearStr, re, rdata, &rightContextOffset))
|
||||
return nullptr;
|
||||
} else {
|
||||
if (!DoMatchForReplaceLocal(cx, res, linearStr, re, rdata))
|
||||
if (!DoMatchForReplaceLocal(cx, res, linearStr, re, rdata, &rightContextOffset))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -3332,9 +3334,9 @@ StrReplaceRegExp(JSContext* cx, ReplaceData& rdata)
|
|||
return rdata.str;
|
||||
}
|
||||
|
||||
JSSubString sub;
|
||||
res->getRightContext(&sub);
|
||||
if (!rdata.sb.appendSubstring(sub.base, sub.offset, sub.length))
|
||||
MOZ_ASSERT(rightContextOffset <= rdata.str->length());
|
||||
size_t length = rdata.str->length() - rightContextOffset;
|
||||
if (!rdata.sb.appendSubstring(rdata.str, rightContextOffset, length))
|
||||
return nullptr;
|
||||
|
||||
return rdata.sb.finishString();
|
||||
|
|
|
@ -118,15 +118,3 @@ RegExpStatics::executeLazy(JSContext* cx)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RegExpStatics::checkRestoredFromModifiedMatch(JSContext* cx)
|
||||
{
|
||||
if (isRestoredFromModifiedMatch) {
|
||||
if (JSScript* script = cx->currentScript()) {
|
||||
const char* filename = script->filename();
|
||||
cx->compartment()->addTelemetry(filename, JSCompartment::DeprecatedRestoredRegExpStatics);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -42,49 +42,13 @@ class RegExpStatics
|
|||
*/
|
||||
int32_t pendingLazyEvaluation;
|
||||
|
||||
/* Linkage for preserving RegExpStatics during nested RegExp execution. */
|
||||
RegExpStatics* bufferLink;
|
||||
bool copied;
|
||||
|
||||
/* ID for each match result, incrementing on each update. */
|
||||
size_t matchId;
|
||||
|
||||
/*
|
||||
* Match result is restored from differnt ID in String.prototype.replace
|
||||
* with function argument. While this value is true, the value of each
|
||||
* RegExp static properties are different from other engines. We are going
|
||||
* to remove PreserveRegExpStatics and make those properties match to
|
||||
* other engines. (See bug 1208835)
|
||||
*/
|
||||
bool isRestoredFromModifiedMatch;
|
||||
|
||||
public:
|
||||
RegExpStatics()
|
||||
: bufferLink(nullptr), copied(false),
|
||||
matchId(0), isRestoredFromModifiedMatch(false)
|
||||
{
|
||||
clear();
|
||||
}
|
||||
RegExpStatics() { clear(); }
|
||||
static RegExpStaticsObject* create(ExclusiveContext* cx, Handle<GlobalObject*> parent);
|
||||
|
||||
private:
|
||||
bool executeLazy(JSContext* cx);
|
||||
|
||||
inline void aboutToWrite();
|
||||
inline void copyTo(RegExpStatics& dst);
|
||||
|
||||
inline void restore();
|
||||
bool save(JSContext* cx, RegExpStatics* buffer) {
|
||||
MOZ_ASSERT(!buffer->copied && !buffer->bufferLink);
|
||||
buffer->bufferLink = bufferLink;
|
||||
bufferLink = buffer;
|
||||
if (!buffer->matches.allocOrExpandArray(matches.length())) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void checkInvariants();
|
||||
|
||||
/*
|
||||
|
@ -97,12 +61,8 @@ class RegExpStatics
|
|||
void markFlagsSet(JSContext* cx);
|
||||
|
||||
struct InitBuffer {};
|
||||
explicit RegExpStatics(InitBuffer)
|
||||
: bufferLink(nullptr), copied(false),
|
||||
matchId(0), isRestoredFromModifiedMatch(false)
|
||||
{}
|
||||
explicit RegExpStatics(InitBuffer) {}
|
||||
|
||||
friend class PreserveRegExpStatics;
|
||||
friend class AutoRegExpStaticsBuffer;
|
||||
|
||||
public:
|
||||
|
@ -112,7 +72,6 @@ class RegExpStatics
|
|||
inline bool updateFromMatchPairs(JSContext* cx, JSLinearString* input, MatchPairs& newPairs);
|
||||
|
||||
void setMultiline(JSContext* cx, bool enabled) {
|
||||
aboutToWrite();
|
||||
if (enabled) {
|
||||
flags = RegExpFlag(flags | MultilineFlag);
|
||||
markFlagsSet(cx);
|
||||
|
@ -125,7 +84,6 @@ class RegExpStatics
|
|||
|
||||
/* Corresponds to JSAPI functionality to set the pending RegExp input. */
|
||||
void reset(JSContext* cx, JSString* newInput, bool newMultiline) {
|
||||
aboutToWrite();
|
||||
clear();
|
||||
pendingInput = newInput;
|
||||
setMultiline(cx, newMultiline);
|
||||
|
@ -142,8 +100,6 @@ class RegExpStatics
|
|||
return matches;
|
||||
}
|
||||
|
||||
bool checkRestoredFromModifiedMatch(JSContext* cx);
|
||||
|
||||
JSString* getPendingInput() const { return pendingInput; }
|
||||
|
||||
RegExpFlag getFlags() const { return flags; }
|
||||
|
@ -179,10 +135,6 @@ class RegExpStatics
|
|||
void getLeftContext(JSSubString* out) const;
|
||||
void getRightContext(JSSubString* out) const;
|
||||
|
||||
const void* addressOfBufferLink() {
|
||||
return &bufferLink;
|
||||
}
|
||||
|
||||
static size_t offsetOfPendingInput() {
|
||||
return offsetof(RegExpStatics, pendingInput);
|
||||
}
|
||||
|
@ -240,31 +192,6 @@ class MOZ_RAII AutoRegExpStaticsBuffer : private JS::CustomAutoRooter
|
|||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class PreserveRegExpStatics
|
||||
{
|
||||
RegExpStatics * const original;
|
||||
AutoRegExpStaticsBuffer buffer;
|
||||
size_t beforeId;
|
||||
|
||||
public:
|
||||
explicit PreserveRegExpStatics(JSContext* cx, RegExpStatics* original)
|
||||
: original(original),
|
||||
buffer(cx),
|
||||
beforeId(original->matchId)
|
||||
{}
|
||||
|
||||
bool init(JSContext* cx) {
|
||||
return original->save(cx, &buffer.getStatics());
|
||||
}
|
||||
|
||||
~PreserveRegExpStatics() {
|
||||
if (original->matchId != beforeId)
|
||||
original->isRestoredFromModifiedMatch = true;
|
||||
|
||||
original->restore();
|
||||
}
|
||||
};
|
||||
|
||||
inline bool
|
||||
RegExpStatics::createDependent(JSContext* cx, size_t start, size_t end, MutableHandleValue out)
|
||||
{
|
||||
|
@ -446,48 +373,11 @@ RegExpStatics::getRightContext(JSSubString* out) const
|
|||
out->init(matchesInput, matches[0].limit, length);
|
||||
}
|
||||
|
||||
inline void
|
||||
RegExpStatics::copyTo(RegExpStatics& dst)
|
||||
{
|
||||
/* Destination buffer has already been reserved by save(). */
|
||||
if (!pendingLazyEvaluation)
|
||||
dst.matches.initArrayFrom(matches);
|
||||
|
||||
dst.matchesInput = matchesInput;
|
||||
dst.lazySource = lazySource;
|
||||
dst.lazyFlags = lazyFlags;
|
||||
dst.lazyIndex = lazyIndex;
|
||||
dst.pendingInput = pendingInput;
|
||||
dst.flags = flags;
|
||||
dst.pendingLazyEvaluation = pendingLazyEvaluation;
|
||||
|
||||
MOZ_ASSERT_IF(pendingLazyEvaluation, lazySource);
|
||||
MOZ_ASSERT_IF(pendingLazyEvaluation, matchesInput);
|
||||
}
|
||||
|
||||
inline void
|
||||
RegExpStatics::aboutToWrite()
|
||||
{
|
||||
if (bufferLink && !bufferLink->copied) {
|
||||
copyTo(*bufferLink);
|
||||
bufferLink->copied = true;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
RegExpStatics::restore()
|
||||
{
|
||||
if (bufferLink->copied)
|
||||
bufferLink->copyTo(*this);
|
||||
bufferLink = bufferLink->bufferLink;
|
||||
}
|
||||
|
||||
inline void
|
||||
RegExpStatics::updateLazily(JSContext* cx, JSLinearString* input,
|
||||
RegExpShared* shared, size_t lastIndex)
|
||||
{
|
||||
MOZ_ASSERT(input && shared);
|
||||
aboutToWrite();
|
||||
|
||||
BarrieredSetPair<JSString, JSLinearString>(cx->zone(),
|
||||
pendingInput, input,
|
||||
|
@ -497,22 +387,17 @@ RegExpStatics::updateLazily(JSContext* cx, JSLinearString* input,
|
|||
lazyFlags = shared->flags;
|
||||
lazyIndex = lastIndex;
|
||||
pendingLazyEvaluation = 1;
|
||||
matchId++;
|
||||
isRestoredFromModifiedMatch = false;
|
||||
}
|
||||
|
||||
inline bool
|
||||
RegExpStatics::updateFromMatchPairs(JSContext* cx, JSLinearString* input, MatchPairs& newPairs)
|
||||
{
|
||||
MOZ_ASSERT(input);
|
||||
aboutToWrite();
|
||||
|
||||
/* Unset all lazy state. */
|
||||
pendingLazyEvaluation = false;
|
||||
this->lazySource = nullptr;
|
||||
this->lazyIndex = size_t(-1);
|
||||
matchId++;
|
||||
isRestoredFromModifiedMatch = false;
|
||||
|
||||
BarrieredSetPair<JSString, JSLinearString>(cx->zone(),
|
||||
pendingInput, input,
|
||||
|
@ -529,8 +414,6 @@ RegExpStatics::updateFromMatchPairs(JSContext* cx, JSLinearString* input, MatchP
|
|||
inline void
|
||||
RegExpStatics::clear()
|
||||
{
|
||||
aboutToWrite();
|
||||
|
||||
matches.forgetArray();
|
||||
matchesInput = nullptr;
|
||||
lazySource = nullptr;
|
||||
|
@ -544,7 +427,6 @@ RegExpStatics::clear()
|
|||
inline void
|
||||
RegExpStatics::setPendingInput(JSString* newInput)
|
||||
{
|
||||
aboutToWrite();
|
||||
pendingInput = newInput;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче