зеркало из https://github.com/mozilla/gecko-dev.git
Bug 671113 - Poison JSScripts when freed to get more crash data (r=dmandelin)
This commit is contained in:
Родитель
8aa36b3b5c
Коммит
1b7adf6bc0
|
@ -559,6 +559,8 @@ JSCompartment::purge(JSContext *cx)
|
|||
#endif
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
js::CheckCompartmentScripts(this);
|
||||
|
||||
for (JSScript *script = (JSScript *)scripts.next;
|
||||
&script->links != &scripts;
|
||||
script = (JSScript *)script->links.next) {
|
||||
|
|
|
@ -1679,8 +1679,12 @@ fun_trace(JSTracer *trc, JSObject *obj)
|
|||
if (fun->atom)
|
||||
MarkString(trc, fun->atom, "atom");
|
||||
|
||||
if (fun->isInterpreted() && fun->script())
|
||||
if (fun->isInterpreted() && fun->script()) {
|
||||
if (fun->script()->compartment != obj->compartment())
|
||||
JS_Assert("compartment mismatch", __FILE__, __LINE__);
|
||||
|
||||
js_TraceScript(trc, fun->script());
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -2421,6 +2421,9 @@ MarkAndSweep(JSContext *cx, JSCompartment *comp, JSGCInvocationKind gckind GCTIM
|
|||
printf("GC HEAP SIZE %lu\n", (unsigned long)rt->gcBytes);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); c++)
|
||||
js::CheckCompartmentScripts(*c);
|
||||
}
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
|
|
|
@ -940,6 +940,7 @@ JSScript::NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natom
|
|||
return NULL;
|
||||
|
||||
PodZero(script);
|
||||
script->cookie1 = script->cookie2 = JS_SCRIPT_COOKIE;
|
||||
script->length = length;
|
||||
script->version = version;
|
||||
new (&script->bindings) Bindings(cx, emptyCallShape);
|
||||
|
@ -1082,6 +1083,7 @@ JSScript::NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 natom
|
|||
#endif
|
||||
|
||||
JS_APPEND_LINK(&script->links, &cx->compartment->scripts);
|
||||
|
||||
JS_ASSERT(script->getVersion() == version);
|
||||
return script;
|
||||
}
|
||||
|
@ -1274,9 +1276,46 @@ js_CallDestroyScriptHook(JSContext *cx, JSScript *script)
|
|||
JS_ClearScriptTraps(cx, script);
|
||||
}
|
||||
|
||||
static void
|
||||
volatile_memcpy(volatile char *dst, void *src, size_t n)
|
||||
{
|
||||
for (size_t i = 0; i < n; i++)
|
||||
dst[i] = ((char *)src)[i];
|
||||
}
|
||||
|
||||
static void
|
||||
CheckScript(JSScript *script, JSScript *prev)
|
||||
{
|
||||
volatile char dbg1[sizeof(JSScript)], dbg2[sizeof(JSScript)];
|
||||
if (script->cookie1 != JS_SCRIPT_COOKIE || script->cookie2 != JS_SCRIPT_COOKIE) {
|
||||
volatile_memcpy(dbg1, script, sizeof(JSScript));
|
||||
if (prev)
|
||||
volatile_memcpy(dbg2, prev, sizeof(JSScript));
|
||||
*(int*)0 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
void
|
||||
CheckCompartmentScripts(JSCompartment *comp)
|
||||
{
|
||||
JSScript *prev = NULL;
|
||||
for (JSScript *script = (JSScript *)comp->scripts.next;
|
||||
&script->links != &comp->scripts;
|
||||
prev = script, script = (JSScript *)script->links.next)
|
||||
{
|
||||
CheckScript(script, prev);
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
static void
|
||||
DestroyScript(JSContext *cx, JSScript *script)
|
||||
{
|
||||
CheckScript(script, NULL);
|
||||
|
||||
if (script->principals)
|
||||
JSPRINCIPALS_DROP(cx, script->principals);
|
||||
|
||||
|
@ -1332,6 +1371,7 @@ DestroyScript(JSContext *cx, JSScript *script)
|
|||
|
||||
script->pcCounters.destroy(cx);
|
||||
|
||||
memset(script, JS_FREE_PATTERN, script->totalSize());
|
||||
cx->free_(script);
|
||||
}
|
||||
|
||||
|
@ -1361,6 +1401,12 @@ js_DestroyCachedScript(JSContext *cx, JSScript *script)
|
|||
void
|
||||
js_TraceScript(JSTracer *trc, JSScript *script)
|
||||
{
|
||||
CheckScript(script, NULL);
|
||||
|
||||
JSRuntime *rt = trc->context->runtime;
|
||||
if (rt->gcCheckCompartment && script->compartment != rt->gcCheckCompartment)
|
||||
JS_Assert("compartment mismatch in GC", __FILE__, __LINE__);
|
||||
|
||||
JSAtomMap *map = &script->atomMap;
|
||||
MarkAtomRange(trc, map->length, map->vector, "atomMap");
|
||||
|
||||
|
|
|
@ -420,6 +420,8 @@ class JSPCCounters {
|
|||
}
|
||||
};
|
||||
|
||||
static const uint32 JS_SCRIPT_COOKIE = 0xc00cee;
|
||||
|
||||
struct JSScript {
|
||||
/*
|
||||
* Two successively less primitive ways to make a new JSScript. The first
|
||||
|
@ -444,6 +446,8 @@ struct JSScript {
|
|||
jsbytecode *code; /* bytecodes and their immediate operands */
|
||||
uint32 length; /* length of code vector */
|
||||
|
||||
uint32 cookie1;
|
||||
|
||||
private:
|
||||
uint16 version; /* JS version under which script was compiled */
|
||||
|
||||
|
@ -528,6 +532,8 @@ struct JSScript {
|
|||
/* array of execution counters for every JSOp in the script, by runmode */
|
||||
JSPCCounters pcCounters;
|
||||
|
||||
uint32 cookie2;
|
||||
|
||||
public:
|
||||
#ifdef JS_METHODJIT
|
||||
// Fast-cached pointers to make calls faster. These are also used to
|
||||
|
@ -732,6 +738,19 @@ js_DestroyScriptFromGC(JSContext *cx, JSScript *script);
|
|||
extern void
|
||||
js_DestroyCachedScript(JSContext *cx, JSScript *script);
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* This diagnostic function checks that a compartment's list of scripts
|
||||
* contains only valid scripts. It also searches for the target script
|
||||
* in the list. If expected is true, it asserts that the target script
|
||||
* is found. If expected is false, it asserts that it's not found.
|
||||
*/
|
||||
void
|
||||
CheckCompartmentScripts(JSCompartment *comp);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern void
|
||||
js_TraceScript(JSTracer *trc, JSScript *script);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче