Bug 1204554 part 3.4 - Ensure that scriptCountsMaps data are still alive until the destruction of compartments. r=terrence,bhackett

This commit is contained in:
Nicolas B. Pierron 2015-10-01 12:41:40 +02:00
parent 27d11f828b
commit 1aefe3b946
2 changed files with 36 additions and 4 deletions

View File

@ -574,7 +574,23 @@ JSCompartment::traceRoots(JSTracer* trc, js::gc::GCRuntime::TraceOrMarkRuntime t
if (objectMetadataTable)
objectMetadataTable->trace(trc);
if (scriptCountsMap && !trc->runtime()->isHeapMinorCollecting()) {
// If code coverage is only enabled with the Debugger or the LCovOutput,
// then the following comment holds.
//
// The scriptCountsMap maps JSScript weak-pointers to ScriptCounts
// structures. It uses a HashMap instead of a WeakMap, so that we can keep
// the data alive for the JSScript::finalize call. Thus, we do not trace the
// keys of the HashMap to avoid adding a strong reference to the JSScript
// pointers. Additionally, we assert that the JSScripts have not been moved
// in JSCompartment::fixupAfterMovingGC.
//
// If the code coverage is either enabled with the --dump-bytecode command
// line option, or with the PCCount JSFriend API functions, then we mark the
// keys of the map to hold the JSScript alive.
if (scriptCountsMap &&
trc->runtime()->profilingScripts &&
!trc->runtime()->isHeapMinorCollecting())
{
MOZ_ASSERT_IF(!trc->runtime()->isBeingDestroyed(), collectCoverage());
for (ScriptCountsMap::Range r = scriptCountsMap->all(); !r.empty(); r.popFront()) {
JSScript* script = const_cast<JSScript*>(r.front().key());
@ -754,6 +770,18 @@ JSCompartment::fixupAfterMovingGC()
fixupGlobal();
fixupInitialShapeTable();
objectGroups.fixupTablesAfterMovingGC();
#ifdef DEBUG
// Assert that none of the JSScript pointers, which are used as key of the
// scriptCountsMap HashMap are moved. We do not mark these keys because we
// need weak references. We do not use a WeakMap because these entries would
// be collected before the JSScript::finalize calls which is used to
// summarized the content of the code coverage.
if (scriptCountsMap) {
for (ScriptCountsMap::Range r = scriptCountsMap->all(); !r.empty(); r.popFront())
MOZ_ASSERT(!IsForwarded(r.front().key()));
}
#endif
}
void
@ -978,9 +1006,8 @@ JSCompartment::updateDebuggerObservesCoverage()
return;
}
// If the runtime flag is enabled, then keep the data until
// StopPCCountProfiling is called.
if (runtimeFromMainThread()->profilingScripts)
// If code coverage is enabled by any other means, keep it.
if (collectCoverage())
return;
clearScriptCounts();

View File

@ -489,6 +489,11 @@ class ScriptCounts
jit::IonScriptCounts* ionCounts_;
};
// Note: The key of this hash map is a weak reference to a JSScript. We do not
// use the WeakMap implementation provided in jsweakmap.h because it would be
// collected at the beginning of the sweeping of the compartment, thus before
// the calls to the JSScript::finalize function which are used to aggregate code
// coverage results on the compartment.
typedef HashMap<JSScript*,
ScriptCounts,
DefaultHasher<JSScript*>,