jitirblock.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 1,108 行 · 第 1/3 页
C
1,108 行
/* * @(#)jitirblock.c 1.97 06/10/25 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */#include "javavm/include/defs.h"#include "javavm/include/objects.h"#include "javavm/include/classes.h"#include "javavm/include/interpreter.h"#include "javavm/include/stacks.h"#include "javavm/include/bcattr.h"#include "javavm/include/utils.h"#include "javavm/include/typeid.h"#include "javavm/include/opcodes.h"#include "javavm/include/globals.h"#include "javavm/include/clib.h"#include "javavm/include/porting/int.h"#include "javavm/include/porting/system.h"#include "javavm/include/bcutils.h"#include "javavm/include/jit/jit.h"#include "javavm/include/jit/jitir.h"#include "javavm/include/jit/jitcontext.h"#include "javavm/include/jit/jitmemory.h"#include "javavm/include/jit/jitopt.h"#include "javavm/include/jit/jitirnode.h"#include "javavm/include/jit/jitirblock.h"#include "javavm/include/jit/jitirrange.h"#include "javavm/include/jit/jitirlist.h"#include "javavm/include/clib.h"static voidCVMJITirblockPhiMerge(CVMJITCompilationContext* con, CVMJITIRBlock* curbk, CVMJITIRBlock* targetbk, CVMJITIRNode* expression1ToEvaluate, CVMJITIRNode* expression2ToEvaluate, CVMJITIRNode* branchNode);static voidCVMJITirblockInit(CVMJITCompilationContext* con, CVMJITIRBlock* bk, CVMUint16 pc){ CVMJITirblockSetBlockPC(bk, pc); CVMJITirblockSetBlockID(bk, 0); CVMJITirblockSetCseID(bk, 0); CVMJITirblockSetRefCount(bk, 0); CVMJITirblockSetFlags(bk, 0); CVMJITirblockSetNext(bk, NULL); CVMJITirblockSetPrev(bk, NULL); CVMJITirblockInitRootList(con, bk); bk->phiCount = -1; bk->phiSize = 0; bk->lastOpenRange = NULL; bk->inDepth = con->mc->compilationDepth; bk->outDepth = bk->inDepth; bk->inMc = con->mc;/* IAI - 20 */#ifdef IAI_VIRTUAL_INLINE_CB_TEST bk->mtIndex = CVMJIT_IAI_VIRTUAL_INLINE_CB_TEST_DEFAULT; bk->oolReturnAddress = CVMJIT_IAI_VIRTUAL_INLINE_CB_TEST_DEFAULT; bk->candidateMb = NULL;#endif/* IAI - 20 */ CVMassert(bk->sandboxRegSet == 0);#ifdef CVM_JIT_REGISTER_LOCALS if (!CVMglobals.jit.registerLocals) { CVMJITirblockNoIncomingLocalsAllowed(bk); }#endif}/* * Create a new block and set it to the block map, or * get an existing block from the block map. * bitset for all branch labels and exception labels. */CVMJITIRBlock*CVMJITirblockNewLabelForPC0(CVMJITCompilationContext* con, CVMUint16 pc){ CVMJITMethodContext* mc = con->mc; CVMJITIRBlock* bk = mc->pcToBlock[pc]; if (bk != NULL) { return bk; } bk = CVMJITirblockCreate(con, pc); /* enter java bytecode pc to the pcToBlock map table bitset for all branch labels and exception labels */ mc->pcToBlock[pc] = bk; CVMJITsetAdd(con, &mc->labelsSet, pc); /* Also add the label to the mapPcSet because it may be used as the on-ramp location of an OSR operation: */ CVMJITsetAdd(con, &mc->mapPcSet, pc); return bk;}CVMJITIRBlock*CVMJITirblockNewLabelForPC(CVMJITCompilationContext* con, CVMUint16 pc){ CVMJITIRBlock *bk = CVMJITirblockNewLabelForPC0(con, pc); CVMJITirblockAddFlags(bk, CVMJITIRBLOCK_IS_BRANCH_TARGET); return bk;}/* * Create a new block and initialize fields in the block. */CVMJITIRBlock*CVMJITirblockCreate(CVMJITCompilationContext* con, CVMUint16 pc){ CVMJITIRBlock* bk = (CVMJITIRBlock*)CVMJITmemNew(con, JIT_ALLOC_IRGEN_OTHER, sizeof(CVMJITIRBlock)); /* Initialize root list and phi list to keep track of root nodes phi nodes */ CVMJITirblockInitRootList(con, bk); /* Initialize fields in block */ CVMJITirblockInit(con, bk, pc); CVMJITsetInit(con, &bk->predecessors); CVMJITsetInit(con, &bk->successors); CVMJITsetInit(con, &bk->dominators); CVMJITlocalrefsInit(con, &bk->localRefs); CVMJITirblockSetBlockID(bk, con->blockIDCounter++); CVMassert(CVMJITirblockGetNext(bk) == NULL); CVMassert(CVMJITirblockGetPrev(bk) == NULL); return bk;}/* * Connect flow between the tail block in block list and the new block */static voidCVMJITirblockAddArc(CVMJITCompilationContext* con, CVMJITIRBlock* curbk, CVMJITIRBlock* targetbk){ CVMJITsetAdd(con, &curbk->successors, CVMJITirblockGetBlockID(targetbk)); CVMJITsetAdd(con, &targetbk->predecessors, CVMJITirblockGetBlockID(curbk)); CVMJITirblockIncRefCount(targetbk); }#ifdef NOT_USED/* * Disconnect flow between the tail block in block list and the new block */static voidCVMJITirblockRemoveArc(CVMJITCompilationContext* con, CVMJITIRBlock* curbk, CVMJITIRBlock* targetbk){ CVMJITsetRemove(con, &curbk->successors, CVMJITirblockGetBlockID(targetbk)); CVMJITsetRemove(con, &targetbk->predecessors, CVMJITirblockGetBlockID(curbk)); CVMJITirblockDecRefCount(targetbk); }#endif/* * Split the current block at 'headPc' by creating a new block * that is a successor of the current one */CVMJITIRBlock*CVMJITirblockSplit(CVMJITCompilationContext* con, CVMJITIRBlock* curbk, CVMUint16 headPc){ CVMJITIRBlock* newbk = con->mc->pcToBlock[headPc]; CVMassert(curbk == con->mc->currBlock); CVMassert(headPc >= curbk->lastOpenRange->startPC); /* We don't want to insert the split block if it already exists. So first check. */ if (newbk == NULL) { newbk = CVMJITirblockNewLabelForPC0(con, headPc); CVMJITirlistInsert(con, &con->bkList, curbk, newbk); CVMJITirblockAddArc(con, curbk, newbk); } return newbk;}/* * Connect blocks in PC straight-line order into the block list */static voidconnectBlocks(CVMJITCompilationContext* con, CVMUint32 elem, void* data){ CVMJITIRBlock* bk = con->mc->pcToBlock[elem]; CVMJITirlistAppend(con, &con->mc->bkList, (void*)bk);}voidCVMJITirblockConnectBlocksInOrder(CVMJITCompilationContext* con){ CVMJITSet* labelsSet = &con->mc->labelsSet; CVMJITsetIterate(con, labelsSet, connectBlocks, NULL); }/* * Discover all exception handler blocks */voidCVMJITirblockFindAllExceptionLabels(CVMJITCompilationContext* con){ CVMJITMethodContext* mc = con->mc; CVMJavaMethodDescriptor* jmd = mc->jmd; CVMExceptionHandler* handler = CVMjmdExceptionTable(jmd); int i; for (i = CVMjmdExceptionTableLength(jmd); i > 0 ; --i, handler++) { CVMUint16 handlerPC = handler->handlerpc; CVMJITIRBlock* handlebk; /* The first instruction of an exception handler is a GC point */ CVMJITsetAdd(con, &mc->gcPointsSet, handlerPC); handlebk = CVMJITirblockNewLabelForPC(con, handlerPC); CVMJITirblockAddFlags(handlebk, CVMJITIRBLOCK_IS_EXC_HANDLER); } return;}/* * Walk through the exceptionTable and and lineNumberTable and mark * every PC mentioned in these tables as a PC that we need to produce * a javaPC -> compiledPC mapping for. */voidCVMJITirblockMarkAllPCsThatNeedMapping(CVMJITCompilationContext* con){ CVMJITMethodContext* mc = con->mc; CVMJavaMethodDescriptor* jmd = mc->jmd; CVMJITSet* mapPcSet = &mc->mapPcSet; int i; /* Mark the various exception handling pc's in the mapPcSet */ { CVMExceptionHandler* handler = CVMjmdExceptionTable(jmd); for (i = CVMjmdExceptionTableLength(jmd); i > 0 ; --i, handler++) { CVMJITsetAdd(con, mapPcSet, handler->handlerpc); CVMJITsetAdd(con, mapPcSet, handler->startpc); CVMJITsetAdd(con, mapPcSet, handler->endpc); } }#ifdef CVM_DEBUG_CLASSINFO /* Mark the line number table pc's in the mapPcSet */ if (con->mc->compilationDepth > 0) { CVMLineNumberEntry* entry = CVMjmdLineNumberTable(jmd); for (i = CVMjmdLineNumberTableLength(jmd); i > 0 ; --i, entry++) { CVMJITsetAdd(con, mapPcSet, entry->startpc); } }#endif return;}static voidmarkJsrTargets(CVMJITCompilationContext* con, CVMUint32 jsrTargetPC, CVMJITIRBlock* jsrTargetBk, CVMJITIRBlock* jsrRetBk){ CVMJavaMethodDescriptor* jmd = con->mc->jmd; CVMUint8* codeBegin = CVMjmdCode(jmd); CVMUint8* targetBlockStartPC = codeBegin + CVMJITirblockGetBlockPC(jsrTargetBk); CVMJITJsrRetEntry* entry; /* Now check that the first instruction of the jsr target is really a store into a local. We don't know how to handle methods that do otherwise (which are very rare, and are never produced by javac) */ switch(*targetBlockStartPC) { case opc_astore: break; case opc_astore_0: break; case opc_astore_1: break; case opc_astore_2: break; case opc_astore_3: break; case opc_wide: if (targetBlockStartPC[1] == opc_astore) { break; } /* fall through */ default: /* The first instruction is not an astore. Can't compile this */ CVMJITerror(con, CANNOT_COMPILE, "jsr target does not start with PC store"); return; } CVMJITirblockAddFlags(jsrTargetBk, CVMJITIRBLOCK_IS_JSR_HANDLER); CVMJITirblockAddFlags(jsrRetBk, CVMJITIRBLOCK_IS_JSR_RETURN_TARGET); /* Create a new entry for jsr return target */ entry = (CVMJITJsrRetEntry*)CVMJITmemNew(con, JIT_ALLOC_IRGEN_OTHER, sizeof(CVMJITJsrRetEntry)); CVMJITjsrRetEntrySetNext(entry, NULL); CVMJITjsrRetEntrySetPrev(entry, NULL); entry->jsrTargetPC = jsrTargetPC; entry->jsrRetBk = jsrRetBk; /* And append the entry onto the list */ CVMJITirlistAppend(con, &con->jsrRetTargetList, (void*)entry);}static CVMJITIRBlock*newLabel(CVMJITCompilationContext* con, CVMUint16 currPC, CVMUint16 targetPC){ CVMJITIRBlock *targetbk = CVMJITirblockNewLabelForPC(con, targetPC); /* note backwards branches */ if (targetPC <= currPC) { CVMJITirblockAddFlags(targetbk, CVMJITIRBLOCK_IS_BACK_BRANCH_TARGET); } return targetbk;}static voidCVMJITsplitNot(CVMJITCompilationContext *con, CVMUint32 i, void *data);/* * This piece of code finds all block headers. * It also marks GC points */voidCVMJITirblockFindAllNormalLabels(CVMJITCompilationContext* con){ CVMJITMethodContext* mc = con->mc; CVMMethodBlock* mb = mc->mb; CVMJavaMethodDescriptor* jmd = mc->jmd; CVMUint8* codeBegin = CVMjmdCode(jmd); CVMUint16 codeLength = CVMmbCodeLength(mb); CVMUint8* codeEnd = &codeBegin[codeLength];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?