Пример #1
0
static void markObjectNonNull(const Object *obj, GcMarkContext *ctx,
                              bool checkFinger)
{
    assert(ctx != NULL);
    assert(obj != NULL);
    assert(dvmIsValidObject(obj));

    if (obj < (Object *)ctx->immuneLimit) {
        assert(isMarked(obj, ctx));
        return;
    }
    if (!setAndReturnMarkBit(ctx, obj)) {
        /* This object was not previously marked.
         */
        if (checkFinger && (void *)obj < ctx->finger) {
            /* This object will need to go on the mark stack.
             */
            MARK_STACK_PUSH(ctx->stack, obj);
        }

#if WITH_HPROF
        if (gDvm.gcHeap->hprofContext != NULL) {
            hprofMarkRootObject(gDvm.gcHeap->hprofContext, obj, 0);
        }
#endif
    }
}
Пример #2
0
static bool
hprofUnreachableBitmapCallback(size_t numPtrs, void **ptrs,
        const void *finger, void *arg)
{
    hprof_context_t *hctx = (hprof_context_t *)arg;
    size_t i;

    for (i = 0; i < numPtrs; i++) {
        Object *obj;

        /* The pointers we're getting back are DvmHeapChunks, not
         * Objects.
         */
        obj = (Object *)chunk2ptr(*ptrs++);

        hprofMarkRootObject(hctx, obj, 0);
        hprofDumpHeapObject(hctx, obj);
    }

    return true;
}
Пример #3
0
static void
_markObjectNonNullCommon(const Object *obj, GcMarkContext *ctx,
        bool checkFinger, bool forceStack)
{
    DvmHeapChunk *hc;

    assert(obj != NULL);

#if GC_DEBUG(GC_DEBUG_PARANOID)
//TODO: make sure we're locked
    assert(obj != (Object *)gDvm.unlinkedJavaLangClass);
    assert(dvmIsValidObject(obj));
#endif

    hc = ptr2chunk(obj);
    if (!setAndReturnMarkBit(ctx, hc)) {
        /* This object was not previously marked.
         */
        if (forceStack || (checkFinger && (void *)hc < ctx->finger)) {
            /* This object will need to go on the mark stack.
             */
            MARK_STACK_PUSH(ctx->stack, obj);
        }

#if WITH_OBJECT_HEADERS
        if (hc->scanGeneration != hc->markGeneration) {
            LOGE("markObject(0x%08x): wasn't scanned last time\n", (uint)obj);
            dvmAbort();
        }
        if (hc->markGeneration == gGeneration) {
            LOGE("markObject(0x%08x): already marked this generation\n",
                    (uint)obj);
            dvmAbort();
        }
        hc->oldMarkGeneration = hc->markGeneration;
        hc->markGeneration = gGeneration;
        hc->markFingerOld = hc->markFinger;
        hc->markFinger = ctx->finger;
        if (gMarkParent != NULL) {
            hc->parentOld = hc->parent;
            hc->parent = gMarkParent;
        } else {
            hc->parent = (const Object *)((uintptr_t)hc->parent | 1);
        }
        hc->markCount++;
#endif
#if WITH_HPROF
        if (gDvm.gcHeap->hprofContext != NULL) {
            hprofMarkRootObject(gDvm.gcHeap->hprofContext, obj, 0);
        }
#endif
#if DVM_TRACK_HEAP_MARKING
        gDvm.gcHeap->markCount++;
        gDvm.gcHeap->markSize += dvmHeapSourceChunkSize((void *)hc) +
                HEAP_SOURCE_CHUNK_OVERHEAD;
#endif

        /* obj->clazz can be NULL if we catch an object between
         * dvmMalloc() and DVM_OBJECT_INIT().  This is ok.
         */
        LOGV_MARK("0x%08x %s\n", (uint)obj,
                obj->clazz == NULL ? "<null class>" : obj->clazz->name);
    }
}