jitemitter.c

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

C
548
字号
/* * @(#)jitemitter.c	1.5 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 CISC jit emitter porting layer. It * implements all of the conditonal instructions, and is meant to be * used by platforms that don't support conditional instructions other * than branches. This probably means every platform other than ARM * will use the versions of the conditional emitters in this file. */#include "javavm/include/defs.h"#include "javavm/include/globals.h"#include "javavm/include/ccee.h"#include "javavm/include/jit/jit.h"#include "javavm/include/jit/jitcontext.h"#include "javavm/include/jit/jitcodebuffer.h"#include "javavm/include/jit/jitcomments.h"#include "javavm/include/jit/jitirnode.h"/* SVMC_JIT d022609 (ML) 2004-02-23.   rename from `jitriscemitter.h'. */#include "javavm/include/jit/jitarchemitter.h"#include "javavm/include/jit/ccmcisc.h"/* Purpose: Patches prologue for the method */voidCVMCPUemitMethodProloguePatch(CVMJITCompilationContext *con,                              CVMCPUPrologueRec* rec){    CVMUint32 capacity;    CVMUint32 opstackOffset;    CVMUint32 boundsOffset;    CVMUint32 argsSize;    CVMUint32 spillAdjust;       /* 1. TOS adjustment. */    argsSize = CVMmbArgsSize(con->mb);    capacity = con->capacity + con->maxTempWords;    /*     * SVMC_JIT PJ 2004-04-22     *            tiny addition to this comment ...     * Instead of the TOS register, we are going to be using      * JSP - argSize << 2   (3 on 64 bit architectures)     */    boundsOffset = capacity - argsSize;    CVMJITcbufPushFixup(con, rec->capacityStartPC);    /* Emit adjustment of TOS by capacity: */    CVMJITprintCodegenComment(("Capacity is %d word(s)", capacity));    CVMCPUemitALUConstant16Scaled_fixed(con, CVMCPU_ADD_OPCODE, CVMCPU_ARG2_REG,					CVMCPU_JSP_REG, boundsOffset, 2);        /* Make sure we are not exceeding the reserved space for TOS adjust */    CVMassert(CVMJITcbufGetLogicalPC(con) <= rec->capacityEndPC);    CVMJITcbufPop(con);    /* 2. Spill adjustment. */    opstackOffset = CVMoffsetof(CVMCompiledFrame, opstackX);    spillAdjust = (con->maxTempWords << 2) + opstackOffset;    /* change pc to the spill adjustment instruction */    CVMJITcbufPushFixup(con, rec->spillStartPC);    /* Emit spill adjustment: */    CVMJITprintCodegenComment(("spillSize is %d word(s), add to JFP+%d",                               con->maxTempWords, opstackOffset));    CVMCPUemitALUConstant16Scaled_fixed(con, CVMCPU_ADD_OPCODE,					CVMCPU_JSP_REG, CVMCPU_JFP_REG,					spillAdjust, 0);    /* Make sure we are not exceeding the reserved space for spill adjust */    CVMassert(CVMJITcbufGetLogicalPC(con) <= rec->spillEndPC);#ifdef CVMCPU_HAS_CP_REG    {#ifdef CVM_DEBUG_ASSERTS        CVMInt32 cpLoadStartPC = CVMJITcbufGetLogicalPC(con);#endif        /* 3. Load Constant pool base register. */        CVMCPUemitLoadConstantPoolBaseRegister(con);#ifdef CVM_DEBUG_ASSERTS        /*          * We better have not over-written the bounds of the reserved space         * for the method prologue.         */        CVMassert(CVMJITcbufGetLogicalPC(con) - cpLoadStartPC <=            CVMCPU_RESERVED_CP_REG_INSTRUCTIONS * CVMCPU_INSTRUCTION_SIZE);#endif    }#endif    CVMJITcbufPop(con);}/* * For non-synchronized invocations, we can finish the work * in the prologue: * *    str MB, [JFP, #OFFSET_CVMFrame_mb] * * As well as emit all the tracing related stuff. */static voidemitRestOfSimpleInvocation(CVMJITCompilationContext* con,                            CVMBool needFlushPREV){    CVMUint32 prevOffset;    CVMUint32 mbOffset;    prevOffset = CVMoffsetof(CVMCompiledFrame, frameX.prevX);    mbOffset   = CVMoffsetof(CVMCompiledFrame, frameX.mb);    CVMJITaddCodegenComment((con, "Store MB into frame"));    CVMCPUemitMemoryReferenceImmediate(con, CVMCPU_STR32_OPCODE,                                       CVMCPU_ARG1_REG, /* mb */                                       CVMCPU_JFP_REG,                                       mbOffset);#ifdef CVM_DEBUG_ASSERTS    /*        mov  arg4, #CONSTANT_CVM_FRAMETYPE_NONE        strb arg4, [JFP, #OFFSET_CVMFrame_type]        mov  arg4, #-1        strb arg4, [JFP, #OFFSET_CVMFrame_flags]    */    {        CVMUint32 typeOffset = CVMoffsetof(CVMFrame, type);        CVMUint32 flagsOffset = CVMoffsetof(CVMFrame, flags);        CVMUint32 topOfStackOffset = CVMoffsetof(CVMFrame, topOfStack);        CVMJITprintCodegenComment(("DEBUG-ONLY CODE"));	/* SVMC_JIT PJ 2003-11-18	              small constant values are no longer loaded into registers,		      but rather used as immediate operands	*/        CVMJITaddCodegenComment((con, "Store NONE into frame.type"));        CVMCPUemitMemoryReferenceImmediateConst(con, CVMCPU_STR8_OPCODE,                                           CVM_FRAMETYPE_NONE, /* NONE */                                           CVMCPU_JFP_REG,                                           typeOffset);        CVMJITaddCodegenComment((con, "Store -1 into frame.flags"));        CVMCPUemitMemoryReferenceImmediateConst(con, CVMCPU_STR8_OPCODE,						0xff /* -1 (must be a byte) */,                                           CVMCPU_JFP_REG,                                           flagsOffset);        CVMJITaddCodegenComment((con, "Store NULL into frame.topOfStack"));        CVMCPUemitMemoryReferenceImmediateConst(con, CVMCPU_STR32_OPCODE,                                           ( int ) NULL, /* NONE */                                           CVMCPU_JFP_REG,                                           topOfStackOffset);        CVMJITprintCodegenComment(("END OF DEBUG-ONLY CODE"));    }#endif    /*     * If we couldn't go the short route of  eliminating the use of PREV,     * we need to flush PREV to the new frame.     */    if (needFlushPREV) {        CVMJITaddCodegenComment((con, "Store curr JFP into new frame"));        CVMCPUemitMemoryReferenceImmediate(con, CVMCPU_STR32_OPCODE,                                           CVMCPU_PROLOGUE_PREVFRAME_REG,                                           CVMCPU_JFP_REG,                                           prevOffset);    }#if 0 /* TODO(rr): enable! */#ifdef CVM_TRACE    {        CVMJITprintCodegenComment(("DEBUG-ONLY CODE FOR TRACING METHOD CALLS"));#ifdef CVMCPU_EE_REG	CVMCPUemitMoveRegister(con, CVMCPU_MOV_OPCODE,			       CVMCPU_ARG1_REG, CVMCPU_EE_REG, CVMJIT_NOSETCC);#else	{	    CVMJITaddCodegenComment((con, "arg1 = ccee->ee"));	    CVMCPUemitCCEEReferenceImmediate(con, CVMCPU_LDR32_OPCODE,		CVMCPU_ARG1_REG, CVMoffsetof(CVMCCExecEnv, eeX));	}#endif        /* MOV arg2, JFP */        CVMJITaddCodegenComment((con, "arg2 = JFP"));        CVMCPUemitMoveRegister(con, CVMCPU_MOV_OPCODE,                               CVMCPU_ARG2_REG, CVMCPU_JFP_REG,                               CVMJIT_NOSETCC);        CVMJITaddCodegenComment((con, "CVMCCMtraceMethodCallGlue()"));        CVMCPUemitAbsoluteCall_GlueCode(con, (void*)CVMCCMtraceMethodCallGlue,                               CVMJIT_NOCPDUMP, CVMJIT_NOCPBRANCH);        CVMJITprintCodegenComment(("END OF DEBUG-ONLY CODE FOR TRACING"));    }#endif#endif /* 0 */}/* Purpose: Emits the prologue code for the compiled method. */voidCVMCPUemitMethodPrologue(CVMJITCompilationContext *con,                         CVMCPUPrologueRec* rec){    CVMInt32 spillPC, prologueStart;    CVMUint32 argsSize, spillAdjust;    CVMUint8* startPC;    CVMMethodBlock* mb;    void*  invokerFunc;    const char *invokerName;    const char *jfpStr;    int jfpReg;    CVMBool simpleInvoke;    CVMBool needFlushPREV = CVM_FALSE;    CVMUint32 prevOffset;    CVMUint32 jspOffset; /* The offset off of JSP to compute the new JFP */    prevOffset = CVMoffsetof(CVMCompiledFrame, frameX.prevX);    mb = con->mb;    argsSize = CVMmbArgsSize(mb);    startPC  = con->codeEntry;    /* Add jspOffset * 4 ( 8 on 64 bit architectures ) to JSP to get the new JFP */    jspOffset = con->numberLocalWords - argsSize;    prologueStart = CVMJITcbufGetLogicalPC(con);    CVMJITaddCodegenComment((con, "Set ARG2 = JSP + (capacity - argsSize) * 4"));    /* Record the start logicalPC for TOS adjustment by capacity */    rec->capacityStartPC = CVMJITcbufGetLogicalPC(con);    /* This is an estimate. Will be patched by method prologue patch      * (SW): The CVMCPU_ARG2_REG register set here is checked by the      * CVMCPUemitStackLimitCheckAndStoreReturnAddr function. */    CVMCPUemitALUConstant16Scaled_fixed(con, CVMCPU_ADD_OPCODE, CVMCPU_ARG2_REG, 					CVMCPU_JSP_REG,con->capacity + 					con->maxTempWords - argsSize, 2);    /* Record end logicalPC after estimate */    rec->capacityEndPC = CVMJITcbufGetLogicalPC(con);    /* Emit what used to be INVOKER_PROLOGUE */    CVMCPUemitStackLimitCheckAndStoreReturnAddr(con);    /* Now do appropriate set-up for this mb */    if (CVMmbIs(mb, SYNCHRONIZED)) {        /* SVMC_JIT PJ 2004-04-22                      cast function pointers in order to avoid                      compiler warnings

⌨️ 快捷键说明

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