/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * Heap object dump
 */
#include "Hprof.h"

#include "alloc/HeapInternal.h"
#include "alloc/HeapSource.h"

/* Set DUMP_PRIM_DATA to 1 if you want to include the contents
 * of primitive arrays (byte arrays, character arrays, etc.)
 * in heap dumps.  This can be a large amount of data.
 */
#define DUMP_PRIM_DATA 1

#define OBJECTS_PER_SEGMENT     ((size_t)128)
#define BYTES_PER_SEGMENT       ((size_t)4096)

int
hprofStartHeapDump(hprof_context_t *ctx)
{
    UNUSED_PARAMETER(ctx);

    ctx->objectsInSegment = OBJECTS_PER_SEGMENT;
    ctx->currentHeap = HPROF_HEAP_DEFAULT;
    return 0;
}

int
hprofFinishHeapDump(hprof_context_t *ctx)
{
    return hprofStartNewRecord(ctx, HPROF_TAG_HEAP_DUMP_END, HPROF_TIME);
}

int
hprofSetGcScanState(hprof_context_t *ctx,
                    hprof_heap_tag_t state, u4 threadSerialNumber)
{
    /* Used by hprofMarkRootObject()
     */
    ctx->gcScanState = state;
    ctx->gcThreadSerialNumber = threadSerialNumber;
    return 0;
}

static hprof_basic_type
signatureToBasicTypeAndSize(const char *sig, size_t *sizeOut)
{
    char c = sig[0];
    hprof_basic_type ret;
    size_t size;

    switch (c) {
    case '[':
    case 'L': ret = hprof_basic_object;  size = 4; break;
    case 'Z': ret = hprof_basic_boolean; size = 1; break;
    case 'C': ret = hprof_basic_char;    size = 2; break;
    case 'F': ret = hprof_basic_float;   size = 4; break;
    case 'D': ret = hprof_basic_double;  size = 8; break;
    case 'B': ret = hprof_basic_byte;    size = 1; break;
    case 'S': ret = hprof_basic_short;   size = 2; break;
    default: assert(false);
    case 'I': ret = hprof_basic_int;     size = 4; break;
    case 'J': ret = hprof_basic_long;    size = 8; break;
    }

    if (sizeOut != NULL) {
        *sizeOut = size;
    }

    return ret;
}

static hprof_basic_type
primitiveToBasicTypeAndSize(PrimitiveType prim, size_t *sizeOut)
{
    hprof_basic_type ret;
    size_t size;

    switch (prim) {
    case PRIM_BOOLEAN: ret = hprof_basic_boolean; size = 1; break;
    case PRIM_CHAR:    ret = hprof_basic_char;    size = 2; break;
    case PRIM_FLOAT:   ret = hprof_basic_float;   size = 4; break;
    case PRIM_DOUBLE:  ret = hprof_basic_double;  size = 8; break;
    case PRIM_BYTE:    ret = hprof_basic_byte;    size = 1; break;
    case PRIM_SHORT:   ret = hprof_basic_short;   size = 2; break;
    default: assert(false);
    case PRIM_INT:     ret = hprof_basic_int;     size = 4; break;
    case PRIM_LONG:    ret = hprof_basic_long;    size = 8; break;
    }

    if (sizeOut != NULL) {
        *sizeOut = size;
    }

    return ret;
}

/* Always called when marking objects, but only does
 * something when ctx->gcScanState is non-zero, which is usually
 * only true when marking the root set or unreachable
 * objects.  Used to add rootset references to obj.
 */
int
hprofMarkRootObject(hprof_context_t *ctx, const Object *obj, jobject jniObj)
{
    hprof_record_t *rec = &ctx->curRec;
    int err;
    hprof_heap_tag_t heapTag = ctx->gcScanState;

    if (heapTag == 0) {
        return 0;
    }

    if (ctx->objectsInSegment >= OBJECTS_PER_SEGMENT ||
        rec->length >= BYTES_PER_SEGMENT)
    {
        /* This flushes the old segment and starts a new one.
         */
        hprofStartNewRecord(ctx, HPROF_TAG_HEAP_DUMP_SEGMENT, HPROF_TIME);
        ctx->objectsInSegment = 0;
    }

    switch (heapTag) {
    /* ID: object ID
     */
    case HPROF_ROOT_UNKNOWN:
    case HPROF_ROOT_STICKY_CLASS:
    case HPROF_ROOT_MONITOR_USED:
    case HPROF_ROOT_INTERNED_STRING:
    case HPROF_ROOT_FINALIZING:
    case HPROF_ROOT_DEBUGGER:
    case HPROF_ROOT_REFERENCE_CLEANUP:
    case HPROF_ROOT_VM_INTERNAL:
        hprofAddU1ToRecord(rec, heapTag);
        hprofAddIdToRecord(rec, (hprof_object_id)obj);
        break;

    /* ID: object ID
     * ID: JNI global ref ID
     */
    case HPROF_ROOT_JNI_GLOBAL:
        hprofAddU1ToRecord(rec, heapTag);
        hprofAddIdToRecord(rec, (hprof_object_id)obj);
        hprofAddIdToRecord(rec, (hprof_id)jniObj);
        break;

    /* ID: object ID
     * u4: thread serial number
     * u4: frame number in stack trace (-1 for empty)
     */
    case HPROF_ROOT_JNI_LOCAL:
    case HPROF_ROOT_JNI_MONITOR:
    case HPROF_ROOT_JAVA_FRAME:
        hprofAddU1ToRecord(rec, heapTag);
        hprofAddIdToRecord(rec, (hprof_object_id)obj);
        hprofAddU4ToRecord(rec, ctx->gcThreadSerialNumber);
        hprofAddU4ToRecord(rec, (u4)-1);
        break;

    /* ID: object ID
     * u4: thread serial number
     */
    case HPROF_ROOT_NATIVE_STACK:
    case HPROF_ROOT_THREAD_BLOCK:
        hprofAddU1ToRecord(rec, heapTag);
        hprofAddIdToRecord(rec, (hprof_object_id)obj);
        hprofAddU4ToRecord(rec, ctx->gcThreadSerialNumber);
        break;

    /* ID: thread object ID
     * u4: thread serial number
     * u4: stack trace serial number
     */
    case HPROF_ROOT_THREAD_OBJECT:
        hprofAddU1ToRecord(rec, heapTag);
        hprofAddIdToRecord(rec, (hprof_object_id)obj);
        hprofAddU4ToRecord(rec, ctx->gcThreadSerialNumber);
        hprofAddU4ToRecord(rec, (u4)-1);    //xxx
        break;

    default:
        err = 0;
        break;
    }

    ctx->objectsInSegment++;

    return err;
}

static int
stackTraceSerialNumber(const void *obj)

{
#if WITH_HPROF_STACK
    DvmHeapChunk *chunk = ptr2chunk(obj);
    return chunk->stackTraceSerialNumber;
#else
    return HPROF_NULL_STACK_TRACE;
#endif
}

int
hprofDumpHeapObject(hprof_context_t *ctx, const Object *obj)
{
    const ClassObject *clazz;
    hprof_record_t *rec = &ctx->curRec;
    HprofHeapId desiredHeap;

    desiredHeap = 
            dvmHeapSourceGetPtrFlag(obj, HS_ALLOCATED_IN_ZYGOTE) ?
            HPROF_HEAP_ZYGOTE : HPROF_HEAP_APP;
    
    if (ctx->objectsInSegment >= OBJECTS_PER_SEGMENT ||
        rec->length >= BYTES_PER_SEGMENT)
    {
        /* This flushes the old segment and starts a new one.
         */
        hprofStartNewRecord(ctx, HPROF_TAG_HEAP_DUMP_SEGMENT, HPROF_TIME);
        ctx->objectsInSegment = 0;

        /* Starting a new HEAP_DUMP resets the heap to default.
         */
        ctx->currentHeap = HPROF_HEAP_DEFAULT;
    }

    if (desiredHeap != ctx->currentHeap) {
        hprof_string_id nameId;

        /* This object is in a different heap than the current one.
         * Emit a HEAP_DUMP_INFO tag to change heaps.
         */
        hprofAddU1ToRecord(rec, HPROF_HEAP_DUMP_INFO);
        hprofAddU4ToRecord(rec, (u4)desiredHeap);   // u4: heap id
        switch (desiredHeap) {
        case HPROF_HEAP_APP:
            nameId = hprofLookupStringId("app");
            break;
        case HPROF_HEAP_ZYGOTE:
            nameId = hprofLookupStringId("zygote");
            break;
        default:
            /* Internal error. */
            assert(!"Unexpected desiredHeap");
            nameId = hprofLookupStringId("<ILLEGAL>");
            break;
        }
        hprofAddIdToRecord(rec, nameId);
        ctx->currentHeap = desiredHeap;
    }

    clazz = obj->clazz;

    if (clazz == NULL) {
        /* This object was probably just allocated and hasn't been
         * initialized yet.  Add an instance entry to make a note of
         * it;  there's not much else that we can do.
         */
        hprofAddU1ToRecord(rec, HPROF_INSTANCE_DUMP);

        hprofAddIdToRecord(rec, (hprof_object_id)obj);
        hprofAddU4ToRecord(rec, stackTraceSerialNumber(obj));
        hprofAddIdToRecord(rec, (hprof_class_object_id)clazz);  // NULL
        hprofAddIdToRecord(rec, 0);    // no instance data
    } else if (clazz == gDvm.unlinkedJavaLangClass) {
        /* obj is a ClassObject that hasn't been linked yet.
         */
        hprofAddU1ToRecord(rec, HPROF_CLASS_DUMP);

    //TODO: use hprofLookupClassId() for this:
        hprofAddIdToRecord(rec, (hprof_class_object_id)obj);
        hprofAddU4ToRecord(rec, stackTraceSerialNumber(obj));
        hprofAddIdToRecord(rec, (hprof_class_object_id)0); // no super class
        hprofAddIdToRecord(rec, (hprof_object_id)0);       // no class loader
        hprofAddIdToRecord(rec, (hprof_object_id)0);       // no signer
        hprofAddIdToRecord(rec, (hprof_object_id)0);       // no prot domain
        hprofAddIdToRecord(rec, (hprof_id)0);              // reserved
        hprofAddIdToRecord(rec, (hprof_id)0);              // reserved
        hprofAddU4ToRecord(rec, 0);                        // zero instance size
        hprofAddU2ToRecord(rec, 0);                        // empty const pool
        hprofAddU2ToRecord(rec, 0);                        // no statics
        hprofAddU2ToRecord(rec, 0);                        // no instance fields
    } else {
        hprof_class_object_id clazzId;

        clazzId = hprofLookupClassId(clazz);

        if (clazz == gDvm.classJavaLangClass) {
            const ClassObject *thisClass = (const ClassObject *)obj;
            int i, n;
            /* obj is a ClassObject.
             */
            hprofAddU1ToRecord(rec, HPROF_CLASS_DUMP);

            hprofAddIdToRecord(rec, hprofLookupClassId(thisClass));
            hprofAddU4ToRecord(rec, stackTraceSerialNumber(thisClass));
            hprofAddIdToRecord(rec, hprofLookupClassId(thisClass->super));
            hprofAddIdToRecord(rec, (hprof_object_id)thisClass->classLoader);
            hprofAddIdToRecord(rec, (hprof_object_id)0);    // no signer
            hprofAddIdToRecord(rec, (hprof_object_id)0);    // no prot domain
            hprofAddIdToRecord(rec, (hprof_id)0);           // reserved
            hprofAddIdToRecord(rec, (hprof_id)0);           // reserved
            if (obj == (Object *)gDvm.classJavaLangClass) {
                hprofAddU4ToRecord(rec, sizeof(ClassObject)); // instance size
            } else {
                hprofAddU4ToRecord(rec, thisClass->objectSize); // instance size
            }

            hprofAddU2ToRecord(rec, 0);                     // empty const pool

            /* Static fields
             */
            n = thisClass->sfieldCount;
            hprofAddU2ToRecord(rec, (u2)n);
            for (i = 0; i < n; i++) {
                const StaticField *f = &thisClass->sfields[i];
                hprof_basic_type t;
                size_t size;

                t = signatureToBasicTypeAndSize(f->field.signature, &size);
                hprofAddIdToRecord(rec, hprofLookupStringId(f->field.name));
                hprofAddU1ToRecord(rec, t);
                if (size == 1) {
                    hprofAddU1ToRecord(rec, (u1)f->value.b);
                } else if (size == 2) {
                    hprofAddU2ToRecord(rec, (u2)f->value.c);
                } else if (size == 4) {
                    hprofAddU4ToRecord(rec, (u4)f->value.i);
                } else if (size == 8) {
                    hprofAddU8ToRecord(rec, (u8)f->value.j);
                } else {
                    assert(false);
                }
            }

            /* Instance fields for this class (no superclass fields)
             */
            n = thisClass->ifieldCount;
            hprofAddU2ToRecord(rec, (u2)n);
            for (i = 0; i < n; i++) {
                const InstField *f = &thisClass->ifields[i];
                hprof_basic_type t;

                t = signatureToBasicTypeAndSize(f->field.signature, NULL);
                hprofAddIdToRecord(rec, hprofLookupStringId(f->field.name));
                hprofAddU1ToRecord(rec, t);
            }
        } else if (IS_CLASS_FLAG_SET(clazz, CLASS_ISARRAY)) {
            const ArrayObject *aobj = (const ArrayObject *)obj;
            u4 length = aobj->length;

            if (IS_CLASS_FLAG_SET(clazz, CLASS_ISOBJECTARRAY)) {
                /* obj is an object array.
                 */
                hprofAddU1ToRecord(rec, HPROF_OBJECT_ARRAY_DUMP);

                hprofAddIdToRecord(rec, (hprof_object_id)obj);
                hprofAddU4ToRecord(rec, stackTraceSerialNumber(obj));
                hprofAddU4ToRecord(rec, length);
                hprofAddIdToRecord(rec, hprofLookupClassId(clazz));

                /* Dump the elements, which are always objects or NULL.
                 */
                hprofAddIdListToRecord(rec,
                        (const hprof_object_id *)aobj->contents, length);
            } else {
                hprof_basic_type t;
                size_t size;

                t = primitiveToBasicTypeAndSize(clazz->elementClass->
                                                primitiveType, &size);

                /* obj is a primitive array.
                 */
#if DUMP_PRIM_DATA
                hprofAddU1ToRecord(rec, HPROF_PRIMITIVE_ARRAY_DUMP);
#else
                hprofAddU1ToRecord(rec, HPROF_PRIMITIVE_ARRAY_NODATA_DUMP);
#endif

                hprofAddIdToRecord(rec, (hprof_object_id)obj);
                hprofAddU4ToRecord(rec, stackTraceSerialNumber(obj));
                hprofAddU4ToRecord(rec, length);
                hprofAddU1ToRecord(rec, t);

#if DUMP_PRIM_DATA
                /* Dump the raw, packed element values.
                 */
                if (size == 1) {
                    hprofAddU1ListToRecord(rec, (const u1 *)aobj->contents,
                            length);
                } else if (size == 2) {
                    hprofAddU2ListToRecord(rec, (const u2 *)aobj->contents,
                            length);
                } else if (size == 4) {
                    hprofAddU4ListToRecord(rec, (const u4 *)aobj->contents,
                            length);
                } else if (size == 8) {
                    hprofAddU8ListToRecord(rec, (const u8 *)aobj->contents,
                            length);
                }
#endif
            }
        } else {
            const ClassObject *sclass;
            size_t sizePatchOffset, savedLen;

            /* obj is an instance object.
             */
            hprofAddU1ToRecord(rec, HPROF_INSTANCE_DUMP);
            hprofAddIdToRecord(rec, (hprof_object_id)obj);
            hprofAddU4ToRecord(rec, stackTraceSerialNumber(obj));
            hprofAddIdToRecord(rec, hprofLookupClassId(clazz));

            /* Reserve some space for the length of the instance
             * data, which we won't know until we're done writing
             * it.
             */
            sizePatchOffset = rec->length;
            hprofAddU4ToRecord(rec, 0x77777777);

            /* Write the instance data;  fields for this
             * class, followed by super class fields, and so on.
             */
            sclass = clazz;
            while (sclass != NULL) {
                int i, ifieldCount;

                ifieldCount = sclass->ifieldCount;
                for (i = 0; i < ifieldCount; i++) {
                    const InstField *f = &sclass->ifields[i];
                    hprof_basic_type t;
                    size_t size;

                    t = signatureToBasicTypeAndSize(f->field.signature, &size);
                    if (size == 1) {
                        hprofAddU1ToRecord(rec,
                                (u1)dvmGetFieldByte(obj, f->byteOffset));
                    } else if (size == 2) {
                        hprofAddU2ToRecord(rec,
                                (u2)dvmGetFieldChar(obj, f->byteOffset));
                    } else if (size == 4) {
                        hprofAddU4ToRecord(rec,
                                (u4)dvmGetFieldInt(obj, f->byteOffset));
                    } else if (size == 8) {
                        hprofAddU8ToRecord(rec,
                                (u8)dvmGetFieldLong(obj, f->byteOffset));
                    } else {
                        assert(false);
                    }
                }

                sclass = sclass->super;
            }

            /* Patch the instance field length.
             */
            savedLen = rec->length;
            rec->length = sizePatchOffset;
            hprofAddU4ToRecord(rec, savedLen - (sizePatchOffset + 4));
            rec->length = savedLen;
        }
    }

    ctx->objectsInSegment++;

    return 0;
}
