Bug 988486 - Move scriptAndCountsVector from GCRuntime to JSRuntime r=terrence

This commit is contained in:
Jon Coppeard 2014-06-07 10:34:56 +01:00
parent b7ca6e1f78
commit 62086f2135
7 changed files with 128 additions and 128 deletions

View File

@ -26,23 +26,6 @@
namespace js {
struct ScriptAndCounts
{
/* This structure is stored and marked from the JSRuntime. */
JSScript *script;
ScriptCounts scriptCounts;
PCCounts &getPCCounts(jsbytecode *pc) const {
return scriptCounts.pcCountsVector[script->pcToOffset(pc)];
}
jit::IonScriptCounts *getIonCounts() const {
return scriptCounts.ionCounts;
}
};
typedef Vector<ScriptAndCounts, 0, SystemAllocPolicy> ScriptAndCountsVector;
namespace gc {
typedef Vector<JS::Zone *, 4, SystemAllocPolicy> ZoneVector;
@ -539,9 +522,6 @@ class GCRuntime
/* The OS allocation granularity may not match the page size. */
size_t systemAllocGranularity;
/* Strong references on scripts held for PCCount profiling API. */
js::ScriptAndCountsVector *scriptAndCountsVector;
#ifdef DEBUG
/*
* Some regions of code are hard for the static rooting hazard analysis to

View File

@ -730,8 +730,8 @@ js::gc::GCRuntime::markRuntime(JSTracer *trc, bool useSavedRoots)
MarkPersistentRootedChains(trc);
if (scriptAndCountsVector) {
ScriptAndCountsVector &vec = *scriptAndCountsVector;
if (rt->scriptAndCountsVector) {
ScriptAndCountsVector &vec = *rt->scriptAndCountsVector;
for (size_t i = 0; i < vec.length(); i++)
MarkScriptRoot(trc, &vec[i].script, "scriptAndCountsVector");
}

View File

@ -1114,7 +1114,6 @@ GCRuntime::GCRuntime(JSRuntime *rt) :
sliceCallback(nullptr),
mallocBytes(0),
mallocGCTriggered(false),
scriptAndCountsVector(nullptr),
#ifdef DEBUG
inUnsafeRegion(0),
#endif
@ -5374,105 +5373,6 @@ js::ReleaseAllJITCode(FreeOp *fop)
#endif
}
/*
* There are three possible PCCount profiling states:
*
* 1. None: Neither scripts nor the runtime have count information.
* 2. Profile: Active scripts have count information, the runtime does not.
* 3. Query: Scripts do not have count information, the runtime does.
*
* When starting to profile scripts, counting begins immediately, with all JIT
* code discarded and recompiled with counts as necessary. Active interpreter
* frames will not begin profiling until they begin executing another script
* (via a call or return).
*
* The below API functions manage transitions to new states, according
* to the table below.
*
* Old State
* -------------------------
* Function None Profile Query
* --------
* StartPCCountProfiling Profile Profile Profile
* StopPCCountProfiling None Query Query
* PurgePCCounts None None None
*/
static void
ReleaseScriptCounts(FreeOp *fop)
{
JSRuntime *rt = fop->runtime();
JS_ASSERT(rt->gc.scriptAndCountsVector);
ScriptAndCountsVector &vec = *rt->gc.scriptAndCountsVector;
for (size_t i = 0; i < vec.length(); i++)
vec[i].scriptCounts.destroy(fop);
fop->delete_(rt->gc.scriptAndCountsVector);
rt->gc.scriptAndCountsVector = nullptr;
}
JS_FRIEND_API(void)
js::StartPCCountProfiling(JSContext *cx)
{
JSRuntime *rt = cx->runtime();
if (rt->profilingScripts)
return;
if (rt->gc.scriptAndCountsVector)
ReleaseScriptCounts(rt->defaultFreeOp());
ReleaseAllJITCode(rt->defaultFreeOp());
rt->profilingScripts = true;
}
JS_FRIEND_API(void)
js::StopPCCountProfiling(JSContext *cx)
{
JSRuntime *rt = cx->runtime();
if (!rt->profilingScripts)
return;
JS_ASSERT(!rt->gc.scriptAndCountsVector);
ReleaseAllJITCode(rt->defaultFreeOp());
ScriptAndCountsVector *vec = cx->new_<ScriptAndCountsVector>(SystemAllocPolicy());
if (!vec)
return;
for (ZonesIter zone(rt, SkipAtoms); !zone.done(); zone.next()) {
for (ZoneCellIter i(zone, FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>();
if (script->hasScriptCounts() && script->types) {
ScriptAndCounts sac;
sac.script = script;
sac.scriptCounts.set(script->releaseScriptCounts());
if (!vec->append(sac))
sac.scriptCounts.destroy(rt->defaultFreeOp());
}
}
}
rt->profilingScripts = false;
rt->gc.scriptAndCountsVector = vec;
}
JS_FRIEND_API(void)
js::PurgePCCounts(JSContext *cx)
{
JSRuntime *rt = cx->runtime();
if (!rt->gc.scriptAndCountsVector)
return;
JS_ASSERT(!rt->profilingScripts);
ReleaseScriptCounts(rt->defaultFreeOp());
}
void
js::PurgeJITCaches(Zone *zone)
{

View File

@ -1936,15 +1936,114 @@ js::IsValidBytecodeOffset(JSContext *cx, JSScript *script, size_t offset)
return false;
}
/*
* There are three possible PCCount profiling states:
*
* 1. None: Neither scripts nor the runtime have count information.
* 2. Profile: Active scripts have count information, the runtime does not.
* 3. Query: Scripts do not have count information, the runtime does.
*
* When starting to profile scripts, counting begins immediately, with all JIT
* code discarded and recompiled with counts as necessary. Active interpreter
* frames will not begin profiling until they begin executing another script
* (via a call or return).
*
* The below API functions manage transitions to new states, according
* to the table below.
*
* Old State
* -------------------------
* Function None Profile Query
* --------
* StartPCCountProfiling Profile Profile Profile
* StopPCCountProfiling None Query Query
* PurgePCCounts None None None
*/
static void
ReleaseScriptCounts(FreeOp *fop)
{
JSRuntime *rt = fop->runtime();
JS_ASSERT(rt->scriptAndCountsVector);
ScriptAndCountsVector &vec = *rt->scriptAndCountsVector;
for (size_t i = 0; i < vec.length(); i++)
vec[i].scriptCounts.destroy(fop);
fop->delete_(rt->scriptAndCountsVector);
rt->scriptAndCountsVector = nullptr;
}
JS_FRIEND_API(void)
js::StartPCCountProfiling(JSContext *cx)
{
JSRuntime *rt = cx->runtime();
if (rt->profilingScripts)
return;
if (rt->scriptAndCountsVector)
ReleaseScriptCounts(rt->defaultFreeOp());
ReleaseAllJITCode(rt->defaultFreeOp());
rt->profilingScripts = true;
}
JS_FRIEND_API(void)
js::StopPCCountProfiling(JSContext *cx)
{
JSRuntime *rt = cx->runtime();
if (!rt->profilingScripts)
return;
JS_ASSERT(!rt->scriptAndCountsVector);
ReleaseAllJITCode(rt->defaultFreeOp());
ScriptAndCountsVector *vec = cx->new_<ScriptAndCountsVector>(SystemAllocPolicy());
if (!vec)
return;
for (ZonesIter zone(rt, SkipAtoms); !zone.done(); zone.next()) {
for (ZoneCellIter i(zone, FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>();
if (script->hasScriptCounts() && script->types) {
ScriptAndCounts sac;
sac.script = script;
sac.scriptCounts.set(script->releaseScriptCounts());
if (!vec->append(sac))
sac.scriptCounts.destroy(rt->defaultFreeOp());
}
}
}
rt->profilingScripts = false;
rt->scriptAndCountsVector = vec;
}
JS_FRIEND_API(void)
js::PurgePCCounts(JSContext *cx)
{
JSRuntime *rt = cx->runtime();
if (!rt->scriptAndCountsVector)
return;
JS_ASSERT(!rt->profilingScripts);
ReleaseScriptCounts(rt->defaultFreeOp());
}
JS_FRIEND_API(size_t)
js::GetPCCountScriptCount(JSContext *cx)
{
JSRuntime *rt = cx->runtime();
if (!rt->gc.scriptAndCountsVector)
if (!rt->scriptAndCountsVector)
return 0;
return rt->gc.scriptAndCountsVector->length();
return rt->scriptAndCountsVector->length();
}
enum MaybeComma {NO_COMMA, COMMA};
@ -1979,12 +2078,12 @@ js::GetPCCountScriptSummary(JSContext *cx, size_t index)
{
JSRuntime *rt = cx->runtime();
if (!rt->gc.scriptAndCountsVector || index >= rt->gc.scriptAndCountsVector->length()) {
if (!rt->scriptAndCountsVector || index >= rt->scriptAndCountsVector->length()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_BUFFER_TOO_SMALL);
return nullptr;
}
const ScriptAndCounts &sac = (*rt->gc.scriptAndCountsVector)[index];
const ScriptAndCounts &sac = (*rt->scriptAndCountsVector)[index];
RootedScript script(cx, sac.script);
/*
@ -2239,12 +2338,12 @@ js::GetPCCountScriptContents(JSContext *cx, size_t index)
{
JSRuntime *rt = cx->runtime();
if (!rt->gc.scriptAndCountsVector || index >= rt->gc.scriptAndCountsVector->length()) {
if (!rt->scriptAndCountsVector || index >= rt->scriptAndCountsVector->length()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_BUFFER_TOO_SMALL);
return nullptr;
}
const ScriptAndCounts &sac = (*rt->gc.scriptAndCountsVector)[index];
const ScriptAndCounts &sac = (*rt->scriptAndCountsVector)[index];
JSScript *script = sac.script;
StringBuffer buf(cx);

View File

@ -1928,6 +1928,21 @@ SweepScriptData(JSRuntime *rt);
extern void
FreeScriptData(JSRuntime *rt);
struct ScriptAndCounts
{
/* This structure is stored and marked from the JSRuntime. */
JSScript *script;
ScriptCounts scriptCounts;
PCCounts &getPCCounts(jsbytecode *pc) const {
return scriptCounts.pcCountsVector[script->pcToOffset(pc)];
}
jit::IonScriptCounts *getIonCounts() const {
return scriptCounts.ionCounts;
}
};
struct GSNCache;
jssrcnote *

View File

@ -181,6 +181,7 @@ JSRuntime::JSRuntime(JSRuntime *parentRuntime)
#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
simulatorRuntime_(nullptr),
#endif
scriptAndCountsVector(nullptr),
NaNValue(DoubleNaNValue()),
negativeInfinityValue(DoubleValue(NegativeInfinity<double>())),
positiveInfinityValue(DoubleValue(PositiveInfinity<double>())),

View File

@ -134,6 +134,8 @@ struct ScopeCoordinateNameCache {
void purge();
};
typedef Vector<ScriptAndCounts, 0, SystemAllocPolicy> ScriptAndCountsVector;
struct EvalCacheEntry
{
JSScript *script;
@ -1002,6 +1004,9 @@ struct JSRuntime : public JS::shadow::Runtime,
void setSimulatorRuntime(js::jit::SimulatorRuntime *srt);
#endif
/* Strong references on scripts held for PCCount profiling API. */
js::ScriptAndCountsVector *scriptAndCountsVector;
/* Well-known numbers held for use by this runtime's contexts. */
const js::Value NaNValue;
const js::Value negativeInfinityValue;