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

📄 jitregman.c

📁 This is a resource based on j2me embedded,if you dont understand,you can connection with me .
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * @(#)jitregman.c	1.167 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.  * *//* * Register manager implementation. */#include "javavm/include/defs.h"#include "javavm/include/objects.h"#include "javavm/include/classes.h"#include "javavm/include/utils.h"#include "javavm/include/bcutils.h"#include "javavm/include/ccee.h"#include "javavm/include/globals.h"#include "javavm/include/jit/jit.h"#include "javavm/include/jit/jitir.h"#include "javavm/include/jit/jitcontext.h"#include "javavm/include/jit/jitcodebuffer.h"#include "javavm/include/jit/jitirnode.h"#include "javavm/include/jit/jitirblock.h"#include "javavm/include/jit/jitcomments.h"#include "javavm/include/jit/jitmemory.h"#include "javavm/include/jit/jitirdump.h"#include "javavm/include/jit/jitstackmap.h"#include "portlibs/jit/risc/include/porting/jitriscemitter.h"#include "portlibs/jit/risc/include/export/jitregman.h"#include "portlibs/jit/risc/jitopcodes.h"#include "portlibs/jit/risc/jitstackman.h"#include "portlibs/jit/risc/jitgrammar.h"#include "javavm/include/clib.h"#ifdef CVM_DEBUG_ASSERTS#define CVMJIT_STRICT_REFLOCAL_ASSERTS#endif#define RM_INITIAL_REF_COUNT_SIZE	64 /* more than ever needed */#define RM_STICKY_REF_COUNT		255#ifdef CVM_JIT_USE_FP_HARDWARE#define RM_MAX_INTERESTING_REG	(con)->maxInteresting#define RM_MIN_INTERESTING_REG	(con)->minInteresting#define RM_SAFE_SET 		(con)->safeSet#define RM_UNSAFE_SET 		(con)->unsafeSet#define RM_ANY_SET 		(con)->anySet#define RM_SINGLE_REG_ALIGN	(con)->singleRegAlignment#define RM_DOUBLE_REG_ALIGN	(con)->doubleRegAlignment#define RM_MOV_OPCODE(_con)	(_con)->movOpcode#define RM_MAX_REG_SIZE(_con)	(_con)->maxRegSize#else    /* not using FP hardware */#define RM_MAX_INTERESTING_REG	CVMCPU_MAX_INTERESTING_REG#define RM_MIN_INTERESTING_REG	CVMCPU_MIN_INTERESTING_REG#define RM_SAFE_SET 		CVMRM_SAFE_SET#define RM_UNSAFE_SET 		CVMRM_UNSAFE_SET#define RM_ANY_SET 		CVMRM_ANY_SET#define RM_SINGLE_REG_ALIGN	CVMCPU_SINGLE_REG_ALIGNMENT#define RM_DOUBLE_REG_ALIGN	CVMCPU_DOUBLE_REG_ALIGNMENT#define RM_MAX_REG_SIZE(_con)	CVMCPU_MAX_REG_SIZE#define RM_MOV_OPCODE(_con)	CVMCPU_MOV_OPCODE#endif#define RM_STORE_OPCODE(_con,_size)	((_con)->storeOpcode[(_size)-1])#define RM_LOAD_OPCODE(_con,_size)	((_con)->loadOpcode[(_size)-1])#if ((CVMCPU_MAX_REG_SIZE != 1) || \	(defined(CVM_JIT_USE_FP_HARDWARE) && (CVMCPU_FP_MAX_REG_SIZE != 1)))/* there are some double-word registers */#define RM_NREGISTERS(_con,_size)	((_size) <= RM_MAX_REG_SIZE(_con) ? 1 : 2)#else/* all the registers are single-word */#define RM_NREGISTERS(_con,_size) 	(_size)#endif#ifdef  CVM_DEBUG_ASSERTS#define RM_INT_KEY	1#define RM_FP_KEY	2#define CVMRMassertContextMatch(cx,rp) CVMassert((cx)->key == (rp)->key)#else#define CVMRMassertContextMatch(cx,rp)#endiftypedef enum {    CVMRM_REGPREF_TARGET,    CVMRM_REGPREF_SCRATCH,    CVMRM_REGPREF_PERSISTENT} CVMRMRegisterPreference;#define DEFAULT_CONSTANT_PREF	CVMRM_REGPREF_PERSISTENT#define DEFAULT_LOCAL_PREF	CVMRM_REGPREF_PERSISTENT#define DEFAULT_RESOURCE_PREF	CVMRM_REGPREF_PERSISTENTstatic voidCVMRMpinResource0(CVMJITRMContext*, CVMRMResource*,    CVMRMregset target, CVMRMregset avoid,    CVMRMRegisterPreference pref, CVMBool strict);#ifdef CVM_JIT_REGISTER_LOCALSstatic voidCVMRMbindAllIncomingLocalNodes(CVMJITCompilationContext* con,			       CVMJITIRBlock* b);#endifstatic voidCVMRMbindAllUsedNodes(CVMJITCompilationContext* con, CVMJITIRBlock* b);static voidCVMRMbindUseToResource(CVMJITCompilationContext* con, CVMJITIRNode* expr);/* Purpose: Gets an available reg from the specified register set. */static intfindMaxRegInSet(    CVMRMregset target,    int minInteresting,    int maxInteresting,    int alignment){#ifndef IAI_ROUNDROBIN_REGISTER_ALLOCATION    int i;    /* The register with the highest ID value in the specified set       will be selected first: */    if (alignment == 2 )	maxInteresting &= ~1; /* round down to even */    for (i=maxInteresting; i>=minInteresting; i-= alignment ) {	if ((target & (1U<<i)) != 0)	    return i;    }    return -1;#else /* !IAI_ROUNDROBIN_REGISTER_ALLOCATION */    /*     * Keep track of last register allocated so next time we can start     * with the register that follows it.     */    static int round = RM_MAX_INTERESTING_REG;    int i;    if (alignment == 2 ) {	maxInteresting &= ~1; /* round down to even */	minInteresting = (minInteresting + 1) & ~1;  /* round up to even */    }    if (round < minInteresting || round > maxInteresting) {	round = maxInteresting;    }    if (alignment == 2 ) {	round &= ~1; /* round down to even */    }    /* Seach the round to find appropriate register.       Seach from the round down to min */    for (i = round; i >= minInteresting; i -= alignment) {	if ((target & (1U<<i)) != 0) { 	    round = i -1;	    return i;	}    }    /* Search from max down to round */    for (i = maxInteresting; i > round; i -= alignment) {	if ((target & (1U<<i)) != 0) { 	    round = i -1;	    return i;	}    }  return -1;#endif /* !IAI_ROUNDROBIN_REGISTER_ALLOCATION */}/* Purpose: Gets an available reg from the specified register set. */static intfindMinRegInSet(    CVMRMregset target,    int minInteresting,    int maxInteresting,    int alignment,    int nregs){    int i;    /*     * Make search easier if a 32-bit pair is needed by masking off the upper     * register of each pair if the lower register is not available.      * This way we know if any bit is set, then the following bit is also set.     */    if (nregs > 1) {	target = target & (target >> 1);    }    /* If alignment is required, then make sure we start on an aligned reg */    CVMassert(alignment > 0);    if (alignment != 1) {	int left = (minInteresting % alignment);	if (left > 0) {	    /* round up to alignment */	    minInteresting += alignment - left;	}    }    CVMassert(minInteresting % alignment == 0);    /* Now we are all set to grab the first available register. */    for (i=minInteresting; i<=maxInteresting; i+= alignment ) {	if ((target & (1U<<i)) != 0)	    return i;    }    return -1;}/* * Spill Location Management. Finding and relinquishing spill locations * using CVMJITSet structures */static voidresizeSpillRefCount(CVMJITCompilationContext* con, int needed){    int newsize = needed;    CVMUint8* newallocation;    /* round up to multiple of 64 */    newsize = (newsize+63) & ~63;    CVMassert(newsize > con->RMcommonContext.spillBusyRefSize);    newallocation = CVMJITmemNew(con, JIT_ALLOC_CGEN_REGMAN,				 newsize*sizeof(CVMUint8));    memcpy(newallocation, con->RMcommonContext.spillBusyRefCount,	   con->RMcommonContext.spillBusyRefSize*sizeof(CVMUint8));    con->RMcommonContext.spillBusyRefCount = newallocation;    con->RMcommonContext.spillBusyRefSize = newsize;}static voidresetSpillMap(CVMJITCompilationContext* con, CVMJITIRBlock* b){	CVMJITRMCommonContext* common = &(con->RMcommonContext);	/* reset the spill set */	CVMJITsetClear(con, &(common->spillBusySet));	memset(common->spillBusyRefCount, 0,	       common->spillBusyRefSize * sizeof(CVMUint8));	/* mark all phiWords as busy */	if (con->maxPhiSize > 0){	    int i;	    int maxPhi = con->maxPhiSize;	    CVMUint8* refElement;	    CVMJITsetPopulate(con, &(common->spillBusySet),			      maxPhi);	    if (maxPhi > common->spillBusyRefSize){		resizeSpillRefCount(con, maxPhi);	    }	    refElement = common->spillBusyRefCount;	    for( i = 0; i < maxPhi; i++){		*(refElement++) = RM_STICKY_REF_COUNT;	    }			}	/* initialize the spill ref set */	CVMJITsetClear(con, &(con->RMcommonContext.spillRefSet));	con->RMcommonContext.maxPhiSize     = con->maxPhiSize;	con->RMcommonContext.maxSpillNumber = con->maxPhiSize-1;}static intfindSpillLoc(    CVMJITCompilationContext* con,    int                       size,    CVMBool                   isRef){    int spilloff, topoff;     CVMBool isBusy;    CVMJITSet*	busySet = &con->RMcommonContext.spillBusySet;    CVMUint8*   refCount=  con->RMcommonContext.spillBusyRefCount;    CVMJITSet*	refSet  = &con->RMcommonContext.spillRefSet;    CVMassert((size == 1) || (size == 2));    CVMassert((size == 1) || !isRef);    for ( spilloff = con->maxPhiSize; ;spilloff += 1){	CVMJITsetContains(busySet, spilloff, isBusy);	if (!isBusy){	    /* this one is available. If double word, look for next, too. */	    if (size > 1){		CVMJITsetContains(busySet, (spilloff+1), isBusy);		if (!isBusy){		    /* a pair of winners */		    CVMJITsetAdd(con, busySet, spilloff);		    CVMJITsetAdd(con, busySet, spilloff+1);		    CVMJITsetRemove(con, refSet, spilloff);		    CVMJITsetRemove(con, refSet, spilloff+1);		    break;		}		/* else keep trying */	    } else {		/* a winner */		CVMJITsetAdd(con, busySet, spilloff);		if (isRef){		    CVMJITsetAdd(con, refSet, spilloff);		} else {		    CVMJITsetRemove(con, refSet, spilloff);		}		break;	    }	}    }    /* location spilloff is available. see if it is a new high water mark */    topoff = spilloff+size-1;    if (topoff > con->RMcommonContext.maxSpillNumber){	con->RMcommonContext.maxSpillNumber = topoff;    }    if (topoff >= con->RMcommonContext.spillBusyRefSize){	resizeSpillRefCount(con, topoff+1);	refCount=  con->RMcommonContext.spillBusyRefCount;    }    refCount[spilloff] = 1;    if (size > 1){	refCount[spilloff+1] = 1;    }    if (spilloff > CVMRM_MAX_SPILL_LOCATION) {        CVMJITlimitExceeded(con, "exceeding max spill locations");    }    return spilloff;}static voidrelinquishSpillLoc(CVMJITCompilationContext*con, int loc, int size){    CVMJITSet*	busySet = &con->RMcommonContext.spillBusySet;    CVMUint8*   refCount=  con->RMcommonContext.spillBusyRefCount;    CVMassert(loc>=0);    CVMassert((size == 1) || (size == 2));#ifdef CVM_DEBUG_ASSERTS    {	CVMBool isBusy;	CVMJITsetContains(busySet, loc, isBusy);	CVMassert(isBusy);	CVMassert((loc+size) <= con->RMcommonContext.spillBusyRefSize);	CVMassert(refCount[loc] > 0);	if (size > 1){	    CVMJITsetContains(busySet, (loc+1), isBusy);	    CVMassert(isBusy);	    CVMassert(refCount[loc+1] == refCount[loc]);	}    }#endif    if (refCount[loc] == RM_STICKY_REF_COUNT)	return; /* cannot deallocate */    if ((refCount[loc] -= 1) == 0){	CVMJITsetRemove(con, busySet, loc);	if (size > 1){	    CVMJITsetRemove(con, busySet, (loc+1));	}    }    if (size > 1){	refCount[loc+1] -= 1;    }}static voidincrementSpillCount(CVMJITCompilationContext*con, int loc, int size){    CVMUint8*   refCount= con->RMcommonContext.spillBusyRefCount;    CVMassert((loc+size) <= con->RMcommonContext.spillBusyRefSize);    if (refCount[loc] == RM_STICKY_REF_COUNT)	return; /* maxed out */    refCount[loc] += 1;    if (size > 1)	refCount[loc+1] += 1;}static voidflushResource(CVMJITRMContext* con, CVMRMResource* rp){    CVMJITCompilationContext* cc = con->compilationContext;    if (CVMRMisLocal(rp)) {        CVMassert(rp->localNo != CVMRM_INVALID_LOCAL_NUMBER);	/* spill directly to local */#if 0	/* Currently locals are write through, so there is no need to	 * spill them. However, because of the way the backend works	 * when we need to force evalauation node, it can lead to	 * a resource for a local being marked as dirty. We can	 * ignore these	 */	CVMCPUemitFrameReference(cc, RM_STORE_OPCODE(con,rp->size), rp->regno,	    CVMCPU_FRAME_LOCAL, rp->localNo);#endif#if 0	/* Sanity check to make sure the local is in sync. We'll load	 * the local into JFP since we know the local can't be there.	 * If it's 64bit, then we'll also use JSP. We also need to save	 * and restore these registers.	 */	if (rp->size == 2) {	    /* Save JSP and load 2nd word into it */	    CVMCPUemitCCEEReferenceImmediate(cc, CVMCPU_STR32_OPCODE,		CVMCPU_JSP_REG,		offsetof(CVMCCExecEnv, ccmStorage) + sizeof(CVMUint32));	    CVMCPUemitFrameReference(cc, CVMCPU_LDR32_OPCODE,				     CVMCPU_JSP_REG, CVMCPU_FRAME_LOCAL,				     rp->localNo+1);	}	/* Save JFP and load 1st word into it */	CVMCPUemitCCEEReferenceImmediate(cc, CVMCPU_STR32_OPCODE,	    CVMCPU_JFP_REG, offsetof(CVMCCExecEnv, ccmStorage));	/* this will trash JFP, so do it after the above frame ref */	CVMCPUemitFrameReference(cc, CVMCPU_LDR32_OPCODE,				 CVMCPU_JFP_REG, CVMCPU_FRAME_LOCAL,				 rp->localNo);	/* this compare will ONLY work for integer registers!! */	CVMassert(con->key == RM_INT_KEY);	CVMCPUemitCompareRegister(cc, CVMCPU_CMP_OPCODE,	    CVMCPU_COND_NE, CVMCPU_JFP_REG, rp->regno);	if (rp->size == 2) {

⌨️ 快捷键说明

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