/*
 * 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/DlMalloc.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()) {
            ALOGW("%s(): can't lock heap to clear when", __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, dvmHeapSourceGetMaximumSize()); 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 {
            ALOGI("%s(): can't lock heap to set when", __func__);
            return false;
        }
        break;
    default:
        ALOGI("%s(): bad when value 0x%08x", __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)))

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

#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 append_chunk(HeapChunkContext *ctx, u1 state, void* ptr, size_t length) {
    /* 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 and 17 bytes for
     * any header.
     */
    {
        size_t needed = (((length/ALLOCATION_UNIT_SIZE + 255) / 256) * 2) + 17;
        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) {
            ALOGW("chunk is too big to transmit (length=%zd, %zd bytes)",
                  length, needed);
            return;
        }
    }
    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)ptr); 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;
    }
    /* Write out the chunk description.
     */
    length /= ALLOCATION_UNIT_SIZE;   // convert to allocation units
    ctx->totalAllocationUnits += length;
    while (length > 256) {
        *ctx->p++ = state | HPSG_PARTIAL;
        *ctx->p++ = 255;     // length - 1
        length -= 256;
    }
    *ctx->p++ = state;
    *ctx->p++ = length - 1;
}

/*
 * Called by dlmalloc_inspect_all. If used_bytes != 0 then start is
 * the start of a malloc-ed piece of memory of size used_bytes. If
 * start is 0 then start is the beginning of any free space not
 * including dlmalloc's book keeping and end the start of the next
 * dlmalloc chunk. Regions purely containing book keeping don't
 * callback.
 */
static void heap_chunk_callback(void* start, void* end, size_t used_bytes,
                                void* arg)
{
    u1 state;
    HeapChunkContext *ctx = (HeapChunkContext *)arg;
    UNUSED_PARAMETER(end);

    if (used_bytes == 0) {
        if (start == NULL) {
            // Reset for start of new heap.
            ctx->startOfNextMemoryChunk = NULL;
            flush_hpsg_chunk(ctx);
        }
        // Only process in use memory so that free region information
        // also includes dlmalloc book keeping.
        return;
    }

    /* 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");

    if (ctx->startOfNextMemoryChunk != NULL) {
        // Transmit any pending free memory. Native free memory of
        // over kMaxFreeLen could be because of the use of mmaps, so
        // don't report. If not free memory then start a new segment.
        bool flush = true;
        if (start > ctx->startOfNextMemoryChunk) {
            const size_t kMaxFreeLen = 2 * SYSTEM_PAGE_SIZE;
            void* freeStart = ctx->startOfNextMemoryChunk;
            void* freeEnd = start;
            size_t freeLen = (char*)freeEnd - (char*)freeStart;
            if (!native || freeLen < kMaxFreeLen) {
                append_chunk(ctx, HPSG_STATE(SOLIDITY_FREE, 0),
                             freeStart, freeLen);
                flush = false;
            }
        }
        if (flush) {
            ctx->startOfNextMemoryChunk = NULL;
            flush_hpsg_chunk(ctx);
        }
    }
    const Object *obj = (const Object *)start;

    /* 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 (dvmIsTheClassClass(clazz)) {
            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);
    }
    append_chunk(ctx, state, start, used_bytes + HEAP_SOURCE_CHUNK_OVERHEAD);
    ctx->startOfNextMemoryChunk =
        (char*)start + used_bytes + HEAP_SOURCE_CHUNK_OVERHEAD;
}

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)

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_inspect_all(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()) {
        ALOGW("Can't lock heap for DDM HPSx dump");
        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)
{
    ALOGI("dvmDdmHandleHpsgChunk(when %d, what %d, heap %d)", when, what,
         native);
    switch (when) {
    case HPSG_WHEN_NEVER:
    case HPSG_WHEN_EVERY_GC:
        break;
    default:
        ALOGI("%s(): bad when value 0x%08x", __func__, when);
        return false;
    }

    switch (what) {
    case HPSG_WHAT_MERGED_OBJECTS:
    case HPSG_WHAT_DISTINCT_OBJECTS:
        break;
    default:
        ALOGI("%s(): bad what value 0x%08x", __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 {
        ALOGI("%s(): can't lock heap to set when/what", __func__);
        return false;
    }

    return true;
}
