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