mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-03 02:25:34 +00:00
Bug 739512: Patch 9: move JSScript::debug into a table. r=jorendorff.
This commit is contained in:
parent
eab1ae6a1b
commit
b99da5a940
@ -93,7 +93,8 @@ JSCompartment::JSCompartment(JSRuntime *rt)
|
||||
mathCache(NULL),
|
||||
watchpointMap(NULL),
|
||||
scriptCountsMap(NULL),
|
||||
sourceMapMap(NULL)
|
||||
sourceMapMap(NULL),
|
||||
debugScriptMap(NULL)
|
||||
{
|
||||
PodArrayZero(evalCache);
|
||||
setGCMaxMallocBytes(rt->gcMaxMallocBytes * 0.9);
|
||||
@ -115,6 +116,7 @@ JSCompartment::~JSCompartment()
|
||||
Foreground::delete_(watchpointMap);
|
||||
Foreground::delete_(scriptCountsMap);
|
||||
Foreground::delete_(sourceMapMap);
|
||||
Foreground::delete_(debugScriptMap);
|
||||
|
||||
#ifdef DEBUG
|
||||
for (size_t i = 0; i < ArrayLength(evalCache); ++i)
|
||||
|
@ -467,6 +467,8 @@ struct JSCompartment
|
||||
js::ScriptCountsMap *scriptCountsMap;
|
||||
|
||||
js::SourceMapMap *sourceMapMap;
|
||||
|
||||
js::DebugScriptMap *debugScriptMap;
|
||||
};
|
||||
|
||||
#define JS_PROPERTY_TREE(cx) ((cx)->compartment->propertyTree)
|
||||
|
@ -1521,19 +1521,7 @@ JSScript::finalize(FreeOp *fop)
|
||||
|
||||
destroyScriptCounts(fop);
|
||||
destroySourceMap(fop);
|
||||
|
||||
if (debug) {
|
||||
jsbytecode *end = code + length;
|
||||
for (jsbytecode *pc = code; pc < end; pc++) {
|
||||
if (BreakpointSite *site = getBreakpointSite(pc)) {
|
||||
/* Breakpoints are swept before finalization. */
|
||||
JS_ASSERT(site->firstBreakpoint() == NULL);
|
||||
site->clearTrap(fop, NULL, NULL);
|
||||
JS_ASSERT(getBreakpointSite(pc) == NULL);
|
||||
}
|
||||
}
|
||||
fop->free_(debug);
|
||||
}
|
||||
destroyDebugScript(fop);
|
||||
|
||||
JS_POISON(data, 0xdb, computedSizeOfData());
|
||||
fop->free_(data);
|
||||
@ -1770,17 +1758,78 @@ js::CloneScript(JSContext *cx, JSScript *script)
|
||||
return newScript;
|
||||
}
|
||||
|
||||
bool
|
||||
JSScript::ensureHasDebug(JSContext *cx)
|
||||
DebugScript *
|
||||
JSScript::debugScript()
|
||||
{
|
||||
if (debug)
|
||||
JS_ASSERT(hasDebugScript);
|
||||
DebugScriptMap *map = compartment()->debugScriptMap;
|
||||
JS_ASSERT(map);
|
||||
DebugScriptMap::Ptr p = map->lookup(this);
|
||||
JS_ASSERT(p);
|
||||
return p->value;
|
||||
}
|
||||
|
||||
DebugScript *
|
||||
JSScript::releaseDebugScript()
|
||||
{
|
||||
JS_ASSERT(hasDebugScript);
|
||||
DebugScriptMap *map = compartment()->debugScriptMap;
|
||||
JS_ASSERT(map);
|
||||
DebugScriptMap::Ptr p = map->lookup(this);
|
||||
JS_ASSERT(p);
|
||||
DebugScript *debug = p->value;
|
||||
map->remove(p);
|
||||
hasDebugScript = false;
|
||||
return debug;
|
||||
}
|
||||
|
||||
void
|
||||
JSScript::destroyDebugScript(FreeOp *fop)
|
||||
{
|
||||
if (hasDebugScript) {
|
||||
jsbytecode *end = code + length;
|
||||
for (jsbytecode *pc = code; pc < end; pc++) {
|
||||
if (BreakpointSite *site = getBreakpointSite(pc)) {
|
||||
/* Breakpoints are swept before finalization. */
|
||||
JS_ASSERT(site->firstBreakpoint() == NULL);
|
||||
site->clearTrap(fop, NULL, NULL);
|
||||
JS_ASSERT(getBreakpointSite(pc) == NULL);
|
||||
}
|
||||
}
|
||||
fop->free_(releaseDebugScript());
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
JSScript::ensureHasDebugScript(JSContext *cx)
|
||||
{
|
||||
if (hasDebugScript)
|
||||
return true;
|
||||
|
||||
size_t nbytes = offsetof(DebugScript, breakpoints) + length * sizeof(BreakpointSite*);
|
||||
debug = (DebugScript *) cx->calloc_(nbytes);
|
||||
DebugScript *debug = (DebugScript *) cx->calloc_(nbytes);
|
||||
if (!debug)
|
||||
return false;
|
||||
|
||||
/* Create compartment's debugScriptMap if necessary. */
|
||||
DebugScriptMap *map = compartment()->debugScriptMap;
|
||||
if (!map) {
|
||||
map = cx->new_<DebugScriptMap>();
|
||||
if (!map || !map->init()) {
|
||||
cx->free_(debug);
|
||||
cx->delete_(map);
|
||||
return false;
|
||||
}
|
||||
compartment()->debugScriptMap = map;
|
||||
}
|
||||
|
||||
if (!map->putNew(this, debug)) {
|
||||
cx->free_(debug);
|
||||
cx->delete_(map);
|
||||
return false;
|
||||
}
|
||||
hasDebugScript = true; // safe to set this; we can't fail after this point
|
||||
|
||||
/*
|
||||
* Ensure that any Interpret() instances running on this script have
|
||||
* interrupts enabled. The interrupts must stay enabled until the
|
||||
@ -1807,8 +1856,9 @@ JSScript::recompileForStepMode(FreeOp *fop)
|
||||
bool
|
||||
JSScript::tryNewStepMode(JSContext *cx, uint32_t newValue)
|
||||
{
|
||||
JS_ASSERT(debug);
|
||||
JS_ASSERT(hasDebugScript);
|
||||
|
||||
DebugScript *debug = debugScript();
|
||||
uint32_t prior = debug->stepMode;
|
||||
debug->stepMode = newValue;
|
||||
|
||||
@ -1816,10 +1866,8 @@ JSScript::tryNewStepMode(JSContext *cx, uint32_t newValue)
|
||||
/* Step mode has been enabled or disabled. Alert the methodjit. */
|
||||
recompileForStepMode(cx->runtime->defaultFreeOp());
|
||||
|
||||
if (!stepModeEnabled() && !debug->numSites) {
|
||||
cx->free_(debug);
|
||||
debug = NULL;
|
||||
}
|
||||
if (!stepModeEnabled() && !debug->numSites)
|
||||
cx->free_(releaseDebugScript());
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -1828,21 +1876,23 @@ JSScript::tryNewStepMode(JSContext *cx, uint32_t newValue)
|
||||
bool
|
||||
JSScript::setStepModeFlag(JSContext *cx, bool step)
|
||||
{
|
||||
if (!ensureHasDebug(cx))
|
||||
if (!ensureHasDebugScript(cx))
|
||||
return false;
|
||||
|
||||
return tryNewStepMode(cx, (debug->stepMode & stepCountMask) | (step ? stepFlagMask : 0));
|
||||
return tryNewStepMode(cx, (debugScript()->stepMode & stepCountMask) |
|
||||
(step ? stepFlagMask : 0));
|
||||
}
|
||||
|
||||
bool
|
||||
JSScript::changeStepModeCount(JSContext *cx, int delta)
|
||||
{
|
||||
if (!ensureHasDebug(cx))
|
||||
if (!ensureHasDebugScript(cx))
|
||||
return false;
|
||||
|
||||
assertSameCompartment(cx, this);
|
||||
JS_ASSERT_IF(delta > 0, cx->compartment->debugMode());
|
||||
|
||||
DebugScript *debug = debugScript();
|
||||
uint32_t count = debug->stepMode & stepCountMask;
|
||||
JS_ASSERT(((count + delta) & stepCountMask) == count + delta);
|
||||
return tryNewStepMode(cx,
|
||||
@ -1856,9 +1906,10 @@ JSScript::getOrCreateBreakpointSite(JSContext *cx, jsbytecode *pc,
|
||||
{
|
||||
JS_ASSERT(size_t(pc - code) < length);
|
||||
|
||||
if (!ensureHasDebug(cx))
|
||||
if (!ensureHasDebugScript(cx))
|
||||
return NULL;
|
||||
|
||||
DebugScript *debug = debugScript();
|
||||
BreakpointSite *&site = debug->breakpoints[pc - code];
|
||||
|
||||
if (!site) {
|
||||
@ -1883,16 +1934,15 @@ JSScript::destroyBreakpointSite(FreeOp *fop, jsbytecode *pc)
|
||||
{
|
||||
JS_ASSERT(unsigned(pc - code) < length);
|
||||
|
||||
DebugScript *debug = debugScript();
|
||||
BreakpointSite *&site = debug->breakpoints[pc - code];
|
||||
JS_ASSERT(site);
|
||||
|
||||
fop->delete_(site);
|
||||
site = NULL;
|
||||
|
||||
if (--debug->numSites == 0 && !stepModeEnabled()) {
|
||||
fop->free_(debug);
|
||||
debug = NULL;
|
||||
}
|
||||
if (--debug->numSites == 0 && !stepModeEnabled())
|
||||
fop->free_(releaseDebugScript());
|
||||
}
|
||||
|
||||
void
|
||||
@ -1970,7 +2020,7 @@ JSScript::markChildren(JSTracer *trc)
|
||||
|
||||
if (hasAnyBreakpointsOrStepMode()) {
|
||||
for (unsigned i = 0; i < length; i++) {
|
||||
BreakpointSite *site = debug->breakpoints[i];
|
||||
BreakpointSite *site = debugScript()->breakpoints[i];
|
||||
if (site && site->trapHandler)
|
||||
MarkValue(trc, &site->trapClosure, "trap closure");
|
||||
}
|
||||
|
@ -347,6 +347,11 @@ class DebugScript
|
||||
BreakpointSite *breakpoints[1];
|
||||
};
|
||||
|
||||
typedef HashMap<JSScript *,
|
||||
DebugScript *,
|
||||
DefaultHasher<JSScript *>,
|
||||
SystemAllocPolicy> DebugScriptMap;
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
static const uint32_t JS_SCRIPT_COOKIE = 0xc00cee;
|
||||
@ -449,7 +454,6 @@ struct JSScript : public js::gc::Cell
|
||||
#endif
|
||||
|
||||
private:
|
||||
js::DebugScript *debug;
|
||||
js::HeapPtrFunction function_;
|
||||
|
||||
size_t useCount; /* Number of times the script has been called
|
||||
@ -476,6 +480,11 @@ struct JSScript : public js::gc::Cell
|
||||
uint32_t idpad;
|
||||
#endif
|
||||
|
||||
#if JS_BITS_PER_WORD == 32
|
||||
private:
|
||||
uint32_t pad32;
|
||||
#endif
|
||||
|
||||
// 16-bit fields.
|
||||
|
||||
private:
|
||||
@ -544,6 +553,8 @@ struct JSScript : public js::gc::Cell
|
||||
JSCompartment::scriptCountsMap */
|
||||
bool hasSourceMap:1; /* script has an entry in
|
||||
JSCompartment::sourceMapMap */
|
||||
bool hasDebugScript:1; /* script has an entry in
|
||||
JSCompartment::debugScriptMap */
|
||||
|
||||
private:
|
||||
/* See comments below. */
|
||||
@ -834,16 +845,19 @@ struct JSScript : public js::gc::Cell
|
||||
/* Attempt to change this->stepMode to |newValue|. */
|
||||
bool tryNewStepMode(JSContext *cx, uint32_t newValue);
|
||||
|
||||
bool ensureHasDebug(JSContext *cx);
|
||||
bool ensureHasDebugScript(JSContext *cx);
|
||||
js::DebugScript *debugScript();
|
||||
js::DebugScript *releaseDebugScript();
|
||||
void destroyDebugScript(js::FreeOp *fop);
|
||||
|
||||
public:
|
||||
bool hasBreakpointsAt(jsbytecode *pc) { return !!getBreakpointSite(pc); }
|
||||
bool hasAnyBreakpointsOrStepMode() { return !!debug; }
|
||||
bool hasAnyBreakpointsOrStepMode() { return hasDebugScript; }
|
||||
|
||||
js::BreakpointSite *getBreakpointSite(jsbytecode *pc)
|
||||
{
|
||||
JS_ASSERT(size_t(pc - code) < length);
|
||||
return debug ? debug->breakpoints[pc - code] : NULL;
|
||||
return hasDebugScript ? debugScript()->breakpoints[pc - code] : NULL;
|
||||
}
|
||||
|
||||
js::BreakpointSite *getOrCreateBreakpointSite(JSContext *cx, jsbytecode *pc,
|
||||
@ -872,10 +886,10 @@ struct JSScript : public js::gc::Cell
|
||||
*/
|
||||
bool changeStepModeCount(JSContext *cx, int delta);
|
||||
|
||||
bool stepModeEnabled() { return debug && !!debug->stepMode; }
|
||||
bool stepModeEnabled() { return hasDebugScript && !!debugScript()->stepMode; }
|
||||
|
||||
#ifdef DEBUG
|
||||
uint32_t stepModeCount() { return debug ? (debug->stepMode & stepCountMask) : 0; }
|
||||
uint32_t stepModeCount() { return hasDebugScript ? (debugScript()->stepMode & stepCountMask) : 0; }
|
||||
#endif
|
||||
|
||||
void finalize(js::FreeOp *fop);
|
||||
@ -893,7 +907,7 @@ struct JSScript : public js::gc::Cell
|
||||
void markChildren(JSTracer *trc);
|
||||
};
|
||||
|
||||
/* If this fails, padding_ can be removed. */
|
||||
/* If this fails, add/remove padding within JSScript. */
|
||||
JS_STATIC_ASSERT(sizeof(JSScript) % js::gc::Cell::CellSize == 0);
|
||||
|
||||
static JS_INLINE unsigned
|
||||
|
Loading…
Reference in New Issue
Block a user