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 + -
显示快捷键?