/*
 * 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.
 */

#include "Hprof.h"
#include "HprofStack.h"

#include "alloc/HeapInternal.h"

static HashTable *gStackFrameHashTable;

static u4 computeStackFrameHash(const StackFrameEntry *stackFrameEntry);

int
hprofStartup_StackFrame()
{
    HashIter iter;

    /* Cache the string "<unknown>" for use when the source file is
     * unknown.
     */
    hprofLookupStringId("<unknown>");

    /* This will be called when a GC begins. */
    for (dvmHashIterBegin(gStackFrameHashTable, &iter);
         !dvmHashIterDone(&iter);
         dvmHashIterNext(&iter)) {
        StackFrameEntry *stackFrameEntry;
        const Method *method;

        /* Clear the 'live' bit at the start of the GC pass. */
        stackFrameEntry = (StackFrameEntry *) dvmHashIterData(&iter);
        stackFrameEntry->live = 0;

        method = stackFrameEntry->frame.method;
        if (method == NULL) {
            continue;
        }

        /* Make sure the method name, descriptor, and source file are in
         * the string table, and that the method class is in the class
         * table. This is needed because strings and classes will be dumped
         * before stack frames.
         */

        if (method->name) {
            hprofLookupStringId(method->name);
        }

        DexStringCache cache;
        const char* descriptor;

        dexStringCacheInit(&cache);
        descriptor = dexProtoGetMethodDescriptor(&method->prototype, &cache);
        hprofLookupStringId(descriptor);
        dexStringCacheRelease(&cache);
        
        const char* sourceFile = dvmGetMethodSourceFile(method);
        if (sourceFile) {
            hprofLookupStringId(sourceFile);
        }

        if (method->clazz) {
            hprofLookupClassId(method->clazz);
        }
    }
    
    return 0;
}

int
hprofShutdown_StackFrame()
{
    HashIter iter;

    /* This will be called when a GC has completed. */
    for (dvmHashIterBegin(gStackFrameHashTable, &iter);
         !dvmHashIterDone(&iter);
         dvmHashIterNext(&iter)) {
        const StackFrameEntry *stackFrameEntry;

        /*
         * If the 'live' bit is 0, the frame is not in use by any current
         * heap object and may be destroyed.
         */
        stackFrameEntry = (const StackFrameEntry *) dvmHashIterData(&iter);
        if (!stackFrameEntry->live) {
            dvmHashTableRemove(gStackFrameHashTable,
                    computeStackFrameHash(stackFrameEntry),
                    (void*) stackFrameEntry);
            free((void*) stackFrameEntry);
        }
    }

    return 0;
}

/* Only hash the 'frame' portion of the StackFrameEntry. */
static u4
computeStackFrameHash(const StackFrameEntry *stackFrameEntry)
{
    u4 hash = 0;
    const char *cp = (char *) &stackFrameEntry->frame;
    int i;
    
    for (i = 0; i < (int) sizeof(StackFrame); i++) {
        hash = 31 * hash + cp[i];
    }
    return hash;
}

/* Only compare the 'frame' portion of the StackFrameEntry. */
static int
stackFrameCmp(const void *tableItem, const void *looseItem)
{
    return memcmp(&((StackFrameEntry *)tableItem)->frame,
            &((StackFrameEntry *) looseItem)->frame, sizeof(StackFrame));
}

static StackFrameEntry *
stackFrameDup(const StackFrameEntry *stackFrameEntry)
{
    StackFrameEntry *newStackFrameEntry = malloc(sizeof(StackFrameEntry));
    memcpy(newStackFrameEntry, stackFrameEntry, sizeof(StackFrameEntry));
    return newStackFrameEntry;
}

hprof_stack_frame_id
hprofLookupStackFrameId(const StackFrameEntry *stackFrameEntry)
{
    StackFrameEntry *val;
    u4 hashValue;

    /*
     * Create the hash table on first contact.  We can't do this in
     * hprofStartupStackFrame, because we have to compute stack trace
     * serial numbers and place them into object headers before the
     * rest of hprof is triggered by a GC event.
     */
    if (gStackFrameHashTable == NULL) {
        gStackFrameHashTable = dvmHashTableCreate(512, free);
    }
    dvmHashTableLock(gStackFrameHashTable);

    hashValue = computeStackFrameHash(stackFrameEntry);
    val = dvmHashTableLookup(gStackFrameHashTable, hashValue,
        (void *)stackFrameEntry, (HashCompareFunc)stackFrameCmp, false);
    if (val == NULL) {
        const StackFrameEntry *newStackFrameEntry;

        newStackFrameEntry = stackFrameDup(stackFrameEntry);
        val = dvmHashTableLookup(gStackFrameHashTable, hashValue,
            (void *)newStackFrameEntry, (HashCompareFunc)stackFrameCmp, true);
        assert(val != NULL);
    }

    /* Mark the frame as live (in use by an object in the current heap). */
    val->live = 1;

    dvmHashTableUnlock(gStackFrameHashTable);

    return (hprof_stack_frame_id) val;
}

int
hprofDumpStackFrames(hprof_context_t *ctx)
{
    HashIter iter;
    hprof_record_t *rec = &ctx->curRec;

    dvmHashTableLock(gStackFrameHashTable);

    for (dvmHashIterBegin(gStackFrameHashTable, &iter);
         !dvmHashIterDone(&iter);
         dvmHashIterNext(&iter))
    {
        const StackFrameEntry *stackFrameEntry;
        const Method *method;
        int pc;
        const char *sourceFile;
        ClassObject *clazz;
        int lineNum;
        
        hprofStartNewRecord(ctx, HPROF_TAG_STACK_FRAME, HPROF_TIME);
        
        stackFrameEntry = (const StackFrameEntry *) dvmHashIterData(&iter);
        assert(stackFrameEntry != NULL);
        
        method = stackFrameEntry->frame.method;
        pc = stackFrameEntry->frame.pc;
        sourceFile = dvmGetMethodSourceFile(method);
        if (sourceFile == NULL) {
            sourceFile = "<unknown>";
            lineNum = 0;
        } else {
            lineNum = dvmLineNumFromPC(method, pc);
        }
        clazz = (ClassObject *) hprofLookupClassId(method->clazz);

        /* STACK FRAME format:
         *
         * ID:     ID for this stack frame
         * ID:     ID for the method name
         * ID:     ID for the method descriptor
         * ID:     ID for the source file name
         * u4:     class serial number
         * u4:     line number, 0 = no line information
         *
         * We use the address of the stack frame as its ID.
         */

        DexStringCache cache;
        const char* descriptor;

        dexStringCacheInit(&cache);
        descriptor = dexProtoGetMethodDescriptor(&method->prototype, &cache);

        hprofAddIdToRecord(rec, (u4) stackFrameEntry);
        hprofAddIdToRecord(rec, hprofLookupStringId(method->name));
        hprofAddIdToRecord(rec, hprofLookupStringId(descriptor));
        hprofAddIdToRecord(rec, hprofLookupStringId(sourceFile));
        hprofAddU4ToRecord(rec, (u4) clazz->serialNumber);
        hprofAddU4ToRecord(rec, (u4) lineNum);

        dexStringCacheRelease(&cache);
    }

    dvmHashTableUnlock(gStackFrameHashTable);
    return 0;
}
