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

#ifndef ART_SRC_COMPILER_COMPILER_UTILITY_H_
#define ART_SRC_COMPILER_COMPILER_UTILITY_H_

#include "Dalvik.h"

namespace art {

/* Each arena page has some overhead, so take a few bytes off */
#define ARENA_DEFAULT_SIZE ((2 * 1024 * 1024) - 256)

/* Allocate the initial memory block for arena-based allocation */
bool oatHeapInit(CompilationUnit* cUnit);

/* Collect memory usage statstics */
//#define WITH_MEMSTATS

struct ArenaMemBlock {
    size_t blockSize;
    size_t bytesAllocated;
    struct ArenaMemBlock *next;
    char ptr[0];
};

void* oatNew(CompilationUnit* cUnit, size_t size, bool zero,
             oatAllocKind kind = kAllocMisc);

void oatArenaReset(CompilationUnit *cUnit);

struct GrowableList {
    size_t numAllocated;
    size_t numUsed;
    intptr_t *elemList;
#ifdef WITH_MEMSTATS
    oatListKind kind;
#endif
};

struct GrowableListIterator {
    GrowableList* list;
    size_t idx;
    size_t size;
};

/*
 * Expanding bitmap, used for tracking resources.  Bits are numbered starting
 * from zero.
 *
 * All operations on a BitVector are unsynchronized.
 */
struct ArenaBitVector {
    bool    expandable;     /* expand bitmap if we run out? */
    u4      storageSize;    /* current size, in 32-bit words */
    u4*     storage;
#ifdef WITH_MEMSTATS
    oatBitMapKind kind;      /* for memory use tuning */
#endif
};

/* Handy iterator to walk through the bit positions set to 1 */
struct ArenaBitVectorIterator {
    ArenaBitVector* pBits;
    u4 idx;
    u4 bitSize;
};

#define GET_ELEM_N(LIST, TYPE, N) (((TYPE*) LIST->elemList)[N])

#define BLOCK_NAME_LEN 80

/* Forward declarations */
struct LIR;
struct BasicBlock;
struct CompilationUnit;

void oatInitGrowableList(CompilationUnit* cUnit,GrowableList* gList,
                         size_t initLength, oatListKind kind = kListMisc);
void oatInsertGrowableList(CompilationUnit* cUnit, GrowableList* gList,
                           intptr_t elem);
void oatDeleteGrowableList(GrowableList* gList, intptr_t elem);
void oatGrowableListIteratorInit(GrowableList* gList,
                                 GrowableListIterator* iterator);
intptr_t oatGrowableListIteratorNext(GrowableListIterator* iterator);
intptr_t oatGrowableListGetElement(const GrowableList* gList, size_t idx);

ArenaBitVector* oatAllocBitVector(CompilationUnit* cUnit,
                                  unsigned int startBits, bool expandable,
                                  oatBitMapKind = kBitMapMisc);
void oatBitVectorIteratorInit(ArenaBitVector* pBits,
                              ArenaBitVectorIterator* iterator);
int oatBitVectorIteratorNext(ArenaBitVectorIterator* iterator);
bool oatSetBit(CompilationUnit *cUnit, ArenaBitVector* pBits, unsigned int num);
bool oatClearBit(ArenaBitVector* pBits, unsigned int num);
void oatMarkAllBits(ArenaBitVector* pBits, bool set);
void oatDebugBitVector(char* msg, const ArenaBitVector* bv, int length);
bool oatIsBitSet(const ArenaBitVector* pBits, unsigned int num);
void oatClearAllBits(ArenaBitVector* pBits);
void oatSetInitialBits(ArenaBitVector* pBits, unsigned int numBits);
void oatCopyBitVector(ArenaBitVector* dest, const ArenaBitVector* src);
bool oatIntersectBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
                            const ArenaBitVector* src2);
bool oatUnifyBitVectors(ArenaBitVector* dest, const ArenaBitVector* src1,
                        const ArenaBitVector* src2);
bool oatCompareBitVectors(const ArenaBitVector* src1,
                          const ArenaBitVector* src2);
bool oatTestBitVectors(const ArenaBitVector* src1, const ArenaBitVector* src2);
int oatCountSetBits(const ArenaBitVector* pBits);

void oatDumpLIRInsn(CompilationUnit* cUnit, struct LIR* lir,
                    unsigned char* baseAddr);
void oatDumpResourceMask(struct LIR* lir, u8 mask, const char* prefix);
void oatDumpBlockBitVector(const GrowableList* blocks, char* msg,
                           const ArenaBitVector* bv, int length);
void oatGetBlockName(struct BasicBlock* bb, char* name);
const char* oatGetShortyFromTargetIdx(CompilationUnit*, int);
void oatDumpRegLocTable(struct RegLocation*, int);
void oatDumpMemStats(CompilationUnit* cUnit);

}  // namespace art

#endif  // ART_SRC_COMPILER_COMPILER_UTILITY_H_
