jitcompile.c

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

C
1,252
字号
/* * @(#)jitcompile.c	1.148 06/10/13 * * 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. *//* * Copyright 2005 Intel Corporation. All rights reserved.   */#include "javavm/include/defs.h"#include "javavm/include/objects.h"#include "javavm/include/classes.h"#include "javavm/include/interpreter.h"#include "javavm/include/directmem.h"#include "javavm/include/utils.h"#include "javavm/include/bcutils.h"#include "javavm/include/ccee.h"#include "javavm/include/jit/jit.h"#include "javavm/include/jit/jitir.h"#include "javavm/include/jit/jitcontext.h"#include "javavm/include/jit/jitdebug.h"#include "javavm/include/jit/jitutils.h"#include "javavm/include/jit/jitmemory.h"#include "javavm/include/jit/jitirnode.h"#include "javavm/include/jit/jitirblock.h"#include "javavm/include/jit/jitcodebuffer.h"#include "javavm/include/jit/jitstackmap.h"#include "javavm/include/jit/jitstats.h"#include "javavm/include/jit/jitasmconstants.h"#include "javavm/include/porting/jit/ccm.h"#include "javavm/include/porting/jit/jit.h"#include "javavm/include/clib.h"#include "javavm/include/porting/ansi/setjmp.h"#if defined(CVM_JIT_COLLECT_STATS) || \    defined(CVM_JIT_ESTIMATE_COMPILATION_SPEED)#include "javavm/include/porting/doubleword.h"#include "javavm/include/porting/time.h"#endif#ifdef CVM_DEBUG_ASSERTS#include "generated/offsets/java_lang_String.h"#endif#define CVMJIT_MIN_MAX_LOCAL_WORDS	300#define CVMJIT_MIN_MAX_CAPACITY		500/* * Mark the method as bad. */static CVMBoolbadMethod(CVMExecEnv *ee, CVMMethodBlock* mb){    CVMBool success = CVM_TRUE;    /* Mark method as bad */    CVM_COMPILEFLAGS_LOCK(ee);    if (CVMmbIsCompiled(mb)) {	success = CVM_FALSE;    } else {	CVMmbCompileFlags(mb) |= CVMJIT_NOT_COMPILABLE;    }    CVM_COMPILEFLAGS_UNLOCK(ee);    return success;}static CVMBoolisBadMethod(CVMExecEnv *ee, CVMMethodBlock *mb){    CVMBool bad = CVM_FALSE;    if (!CVMmbIsCompiled(mb)) {        /* If already not compilable: */	if ((CVMmbCompileFlags(mb) & CVMJIT_NOT_COMPILABLE) != 0) {	    bad = CVM_TRUE;        /* Reject the method if it is a <clinit>(): */        } else if (CVMtypeidIsStaticInitializer(CVMmbNameAndTypeID(mb))) {            /* Mark method as not compilable: */            CVM_COMPILEFLAGS_LOCK(ee);            CVMmbCompileFlags(mb) |= CVMJIT_NOT_COMPILABLE;            CVM_COMPILEFLAGS_UNLOCK(ee);            bad = CVM_TRUE;#ifdef CVM_JIT_DEBUG        } else if (!CVMJITdebugMethodIsToBeCompiled(ee, mb)) {	    /* TODO: add option to allow if caller frame is compiled	       (transitive closure) */            /* Mark method as not compilable: */            CVM_COMPILEFLAGS_LOCK(ee);            CVMmbCompileFlags(mb) |= CVMJIT_NOT_COMPILABLE;            CVM_COMPILEFLAGS_UNLOCK(ee);            bad = CVM_TRUE;#endif /* CVM_JIT_DEBUG */        }    }    return bad;}#ifdef CVM_DEBUG_ASSERTS/* Purpose: Assert some assumptions made in the implementation of the JIT. */void CVMJITassertMiscJITAssumptions(void){    /* The following are sanity checks for the JIT system in general that       does not have anything to do with the current context of compilation.       These assertions can be called from anywhere with the same result.       NOTE: Each of these assertions corresponds to a constant or offset       value defined in jitasmconstants.h.    */    /* Verifying CVMClassBlock offsets: */    CVMassert(OFFSET_CVMClassBlock_classNameX ==	      offsetof(CVMClassBlock, classNameX));    CVMassert(OFFSET_CVMClassBlock_superClassCb ==	      offsetof(CVMClassBlock, superclassX.superclassCb));    CVMassert(OFFSET_CVMClassBlock_interfacesX ==	      offsetof(CVMClassBlock, interfacesX));    CVMassert(OFFSET_CVMClassBlock_arrayInfoX ==	      offsetof(CVMClassBlock, cpX.arrayInfoX));    CVMassert(OFFSET_CVMClassBlock_accessFlagsX ==	      offsetof(CVMClassBlock, accessFlagsX));    CVMassert(OFFSET_CVMClassBlock_instanceSizeX ==	      offsetof(CVMClassBlock, instanceSizeX));    CVMassert(OFFSET_CVMClassBlock_javaInstanceX ==	      offsetof(CVMClassBlock, javaInstanceX));    CVMassert(OFFSET_CVMClassBlock_methodTablePtrX ==	      offsetof(CVMClassBlock, methodTablePtrX));        /* Verifying CVMArrayInfo offsets and constants: */    CVMassert(OFFSET_CVMArrayInfo_elementCb ==	      offsetof(CVMArrayInfo, elementCb));    /* Offsets and constants for CVMTypeID */    CVMassert(CONSTANT_CVMtypeidArrayShift == CONSTANT_CVMtypeidArrayShift);    CVMassert(CONSTANT_CVMtypeidArrayMask == CONSTANT_CVMtypeidArrayMask);    CVMassert(CONSTANT_CVM_TYPEID_INT_ARRAY ==	      CVMtypeidEncodeBasicPrimitiveArrayType(CVM_TYPEID_INT));    CVMassert(CONSTANT_CVM_TYPEID_SHORT_ARRAY ==	      CVMtypeidEncodeBasicPrimitiveArrayType(CVM_TYPEID_SHORT));    CVMassert(CONSTANT_CVM_TYPEID_CHAR_ARRAY ==	      CVMtypeidEncodeBasicPrimitiveArrayType(CVM_TYPEID_CHAR));    CVMassert(CONSTANT_CVM_TYPEID_LONG_ARRAY ==	      CVMtypeidEncodeBasicPrimitiveArrayType(CVM_TYPEID_LONG));    CVMassert(CONSTANT_CVM_TYPEID_BYTE_ARRAY ==	      CVMtypeidEncodeBasicPrimitiveArrayType(CVM_TYPEID_BYTE));    CVMassert(CONSTANT_CVM_TYPEID_FLOAT_ARRAY ==	      CVMtypeidEncodeBasicPrimitiveArrayType(CVM_TYPEID_FLOAT));    CVMassert(CONSTANT_CVM_TYPEID_DOUBLE_ARRAY ==	      CVMtypeidEncodeBasicPrimitiveArrayType(CVM_TYPEID_DOUBLE));    CVMassert(CONSTANT_CVM_TYPEID_BOOLEAN_ARRAY ==	      CVMtypeidEncodeBasicPrimitiveArrayType(CVM_TYPEID_BOOLEAN));    /* Verifying CVMMethodBlock offsets and constants: */#ifdef CVM_METHODBLOCK_HAS_CB    CVMassert(OFFSET_CVMMethodBlock_cbX ==	      offsetof(CVMMethodBlock, immutX.cbX));#endif    CVMassert(OFFSET_CVMMethodBlock_jitInvokerX ==	      offsetof(CVMMethodBlock, jitInvokerX));    CVMassert(OFFSET_CVMMethodBlock_methodTableIndexX ==	      offsetof(CVMMethodBlock, immutX.methodTableIndexX));    CVMassert(OFFSET_CVMMethodBlock_argsSizeX ==	      offsetof(CVMMethodBlock, immutX.argsSizeX));    CVMassert(OFFSET_CVMMethodBlock_methodIndexX ==	      offsetof(CVMMethodBlock, immutX.methodIndexX));    CVMassert(OFFSET_CVMMethodBlock_invokerAndAccessFlagsX ==	      offsetof(CVMMethodBlock, immutX.invokerAndAccessFlagsX));    CVMassert(OFFSET_CVMMethodBlock_codeX ==	      offsetof(CVMMethodBlock, immutX.codeX));    CVMassert(CONSTANT_CVMMethodBlock_size == sizeof(CVMMethodBlock));    /* Verifying CVMMethodRange offsets and constants: */    CVMassert(OFFSET_CVMMethodRange_mb ==	      offsetof(CVMMethodRange, mb));    /* Verifying CVMJavaMethodDescriptor offsets and constants: */    CVMassert(OFFSET_CVMJmd_maxLocalsX ==	      offsetof(CVMJavaMethodDescriptor, maxLocalsX));    /* Verifying CVMCompiledFrame offsets and constants: */    CVMassert(OFFSET_CVMCompiledFrame_PC == offsetof(CVMCompiledFrame, pcX));    CVMassert(OFFSET_CVMCompiledFrame_receiverObjX ==	      offsetof(CVMCompiledFrame, receiverObjX));#ifdef CVMCPU_HAS_CP_REG    CVMassert(OFFSET_CVMCompiledFrame_cpBaseRegX ==	      offsetof(CVMCompiledFrame, cpBaseRegX));#endif    CVMassert(OFFSET_CVMCompiledFrame_opstackX ==	      offsetof(CVMCompiledFrame, opstackX));    /* Verifying CVMFrame offsets and constants: */    CVMassert(OFFSET_CVMFrame_prevX == offsetof(CVMFrame, prevX));    CVMassert(OFFSET_CVMFrame_type == offsetof(CVMFrame, type));    CVMassert(OFFSET_CVMFrame_flags == offsetof(CVMFrame, flags));    CVMassert(OFFSET_CVMFrame_topOfStack == offsetof(CVMFrame, topOfStack));    CVMassert(OFFSET_CVMFrame_mb == offsetof(CVMFrame, mb));    /* Verifying CVMExecEnv offsets and constants: */    CVMassert(OFFSET_CVMExecEnv_tcstate_GCSAFE ==	      offsetof(CVMExecEnv, tcstate[CVM_GC_SAFE]));    CVMassert(OFFSET_CVMExecEnv_interpreterStack ==	      offsetof(CVMExecEnv, interpreterStack));    CVMassert(OFFSET_CVMExecEnv_miscICell ==	      offsetof(CVMExecEnv, miscICell));    CVMassert(OFFSET_CVMExecEnv_objLocksOwned ==	      offsetof(CVMExecEnv, objLocksOwned));    CVMassert(OFFSET_CVMExecEnv_objLocksFreeOwned ==	      offsetof(CVMExecEnv, objLocksFreeOwned));    CVMassert(OFFSET_CVMExecEnv_invokeMb ==	      offsetof(CVMExecEnv, invokeMb));    /* Verifying CVMInterfaceTable offsets and constants: */    CVMassert((1 << CONSTANT_LOG2_CVMInterfaceTable_SIZE) ==	      sizeof(CVMInterfaceTable));    CVMassert((1 << CONSTANT_LOG2_CVMInterfaceTable_methodTableIndex_SIZE) ==	      sizeof(*CVMcbInterfaceMethodTableIndices(                        CVMsystemClass(java_lang_Class), 0)));    /* Verifying CVMInterfaces offsets and constants: */    CVMassert(OFFSET_CVMInterfaces_interfaceCountX == 	      offsetof(CVMInterfaces, interfaceCountX));    CVMassert(OFFSET_CVMInterfaces_itable ==	      offsetof(CVMInterfaces, itable));    CVMassert(OFFSET_CVMInterfaces_itable0_intfInfoX ==	      offsetof(CVMInterfaces, itable[0].intfInfoX));    /* Verifying CVMStack offsets and constants: */    CVMassert(OFFSET_CVMStack_currentFrame ==	      offsetof(CVMStack, currentFrame));    CVMassert(OFFSET_CVMStack_stackChunkEnd ==	      offsetof(CVMStack, stackChunkEnd));    /* Verifying CVMCCExecEnv offsets and constants: */    CVMassert(OFFSET_CVMCCExecEnv_ee ==	      offsetof(CVMCCExecEnv, eeX));    CVMassert(OFFSET_CVMCCExecEnv_stackChunkEnd ==	      offsetof(CVMCCExecEnv, stackChunkEndX));#ifndef CVM_JIT_COPY_CCMCODE_TO_CODECACHE    CVMassert(OFFSET_CVMCCExecEnv_ccmGCRendezvousGlue ==	      offsetof(CVMCCExecEnv, ccmGCRendezvousGlue));#endif#if defined(CVMJIT_TRAP_BASED_GC_CHECKS) && defined(CVMCPU_HAS_VOLATILE_GC_REG)    CVMassert(OFFSET_CVMCCExecEnv_gcTrapAddr ==	      offsetof(CVMCCExecEnv, gcTrapAddr));#endif    CVMassert(OFFSET_CVMCCExecEnv_ccmStorage ==	      offsetof(CVMCCExecEnv, ccmStorage));    CVMassert(CONSTANT_CVMCCExecEnv_size ==	      (size_t)(((CVMCCExecEnv *)0) + 1));    /* Verifying CVMGlobalState offsets and constants: */    CVMassert(OFFSET_CVMGlobalState_allocPtrPtr ==	      offsetof(CVMGlobalState, allocPtrPtr));    CVMassert(OFFSET_CVMGlobalState_allocTopPtr ==	      offsetof(CVMGlobalState, allocTopPtr));#ifdef CVM_ADV_ATOMIC_SWAP    CVMassert(OFFSET_CVMGlobalState_fastHeapLock ==	      offsetof(CVMGlobalState, fastHeapLock));#endif#ifdef CVM_TRACE_ENABLED    CVMassert(OFFSET_CVMGlobalState_debugFlags ==	      offsetof(CVMGlobalState, debugFlags));#endif#ifdef CVM_TRACE_JIT    CVMassert(OFFSET_CVMGlobalState_debugJITFlags ==	      offsetof(CVMGlobalState, debugJITFlags));#endif    CVMassert(OFFSET_CVMGlobalState_cstate_GCSAFE ==	      offsetof(CVMGlobalState, cstate));    /* Verifying CVMCState offsets and constants: */    CVMassert(OFFSET_CVMCState_request == offsetof(CVMCState, request));    /* Verifying CVMObjectHeader offsets and constants: */    CVMassert(OFFSET_CVMObjectHeader_clas ==	      offsetof(CVMObjectHeader, clas));    CVMassert(OFFSET_CVMObjectHeader_various32 ==	      offsetof(CVMObjectHeader, various32));    /* Verifying CVMOwnedMonitor offsets and constants: */    CVMassert(CONSTANT_CVM_OBJECT_NO_HASH == CVM_OBJECT_NO_HASH);    CVMassert(CONSTANT_CVM_SYNC_BITS == CVM_SYNC_BITS);    CVMassert(CONSTANT_CVM_HASH_BITS == CVM_HASH_BITS);    CVMassert(CONSTANT_CVM_HASH_MASK == CVM_HASH_MASK);    CVMassert(OFFSET_CVMObjMonitor_bits == offsetof(CVMObjMonitor, bits));    CVMassert(OFFSET_CVMOwnedMonitor_owner ==	      offsetof(CVMOwnedMonitor, owner));    CVMassert(OFFSET_CVMOwnedMonitor_type ==	      offsetof(CVMOwnedMonitor, type));    CVMassert(OFFSET_CVMOwnedMonitor_object ==	      offsetof(CVMOwnedMonitor, object));    CVMassert(OFFSET_CVMOwnedMonitor_u_fast_bits ==	      offsetof(CVMOwnedMonitor, u.fast.bits));    CVMassert(OFFSET_CVMOwnedMonitor_next ==	      offsetof(CVMOwnedMonitor, next));#if CVM_FASTLOCK_TYPE != CVM_FASTLOCK_NONE    CVMassert(OFFSET_CVMOwnedMonitor_count ==	      offsetof(CVMOwnedMonitor, count));#endif#ifdef CVM_DEBUG    CVMassert(OFFSET_CVMOwnedMonitor_magic ==	      offsetof(CVMOwnedMonitor, magic));    CVMassert(OFFSET_CVMOwnedMonitor_state ==	      offsetof(CVMOwnedMonitor, state));    CVMassert(CONSTANT_CVM_OWNEDMON_FREE == CVM_OWNEDMON_FREE);    CVMassert(CONSTANT_CVM_OWNEDMON_OWNED == CVM_OWNEDMON_OWNED);#endif    CVMassert(CONSTANT_CVM_LOCKSTATE_UNLOCKED == CVM_LOCKSTATE_UNLOCKED);    CVMassert(CONSTANT_CVM_LOCKSTATE_LOCKED == CVM_LOCKSTATE_LOCKED);    CVMassert(CONSTANT_CVM_INVALID_REENTRY_COUNT == CVM_INVALID_REENTRY_COUNT);        CVMassert(CONSTANT_CLASS_ACC_FINALIZABLE == CVM_CLASS_ACC_FINALIZABLE);    CVMassert(CONSTANT_METHOD_ACC_STATIC == CVM_METHOD_ACC_STATIC);    CVMassert(CONSTANT_METHOD_ACC_SYNCHRONIZED == CVM_METHOD_ACC_SYNCHRONIZED);    CVMassert(CONSTANT_METHOD_ACC_NATIVE == CVM_METHOD_ACC_NATIVE);    CVMassert(CONSTANT_METHOD_ACC_ABSTRACT == CVM_METHOD_ACC_ABSTRACT);    CVMassert(CONSTANT_INVOKE_CNI_METHOD == CVM_INVOKE_CNI_METHOD);    CVMassert(CONSTANT_INVOKE_JNI_METHOD == CVM_INVOKE_JNI_METHOD);    CVMassert(CONSTANT_CNI_NEW_TRANSITION_FRAME == CNI_NEW_TRANSITION_FRAME);    CVMassert(CONSTANT_CNI_NEW_MB == CNI_NEW_MB);    CVMassert(CONSTANT_CMD_SIZE ==	      (size_t)(((CVMCompiledMethodDescriptor *)0) + 1));    CVMassert(CONSTANT_TRACE_METHOD == sun_misc_CVM_DEBUGFLAG_TRACE_METHOD);        CVMassert(CONSTANT_CVM_FRAME_MASK_SPECIAL == CVM_FRAME_MASK_SPECIAL);    CVMassert(CONSTANT_CVM_FRAME_MASK_SLOW == CVM_FRAME_MASK_SLOW);    CVMassert(CONSTANT_CVM_FRAME_MASK_ALL == CVM_FRAME_MASK_ALL);#ifdef CVM_DEBUG_ASSERTS    CVMassert(CONSTANT_CVM_FRAMETYPE_NONE == CVM_FRAMETYPE_NONE);#endif    CVMassert(CONSTANT_CVM_FRAMETYPE_COMPILED == CVM_FRAMETYPE_COMPILED);    /* Offsets and constants for the java.lang.String class: */    CVMassert(OFFSET_java_lang_String_value ==              CVMoffsetOfjava_lang_String_value * sizeof(CVMUint32));    CVMassert(OFFSET_java_lang_String_offset ==              CVMoffsetOfjava_lang_String_offset * sizeof(CVMUint32));    CVMassert(OFFSET_java_lang_String_count ==              CVMoffsetOfjava_lang_String_count * sizeof(CVMUint32));    /* Offset and constants for Array classes: */    CVMassert(OFFSET_ARRAY_LENGTH == offsetof(CVMArrayOfAnyType, length));    CVMassert(OFFSET_ARRAY_ELEMENTS == offsetof(CVMArrayOfAnyType, elems));    /* Offset and constants for GC: */#if (CVM_GCCHOICE == CVM_GC_GENERATIONAL) && !defined(CVM_SEGMENTED_HEAP)    CVMassert(CONSTANT_CARD_DIRTY_BYTE == CARD_DIRTY_BYTE);    CVMassert(CONSTANT_CVM_GENGC_CARD_SHIFT == CVM_GENGC_CARD_SHIFT);    CVMassert(CONSTANT_NUM_BYTES_PER_CARD == NUM_BYTES_PER_CARD);#endif    /* We only have 8 bits for the encoding of the CVMJITIROpcodeTag: */    CVMassert(CVMJIT_TOTAL_IR_OPCODE_TAGS <= 256);        /* We only have 4 bits for the encoding of the CVMJITIRNodeTag: */    CVMassert(CVMJIT_TOTAL_IR_NODE_TAGS <= 16);    /* The following nodes should be polymorphic with respect to       CVMJITBinaryOp:                CVMJITConditionalBranch    */    CVMassert(offsetof(CVMJITConditionalBranch, rhs) ==	      offsetof(CVMJITBinaryOp, rhs));    /* The following nodes should be polymorphic with respect to       CVMJITGenericSubNode:                CVMJITDefineOp                CVMJITTableSwitch                CVMJITLookupSwitch                CVMJITConditionalBranch                CVMJITBinaryOp                CVMJITUnaryOp    */    CVMassert(offsetof(CVMJITDefineOp, operand) ==	      offsetof(CVMJITGenericSubNode, firstOperand));    CVMassert(offsetof(CVMJITTableSwitch, key) ==	      offsetof(CVMJITGenericSubNode, firstOperand));    CVMassert(offsetof(CVMJITLookupSwitch, key) ==	      offsetof(CVMJITGenericSubNode, firstOperand));    CVMassert(offsetof(CVMJITConditionalBranch, lhs) ==	      offsetof(CVMJITGenericSubNode, firstOperand));    CVMassert(offsetof(CVMJITBinaryOp, lhs) ==	      offsetof(CVMJITGenericSubNode, firstOperand));

⌨️ 快捷键说明

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