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

/*
 * Reference table management.
 */
#include "Dalvik.h"

/*
 * Initialize a ReferenceTable structure.
 */
bool dvmInitReferenceTable(ReferenceTable* pRef, int initialCount,
    int maxCount)
{
    assert(initialCount > 0);
    assert(initialCount <= maxCount);

    pRef->table = (Object**) malloc(initialCount * sizeof(Object*));
    if (pRef->table == NULL)
        return false;
#ifndef NDEBUG
    memset(pRef->table, 0xdd, initialCount * sizeof(Object*));
#endif
    pRef->nextEntry = pRef->table;
    pRef->allocEntries = initialCount;
    pRef->maxEntries = maxCount;

    return true;
}

/*
 * Clears out the contents of a ReferenceTable, freeing allocated storage.
 */
void dvmClearReferenceTable(ReferenceTable* pRef)
{
    free(pRef->table);
    pRef->table = pRef->nextEntry = NULL;
    pRef->allocEntries = pRef->maxEntries = -1;
}

/*
 * Add "obj" to "pRef".
 */
bool dvmAddToReferenceTable(ReferenceTable* pRef, Object* obj)
{
    assert(obj != NULL);
    assert(dvmIsHeapAddress(obj));
    assert(pRef->table != NULL);
    assert(pRef->allocEntries <= pRef->maxEntries);

    if (pRef->nextEntry == pRef->table + pRef->allocEntries) {
        /* reached end of allocated space; did we hit buffer max? */
        if (pRef->nextEntry == pRef->table + pRef->maxEntries) {
            LOGW("ReferenceTable overflow (max=%d)", pRef->maxEntries);
            return false;
        }

        Object** newTable;
        int newSize;

        newSize = pRef->allocEntries * 2;
        if (newSize > pRef->maxEntries)
            newSize = pRef->maxEntries;
        assert(newSize > pRef->allocEntries);

        newTable = (Object**) realloc(pRef->table, newSize * sizeof(Object*));
        if (newTable == NULL) {
            LOGE("Unable to expand ref table (from %d to %d %d-byte entries)",
                pRef->allocEntries, newSize, sizeof(Object*));
            return false;
        }
        LOGVV("Growing %p from %d to %d", pRef, pRef->allocEntries, newSize);

        /* update entries; adjust "nextEntry" in case memory moved */
        pRef->nextEntry = newTable + (pRef->nextEntry - pRef->table);
        pRef->table = newTable;
        pRef->allocEntries = newSize;
    }

    *pRef->nextEntry++ = obj;
    return true;
}

/*
 * Returns NULL if not found.
 */
Object** dvmFindInReferenceTable(const ReferenceTable* pRef, Object** bottom,
    Object* obj)
{
    Object** ptr;

    ptr = pRef->nextEntry;
    while (--ptr >= bottom) {
        if (*ptr == obj)
            return ptr;
    }
    return NULL;
}

/*
 * Remove "obj" from "pRef".  We start at the end of the list (where the
 * most-recently-added element is), and stop searching for a match after
 * examining the element at "bottom".
 *
 * Most of the time "obj" is at or near the end of the list.  If not, we
 * compact it down.
 */
bool dvmRemoveFromReferenceTable(ReferenceTable* pRef, Object** bottom,
    Object* obj)
{
    Object** ptr;

    assert(pRef->table != NULL);

    /*
     * Scan from the most-recently-added entry up to the bottom entry for
     * this frame.
     */
    ptr = dvmFindInReferenceTable(pRef, bottom, obj);
    if (ptr == NULL)
        return false;

    /*
     * Delete the entry.
     */
    pRef->nextEntry--;
    int moveCount = pRef->nextEntry - ptr;
    if (moveCount != 0) {
        /* remove from middle, slide the rest down */
        memmove(ptr, ptr+1, moveCount * sizeof(Object*));
        //LOGV("LREF delete %p, shift %d down", obj, moveCount);
    } else {
        /* last entry, falls off the end */
        //LOGV("LREF delete %p from end", obj);
    }

    return true;
}

/*
 * If "obj" is an array, return the number of elements in the array.
 * Otherwise, return zero.
 */
static size_t getElementCount(const Object* obj)
{
    const ArrayObject* arrayObj = (ArrayObject*) obj;
    if (arrayObj == NULL || arrayObj == kClearedJniWeakGlobal ||
            arrayObj->clazz == NULL || !dvmIsArray(arrayObj)) {
        return 0;
    }
    return arrayObj->length;
}

/*
 * This is a qsort() callback.  We sort Object* by class, allocation size,
 * and then by the Object* itself.
 */
static int compareObject(const void* vobj1, const void* vobj2)
{
    const Object* obj1 = *((Object* const*) vobj1);
    const Object* obj2 = *((Object* const*) vobj2);

    // Ensure null references and cleared jweaks appear at the end.
    if (obj1 == NULL) {
        if (obj2 == NULL) {
            return 0;
        } else {
            return 1;
        }
    } else if (obj2 == NULL) {
        return -1;
    }
    if (obj1 == kClearedJniWeakGlobal) {
        if (obj2 == kClearedJniWeakGlobal) {
            return 0;
        } else {
            return 1;
        }
    } else if (obj2 == kClearedJniWeakGlobal) {
        return -1;
    }

    if (obj1->clazz != obj2->clazz) {
        return (u1*)obj1->clazz - (u1*)obj2->clazz;
    } else {
        size_t count1 = getElementCount(obj1);
        size_t count2 = getElementCount(obj2);
        if (count1 != count2) {
            return count1 - count2;
        } else {
            return (u1*)obj1 - (u1*)obj2;
        }
    }
}

/*
 * Log an object with some additional info.
 *
 * Pass in the number of elements in the array (or 0 if this is not an
 * array object), and the number of additional objects that are identical
 * or equivalent to the original.
 */
static void logSummaryLine(const Object* obj, size_t elems, int identical, int equiv)
{
    if (obj == NULL) {
        LOGW("    NULL reference (count=%d)", equiv);
        return;
    }
    if (obj == kClearedJniWeakGlobal) {
        LOGW("    cleared jweak (count=%d)", equiv);
        return;
    }

    std::string className(dvmHumanReadableType(obj));
    if (obj->clazz == gDvm.classJavaLangClass) {
        // We're summarizing multiple instances, so using the exemplar
        // Class' type parameter here would be misleading.
        className = "java.lang.Class";
    }
    if (elems != 0) {
        StringAppendF(&className, " (%zd elements)", elems);
    }

    size_t total = identical + equiv + 1;
    std::string msg(StringPrintf("%5d of %s", total, className.c_str()));
    if (identical + equiv != 0) {
        StringAppendF(&msg, " (%d unique instances)", equiv + 1);
    }
    LOGW("    %s", msg.c_str());
}

/*
 * Dump a summary of an array of references to the log file.
 *
 * This is used to dump the contents of ReferenceTable and IndirectRefTable
 * structs.
 */
void dvmDumpReferenceTableContents(Object* const* refs, size_t count,
    const char* descr)
{
    LOGW("%s reference table (%p) dump:", descr, refs);

    if (count == 0) {
        LOGW("  (empty)");
        return;
    }

    // Dump the most recent N entries.
    const size_t kLast = 10;
    int first = count - kLast;
    if (first < 0) {
        first = 0;
    }
    LOGW("  Last %d entries (of %d):", (count - first), count);
    for (int idx = count - 1; idx >= first; --idx) {
        const Object* ref = refs[idx];
        if (ref == NULL) {
            continue;
        }
        if (ref == kClearedJniWeakGlobal) {
            LOGW("    %5d: cleared jweak", idx);
            continue;
        }
        if (ref->clazz == NULL) {
            // should only be possible right after a plain dvmMalloc().
            size_t size = dvmObjectSizeInHeap(ref);
            LOGW("    %5d: %p (raw) (%zd bytes)", idx, ref, size);
            continue;
        }

        std::string className(dvmHumanReadableType(ref));

        std::string extras;
        size_t elems = getElementCount(ref);
        if (elems != 0) {
            StringAppendF(&extras, " (%zd elements)", elems);
        } else if (ref->clazz == gDvm.classJavaLangString) {
            const StringObject* str =
                    reinterpret_cast<const StringObject*>(ref);
            extras += " \"";
            size_t count = 0;
            char* s = dvmCreateCstrFromString(str);
            char* p = s;
            for (; *p && count < 16; ++p, ++count) {
                extras += *p;
            }
            if (*p == 0) {
                extras += "\"";
            } else {
                StringAppendF(&extras, "... (%d chars)", str->length());
            }
            free(s);
        }
        LOGW("    %5d: %p %s%s", idx, ref, className.c_str(), extras.c_str());
    }

    // Make a copy of the table, and sort it.
    Object** tableCopy = (Object**)malloc(sizeof(Object*) * count);
    if (tableCopy == NULL) {
        LOGE("Unable to copy table with %d elements", count);
        return;
    }
    memcpy(tableCopy, refs, sizeof(Object*) * count);
    qsort(tableCopy, count, sizeof(Object*), compareObject);
    refs = tableCopy;       // use sorted list

    // Remove any uninteresting stuff from the list. The sort moved them all to the end.
    while (count > 0 && refs[count-1] == NULL) {
        --count;
    }
    while (count > 0 && refs[count-1] == kClearedJniWeakGlobal) {
        --count;
    }
    if (count == 0) {
        return;
    }

    // Dump a summary of the whole table.
    LOGW("  Summary:");
    size_t equiv, identical;
    equiv = identical = 0;
    size_t idx;
    size_t elems;
    for (idx = 1; idx < count; idx++) {
        elems = getElementCount(refs[idx-1]);

        if (refs[idx] == refs[idx-1]) {
            // same reference, added more than once.
            identical++;
        } else if (refs[idx]->clazz == refs[idx-1]->clazz &&
            getElementCount(refs[idx]) == elems)
        {
            // same class / element count, different object.
            equiv++;
        } else {
            // different class.
            logSummaryLine(refs[idx-1], elems, identical, equiv);
            equiv = identical = 0;
        }
    }

    // Handle the last entry (everything above outputs refs[i-1]).
    elems = getElementCount(refs[idx-1]);
    logSummaryLine(refs[count-1], elems, identical, equiv);

    free(tableCopy);
}

/*
 * Dump the contents of a ReferenceTable to the log.
 */
void dvmDumpReferenceTable(const ReferenceTable* pRef, const char* descr)
{
    dvmDumpReferenceTableContents(pRef->table, dvmReferenceTableEntries(pRef),
        descr);
}
