/*
 * 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.
 */
/*
 * DDM-related heap functions
 */
#include <sys/time.h>
#include <time.h>

#include "Dalvik.h"
#include "alloc/Heap.h"
#include "alloc/HeapInternal.h"
#include "alloc/DdmHeap.h"
#include "alloc/HeapSource.h"

#define DEFAULT_HEAP_ID  1

enum HpifWhen {
    HPIF_WHEN_NEVER = 0,
    HPIF_WHEN_NOW = 1,
    HPIF_WHEN_NEXT_GC = 2,
    HPIF_WHEN_EVERY_GC = 3
};

/*
 * Chunk HPIF (client --> server)
 * 
 * Heap Info. General information about the heap,
 * suitable for a summary display.
 * 
 *   [u4]: number of heaps
 * 
 *   For each heap:
 *     [u4]: heap ID
 *     [u8]: timestamp in ms since Unix epoch
 *     [u1]: capture reason (same as 'when' value from server)
 *     [u4]: max heap size in bytes (-Xmx)
 *     [u4]: current heap size in bytes
 *     [u4]: current number of bytes allocated
 *     [u4]: current number of objects allocated
 */
#define HPIF_SIZE(numHeaps) \
        (sizeof(u4) + (numHeaps) * (5 * sizeof(u4) + sizeof(u1) + sizeof(u8)))
void
dvmDdmSendHeapInfo(int reason, bool shouldLock)
{
    struct timeval now;
    u8 nowMs;
    u1 *buf, *b;

    buf = (u1 *)malloc(HPIF_SIZE(1));
    if (buf == NULL) {
        return;
    }
    b = buf;

    /* If there's a one-shot 'when', reset it.
     */
    if (reason == gDvm.gcHeap->ddmHpifWhen) {
        if (shouldLock && ! dvmLockHeap()) {
            LOGW("%s(): can't lock heap to clear when\n", __func__);
            goto skip_when;
        }
        if (reason == gDvm.gcHeap->ddmHpifWhen) {
            if (gDvm.gcHeap->ddmHpifWhen == HPIF_WHEN_NEXT_GC) {
                gDvm.gcHeap->ddmHpifWhen = HPIF_WHEN_NEVER;
            }
        }
        if (shouldLock) {
            dvmUnlockHeap();
        }
    }
skip_when:

    /* The current time, in milliseconds since 0:00 GMT, 1/1/70.
     */
    if (gettimeofday(&now, NULL) < 0) {
        nowMs = 0;
    } else {
        nowMs = (u8)now.tv_sec * 1000 + now.tv_usec / 1000;
    }

    /* number of heaps */
    set4BE(b, 1); b += 4;

    /* For each heap (of which there is one) */
    {
        /* heap ID */
        set4BE(b, DEFAULT_HEAP_ID); b += 4;

        /* timestamp */
        set8BE(b, nowMs); b += 8;

        /* 'when' value */
        *b++ = (u1)reason;

        /* max allowed heap size in bytes */
        set4BE(b, gDvm.heapSizeMax); b += 4;

        /* current heap size in bytes */
        set4BE(b, dvmHeapSourceGetValue(HS_FOOTPRINT, NULL, 0)); b += 4;

        /* number of bytes allocated */
        set4BE(b, dvmHeapSourceGetValue(HS_BYTES_ALLOCATED, NULL, 0)); b += 4;

        /* number of objects allocated */
        set4BE(b, dvmHeapSourceGetValue(HS_OBJECTS_ALLOCATED, NULL, 0)); b += 4;
    }
    assert((intptr_t)b == (intptr_t)buf + (intptr_t)HPIF_SIZE(1));

    dvmDbgDdmSendChunk(CHUNK_TYPE("HPIF"), b - buf, buf);
}

bool
dvmDdmHandleHpifChunk(int when)
{
    switch (when) {
    case HPIF_WHEN_NOW:
        dvmDdmSendHeapInfo(when, true);
        break;
    case HPIF_WHEN_NEVER:
    case HPIF_WHEN_NEXT_GC:
    case HPIF_WHEN_EVERY_GC:
        if (dvmLockHeap()) {
            gDvm.gcHeap->ddmHpifWhen = when;
            dvmUnlockHeap();
        } else {
            LOGI("%s(): can't lock heap to set when\n", __func__);
            return false;
        }
        break;
    default:
        LOGI("%s(): bad when value 0x%08x\n", __func__, when);
        return false;
    }

    return true;
}

enum HpsgSolidity {
    SOLIDITY_FREE = 0,
    SOLIDITY_HARD = 1,
    SOLIDITY_SOFT = 2,
    SOLIDITY_WEAK = 3,
    SOLIDITY_PHANTOM = 4,
    SOLIDITY_FINALIZABLE = 5,
    SOLIDITY_SWEEP = 6,
};

enum HpsgKind {
    KIND_OBJECT = 0,
    KIND_CLASS_OBJECT = 1,
    KIND_ARRAY_1 = 2,
    KIND_ARRAY_2 = 3,
    KIND_ARRAY_4 = 4,
    KIND_ARRAY_8 = 5,
    KIND_UNKNOWN = 6,
    KIND_NATIVE = 7,
};

#define HPSG_PARTIAL (1<<7)
#define HPSG_STATE(solidity, kind) \
    ((u1)((((kind) & 0x7) << 3) | ((solidity) & 0x7)))

typedef struct HeapChunkContext {
    u1 *buf;
    u1 *p;
    u1 *pieceLenField;
    size_t bufLen;
    size_t totalAllocationUnits;
    int type;
    bool merge;
    bool needHeader;
} HeapChunkContext;

#define ALLOCATION_UNIT_SIZE 8

static void
flush_hpsg_chunk(HeapChunkContext *ctx)
{
    /* Patch the "length of piece" field.
     */
    assert(ctx->buf <= ctx->pieceLenField &&
            ctx->pieceLenField <= ctx->p);
    set4BE(ctx->pieceLenField, ctx->totalAllocationUnits);

    /* Send the chunk.
     */
    dvmDbgDdmSendChunk(ctx->type, ctx->p - ctx->buf, ctx->buf);

    /* Reset the context.
     */
    ctx->p = ctx->buf;
    ctx->totalAllocationUnits = 0;
    ctx->needHeader = true;
    ctx->pieceLenField = NULL;
}

static void
heap_chunk_callback(const void *chunkptr, size_t chunklen,
                    const void *userptr, size_t userlen, void *arg)
{
    HeapChunkContext *ctx = (HeapChunkContext *)arg;
    u1 state;

    UNUSED_PARAMETER(userlen);

    assert((chunklen & (ALLOCATION_UNIT_SIZE-1)) == 0);

    /* Make sure there's enough room left in the buffer.
     * We need to use two bytes for every fractional 256
     * allocation units used by the chunk.
     */
    {
        size_t needed = (((chunklen/ALLOCATION_UNIT_SIZE + 255) / 256) * 2);
        size_t bytesLeft = ctx->bufLen - (size_t)(ctx->p - ctx->buf);
        if (bytesLeft < needed) {
            flush_hpsg_chunk(ctx);
        }

        bytesLeft = ctx->bufLen - (size_t)(ctx->p - ctx->buf);
        if (bytesLeft < needed) {
            LOGW("chunk is too big to transmit (chunklen=%zd, %zd bytes)\n",
                chunklen, needed);
            return;
        }
    }

//TODO: notice when there's a gap and start a new heap, or at least a new range.
    if (ctx->needHeader) {
        /*
         * Start a new HPSx chunk.
         */

        /* [u4]: heap ID */
        set4BE(ctx->p, DEFAULT_HEAP_ID); ctx->p += 4;

        /* [u1]: size of allocation unit, in bytes */
        *ctx->p++ = 8;

        /* [u4]: virtual address of segment start */
        set4BE(ctx->p, (uintptr_t)chunkptr); ctx->p += 4;

        /* [u4]: offset of this piece (relative to the virtual address) */
        set4BE(ctx->p, 0); ctx->p += 4;

        /* [u4]: length of piece, in allocation units
         * We won't know this until we're done, so save the offset
         * and stuff in a dummy value.
         */
        ctx->pieceLenField = ctx->p;
        set4BE(ctx->p, 0x55555555); ctx->p += 4;

        ctx->needHeader = false;
    }

    /* Determine the type of this chunk.
     */
    if (userptr == NULL) {
        /* It's a free chunk.
         */
        state = HPSG_STATE(SOLIDITY_FREE, 0);
    } else {
        const Object *obj = userptr;
        /* If we're looking at the native heap, we'll just return 
         * (SOLIDITY_HARD, KIND_NATIVE) for all allocated chunks
         */
        bool native = ctx->type == CHUNK_TYPE("NHSG");

        /* It's an allocated chunk.  Figure out what it is.
         */
//TODO: if ctx.merge, see if this chunk is different from the last chunk.
//      If it's the same, we should combine them.
        if (!native && dvmIsValidObject(obj)) {
            ClassObject *clazz = obj->clazz;
            if (clazz == NULL) {
                /* The object was probably just created
                 * but hasn't been initialized yet.
                 */
                state = HPSG_STATE(SOLIDITY_HARD, KIND_OBJECT);
            } else if (clazz == gDvm.unlinkedJavaLangClass ||
                       clazz == gDvm.classJavaLangClass)
            {
                state = HPSG_STATE(SOLIDITY_HARD, KIND_CLASS_OBJECT);
            } else if (IS_CLASS_FLAG_SET(clazz, CLASS_ISARRAY)) {
                if (IS_CLASS_FLAG_SET(clazz, CLASS_ISOBJECTARRAY)) {
                    state = HPSG_STATE(SOLIDITY_HARD, KIND_ARRAY_4);
                } else {
                    switch (clazz->elementClass->primitiveType) {
                    case PRIM_BOOLEAN:
                    case PRIM_BYTE:
                        state = HPSG_STATE(SOLIDITY_HARD, KIND_ARRAY_1);
                        break;
                    case PRIM_CHAR:
                    case PRIM_SHORT:
                        state = HPSG_STATE(SOLIDITY_HARD, KIND_ARRAY_2);
                        break;
                    case PRIM_INT:
                    case PRIM_FLOAT:
                        state = HPSG_STATE(SOLIDITY_HARD, KIND_ARRAY_4);
                        break;
                    case PRIM_DOUBLE:
                    case PRIM_LONG:
                        state = HPSG_STATE(SOLIDITY_HARD, KIND_ARRAY_8);
                        break;
                    default:
                        assert(!"Unknown GC heap object type");
                        state = HPSG_STATE(SOLIDITY_HARD, KIND_UNKNOWN);
                        break;
                    }
                }
            } else {
                state = HPSG_STATE(SOLIDITY_HARD, KIND_OBJECT);
            }
        } else {
            obj = NULL; // it's not actually an object
            state = HPSG_STATE(SOLIDITY_HARD, KIND_NATIVE);
        }
    }

    /* Write out the chunk description.
     */
    chunklen /= ALLOCATION_UNIT_SIZE;   // convert to allocation units
    ctx->totalAllocationUnits += chunklen;
    while (chunklen > 256) {
        *ctx->p++ = state | HPSG_PARTIAL;
        *ctx->p++ = 255;     // length - 1
        chunklen -= 256;
    }
    *ctx->p++ = state;
    *ctx->p++ = chunklen - 1;
}

enum HpsgWhen {
    HPSG_WHEN_NEVER = 0,
    HPSG_WHEN_EVERY_GC = 1,
};
enum HpsgWhat {
    HPSG_WHAT_MERGED_OBJECTS = 0,
    HPSG_WHAT_DISTINCT_OBJECTS = 1,
};

/*
 * Maximum chunk size.  Obtain this from the formula:
 *
 * (((maximum_heap_size / ALLOCATION_UNIT_SIZE) + 255) / 256) * 2
 */
#define HPSx_CHUNK_SIZE (16384 - 16)

void dlmalloc_walk_heap(void(*)(const void*, size_t, const void*, size_t, void*),void*);

static void
walkHeap(bool merge, bool native)
{
    HeapChunkContext ctx;
    
    memset(&ctx, 0, sizeof(ctx));
    ctx.bufLen = HPSx_CHUNK_SIZE;
    ctx.buf = (u1 *)malloc(ctx.bufLen);
    if (ctx.buf == NULL) {
        return;
    }

    ctx.merge = merge;
    if (native) {
        ctx.type = CHUNK_TYPE("NHSG");
    } else {
        if (ctx.merge) {
            ctx.type = CHUNK_TYPE("HPSG");
        } else {
            ctx.type = CHUNK_TYPE("HPSO");
        }
    }

    ctx.p = ctx.buf;
    ctx.needHeader = true;
    if (native) {
        dlmalloc_walk_heap(heap_chunk_callback, (void *)&ctx);
    } else {
        dvmHeapSourceWalk(heap_chunk_callback, (void *)&ctx);
    }
    if (ctx.p > ctx.buf) {
        flush_hpsg_chunk(&ctx);
    }

    free(ctx.buf);
}

void
dvmDdmSendHeapSegments(bool shouldLock, bool native)
{
    u1 heapId[sizeof(u4)];
    GcHeap *gcHeap = gDvm.gcHeap;
    int when, what;
    bool merge;

    /* Don't even grab the lock if there's nothing to do when we're called.
     */
    if (!native) {
        when = gcHeap->ddmHpsgWhen;
        what = gcHeap->ddmHpsgWhat;
        if (when == HPSG_WHEN_NEVER) {
            return;
        }
    } else {
        when = gcHeap->ddmNhsgWhen;
        what = gcHeap->ddmNhsgWhat;
        if (when == HPSG_WHEN_NEVER) {
            return;
        }
    }
    if (shouldLock && !dvmLockHeap()) {
        LOGW("Can't lock heap for DDM HPSx dump\n");
        return;
    }

    /* Figure out what kind of chunks we'll be sending.
     */
    if (what == HPSG_WHAT_MERGED_OBJECTS) {
        merge = true;
    } else if (what == HPSG_WHAT_DISTINCT_OBJECTS) {
        merge = false;
    } else {
        assert(!"bad HPSG.what value");
        return;
    }

    /* First, send a heap start chunk.
     */
    set4BE(heapId, DEFAULT_HEAP_ID);
    dvmDbgDdmSendChunk(native ? CHUNK_TYPE("NHST") : CHUNK_TYPE("HPST"),
        sizeof(u4), heapId);

    /* Send a series of heap segment chunks.
     */
    walkHeap(merge, native);

    /* Finally, send a heap end chunk.
     */
    dvmDbgDdmSendChunk(native ? CHUNK_TYPE("NHEN") : CHUNK_TYPE("HPEN"),
        sizeof(u4), heapId);

    if (shouldLock) {
        dvmUnlockHeap();
    }
}

bool
dvmDdmHandleHpsgNhsgChunk(int when, int what, bool native)
{
    LOGI("dvmDdmHandleHpsgChunk(when %d, what %d, heap %d)\n", when, what,
         native);
    switch (when) {
    case HPSG_WHEN_NEVER:
    case HPSG_WHEN_EVERY_GC:
        break;
    default:
        LOGI("%s(): bad when value 0x%08x\n", __func__, when);
        return false;
    }

    switch (what) {
    case HPSG_WHAT_MERGED_OBJECTS:
    case HPSG_WHAT_DISTINCT_OBJECTS:
        break;
    default:
        LOGI("%s(): bad what value 0x%08x\n", __func__, what);
        return false;
    }

    if (dvmLockHeap()) {
        if (!native) {
            gDvm.gcHeap->ddmHpsgWhen = when;
            gDvm.gcHeap->ddmHpsgWhat = what;
        } else {
            gDvm.gcHeap->ddmNhsgWhen = when;
            gDvm.gcHeap->ddmNhsgWhat = what;
        }
//TODO: if what says we should dump immediately, signal (or do) it from here
        dvmUnlockHeap();
    } else {
        LOGI("%s(): can't lock heap to set when/what\n", __func__);
        return false;
    }

    return true;
}
