diff options
author | Ben Cheng <bccheng@android.com> | 2010-10-28 11:13:58 -0700 |
---|---|---|
committer | Ben Cheng <bccheng@android.com> | 2010-12-13 16:49:33 -0800 |
commit | 00603079b8723b32c955513eae63a8f97898074d (patch) | |
tree | 3f7b93b0bdb9ac2d64896a9d0bbf5e5c7153cc71 /vm/compiler/Utility.c | |
parent | 823a87840e570ad06c4426537477a21243474a1c (diff) | |
download | android_dalvik-00603079b8723b32c955513eae63a8f97898074d.tar.gz android_dalvik-00603079b8723b32c955513eae63a8f97898074d.tar.bz2 android_dalvik-00603079b8723b32c955513eae63a8f97898074d.zip |
Implement method parser and SSA transformation.
Change-Id: If3fb3a36f33aaee8e5fdded4e9fa607be54f0bfb
Diffstat (limited to 'vm/compiler/Utility.c')
-rw-r--r-- | vm/compiler/Utility.c | 116 |
1 files changed, 105 insertions, 11 deletions
diff --git a/vm/compiler/Utility.c b/vm/compiler/Utility.c index 4b942ef40..fe258331f 100644 --- a/vm/compiler/Utility.c +++ b/vm/compiler/Utility.c @@ -82,7 +82,8 @@ retry: LOGI("Total arena pages for JIT: %d", numArenaBlocks); goto retry; } - return NULL; + /* Should not reach here */ + dvmAbort(); } /* Reclaim all the arena blocks allocated so far */ @@ -101,8 +102,8 @@ void dvmInitGrowableList(GrowableList *gList, size_t initLength) { gList->numAllocated = initLength; gList->numUsed = 0; - gList->elemList = (void **) dvmCompilerNew(sizeof(void *) * initLength, - true); + gList->elemList = (intptr_t *) dvmCompilerNew(sizeof(intptr_t) * initLength, + true); } /* Expand the capacity of a growable list */ @@ -114,14 +115,15 @@ static void expandGrowableList(GrowableList *gList) } else { newLength += 128; } - void *newArray = dvmCompilerNew(sizeof(void *) * newLength, true); - memcpy(newArray, gList->elemList, sizeof(void *) * gList->numAllocated); + intptr_t *newArray = + (intptr_t *) dvmCompilerNew(sizeof(intptr_t) * newLength, true); + memcpy(newArray, gList->elemList, sizeof(intptr_t) * gList->numAllocated); gList->numAllocated = newLength; - gList->elemList = (void **)newArray; + gList->elemList = newArray; } /* Insert a new element into the growable list */ -void dvmInsertGrowableList(GrowableList *gList, void *elem) +void dvmInsertGrowableList(GrowableList *gList, intptr_t elem) { assert(gList->numAllocated != 0); if (gList->numUsed == gList->numAllocated) { @@ -130,10 +132,30 @@ void dvmInsertGrowableList(GrowableList *gList, void *elem) gList->elemList[gList->numUsed++] = elem; } +void dvmGrowableListIteratorInit(GrowableList *gList, + GrowableListIterator *iterator) +{ + iterator->list = gList; + iterator->idx = 0; + iterator->size = gList->numUsed; +} + +intptr_t dvmGrowableListIteratorNext(GrowableListIterator *iterator) +{ + assert(iterator->size == iterator->list->numUsed); + if (iterator->idx == iterator->size) return 0; + return iterator->list->elemList[iterator->idx++]; +} + +intptr_t dvmGrowableListGetElement(const GrowableList *gList, size_t idx) +{ + assert(idx < gList->numUsed); + return gList->elemList[idx]; +} + /* Debug Utility - dump a compilation unit */ void dvmCompilerDumpCompilationUnit(CompilationUnit *cUnit) { - int i; BasicBlock *bb; char *blockTypeNames[] = { "Normal Chaining Cell", @@ -156,9 +178,13 @@ void dvmCompilerDumpCompilationUnit(CompilationUnit *cUnit) cUnit->method->name); LOGD("%d insns", dvmGetMethodInsnsSize(cUnit->method)); LOGD("%d blocks in total", cUnit->numBlocks); + GrowableListIterator iterator; + + dvmGrowableListIteratorInit(&cUnit->blockList, &iterator); - for (i = 0; i < cUnit->numBlocks; i++) { - bb = cUnit->blockList[i]; + while (true) { + bb = (BasicBlock *) dvmGrowableListIteratorNext(&iterator); + if (bb == NULL) break; LOGD("Block %d (%s) (insn %04x - %04x%s)\n", bb->id, blockTypeNames[bb->blockType], @@ -275,7 +301,7 @@ bool dvmCompilerSetBit(BitVector *pBits, int num) assert(num >= 0); if (num >= pBits->storageSize * (int)sizeof(u4) * 8) { if (!pBits->expandable) - return false; + dvmAbort(); /* Round up to word boundaries for "num+1" bits */ int newSize = (num + 1 + 31) >> 5; @@ -292,6 +318,36 @@ bool dvmCompilerSetBit(BitVector *pBits, int num) 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: this is the sister implementation of dvmClearBit. In this version + * memory is allocated from the compiler arena. + */ +bool dvmCompilerClearBit(BitVector *pBits, int num) +{ + assert(num >= 0); + if (num >= pBits->storageSize * (int)sizeof(u4) * 8) { + LOGE("Trying to clear a bit that is not set in the vector yet!"); + dvmAbort(); + } + + pBits->storage[num >> 5] &= ~(1 << (num & 0x1f)); + return true; +} + +/* + * If set is true, mark all bits as 1. Otherwise mark all bits as 0. + */ +void dvmCompilerMarkAllBits(BitVector *pBits, bool set) +{ + int value = set ? -1 : 0; + memset(pBits->storage, value, pBits->storageSize * (int)sizeof(u4)); +} + void dvmDebugBitVector(char *msg, const BitVector *bv, int length) { int i; @@ -315,3 +371,41 @@ void dvmCompilerAbort(CompilationUnit *cUnit) */ longjmp(*cUnit->bailPtr, 1); } + +void dvmDumpBlockBitVector(const GrowableList *blocks, char *msg, + const BitVector *bv, int length) +{ + int i; + + LOGE("%s", msg); + for (i = 0; i < length; i++) { + if (dvmIsBitSet(bv, i)) { + BasicBlock *bb = + (BasicBlock *) dvmGrowableListGetElement(blocks, i); + char blockName[BLOCK_NAME_LEN]; + dvmGetBlockName(bb, blockName); + LOGE("Bit %d / %s is set", i, blockName); + } + } +} + +void dvmGetBlockName(BasicBlock *bb, char *name) +{ + switch (bb->blockType) { + case kMethodEntryBlock: + snprintf(name, BLOCK_NAME_LEN, "entry"); + break; + case kMethodExitBlock: + 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; + } +} |