⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jitconstantpool.c

📁 This is a resource based on j2me embedded,if you dont understand,you can connection with me .
💻 C
字号:
/* * @(#)jitconstantpool.c	1.51 06/10/10 * * 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/jit/jit.h"#include "javavm/include/jit/jitcontext.h"#include "javavm/include/jit/jitfixup.h"#include "javavm/include/jit/jitconstantpool.h"#include "javavm/include/jit/jitcodebuffer.h"#include "javavm/include/jit/jitmemory.h"#include "javavm/include/jit/jitcomments.h"#include "javavm/include/jit/jitstats.h"#include "javavm/include/porting/jit/jit.h"#include "javavm/include/porting/doubleword.h"/* * This implementation of run-time constant management * is for PC-relative pools intermixed with the program text, * as the CPU uses. Other implementations will be required for other * strategies. *//* * a comparison function type used to lookup a value * CVM_TRUE  => equal * CVM_FALSE => not equal */typedef CVMBool (*CVMCompareFunction)(CVMJITConstantEntry* ep, void* vp);/* * a function for filling in information in an entry being created */typedef void (*CVMFillinFunction)(CVMJITConstantEntry* ep, void* vp);/* * Look for the existing constant. * This can be called repeatedly, because a constant can be * in the constant pool multiple times with different addresses. * This is required by reachability constraints. */static CVMJITConstantEntry *findConstantEntry(    int constSize,    CVMCompareFunction cfp,    void* vp,    CVMJITConstantEntry *head){    CVMJITConstantEntry *thisEntry = head;    while (thisEntry != NULL){	/* We ignore cached constants since they aren't real constants */	if ((!thisEntry->isCachedConstant) &&	    (thisEntry->constSize == constSize) && (*cfp)(thisEntry, vp))	{	    return thisEntry;	}	thisEntry = thisEntry->next;    }    return NULL;}static CVMJITConstantEntry *addConstantEntry(    CVMJITCompilationContext *con,    CVMFillinFunction ffp,    void* vp,    CVMUint8 isCachedConstant){    CVMJITConstantEntry *thisEntry;    thisEntry = (CVMJITConstantEntry*)	CVMJITmemNew(con, JIT_ALLOC_CGEN_OTHER, sizeof(CVMJITConstantEntry));    thisEntry->hasBeenEmitted = CVM_FALSE;    thisEntry->references = NULL;    thisEntry->isCachedConstant = isCachedConstant;    (*ffp)(thisEntry, vp); /* fill in type and value */#ifdef CVM_TRACE_JIT    thisEntry->printName = CVMJITgetSymbolName(con);#endif    thisEntry->next = con->constantPool;    con->constantPool = thisEntry;    con->constantPoolSize += (thisEntry->constSize == shortConst) ? 4 : 8;    return thisEntry;}/* * Periodic check point to see if the constant pool needs to be dumped * any time soon */CVMBoolCVMJITcpoolNeedDump(CVMJITCompilationContext* con){#ifndef CVMCPU_HAS_CP_REG    /* Make sure we haven't used more than half our load/store offset range. */    if (con->numEntriesToEmit != 0) {	CVMInt32 logicalAddress = CVMJITcbufGetLogicalPC(con);#ifdef CVM_JIT_USE_FP_HARDWARE	if (con->earliestFPConstantRefPC != MAX_LOGICAL_PC &&	    !CVMJITcanReachAddress(con, 	        logicalAddress, con->earliestFPConstantRefPC,	        CVMJIT_FPMEMSPEC_ADDRESS_MODE, CVM_TRUE)) {	    /* We are drifting dangerously towards not being able to reach	       the constants. */	    return CVM_TRUE;	}#endif	if (con->earliestConstantRefPC != MAX_LOGICAL_PC && 	    !CVMJITcanReachAddress(con,	        logicalAddress, con->earliestConstantRefPC,	        CVMJIT_MEMSPEC_ADDRESS_MODE, CVM_TRUE)) {	    /* We are drifting dangerously towards not being able to reach	       the constants. */	    return CVM_TRUE;	}    }#endif    return CVM_FALSE;}static CVMInt32CVMJITgetRuntimeConstantReference(    CVMJITCompilationContext* con,    CVMInt32 logicalAddress,    int constSize,    CVMCompareFunction cfp,    CVMFillinFunction  ffp,    void* vp,    CVMUint8 isCachedConstant, CVMBool isFloat){    CVMJITConstantEntry *thisEntry;    if (isCachedConstant) {	/* don't bother looking for cached constants. They are always unique */	thisEntry = NULL;    } else {	thisEntry = GET_CONSTANT_POOL_LIST_HEAD(con);#ifdef CVMCPU_HAS_CP_REG	thisEntry = findConstantEntry(constSize, cfp, vp, thisEntry);#else        /* See if this constant has been emitted and is still in range */        while (thisEntry != NULL){	    thisEntry = findConstantEntry(constSize, cfp, vp, thisEntry);	    if (thisEntry == NULL)		break;	    if (!(thisEntry->hasBeenEmitted))		break;	    /* We found an already emitted entry. Return its address if it can	       be reached from 'logicalAddress'. */#ifdef CVM_JIT_USE_FP_HARDWARE 	    if (isFloat && CVMJITcanReachAddress(con,				   logicalAddress, thisEntry->address,				   CVMJIT_FPMEMSPEC_ADDRESS_MODE, CVM_FALSE)) {		return thisEntry->address;	    }#endif	    if (!isFloat && CVMJITcanReachAddress(con,				      logicalAddress, thisEntry->address,				      CVMJIT_MEMSPEC_ADDRESS_MODE, CVM_FALSE)){		return thisEntry->address;	    }	    /* If we are here, we found an already emitted constant that is	       out of reach of the current 'logicalAddress'. Therefore we	       keep looking */	    thisEntry = thisEntry->next;	}#endif    }    if (thisEntry == NULL){	/* No constant has been found, reachable or not */	thisEntry = addConstantEntry(con, ffp, vp, isCachedConstant);	/* Remember how many we have to write out at the next dump */	con->numEntriesToEmit++;    }    CVMassert(!thisEntry->hasBeenEmitted);    CVMJITfixupAddElement(con, &(thisEntry->references), logicalAddress);    CVMJITresetSymbolName(con);#ifdef CVM_JIT_USE_FP_HARDWARE    if (isFloat) {	if (logicalAddress < con->earliestFPConstantRefPC) {	    /* See the farthest away constant reference */	    con->earliestFPConstantRefPC = logicalAddress;	}    } else#endif    {	if (logicalAddress < con->earliestConstantRefPC) {	    /* See the farthest away constant reference */	    con->earliestConstantRefPC = logicalAddress;	}    }    return 0;}/* * Helper functions for CVMJITgetRuntimeConstantReference32 */static CVMBoolCVMCompareEntry32(CVMJITConstantEntry* thisEntry, void* vp){    CVMassert(thisEntry->constSize == shortConst);    return (thisEntry->v.single == *(CVMInt32*)vp);}static voidCVMFillinEntry32(CVMJITConstantEntry* thisEntry, void* vp){    thisEntry->constSize = shortConst;    if (!thisEntry->isCachedConstant) {	thisEntry->v.single = *(CVMInt32*)vp;    }}/* * Lookup and insert a 32-bit constant */CVMInt32CVMJITgetRuntimeConstantReference32(    CVMJITCompilationContext* con,    CVMInt32 logicalAddress,    CVMInt32 v){    return CVMJITgetRuntimeConstantReference( con, logicalAddress, shortConst,        &CVMCompareEntry32, &CVMFillinEntry32, &v, CVM_FALSE, CVM_FALSE);}#ifdef CVM_JIT_USE_FP_HARDWARECVMInt32CVMJITgetRuntimeFPConstantReference32(    CVMJITCompilationContext* con,    CVMInt32 logicalAddress,    CVMInt32 v){    return CVMJITgetRuntimeConstantReference( con, logicalAddress, shortConst,        &CVMCompareEntry32, &CVMFillinEntry32, &v, CVM_FALSE, CVM_TRUE);}#endif#ifdef IAI_CACHEDCONSTANT/* * Insert a 32-bit cached constant */voidCVMJITgetRuntimeCachedConstant32(    CVMJITCompilationContext* con){    CVMInt32 logicalAddress = CVMJITcbufGetLogicalPC(con);    /* Reserve a slot for the cached constant */    CVMJITgetRuntimeConstantReference(	con, logicalAddress, shortConst,        &CVMCompareEntry32, &CVMFillinEntry32, NULL, CVM_TRUE, CVM_FALSE);    /*     * Emit code to load the address of the constant into a platform     * specific register. We don't know the true address of the cached     * constant yet, so just use the address where code to load the     * cache constant address will be emitted at. Later on this will     * get patched when the constant is dumped.     */    CVMJITemitLoadConstantAddress(con, logicalAddress);}#endif /* IAI_CACHEDCONSTANT *//* * Helper functions for CVMJITgetRuntimeConstantReference64 */static CVMBoolCVMCompareEntry64(CVMJITConstantEntry* thisEntry, void* vp){    CVMJavaLong l1 = CVMjvm2Long(thisEntry->v.longVal.v);    CVMJavaLong l2 = CVMjvm2Long(((CVMJavaVal64*)vp)->v);    CVMassert(thisEntry->constSize == longConst);    return (CVMlongCompare(l1, l2) == 0);}static voidCVMFillinEntry64(CVMJITConstantEntry* thisEntry, void* vp){    thisEntry->constSize = longConst;    CVMmemCopy64(thisEntry->v.longVal.v,  ((CVMJavaVal64*)vp)->v);}/* * Lookup and insert a 64-bit constant */CVMInt32CVMJITgetRuntimeConstantReference64(    CVMJITCompilationContext* con,    CVMInt32 logicalAddress,    CVMJavaVal64* vp){    return CVMJITgetRuntimeConstantReference( con, logicalAddress, longConst,        &CVMCompareEntry64, &CVMFillinEntry64, vp, CVM_FALSE, CVM_FALSE);}#ifdef CVM_JIT_USE_FP_HARDWARECVMInt32CVMJITgetRuntimeFPConstantReference64(    CVMJITCompilationContext* con,    CVMInt32 logicalAddress,    CVMJavaVal64* vp){    return CVMJITgetRuntimeConstantReference( con, logicalAddress, longConst,        &CVMCompareEntry64, &CVMFillinEntry64, vp, CVM_FALSE, CVM_TRUE);}#endifvoidCVMJITdumpRuntimeConstantPool(CVMJITCompilationContext* con, CVMBool forceDump){    CVMJITConstantEntry *thisEntry;    CVMJITFixupElement *thisRef;    CVMInt32 emitted = 0; /* Count those emitted */    CVMUint32 size;#ifdef IAI_CODE_SCHEDULER_SCORE_BOARD    CVMJITCSConstantPoolDumpInfo* dumpInfoItem;#endif    if (con->numEntriesToEmit == 0) {	return;    }    /* Check whether constants still reachable */    if (!forceDump && !CVMJITcpoolNeedDump(con)) {	return;    }#ifdef IAI_CODE_SCHEDULER_SCORE_BOARD    CVMJITcsSetEmitInPlace(con);    dumpInfoItem = CVMJITcsAllocateConstantPoolDumpInfoEntry(con);    dumpInfoItem->startPC = CVMJITcbufGetLogicalPC(con);#endif /*IAI_CODE_SCHEDULER_SCORE_BOARD*/    /* align constant pool to 4 byte boundary if necessary */#if (CVMCPU_INSTRUCTION_SIZE != 4)    {	int i = (CVMUint32)CVMJITcbufGetPhysicalPC(con) & 0x3;	if (i != 0) {	    for (; i < 4; i++) {		CVMtraceJITCodegenExec({		    CVMconsolePrintf("0x%8.8x\t%d:",				     CVMJITcbufGetPhysicalPC(con),				     CVMJITcbufGetLogicalPC(con));		    CVMconsolePrintf("	.byte	%d\n", i);		});		CVMJITcbufEmit1(con, i);	    }	}    }#endif    /*     * Dump the 1 word constants first, followed by the 2 word constants.     * This way we can align the two work constants if necessary.     */    size = shortConst; dumpForNewSize:    thisEntry = GET_CONSTANT_POOL_LIST_HEAD(con);    while (thisEntry != NULL) {	if (!thisEntry->hasBeenEmitted && thisEntry->constSize == size) {	    CVMInt32 thisLogicalAddress = CVMJITcbufGetLogicalPC(con);            CVMJITaddCodegenComment((con, thisEntry->printName));            CVMJITstatsRecordInc(con,                CVMJIT_STATS_NUMBER_OF_CONSTANTS_EMITTED);	    if (thisEntry->constSize == shortConst) {		CVMJITemitWord(con, thisEntry->v.single);	    } else {		/*		 * We left it up to the user to order the words		 * in the right order. We just put them out.		 */		CVMJITemitWord(con, thisEntry->v.longVal.v[0]);		CVMJITemitWord(con, thisEntry->v.longVal.v[1]);	    }	    thisRef = thisEntry->references;	    while (thisRef != NULL) {	       if (thisEntry->isCachedConstant) {#ifdef IAI_CACHEDCONSTANT		   CVMtraceJITCodegen((			":::::Fixed instruction at %d to reference %d\n",			thisRef->logicalAddress, thisLogicalAddress));		   CVMJITcbufPushFixup(con, thisRef->logicalAddress);                   CVMJITcsSetEmitInPlace(con);		   CVMJITemitLoadConstantAddress(con, thisLogicalAddress);                   CVMJITcsClearEmitInPlace(con);		   CVMJITcbufPop(con);#endif /* IAI_CACHEDCONSTANT */	       } else {		   /* patch constant reference to proper address */		   CVMJITfixupAddress(con,			thisRef->logicalAddress, thisLogicalAddress,			CVMJIT_MEMSPEC_ADDRESS_MODE);	       }	       thisRef = thisRef->next;	    }	    thisEntry->hasBeenEmitted = CVM_TRUE;	    thisEntry->address = thisLogicalAddress;	    emitted++;	}	thisEntry = thisEntry->next;    }    if (size == shortConst) {	/* see if we have some 64-bit constants to emit */	if (con->numEntriesToEmit != emitted) {	    /* align 64-bit constants */	    if (((CVMUint32)CVMJITcbufGetPhysicalPC(con) & 0x4) != 0) {		CVMJITemitWord(con, 0);	    }	    /* emit the 64-bit constants */	    size = longConst;	    goto dumpForNewSize;	}    }    CVMassert(con->numEntriesToEmit == emitted);    con->numEntriesToEmit = 0;    /* 64 bit align for dumping 64 bit constants */    con->constantPoolSize = 4;    con->earliestConstantRefPC = MAX_LOGICAL_PC;#ifdef CVM_JIT_USE_FP_HARDWARE    con->earliestFPConstantRefPC = MAX_LOGICAL_PC;#endif#ifdef IAI_CODE_SCHEDULER_SCORE_BOARD    CVMJITcsClearEmitInPlace(con);    dumpInfoItem->endPC = CVMJITcbufGetLogicalPC(con);    CVMJITcsBeginBlock(con);#endif /*IAI_CODE_SCHEDULER_SCORE_BOARD*/}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -