jit_cisc.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 690 行 · 第 1/2 页

C
690
字号
/* * @(#)jit_cisc.c	1.7 06/10/23 *  * Portions Copyright  2000-2008 Sun Microsystems, Inc. All Rights * Reserved.  Use is subject to license terms. * 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. *//* * This file implements part of the jit porting layer. */#include "javavm/include/jit/jit.h"#include "javavm/include/jit/jitcontext.h"#include "javavm/include/jit/jitirlist.h"#include "javavm/include/jit/jitirdump.h"#include "javavm/include/jit/jitirnode.h"#include "javavm/include/jit/jitirblock.h"#include "javavm/include/jit/jitconstantpool.h"#include "javavm/include/jit/jitcodebuffer.h"#include "javavm/include/jit/jitfixup.h"#include "javavm/include/jit/jitstats.h"#include "javavm/include/jit/jitmemory.h"#include "javavm/include/jit/jitcomments.h"#include "javavm/include/jit/jitdebug.h"#include "javavm/include/globals.h"/* SVMC_JIT d022609 (ML) 2004-02-23. *//* #include "portlibs/jit/cisc/include/porting/jitciscemitter.h" */#include "javavm/include/jit/jitarchemitter.h"#include "javavm/include/jit/ccmcisc.h"#include "javavm/include/jit/jitregman.h"/* SVMC_JIT d022609 (ML) 2004-02-23. *//* #include "portlibs/jit/cisc/jitstackman.h" */#include "javavm/include/jit/jitstackman.h"#include "javavm/include/jit/jitgrammar.h"#include "javavm/include/porting/jit/jit.h"#include "generated/javavm/include/jit/jitcodegen.h"/* * Special backend actions to be done at the beginning and end of each * codegen rule. Usually only enabled when debugging. */#ifdef MIN#undef MIN#endif#define MIN(x,y) ((x) < (y) ? (x) : (y))voidCVMJITdoStartOfCodegenRuleAction(CVMJITCompilationContext *con, int ruleno,                                 const char *description, CVMJITIRNode* node){    /* Check to see if we need a constantpool dump.  If so, emit the dump       with a branch around it: */    CVMX86emitConstantPoolDumpWithBranchAroundIfNeeded(con);    /* The following is intentionally left here to assist in future codegen       rules debugging needs if necessary: */#ifdef CVM_DEBUG_JIT_TRACE_CODEGEN_RULE_EXECUTION    /* Tell about the codegen rule that is being executed: */    CVMJITprintCodegenComment(("Doing node %4d codegen rule %s",                               CVMJITirnodeGetID(node), description));#endif}#if defined(CVM_DEBUG_ASSERTS)void CVMJITdoEndOfCodegenRuleAction(CVMJITCompilationContext *con){    /* There should not be any pinned registers at the end of a codegen rule */    CVMassert(CVMRMhasNoPinnedRegisters(con));}#endif#ifdef CVMJIT_PATCH_BASED_GC_CHECKS/************************************************************************** * GC CheckPoints support. * * Instead of generating gc checks, you can just apply a patch that * calls the gc rendezvous code when requested.  This is what we * choose to do for our shared risc implementations.  If you do gc * checks inline, then these functions can have empty implementations. **************************************************************************//* * Patch or unpatch gc checkpoints. */static voidcsPatchHelper(CVMExecEnv* ee){    CVMUint8* cbuf;    CVMJITGlobalState* jgs = &CVMglobals.jit;    CVMassert(CVMsysMutexIAmOwner(ee, &CVMglobals.jitLock));    if (jgs->destroyed) {        return;    }#ifdef CVM_JIT_COPY_CCMCODE_TO_CODECACHE /* SVMC_JIT d022609 (ML) */#if CVMCPU_NUM_CCM_PATCH_POINTS > 0    /* Patch CCM method call and return spots */    {        int i;        for (i=0; i < CVMCPU_NUM_CCM_PATCH_POINTS; i++) {            CVMCCMGCPatchPoint* gcPatchPoint = &jgs->ccmGcPatchPoints[i];            CVMCPUInstruction tmpInstr;            CVMCPUInstruction* instrPtr;            if (gcPatchPoint->patchPoint == NULL) {                continue;            }            instrPtr = (CVMCPUInstruction*)gcPatchPoint->patchPoint;            tmpInstr = gcPatchPoint->patchInstruction;            gcPatchPoint->patchInstruction = *instrPtr;            /* swap current instruction with saved instruction */            CVMatomicSwap64(instrPtr, tmpInstr);        }    }#endif#endif /* CVM_JIT_COPY_CCMCODE_TO_CODECACHE */    /* iterate over the code cache, patching all gc points */    for (cbuf = jgs->codeCacheStart;         cbuf < jgs->codeCacheEnd;         cbuf += CVMJITcbufSize(cbuf)) {        if (CVMJITcbufIsCommitted(cbuf)) {            CVMCompiledMethodDescriptor* cmd = CVMJITcbufCmd(cbuf);            CVMCompiledGCCheckPCs* gcpcs = CVMcmdGCCheckPCs(cmd);            CVMUint8* codeBufAddr = CVMcmdCodeBufAddr(cmd);            if (gcpcs != NULL) {                int i;                CVMCPUInstruction* patchedInstructions =                  CVMCompiledGCCheckPCs_patchedInstructions(gcpcs, gcpcs->noEntries);                for (i = 0; i < gcpcs->noEntries; i++) {                    if (gcpcs->pcEntries[i] != 0) {                        CVMCPUInstruction tmpInstr;                        CVMCPUInstruction* instrPtr = (CVMCPUInstruction*)                            (gcpcs->pcEntries[i] + codeBufAddr);                        /* swap current instruction with saved instruction */                        tmpInstr = patchedInstructions[i];                        patchedInstructions[i] = *instrPtr;                        /* SVMC_JIT rr 01Sept2003: On CISC                         * `*instrPtr = tmpInstr;' in general is not                         * atomic.                         * Used cmpxchg8b to achieve atomic swap. This means                         * more instruction overhead. But x86 does not support                         * any other atomic 64 bit move! Need lock prefix too.                         */                        CVMatomicSwap64(instrPtr, tmpInstr);                    }                }            }        }    }    /* Flush cache */    CVMJITflushCache(jgs->codeCacheStart, jgs->codeCacheEnd);}voidCVMJITenableRendezvousCalls(CVMExecEnv* ee){    csPatchHelper(ee);}voidCVMJITdisableRendezvousCalls(CVMExecEnv* ee){    csPatchHelper(ee);}#endif#ifdef CVMJIT_TRAP_BASED_GC_CHECKSvoidCVMJITenableRendezvousCalls(CVMExecEnv* ee){    CVMJITenableRendezvousCallsTrapbased(ee);}voidCVMJITdisableRendezvousCalls(CVMExecEnv* ee){   CVMJITdisableRendezvousCallsTrapbased(ee);}#endif/* * fixBranchesToBlock - store the proper branch offset in the branch * instructions that reference the specified ir block. This is * needed for forward branches. */static voidfixBranchesToBlock(CVMJITCompilationContext* con, CVMJITIRBlock* bk,		   CVMJITFixupElement* fixupList, CVMJITAddressMode addrMode){    CVMInt32 logicalTargetAddress = bk->logicalAddress;    CVMJITFixupElement* thisRef = fixupList;    while (thisRef != NULL) {	CVMJITFixupElement* nextRef = thisRef->next;	CVMJITfixupAddress(con, thisRef->logicalAddress, logicalTargetAddress,			   addrMode);	thisRef = nextRef;    }    }static voidallocateCodeBuffer(CVMJITCompilationContext* con);/* * CVMJITcompileGenerateCode: Main function for compiler back-end * responsible for generating platform specific machine code. By the time * this function is called the IR has already been generated. */#undef  MAX#define MAX(a,b) (((a) > (b)) ? (a) : (b))void CVMJITcompileGenerateCode(CVMJITCompilationContext* con){    CVMJITIRBlock* bk;    int		   maxStructSize;    int		   maxStructNumber;    int		   maxStateMachineAllocation;    int		   allocationSize;    CVMCPUPrologueRec prec;    CVMBool	   success = CVM_TRUE;        /*     * Allocate sufficient room for compile-time stacks.     * These are VERY generous.     */     maxStructSize = MAX(	sizeof(struct CVMJITCompileExpression_rule_computation_state),	sizeof(struct CVMJITCompileExpression_match_computation_state)    );    /* Estimate the max stack depth for the compilation stacks: */    maxStructNumber = (con->saveRootCnt + 1) * 3;    CVMJITstatsRecordSetCount(con, CVMJIT_STATS_COMPUTED_COMP_STACK_MAX,                              maxStructNumber);    maxStateMachineAllocation = maxStructSize * maxStructNumber;    allocationSize  = maxStateMachineAllocation +        sizeof(struct CVMJITStackElement) * maxStructNumber;    con->compilationStateStack = CVMJITmemNew(con, JIT_ALLOC_CGEN_OTHER,					      allocationSize);    con->cgstackInit = (struct CVMJITStackElement*)	((char*)(con->compilationStateStack) + maxStateMachineAllocation);    con->cgstackLimit = con->cgstackInit + maxStructNumber;    /*     * Initialize subsystems     */    CVMRMinit(con);    CVMSMinit(con);    allocateCodeBuffer(con);    /* Emit prologue and get patchable instruction state into prec */    CVMJITprintCodegenComment(("Method prologue"));    CVMCPUemitMethodPrologue(con, &prec);    CVMJITsetInit(con, &con->localRefSet);    /* Support for passing phis in registers.  Decide       the register assignments and store the result       in the USED nodes */    bk = (CVMJITIRBlock*)CVMJITirlistGetHead(&(con->bkList));    while ( bk != NULL){	if (CVMJITirblockIsTranslated(bk)) {	    if (bk->phiCount > 0) {		CVMRMallocatePhiRegisters(con, bk);	    }#ifdef CVM_JIT_REGISTER_LOCALS	    if (bk->incomingLocalsCount > 0) {		CVMassert(bk->phiCount <= 0);		CVMRMallocateIncomingLocalsRegisters(con, bk);	    }#endif	}	bk = CVMJITirblockGetNext(bk);    }    bk = (CVMJITIRBlock*)CVMJITirlistGetHead(&(con->bkList));    while ( bk != NULL){	CVMJITIRRoot* root =             (CVMJITIRRoot*)CVMJITirlistGetHead(CVMJITirblockGetRootList(bk));        CVMtraceJITCodegen(("%d:	L%d:\n",            CVMJITcbufGetLogicalPC(con), CVMJITirblockGetBlockID(bk)));	if (!CVMJITirblockIsTranslated(bk)) {	    CVMassert(root == NULL);	    CVMassert(bk->branchFixupList == NULL);	    CVMassert(bk->condBranchFixupList == NULL);	    CVMassert(bk->condBranchFixupList == NULL);	} else {	    con->currentCompilationBlock = bk;            /* NOTE: CVMRMbeginBlock() may need to emit some code for the               start of the block e.g. the GC rendezvous code.  Hence, we               should record the starting address of the block before calling               CVMRMbeginBlock().            */	    bk->flags |= CVMJITIRBLOCK_ADDRESS_FIXED;	    bk->logicalAddress = CVMJITcbufGetLogicalPC(con);	    fixBranchesToBlock(con, bk, bk->branchFixupList,			       CVMJIT_BRANCH_ADDRESS_MODE);	    fixBranchesToBlock(con, bk, bk->condBranchFixupList,			       CVMJIT_COND_BRANCH_ADDRESS_MODE);	    CVMRMbeginBlock(con, bk);	    while (root != NULL){    		int compilationResult;		con->cgsp = con->cgstackInit;#ifdef CVM_JIT_ENABLE_IR_CFG

⌨️ 快捷键说明

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