/*
 * 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 "Dalvik.h"
#include "alloc/HeapTable.h"
#include "alloc/HeapInternal.h"

#include <limits.h> // for INT_MAX

static void *heapTableRealloc(void *oldPtr, size_t newSize)
{
    /* Don't just call realloc(), in case the native system
     * doesn't malloc() on realloc(NULL).
     */
    if (oldPtr != NULL) {
        return realloc(oldPtr, newSize);
    } else {
        return malloc(newSize);
    }
}

void dvmHeapHeapTableFree(void *ptr)
{
    free(ptr);
}

#define heapRefTableIsFull(refs) \
    ({ \
        const HeapRefTable *HRTIF_refs = (refs); \
        dvmIsReferenceTableFull(refs); \
    })

bool dvmHeapInitHeapRefTable(HeapRefTable *refs, size_t nelems)
{
    memset(refs, 0, sizeof(*refs));
    return dvmInitReferenceTable(refs, nelems, INT_MAX);
}

/* Frees the array inside the HeapRefTable, not the HeapRefTable itself.
 */
void dvmHeapFreeHeapRefTable(HeapRefTable *refs)
{
    dvmClearReferenceTable(refs);
}

/*
 * Large, non-contiguous reference tables
 */

#define kLargeHeapRefTableNElems 1024
bool dvmHeapAddRefToLargeTable(LargeHeapRefTable **tableP, Object *ref)
{
    LargeHeapRefTable *table;

    assert(tableP != NULL);
    assert(ref != NULL);

    /* Make sure that a table with a free slot is
     * at the head of the list.
     */
    if (*tableP != NULL) {
        table = *tableP;
        LargeHeapRefTable *prevTable;

        /* Find an empty slot for this reference.
         */
        prevTable = NULL;
        while (table != NULL && heapRefTableIsFull(&table->refs)) {
            prevTable = table;
            table = table->next;
        }
        if (table != NULL) {
            if (prevTable != NULL) {
                /* Move the table to the head of the list.
                 */
                prevTable->next = table->next;
                table->next = *tableP;
                *tableP = table;
            }
            /* else it's already at the head. */

            goto insert;
        }
        /* else all tables are already full;
         * fall through to the alloc case.
         */
    }

    /* Allocate a new table.
     */
    table = (LargeHeapRefTable *)heapTableRealloc(NULL,
            sizeof(LargeHeapRefTable));
    if (table == NULL) {
        LOGE_HEAP("Can't allocate a new large ref table\n");
        return false;
    }
    if (!dvmHeapInitHeapRefTable(&table->refs, kLargeHeapRefTableNElems)) {
        LOGE_HEAP("Can't initialize a new large ref table\n");
        dvmHeapHeapTableFree(table);
        return false;
    }

    /* Stick it at the head.
     */
    table->next = *tableP;
    *tableP = table;

insert:
    /* Insert the reference.
     */
    assert(table == *tableP);
    assert(table != NULL);
    assert(!heapRefTableIsFull(&table->refs));
    *table->refs.nextEntry++ = ref;

    return true;
}

bool dvmHeapAddTableToLargeTable(LargeHeapRefTable **tableP, HeapRefTable *refs)
{
    LargeHeapRefTable *table;

    /* Allocate a node.
     */
    table = (LargeHeapRefTable *)heapTableRealloc(NULL,
            sizeof(LargeHeapRefTable));
    if (table == NULL) {
        LOGE_HEAP("Can't allocate a new large ref table\n");
        return false;
    }
    table->refs = *refs;

    /* Insert the table into the list.
     */
    table->next = *tableP;
    *tableP = table;

    return true;
}

/* Frees everything associated with the LargeHeapRefTable.
 */
void dvmHeapFreeLargeTable(LargeHeapRefTable *table)
{
    while (table != NULL) {
        LargeHeapRefTable *next = table->next;
        dvmHeapFreeHeapRefTable(&table->refs);
        dvmHeapHeapTableFree(table);
        table = next;
    }
}

Object *dvmHeapGetNextObjectFromLargeTable(LargeHeapRefTable **pTable)
{
    LargeHeapRefTable *table;
    Object *obj;

    assert(pTable != NULL);

    obj = NULL;
    table = *pTable;
    if (table != NULL) {
        GcHeap *gcHeap = gDvm.gcHeap;
        HeapRefTable *refs = &table->refs;

        /* We should never have an empty table node in the list.
         */
        assert(dvmReferenceTableEntries(refs) != 0);

        /* Remove and return the last entry in the list.
         */
        obj = *--refs->nextEntry;

        /* If this was the last entry in the table node,
         * free it and patch up the list.
         */
        if (refs->nextEntry == refs->table) {
            *pTable = table->next;
            dvmClearReferenceTable(refs);
            dvmHeapHeapTableFree(table);
        }
    }

    return obj;
}

void dvmHeapMarkLargeTableRefs(LargeHeapRefTable *table, bool stripLowBits)
{
    while (table != NULL) {
        Object **ref, **lastRef;

        ref = table->refs.table;
        lastRef = table->refs.nextEntry;
        if (stripLowBits) {
            /* This case is used for marking reference objects that
             * are still waiting for the heap worker thread to get to
             * them.  The referents pointed to by the references are
             * marked when a SCHEDULED_REFERENCE_MAGIC is encountered
             * during scanning.
             */
            while (ref < lastRef) {
                dvmMarkObjectNonNull((Object *)((uintptr_t)*ref++ & ~3));
            }
        } else {
            while (ref < lastRef) {
                dvmMarkObjectNonNull(*ref++);
            }
        }
        table = table->next;
    }
}


