preloader.c

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

C
1,487
字号
/* * @(#)preloader.c	1.113 06/10/25 * * 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.  * */#include "javavm/include/defs.h"#include "javavm/include/objects.h"#include "javavm/include/classes.h"#include "javavm/include/typeid.h"#include "javavm/include/typeid_impl.h"#include "javavm/include/indirectmem.h"#include "javavm/include/interpreter.h"#include "javavm/include/preloader.h"#include "javavm/include/preloader_impl.h"#include "javavm/include/stackmaps.h"#include "javavm/include/utils.h"#include "javavm/include/clib.h"#include "javavm/include/string_impl.h"#include "generated/offsets/java_lang_String.h"#ifdef CVM_JIT#include "javavm/include/porting/jit/ccm.h"#endif#ifdef CVM_HW#include "include/hw.h"#endif#ifdef CVM_DEBUG_ASSERTSstatic voidCVMpreloaderVerifyGCMap(const CVMClassBlock* cb);static voidCVMpreloaderVerifyGCMaps();#endifextern const char *CVMROMClassLoaderNames;extern CVMAddr * const CVMROMClassLoaderRefs;extern const int CVMROMNumClassLoaders;const char *CVMpreloaderGetClassLoaderNames(CVMExecEnv *ee){    return CVMROMClassLoaderNames;}voidCVMpreloaderRegisterClassLoaderUnsafe(CVMExecEnv *ee, CVMInt32 index,    CVMClassLoaderICell *loader){    CVMInt32 clIndex = index * 2;    CVMInt32 pdIndex = clIndex + 1;    CVMObjectICell *refStatics = (CVMObjectICell *)CVMROMClassLoaderRefs;    CVMassert(index < CVMROMNumClassLoaders);    CVMID_icellAssignDirect(ee, &refStatics[clIndex], loader);    (void)pdIndex;}/* * Look up class by name. Only used from debuggers. */#ifdef CVM_DEBUGconst CVMClassBlock* CVMpreloaderLookup(const char* className){    CVMClassTypeID typeID = 	CVMtypeidLookupClassID(NULL, className, (int)strlen(className) );    if (typeID == CVM_TYPEID_ERROR) {	return NULL; /* not in type table, so don't bother looking. */    }    return CVMpreloaderLookupFromType(CVMgetEE(), typeID, NULL);}#endifstatic CVMClassBlock *CVMpreloaderLookupFromType0(CVMClassTypeID typeID){    CVMClassTypeID i, lowest, highbound;    /* No CVMFieldTypeIDs allowed. Upper bits must never be set. */    CVMassert(CVMtypeidGetType(typeID) == typeID);    if (CVMtypeidIsPrimitive(typeID)) {	/* NOTE: casting away const is safe here because we know that           run-time flags are separated from ROMized classblocks */	return (CVMClassBlock*) CVMterseTypeClassblocks[typeID];    }    /* NOTE: The Class instances of the Class and Array types in the       CVM_ROMClasses[] are sorted in incremental order of typeid values.  The       only exception is that deep array types (i.e. array types with depth >=       3) will be sorted based only on the basetype field of their typeids       (i.e. the depth field is ignored ... hence the masking operation in the       computation of the index for the deep array case below).  This is what       makes it possible to access Class instances for Class and Deep array       types in CVM_ROMClasses[] by indexing.        The sorted order looks like this:             .---------------------------------------.             |  Primtive classes                     |             |---------------------------------------|             |  Regular Loaded classes               | <= e1             |  e.g. java.lang.Object                |             |                                       |             |  Big Array classes                    |             |  i.e. depth exceeds or equals the     |             |  the value of CVMtypeArrayMask.       |             |             |---------------------------------------|             |  Single Dimension Array classes       | <= e2             |  e.g. [I or [Ljava.lang.Object;       |             |                                       | <= e3             |---------------------------------------|             |  Multi Dimension Array classes        |             |  e.g. [[I or [[Ljava.lang.Object; or  |             |       [[[I, etc.                      |             |                                       |             '---------------------------------------'                In the above illustration, entry e1 is the first entry in the       Regular Loaded classes section.  Entry e2 is the first entry in the       Single Dimension Array classes section, and entry e3 is the       last entry in this same section.       The Regular Loaded classes section currectly also holds the Big       Array classes whose dimension depth exceeds or equals the bits       in CVMtypeArrayMask (currently 3).  In the current implemetation       the Big Array classes always come at the end of this section after       the Regular Loaded classes.       CVM_firstNonPrimitiveClass to be the index of entry e1,       CVM_firstSingleDimensionArrayClass to be the index of entry e2, and       CVM_lastSingleDimensionArrayClass to be the index of entry e3.     */    if ( !CVMtypeidIsArray(typeID)) {	const CVMClassBlock * cb;	        /* If we get here, then we're looking for a normal class i.e. not           a primitive class and not an array class.           The index should be within the range of regular loaded (or           preloaded in this case) classes if its there: */	i = typeID-CVMtypeidLastScalar-1;        if ((i < CVM_firstROMNonPrimitiveClass) ||            (i >= CVM_firstROMSingleDimensionArrayClass)) {	    return NULL; /* not here! */	}	cb = CVM_ROMClassblocks[i];        CVMassert(cb == NULL || CVMcbClassName(cb) == typeID);	return (CVMClassBlock*)cb;    }    if (CVMtypeidIsBigArray(typeID)){        const CVMClassBlock * cb;        /* If we get here, then we're looking for a Big Array class.           The index should come before the first single dimension array           class if it's there: */        i = (typeID & CVMtypeidBasetypeMask)-CVMtypeidLastScalar-1;        if (i >= CVM_firstROMSingleDimensionArrayClass) {            return NULL; /* not here! */        }        cb = CVM_ROMClassblocks[i];        CVMassert(CVMcbClassName(cb) == typeID);        return (CVMClassBlock*)cb;    }    /*     * It is either a one-dimensional array or a higher-dimensional     * array. Choose the appropriate partition of the ROMClasses array     * and binary search for it.     */    if (CVMtypeidGetArrayDepth(typeID) == 1) {        /* If we get here, we are looking for a single dimension array class.           The index should be between the first and last single dimension           array class if its there: */        lowest = CVM_firstROMSingleDimensionArrayClass;        highbound= CVM_lastROMSingleDimensionArrayClass+1;    } else {        /* Else, we're looking for a multi-dimension (2 or more but less           than the BigArray depth which is currently 4) array class.           The index should be between the last single dimension           array class and the end of the list if its there: */        lowest = CVM_lastROMSingleDimensionArrayClass+1;	highbound= CVM_nROMClasses;    }    /* Do a binary search to see if the sought array class is there: */    while (lowest < highbound) {	const CVMClassBlock * cb;	int candidateID;	i = lowest + (highbound-lowest)/2;	cb = CVM_ROMClassblocks[i];	candidateID = CVMcbClassName(cb);        if (candidateID == typeID) return (CVMClassBlock*)cb;        if (candidateID < typeID) {            lowest = i+1;        } else {            highbound = i;        }    }    /*     * Fell out of while loop.     * not in table.     */    return NULL;}CVMClassBlock*CVMpreloaderLookupFromType(CVMExecEnv *ee,    CVMClassTypeID typeID, CVMClassLoaderICell *loader){    CVMBool match;    CVMClassBlock *cb = CVMpreloaderLookupFromType0(typeID);    if (cb == NULL) {	return cb;    }    CVMID_icellSameObjectNullCheck(ee, loader, CVMcbClassLoader(cb), match);    if (match) {	return cb;    }    return NULL;}/* * Only for lookup of primitive VM-defined types, by type name. */CVMClassBlock*CVMpreloaderLookupPrimitiveClassFromType(CVMClassTypeID classType){    int i;    const CVMClassBlock* cb;    i = classType-CVMtypeidLastScalar-1;    if ( (i < 0) || ( i >= CVM_firstROMNonPrimitiveClass) ){	return NULL; /* not here! */    }    cb = CVM_ROMClassblocks[i];    CVMassert( CVMcbClassName(cb) == classType );    return (CVMClassBlock*)cb;}#ifdef CVM_DEBUG_ASSERTSvoidCVMpreloaderCheckROMClassInitState(CVMExecEnv* ee){    int i;    for (i = 0; i < CVM_nROMClasses; ++i) {	const CVMClassBlock* cb = CVM_ROMClassblocks[i];	if (cb == NULL) {	    continue;	}	CVMassert(CVMcbIsInROM(cb));	CVMassert(CVMcbCheckRuntimeFlag(cb, LINKED));	CVMassert(CVMcbGetClinitEE(ee, cb) == NULL);	CVMassert(CVMcbHasStaticsOrClinit(cb)	    || CVMcbInitializationDoneFlag(ee, cb));	CVMassert(!CVMcbCheckErrorFlag(ee, cb));    }}#endif /* CVM_DEBUG_ASSERTS */#ifdef CVM_JITstatic voidsetJitInvoker(CVMMethodBlock* mb){    /* First check for CNI or JNI */    if (CVMmbIs(mb, NATIVE)) {	if (CVMmbInvokerIdx(mb) == CVM_INVOKE_CNI_METHOD) {	    CVMmbJitInvoker(mb) = (void*)CVMCCMinvokeCNIMethod;	} else {	    /* JNI method */	    CVMassert(CVMmbInvokerIdx(mb) == CVM_INVOKE_JNI_METHOD ||		      CVMmbInvokerIdx(mb) == CVM_INVOKE_JNI_SYNC_METHOD);	    CVMmbJitInvoker(mb) = (void*)CVMCCMinvokeJNIMethod;	}    } else {	CVMmbJitInvoker(mb) = (void*)CVMCCMletInterpreterDoInvoke;    }}#endifstatic voidunpack(CVMMethodBlockImmutable* mbImm,       CVMMethodBlockImmutableCompressed* mbComp){#define CVM_DO_MB_UNPACK_FROM_COMPRESSED(fieldName) \    mbImm->fieldName = mbComp->fieldName;#ifdef CVM_METHODBLOCK_HAS_CB    CVM_DO_MB_UNPACK_FROM_COMPRESSED(cbX);#endif    CVM_DO_MB_UNPACK_FROM_COMPRESSED(nameAndTypeIDX);    CVM_DO_MB_UNPACK_FROM_COMPRESSED(methodTableIndexX);    CVM_DO_MB_UNPACK_FROM_COMPRESSED(methodIndexX);    CVM_DO_MB_UNPACK_FROM_COMPRESSED(checkedExceptionsOffsetX);    CVM_DO_MB_UNPACK_FROM_COMPRESSED(codeX.jmd);    mbImm->argsSizeX = argsInvokerAccess[mbComp->entryIdxX * 3];    CVMprivateMbImmSetInvokerAndAccessFlags(mbImm,        argsInvokerAccess[mbComp->entryIdxX * 3 + 1],        argsInvokerAccess[mbComp->entryIdxX * 3 + 2]);}#ifdef CVM_DEBUG_ASSERTSCVMBoolCVMpreloaderReallyInROM(CVMObject* ref){    extern char * const CVM_CharacterX_data_start;    extern const  CVMUint32 CVM_CharacterX_data_size;    extern char * const CVM_CharacterY_data_start;    extern const  CVMUint32 CVM_CharacterY_data_size;    extern char * const CVM_CharacterA_data_start;    extern const  CVMUint32 CVM_CharacterA_data_size;#ifndef CDC_10    extern char * const CVM_CharacterLatinA_data_start;    extern const  CVMUint32 CVM_CharacterLatinA_data_size;    extern const char * const CVM_CharacterCharMap_data_start[];    extern const CVMUint32 CVM_CharacterCharMap_data_size[];    extern const CVMUint32 CVM_CharacterCharMap_number_of_elements;    int i;#endif    if (CVMpreloaderIsPreloadedObject(ref)) {	return CVM_TRUE;    }        if (((char*)ref >= CVM_CharacterX_data_start) &&	((char*)ref <  CVM_CharacterX_data_start + CVM_CharacterX_data_size))	return CVM_TRUE;        if (((char*)ref >= CVM_CharacterY_data_start) &&	((char*)ref <  CVM_CharacterY_data_start + CVM_CharacterY_data_size))	return CVM_TRUE;        if (((char*)ref >= CVM_CharacterA_data_start) &&	((char*)ref <  CVM_CharacterA_data_start + CVM_CharacterA_data_size))	return CVM_TRUE;#ifndef CDC_10    if (((char*)ref >= CVM_CharacterLatinA_data_start) &&	((char*)ref <  CVM_CharacterLatinA_data_start + CVM_CharacterLatinA_data_size))	return CVM_TRUE;    for (i = 0; i < CVM_CharacterCharMap_number_of_elements; i++) {       if (((char*)ref >= CVM_CharacterCharMap_data_start[i]) &&           ((char*)ref <  CVM_CharacterCharMap_data_start[i] + CVM_CharacterCharMap_data_size[i]))	   return CVM_TRUE;    }#endif

⌨️ 快捷键说明

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