Beispiel #1
0
void
JSCompartment::traceRoots(JSTracer* trc, js::gc::GCRuntime::TraceOrMarkRuntime traceOrMark)
{
    if (objectMetadataState.is<PendingMetadata>()) {
        TraceRoot(trc,
                  objectMetadataState.as<PendingMetadata>().unsafeGet(),
                  "on-stack object pending metadata");
    }

    if (!trc->runtime()->isHeapMinorCollecting()) {
        // JIT code and the global are never nursery allocated, so we only need
        // to trace them when not doing a minor collection.

        if (jitCompartment_)
            jitCompartment_->mark(trc, this);

        // If a compartment is on-stack, we mark its global so that
        // JSContext::global() remains valid.
        if (enterCompartmentDepth && global_.unbarrieredGet())
            TraceRoot(trc, global_.unsafeGet(), "on-stack compartment global");
    }

    // Nothing below here needs to be treated as a root if we aren't marking
    // this zone for a collection.
    if (traceOrMark == js::gc::GCRuntime::MarkRuntime && !zone()->isCollecting())
        return;

    // During a GC, these are treated as weak pointers.
    if (traceOrMark == js::gc::GCRuntime::TraceRuntime) {
        if (watchpointMap)
            watchpointMap->markAll(trc);
    }

    /* Mark debug scopes, if present */
    if (debugScopes)
        debugScopes->mark(trc);

    if (lazyArrayBuffers)
        lazyArrayBuffers->trace(trc);

    if (objectMetadataTable)
        objectMetadataTable->trace(trc);

    if (scriptCountsMap && !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());
            MOZ_ASSERT(script->hasScriptCounts());
            TraceRoot(trc, &script, "profilingScripts");
            MOZ_ASSERT(script == r.front().key(), "const_cast is only a work-around");
        }
    }
}
Beispiel #2
0
JS_DumpCompartmentPCCounts(JSContext *cx)
{
    for (CellIter i(cx->zone(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
        JSScript *script = i.get<JSScript>();
        if (script->compartment() != cx->compartment())
            continue;

        if (script->hasScriptCounts())
            JS_DumpPCCounts(cx, script);
    }

#if defined(JS_ION)
    for (unsigned thingKind = FINALIZE_OBJECT0; thingKind < FINALIZE_OBJECT_LIMIT; thingKind++) {
        for (CellIter i(cx->zone(), (AllocKind) thingKind); !i.done(); i.next()) {
            JSObject *obj = i.get<JSObject>();
            if (obj->compartment() != cx->compartment())
                continue;

            if (obj->is<AsmJSModuleObject>()) {
                AsmJSModule &module = obj->as<AsmJSModuleObject>().module();

                Sprinter sprinter(cx);
                if (!sprinter.init())
                    return;

                fprintf(stdout, "--- Asm.js Module ---\n");

                for (size_t i = 0; i < module.numFunctionCounts(); i++) {
                    jit::IonScriptCounts *counts = module.functionCounts(i);
                    DumpIonScriptCounts(&sprinter, counts);
                }

                fputs(sprinter.string(), stdout);
                fprintf(stdout, "--- END Asm.js Module ---\n");
            }
        }
    }
#endif
}
Beispiel #3
0
void
JSCompartment::traceRoots(JSTracer* trc, js::gc::GCRuntime::TraceOrMarkRuntime traceOrMark)
{
    if (objectMetadataState.is<PendingMetadata>()) {
        TraceRoot(trc,
                  &objectMetadataState.as<PendingMetadata>(),
                  "on-stack object pending metadata");
    }

    if (!trc->runtime()->isHeapMinorCollecting()) {
        // JIT code and the global are never nursery allocated, so we only need
        // to trace them when not doing a minor collection.

        if (jitCompartment_)
            jitCompartment_->trace(trc, this);

        // If a compartment is on-stack, we mark its global so that
        // JSContext::global() remains valid.
        if (enterCompartmentDepth && global_.unbarrieredGet())
            TraceRoot(trc, global_.unsafeUnbarrieredForTracing(), "on-stack compartment global");
    }

    // Nothing below here needs to be treated as a root if we aren't marking
    // this zone for a collection.
    if (traceOrMark == js::gc::GCRuntime::MarkRuntime && !zone()->isCollecting())
        return;

    // During a GC, these are treated as weak pointers.
    if (traceOrMark == js::gc::GCRuntime::TraceRuntime) {
        if (watchpointMap)
            watchpointMap->trace(trc);
    }

    /* Mark debug scopes, if present */
    if (debugEnvs)
        debugEnvs->trace(trc);

    if (lazyArrayBuffers)
        lazyArrayBuffers->trace(trc);

    if (objectMetadataTable)
        objectMetadataTable->trace(trc);

    // 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.
    //
    // 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());
            MOZ_ASSERT(script->hasScriptCounts());
            TraceRoot(trc, &script, "profilingScripts");
            MOZ_ASSERT(script == r.front().key(), "const_cast is only a work-around");
        }
    }

    if (nonSyntacticLexicalEnvironments_)
        nonSyntacticLexicalEnvironments_->trace(trc);

    wasm.trace(trc);
}