/*
 * Copyright (C) 2011 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 "CompilerInternals.h"

namespace art {

#ifdef WITH_MEMSTATS
typedef struct Memstats {
    u4 allocStats[kNumAllocKinds];
    int listSizes[kNumListKinds];
    int listWasted[kNumListKinds];
    int listGrows[kNumListKinds];
    int listMaxElems[kNumListKinds];
    int bitMapSizes[kNumBitMapKinds];
    int bitMapWasted[kNumBitMapKinds];
    int bitMapGrows[kNumBitMapKinds];
} memstats;

const char* allocNames[kNumAllocKinds] = {
    "Misc       ",
    "BasicBlock ",
    "LIR        ",
    "MIR        ",
    "DataFlow   ",
    "GrowList   ",
    "GrowBitMap ",
    "Dalvik2SSA ",
    "DebugInfo  ",
    "Successor  ",
    "RegAlloc   ",
    "Data       ",
    "Preds      ",
};

const char* listNames[kNumListKinds] = {
    "Misc                  ",
    "blockList             ",
    "SSAtoDalvik           ",
    "dfsOrder              ",
    "dfsPostOrder          ",
    "domPostOrderTraversal ",
    "throwLaunchPads       ",
    "suspendLaunchPads     ",
    "switchTables          ",
    "fillArrayData         ",
    "SuccessorBlocks       ",
    "Predecessors          ",
};

const char* bitMapNames[kNumBitMapKinds] = {
    "Misc                  ",
    "Use                   ",
    "Def                   ",
    "LiveIn                ",
    "BlockMatrix           ",
    "Dominators            ",
    "IDominated            ",
    "DomFrontier           ",
    "Phi                   ",
    "TmpBlocks             ",
    "InputBlocks           ",
    "RegisterV             ",
    "TempSSARegisterV      ",
    "Null Check            ",
    "TmpBlockV             ",
    "Predecessors          ",
};
#endif

#define kArenaBitVectorGrowth    4   /* increase by 4 u4s when limit hit */

/* Allocate the initial memory block for arena-based allocation */
bool oatHeapInit(CompilationUnit* cUnit)
{
    DCHECK(cUnit->arenaHead == NULL);
    cUnit->arenaHead =
        (ArenaMemBlock *) malloc(sizeof(ArenaMemBlock) + ARENA_DEFAULT_SIZE);
    if (cUnit->arenaHead == NULL) {
        LOG(FATAL) << "No memory left to create compiler heap memory";
    }
    cUnit->arenaHead->blockSize = ARENA_DEFAULT_SIZE;
    cUnit->currentArena = cUnit->arenaHead;
    cUnit->currentArena->bytesAllocated = 0;
    cUnit->currentArena->next = NULL;
    cUnit->numArenaBlocks = 1;
#ifdef WITH_MEMSTATS
    cUnit->mstats = (Memstats*) oatNew(cUnit, sizeof(Memstats), true,
                     kAllocDebugInfo);
#endif
    return true;
}

/* Arena-based malloc for compilation tasks */
void* oatNew(CompilationUnit* cUnit, size_t size, bool zero, oatAllocKind kind)
{
    size = (size + 3) & ~3;
#ifdef WITH_MEMSTATS
    if (cUnit->mstats != NULL) {
        cUnit->mstats->allocStats[kind] += size;
    }
#endif
retry:
    /* Normal case - space is available in the current page */
    if (size + cUnit->currentArena->bytesAllocated <=
        cUnit->currentArena->blockSize) {
        void *ptr;
        ptr = &cUnit->currentArena->ptr[cUnit->currentArena->bytesAllocated];
        cUnit->currentArena->bytesAllocated += size;
        if (zero) {
            memset(ptr, 0, size);
        }
        return ptr;
    } else {
        /*
         * See if there are previously allocated arena blocks before the last
         * reset
         */
        if (cUnit->currentArena->next) {
            cUnit->currentArena = cUnit->currentArena->next;
            cUnit->currentArena->bytesAllocated = 0;
            goto retry;
        }

        size_t blockSize = (size < ARENA_DEFAULT_SIZE) ?
                          ARENA_DEFAULT_SIZE : size;
        /* Time to allocate a new arena */
        ArenaMemBlock *newArena = (ArenaMemBlock *)
            malloc(sizeof(ArenaMemBlock) + blockSize);
        if (newArena == NULL) {
            LOG(FATAL) << "Arena allocation failure";
        }
        newArena->blockSize = blockSize;
        newArena->bytesAllocated = 0;
        newArena->next = NULL;
        cUnit->currentArena->next = newArena;
        cUnit->currentArena = newArena;
        cUnit->numArenaBlocks++;
        if (cUnit->numArenaBlocks > 20000) {
            LOG(INFO) << "Total arena pages: " << cUnit->numArenaBlocks;
        }
        goto retry;
    }
}

/* Reclaim all the arena blocks allocated so far */
void oatArenaReset(CompilationUnit* cUnit)
{
    ArenaMemBlock* head = cUnit->arenaHead;
    while (head != NULL) {
        ArenaMemBlock* p = head;
        head = head->next;
        free(p);
    }
    cUnit->arenaHead = NULL;
    cUnit->currentArena = NULL;
}

/* Growable List initialization */
void oatInitGrowableList(CompilationUnit* cUnit, GrowableList* gList,
                         size_t initLength, oatListKind kind)
{
    gList->numAllocated = initLength;
    gList->numUsed = 0;
    gList->elemList = (intptr_t *) oatNew(cUnit, sizeof(intptr_t) * initLength,
                                          true, kAllocGrowableList);
#ifdef WITH_MEMSTATS
    cUnit->mstats->listSizes[kind] += sizeof(intptr_t) * initLength;
    gList->kind = kind;
    if ((int)initLength > cUnit->mstats->listMaxElems[kind]) {
        cUnit->mstats->listMaxElems[kind] = initLength;
    }
#endif
}

/* Expand the capacity of a growable list */
STATIC void expandGrowableList(CompilationUnit* cUnit, GrowableList* gList)
{
    int newLength = gList->numAllocated;
    if (newLength < 128) {
        newLength <<= 1;
    } else {
        newLength += 128;
    }
    intptr_t *newArray =
        (intptr_t *) oatNew(cUnit, sizeof(intptr_t) * newLength, true,
                            kAllocGrowableList);
    memcpy(newArray, gList->elemList, sizeof(intptr_t) * gList->numAllocated);
#ifdef WITH_MEMSTATS
    cUnit->mstats->listSizes[gList->kind] += sizeof(intptr_t) * newLength;
    cUnit->mstats->listWasted[gList->kind] +=
        sizeof(intptr_t) * gList->numAllocated;
    cUnit->mstats->listGrows[gList->kind]++;
    if (newLength > cUnit->mstats->listMaxElems[gList->kind]) {
        cUnit->mstats->listMaxElems[gList->kind] = newLength;
    }
#endif
    gList->numAllocated = newLength;
    gList->elemList = newArray;
}

/* Insert a new element into the growable list */
void oatInsertGrowableList(CompilationUnit* cUnit, GrowableList* gList,
                           intptr_t elem)
{
    DCHECK_NE(gList->numAllocated, 0U);
    if (gList->numUsed == gList->numAllocated) {
        expandGrowableList(cUnit, gList);
    }
    gList->elemList[gList->numUsed++] = elem;
}

/* Delete an element from a growable list. Element must be present */
void oatDeleteGrowableList(GrowableList* gList, intptr_t elem)
{
    bool found = false;
    for (unsigned int i = 0; i < gList->numUsed; i++) {
        if (!found && gList->elemList[i] == elem) {
            found = true;
        }
        if (found) {
            gList->elemList[i] = gList->elemList[i+1];
        }
    }
    DCHECK_EQ(found, true);
    gList->numUsed--;
}

void oatGrowableListIteratorInit(GrowableList* gList,
                                 GrowableListIterator* iterator)
{
    iterator->list = gList;
    iterator->idx = 0;
    iterator->size = gList->numUsed;
}

intptr_t oatGrowableListIteratorNext(GrowableListIterator* iterator)
{
    DCHECK_EQ(iterator->size, iterator->list->numUsed);
    if (iterator->idx == iterator->size) return 0;
    return iterator->list->elemList[iterator->idx++];
}

intptr_t oatGrowableListGetElement(const GrowableList* gList, size_t idx)
{
    DCHECK_LT(idx, gList->numUsed);
    return gList->elemList[idx];
}

#ifdef WITH_MEMSTATS
/* Dump memory usage stats */
void oatDumpMemStats(CompilationUnit* cUnit)
{
    u4 total = 0;
    for (int i = 0; i < kNumAllocKinds; i++) {
        total += cUnit->mstats->allocStats[i];
    }
    if (total > (10 * 1024 * 1024)) {
        LOG(INFO) << "MEMUSAGE: " << total << " : "
            << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
        LOG(INFO) << "insnsSize: " << cUnit->insnsSize;
        if (cUnit->disableDataflow) {
            LOG(INFO) << " ** Dataflow disabled ** ";
        }
        LOG(INFO) << "===== Overall allocations";
        for (int i = 0; i < kNumAllocKinds; i++) {
            LOG(INFO) << allocNames[i] << std::setw(10) <<
            cUnit->mstats->allocStats[i];
        }
        LOG(INFO) << "===== GrowableList allocations";
        for (int i = 0; i < kNumListKinds; i++) {
            LOG(INFO) << listNames[i]
                << " S:" << cUnit->mstats->listSizes[i]
                << ", W:" << cUnit->mstats->listWasted[i]
                << ", G:" << cUnit->mstats->listGrows[i]
                << ", E:" << cUnit->mstats->listMaxElems[i];
        }
        LOG(INFO) << "===== GrowableBitMap allocations";
        for (int i = 0; i < kNumBitMapKinds; i++) {
            LOG(INFO) << bitMapNames[i]
                << " S:" << cUnit->mstats->bitMapSizes[i]
                << ", W:" << cUnit->mstats->bitMapWasted[i]
                << ", G:" << cUnit->mstats->bitMapGrows[i];
        }
    }
}
#endif

/* Debug Utility - dump a compilation unit */
void oatDumpCompilationUnit(CompilationUnit* cUnit)
{
    BasicBlock* bb;
    const char* blockTypeNames[] = {
        "Entry Block",
        "Code Block",
        "Exit Block",
        "Exception Handling",
        "Catch Block"
    };

    LOG(INFO) << "Compiling " << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
    LOG(INFO) << cUnit->insns << " insns";
    LOG(INFO) << cUnit->numBlocks << " blocks in total";
    GrowableListIterator iterator;

    oatGrowableListIteratorInit(&cUnit->blockList, &iterator);

    while (true) {
        bb = (BasicBlock *) oatGrowableListIteratorNext(&iterator);
        if (bb == NULL) break;
        char buf[100];
        snprintf(buf, 100, "Block %d (%s) (insn %04x - %04x%s)",
             bb->id,
             blockTypeNames[bb->blockType],
             bb->startOffset,
             bb->lastMIRInsn ? bb->lastMIRInsn->offset : bb->startOffset,
             bb->lastMIRInsn ? "" : " empty");
        LOG(INFO) << buf;
        if (bb->taken) {
            LOG(INFO) << "  Taken branch: block " << bb->taken->id <<
                 "(0x" << std::hex << bb->taken->startOffset << ")";
        }
        if (bb->fallThrough) {
            LOG(INFO) << "  Fallthrough : block " << bb->fallThrough->id <<
                 " (0x" << std::hex << bb->fallThrough->startOffset << ")";
        }
    }
}

/*
 * Dump the current stats of the compiler.
 */
void oatDumpStats(void)
{
    oatArchDump();
}

static uint32_t checkMasks[32] = {
    0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
    0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200,
    0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000,
    0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000,
    0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000,
    0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000,
    0x40000000, 0x80000000 };

/*
 * Allocate a bit vector with enough space to hold at least the specified
 * number of bits.
 *
 * NOTE: memory is allocated from the compiler arena.
 */
ArenaBitVector* oatAllocBitVector(CompilationUnit* cUnit,
                                  unsigned int startBits, bool expandable,
                                  oatBitMapKind kind)
{
    ArenaBitVector* bv;
    unsigned int count;

    DCHECK_EQ(sizeof(bv->storage[0]), 4U);        /* assuming 32-bit units */

    bv = (ArenaBitVector*) oatNew(cUnit, sizeof(ArenaBitVector), false,
                                  kAllocGrowableBitMap);

    count = (startBits + 31) >> 5;

    bv->storageSize = count;
    bv->expandable = expandable;
    bv->storage = (u4*) oatNew(cUnit, count * sizeof(u4), true,
                               kAllocGrowableBitMap);
#ifdef WITH_MEMSTATS
    bv->kind = kind;
    cUnit->mstats->bitMapSizes[kind] += count * sizeof(u4);
#endif
    return bv;
}

/*
 * Determine whether or not the specified bit is set.
 */
bool oatIsBitSet(const ArenaBitVector* pBits, unsigned int num)
{
    DCHECK_LT(num, pBits->storageSize * sizeof(u4) * 8);

    unsigned int val = pBits->storage[num >> 5] & checkMasks[num & 0x1f];
    return (val != 0);
}

/*
 * Mark all bits bit as "clear".
 */
void oatClearAllBits(ArenaBitVector* pBits)
{
    unsigned int count = pBits->storageSize;
    memset(pBits->storage, 0, count * sizeof(u4));
}

/*
 * Mark the specified bit as "set".
 *
 * Returns "false" if the bit is outside the range of the vector and we're
 * not allowed to expand.
 *
 * NOTE: memory is allocated from the compiler arena.
 */
bool oatSetBit(CompilationUnit* cUnit, ArenaBitVector* pBits, unsigned int num)
{
    if (num >= pBits->storageSize * sizeof(u4) * 8) {
        if (!pBits->expandable) {
            LOG(FATAL) << "Can't expand";
        }

        /* Round up to word boundaries for "num+1" bits */
        unsigned int newSize = (num + 1 + 31) >> 5;
        DCHECK_GT(newSize, pBits->storageSize);
        u4 *newStorage = (u4*)oatNew(cUnit, newSize * sizeof(u4), false,
                                     kAllocGrowableBitMap);
        memcpy(newStorage, pBits->storage, pBits->storageSize * sizeof(u4));
        memset(&newStorage[pBits->storageSize], 0,
               (newSize - pBits->storageSize) * sizeof(u4));
#ifdef WITH_MEMSTATS
        cUnit->mstats->bitMapWasted[pBits->kind] +=
            pBits->storageSize * sizeof(u4);
        cUnit->mstats->bitMapSizes[pBits->kind] += newSize * sizeof(u4);
        cUnit->mstats->bitMapGrows[pBits->kind]++;
#endif
        pBits->storage = newStorage;
        pBits->storageSize = newSize;
    }

    pBits->storage[num >> 5] |= checkMasks[num & 0x1f];
    return true;
}

/*
 * Mark the specified bit as "unset".
 *
 * Returns "false" if the bit is outside the range of the vector and we're
 * not allowed to expand.
 *
 * NOTE: memory is allocated from the compiler arena.
 */
bool oatClearBit(ArenaBitVector* pBits, unsigned int num)
{
    if (num >= pBits->storageSize * sizeof(u4) * 8) {
        LOG(FATAL) << "Attempt to clear a bit not set in the vector yet";;
    }

    pBits->storage[num >> 5] &= ~checkMasks[num & 0x1f];
    return true;
}

/*
 * If set is true, mark all bits as 1. Otherwise mark all bits as 0.
 */
void oatMarkAllBits(ArenaBitVector* pBits, bool set)
{
    int value = set ? -1 : 0;
    memset(pBits->storage, value, pBits->storageSize * (int)sizeof(u4));
}

void oatDebugBitVector(char* msg, const ArenaBitVector* bv, int length)
{
    int i;

    LOG(INFO) <<  msg;
    for (i = 0; i < length; i++) {
        if (oatIsBitSet(bv, i)) {
            LOG(INFO) << "    Bit " << i << " is set";
        }
    }
}

void oatAbort(CompilationUnit* cUnit)
{
    LOG(FATAL) << "Compiler aborting";
}

void oatDumpBlockBitVector(const GrowableList* blocks, char* msg,
                           const ArenaBitVector* bv, int length)
{
    int i;

    LOG(INFO) <<  msg;
    for (i = 0; i < length; i++) {
        if (oatIsBitSet(bv, i)) {
            BasicBlock *bb =
                (BasicBlock *) oatGrowableListGetElement(blocks, i);
            char blockName[BLOCK_NAME_LEN];
            oatGetBlockName(bb, blockName);
            LOG(INFO) << "Bit " << i << " / " << blockName << " is set";
        }
    }
}
/* Initialize the iterator structure */
void oatBitVectorIteratorInit(ArenaBitVector* pBits,
                              ArenaBitVectorIterator* iterator)
{
    iterator->pBits = pBits;
    iterator->bitSize = pBits->storageSize * sizeof(u4) * 8;
    iterator->idx = 0;
}

/*
 * If the vector sizes don't match, log an error and abort.
 */
STATIC void checkSizes(const ArenaBitVector* bv1, const ArenaBitVector* bv2)
{
    if (bv1->storageSize != bv2->storageSize) {
        LOG(FATAL) << "Mismatched vector sizes (" << bv1->storageSize <<
            ", " << bv2->storageSize << ")";
    }
}

/*
 * Copy a whole vector to the other. Only do that when the both vectors have
 * the same size.
 */
void oatCopyBitVector(ArenaBitVector* dest, const ArenaBitVector* src)
{
    /* if dest is expandable and < src, we could expand dest to match */
    checkSizes(dest, src);

    memcpy(dest->storage, src->storage, sizeof(u4) * dest->storageSize);
}

/*
 * Intersect two bit vectors and store the result to the dest vector.
 */

bool oatIntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
                            const ArenaBitVector* src2)
{
    DCHECK(src1 != NULL);
    DCHECK(src2 != NULL);
    if (dest->storageSize != src1->storageSize ||
        dest->storageSize != src2->storageSize ||
        dest->expandable != src1->expandable ||
        dest->expandable != src2->expandable)
        return false;

    unsigned int idx;
    for (idx = 0; idx < dest->storageSize; idx++) {
        dest->storage[idx] = src1->storage[idx] & src2->storage[idx];
    }
    return true;
}

/*
 * Unify two bit vectors and store the result to the dest vector.
 */
bool oatUnifyBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
                        const ArenaBitVector* src2)
{
    DCHECK(src1 != NULL);
    DCHECK(src2 != NULL);
    if (dest->storageSize != src1->storageSize ||
        dest->storageSize != src2->storageSize ||
        dest->expandable != src1->expandable ||
        dest->expandable != src2->expandable)
        return false;

    unsigned int idx;
    for (idx = 0; idx < dest->storageSize; idx++) {
        dest->storage[idx] = src1->storage[idx] | src2->storage[idx];
    }
    return true;
}

/*
 * Compare two bit vectors and return true if difference is seen.
 */
bool oatCompareBitVectors(const ArenaBitVector* src1,
                          const ArenaBitVector* src2)
{
    if (src1->storageSize != src2->storageSize ||
        src1->expandable != src2->expandable)
        return true;

    unsigned int idx;
    for (idx = 0; idx < src1->storageSize; idx++) {
        if (src1->storage[idx] != src2->storage[idx]) return true;
    }
    return false;
}

/*
 * Count the number of bits that are set.
 */
int oatCountSetBits(const ArenaBitVector* pBits)
{
    unsigned int word;
    unsigned int count = 0;

    for (word = 0; word < pBits->storageSize; word++) {
        u4 val = pBits->storage[word];

        if (val != 0) {
            if (val == 0xffffffff) {
                count += 32;
            } else {
                /* count the number of '1' bits */
                while (val != 0) {
                    val &= val - 1;
                    count++;
                }
            }
        }
    }

    return count;
}

/* Return the next position set to 1. -1 means end-of-element reached */
int oatBitVectorIteratorNext(ArenaBitVectorIterator* iterator)
{
    ArenaBitVector* pBits = iterator->pBits;
    u4 bitIndex = iterator->idx;
    u4 bitSize = iterator->bitSize;

    DCHECK_EQ(bitSize, pBits->storageSize * sizeof(u4) * 8);

    if (bitIndex >= bitSize) return -1;

    u4 wordIndex = bitIndex >> 5;
    u4 endWordIndex = bitSize >> 5;
    u4* storage = pBits->storage;
    u4 word = storage[wordIndex++];

    // Mask out any bits in the first word we've already considered
    word &= ~((1 << (bitIndex & 0x1f))-1);

    for (; wordIndex <= endWordIndex;) {
        u4 bitPos = bitIndex & 0x1f;
        if (word == 0) {
            bitIndex += (32 - bitPos);
            word = storage[wordIndex++];
            continue;
        }
        for (; bitPos < 32; bitPos++) {
            if (word & (1 << bitPos)) {
                iterator->idx = bitIndex + 1;
                return bitIndex;
            }
            bitIndex++;
        }
        word = storage[wordIndex++];
    }
    iterator->idx = iterator->bitSize;
    return -1;
}

/*
 * Mark specified number of bits as "set". Cannot set all bits like ClearAll
 * since there might be unused bits - setting those to one will confuse the
 * iterator.
 */
void oatSetInitialBits(ArenaBitVector* pBits, unsigned int numBits)
{
    unsigned int idx;
    DCHECK_LE(((numBits + 31) >> 5), pBits->storageSize);
    for (idx = 0; idx < (numBits >> 5); idx++) {
        pBits->storage[idx] = -1;
    }
    unsigned int remNumBits = numBits & 0x1f;
    if (remNumBits) {
        pBits->storage[idx] = (1 << remNumBits) - 1;
    }
}

void oatGetBlockName(BasicBlock* bb, char* name)
{
    switch (bb->blockType) {
        case kEntryBlock:
            snprintf(name, BLOCK_NAME_LEN, "entry");
            break;
        case kExitBlock:
            snprintf(name, BLOCK_NAME_LEN, "exit");
            break;
        case kDalvikByteCode:
            snprintf(name, BLOCK_NAME_LEN, "block%04x", bb->startOffset);
            break;
        case kExceptionHandling:
            snprintf(name, BLOCK_NAME_LEN, "exception%04x", bb->startOffset);
            break;
        default:
            snprintf(name, BLOCK_NAME_LEN, "??");
            break;
    }
}

const char* oatGetShortyFromTargetIdx(CompilationUnit *cUnit, int targetIdx)
{
    const DexFile::MethodId& methodId = cUnit->dex_file->GetMethodId(targetIdx);
    return cUnit->dex_file->GetShorty(methodId.proto_idx_);
}

}  // namespace art
