Follow-up for 560358, poke the GC when overwriting the value of RegExpStatics.input (fix leak).

This commit is contained in:
Andreas Gal 2010-04-28 18:49:36 -07:00
parent 6e29637654
commit 7bf56e15a7
3 changed files with 36 additions and 27 deletions

View File

@ -5507,9 +5507,9 @@ JS_SetRegExpInput(JSContext *cx, JSString *input, JSBool multiline)
CHECK_REQUEST(cx);
/* No locking required, cx is thread-private and input must be live. */
res = &cx->regExpStatics;
res->clearRoots();
res->input = input;
res->multiline = multiline;
cx->runtime->gcPoke = JS_TRUE;
}
JS_PUBLIC_API(void)
@ -5517,18 +5517,13 @@ JS_ClearRegExpStatics(JSContext *cx)
{
/* No locking required, cx is thread-private and input must be live. */
cx->regExpStatics.clear();
cx->runtime->gcPoke = JS_TRUE;
}
JS_PUBLIC_API(void)
JS_ClearRegExpRoots(JSContext *cx)
{
JSRegExpStatics *res;
/* No locking required, cx is thread-private and input must be live. */
res = &cx->regExpStatics;
res->input = NULL;
cx->runtime->gcPoke = JS_TRUE;
cx->regExpStatics.clearRoots();
}
/* TODO: compile, execute, get/set other statics... */

View File

@ -1179,6 +1179,7 @@ class AutoGCRooter;
}
struct JSRegExpStatics {
JSContext *cx;
JSString *input; /* input string to match (perl $_, GC root) */
JSBool multiline; /* whether input contains newlines (perl $*) */
JSSubString lastMatch; /* last string matched (perl $&) */
@ -1187,27 +1188,11 @@ struct JSRegExpStatics {
JSSubString rightContext; /* input to right of last match (perl $') */
js::Vector<JSSubString> parens; /* last set of parens matched (perl $1, $2) */
JSRegExpStatics(JSContext *cx) : parens(cx) {}
JSRegExpStatics(JSContext *cx) : cx(cx), parens(cx) {}
bool copy(const JSRegExpStatics& other) {
input = other.input;
multiline = other.multiline;
lastMatch = other.lastMatch;
lastParen = other.lastParen;
leftContext = other.leftContext;
rightContext = other.rightContext;
if (!parens.resize(other.parens.length()))
return false;
memcpy(parens.begin(), other.parens.begin(), sizeof(JSSubString) * parens.length());
return true;
}
void clear() {
input = NULL;
multiline = false;
lastMatch = lastParen = leftContext = rightContext = js_EmptySubString;
parens.clear();
}
bool copy(const JSRegExpStatics& other);
void clearRoots();
void clear();
};
struct JSContext

View File

@ -353,6 +353,35 @@ typedef struct REGlobalData {
size_t backTrackLimit; /* upper limit on backtrack states */
} REGlobalData;
void
JSRegExpStatics::clearRoots() {
input = NULL;
cx->runtime->gcPoke = JS_TRUE;
}
bool
JSRegExpStatics::copy(const JSRegExpStatics& other) {
clearRoots();
input = other.input;
multiline = other.multiline;
lastMatch = other.lastMatch;
lastParen = other.lastParen;
leftContext = other.leftContext;
rightContext = other.rightContext;
if (!parens.resize(other.parens.length()))
return false;
memcpy(parens.begin(), other.parens.begin(), sizeof(JSSubString) * parens.length());
return true;
}
void
JSRegExpStatics::clear() {
clearRoots();
multiline = false;
lastMatch = lastParen = leftContext = rightContext = js_EmptySubString;
parens.clear();
}
/*
* 1. If IgnoreCase is false, return ch.
* 2. Let u be ch converted to upper case as if by calling