Exemplo n.º 1
0
void
js::Nursery::collect(JSRuntime *rt, JS::gcreason::Reason reason)
{
    JS_AbortIfWrongThread(rt);

    if (rt->mainThread.suppressGC)
        return;

    if (!isEnabled())
        return;

    if (position() == start())
        return;

    rt->gcHelperThread.waitBackgroundSweepEnd();

    AutoStopVerifyingBarriers av(rt, false);

    /* Move objects pointed to by roots from the nursery to the major heap. */
    MinorCollectionTracer trc(rt, this);
    MarkRuntime(&trc);
    Debugger::markAll(&trc);
    for (CompartmentsIter comp(rt); !comp.done(); comp.next()) {
        comp->markAllCrossCompartmentWrappers(&trc);
        comp->markAllInitialShapeTableEntries(&trc);
    }
    markStoreBuffer(&trc);
    rt->newObjectCache.clearNurseryObjects(rt);

    /*
     * Most of the work is done here. This loop iterates over objects that have
     * been moved to the major heap. If these objects have any outgoing pointers
     * to the nursery, then those nursery objects get moved as well, until no
     * objects are left to move. That is, we iterate to a fixed point.
     */
    for (RelocationOverlay *p = trc.head; p; p = p->next()) {
        JSObject *obj = static_cast<JSObject*>(p->forwardingAddress());
        JS_TraceChildren(&trc, obj, MapAllocToTraceKind(obj->tenuredGetAllocKind()));
    }

    /* Resize the nursery. */
    double promotionRate = trc.tenuredSize / double(allocationEnd() - start());
    if (promotionRate > 0.5)
        growAllocableSpace();
    else if (promotionRate < 0.1)
        shrinkAllocableSpace();

    /* Sweep. */
    sweep(rt->defaultFreeOp());
    rt->gcStoreBuffer.clear();

    /*
     * We ignore gcMaxBytes when allocating for minor collection. However, if we
     * overflowed, we disable the nursery. The next time we allocate, we'll fail
     * because gcBytes >= gcMaxBytes.
     */
    if (rt->gcBytes >= rt->gcMaxBytes)
        disable();
}
Exemplo n.º 2
0
void
js::Nursery::collectToFixedPoint(MinorCollectionTracer *trc)
{
    for (RelocationOverlay *p = trc->head; p; p = p->next()) {
        JSObject *obj = static_cast<JSObject*>(p->forwardingAddress());
        traceObject(trc, obj);
    }
}
Exemplo n.º 3
0
void
js::Nursery::collectToFixedPoint(MinorCollectionTracer *trc, TenureCountCache &tenureCounts)
{
    for (RelocationOverlay *p = trc->head; p; p = p->next()) {
        JSObject *obj = static_cast<JSObject*>(p->forwardingAddress());
        traceObject(trc, obj);

        TenureCount &entry = tenureCounts.findEntry(obj->type());
        if (entry.type == obj->type()) {
            entry.count++;
        } else if (!entry.type) {
            entry.type = obj->type();
            entry.count = 1;
        }
    }
}
Exemplo n.º 4
0
void *
ForkJoinNursery::moveObjectToTospace(JSObject *src)
{
    AllocKind dstKind = getObjectAllocKind(src);
    JSObject *dst = static_cast<JSObject *>(allocateInTospace(dstKind));
    if (!dst)
        CrashAtUnhandlableOOM("Failed to allocate object while moving object.");

    movedSize_ += copyObjectToTospace(dst, src, dstKind);

    RelocationOverlay *overlay = reinterpret_cast<RelocationOverlay *>(src);
    overlay->forwardTo(dst);
    insertIntoFixupList(overlay);

    return static_cast<void *>(dst);
}
Exemplo n.º 5
0
void *
js::Nursery::moveToTenured(MinorCollectionTracer *trc, JSObject *src)
{
    Zone *zone = src->zone();
    AllocKind dstKind = GetObjectAllocKindForCopy(trc->runtime(), src);
    JSObject *dst = static_cast<JSObject *>(allocateFromTenured(zone, dstKind));
    if (!dst)
        CrashAtUnhandlableOOM("Failed to allocate object while tenuring.");

    trc->tenuredSize += moveObjectToTenured(dst, src, dstKind);

    RelocationOverlay *overlay = reinterpret_cast<RelocationOverlay *>(src);
    overlay->forwardTo(dst);
    trc->insertIntoFixupList(overlay);

    return static_cast<void *>(dst);
}
Exemplo n.º 6
0
void *
js::Nursery::moveToTenured(MinorCollectionTracer *trc, JSObject *src)
{
    Zone *zone = src->zone();
    AllocKind dstKind = GetObjectAllocKindForCopy(src);
    JSObject *dst = static_cast<JSObject *>(allocateFromTenured(zone, dstKind));
    if (!dst)
        MOZ_CRASH();

    moveObjectToTenured(dst, src, dstKind);

    RelocationOverlay *overlay = reinterpret_cast<RelocationOverlay *>(src);
    overlay->forwardTo(dst);
    trc->insertIntoFixupList(overlay);

    return static_cast<void *>(dst);
}
Exemplo n.º 7
0
void
js::Nursery::collectToFixedPoint(MinorCollectionTracer *trc)
{
    for (RelocationOverlay *p = trc->head; p; p = p->next()) {
        JSObject *obj = static_cast<JSObject*>(p->forwardingAddress());
        traceObject(trc, obj);

        /*
         * Increment tenure count and recompile the script for pre-tenuring if
         * long-lived. Attempt to distinguish between tenuring because the
         * object is long lived and tenuring while the nursery is still
         * smaller than the working set size.
         */
        if (isFullyGrown() && !obj->hasLazyType() && obj->type()->hasNewScript() &&
            obj->type()->incrementTenureCount())
        {
            MaybeInvalidateScriptUsedWithNew(trc->runtime, obj->type());
        }
    }
}
Exemplo n.º 8
0
void
ForkJoinNursery::collectToFixedPoint(ForkJoinNurseryCollectionTracer *trc)
{
    for (RelocationOverlay *p = head_; p; p = p->next())
        traceObject(trc, static_cast<JSObject *>(p->forwardingAddress()));
}