jvmtidumper.c

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

C
1,612
字号
/* * @(#)jvmtiDumper.c	1.0 07/01/16 * * 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.  * *//* * This file is derived from the original CVM jvmpi.c file.	 In addition * the 'jvmti' components of this file are derived from the J2SE * jvmtiEnv.cpp class.	The primary purpose of this file is to  * instantiate the JVMTI API to external libraries. */ #include "javavm/include/porting/ansi/stdarg.h"#include "javavm/include/defs.h"#include "javavm/include/indirectmem.h"#include "javavm/include/globalroots.h"#include "javavm/include/localroots.h"#include "javavm/include/interpreter.h"#include "javavm/include/basictypes.h"#include "javavm/include/signature.h"#include "javavm/include/globals.h"#include "javavm/include/stackmaps.h"#include "javavm/include/bag.h"#include "javavm/include/porting/time.h"#include "javavm/include/path_md.h"#include "javavm/include/common_exceptions.h"#include "javavm/include/named_sys_monitor.h"#include "javavm/include/opcodes.h"#include "generated/offsets/java_lang_String.h"#include "javavm/export/jvm.h"#include "javavm/export/jni.h"#include "javavm/export/jvmti.h"#include "javavm/include/jvmti_jni.h"#include "javavm/include/jvmtiEnv.h"#include "javavm/include/jvmtiDumper.h"#include "javavm/include/jvmtiCapabilities.h"/* * Object type constants. */#define JVMTI_NORMAL_OBJECT	         ((jint)0)#define JVMTI_CLASS		         ((jint)2)#define JVMTI_BOOLEAN	                 ((jint)4)#define JVMTI_CHAR                       ((jint)5)#define JVMTI_FLOAT                      ((jint)6)#define JVMTI_DOUBLE                     ((jint)7)#define JVMTI_BYTE                       ((jint)8)#define JVMTI_SHORT                      ((jint)9)#define JVMTI_INT                        ((jint)10)#define JVMTI_LONG                       ((jint)11)    #define NUM_ENTRIES 20static voidcbProcessed(CVMInt32 *curBlk, CVMInt32 *pMax,           CVMClassBlock ***processed, const CVMClassBlock *cb){    CVMClassBlock **tmpP;    if (*curBlk == *pMax) {        if (CVMjvmtiAllocate(sizeof(CVMClassBlock*)*(*pMax + NUM_ENTRIES),                             (unsigned char **)&tmpP) == JVMTI_ERROR_NONE) {            memcpy(tmpP, *processed, *pMax * sizeof(CVMClassBlock*));            CVMjvmtiDeallocate((unsigned char*)processed);            *processed = tmpP;            *pMax += NUM_ENTRIES;        } else {            /* out of memory, we'll just process this cb again which may             * cause the agent some grief but that's the best we can             * do at this point.  This should never happen in real life.             */            return;        }    }    (*processed)[(*curBlk)++] = (CVMClassBlock *)cb;}static CVMBoolcheckProcessed(CVMInt32 *curBlk, CVMClassBlock ***processed,           CVMClassBlock *iCb){    int j;    for (j = 0; j < *curBlk; j++) {        if (iCb == (*processed)[j]) {            return CVM_TRUE;        }    }    return CVM_FALSE;}/* Search through all implemented interfaces (and super interfaces) * as well as super classes to determine the starting index of  * fields *in this class*.  Note that when dumping an instance we dump * all the super classes fields first so we don't include super classes * in this calculation.  When dumping a Class, which includes * the statics of that class, we don't dump all super class statics * so we must count super class fields in this calculation * For all the gory details see this reference in the JVMTI spec * http://java.sun.com/javase/6/docs/platform/jvmti/jvmti.html#jvmtiHeapReferenceInfoField */static CVMInt32jvmtiFindFieldStartingIndex_X(const CVMClassBlock* fieldCb, int index,			    CVMBool isStatic,			    CVMClassBlock ***processed, 			    CVMInt32 *curBlk, CVMInt32 *pMax){    CVMClassBlock* iCb;    int i;    /* C stack redzone check */    if (!CVMCstackCheckSize(CVMgetEE(),            CVM_REDZONE_CVMcpFindFieldInSuperInterfaces,            "CVMcpFindFieldInSuperInterfaces", CVM_FALSE)) {        return 0;    }    /* count direct interfaces */    for (i = 0; i < CVMcbImplementsCount(fieldCb); i++) {        iCb = CVMcbInterfacecb(fieldCb, i);        if (checkProcessed(curBlk, processed, iCb)) {            /* already processed this interface, so skip it */            continue;        }	/* count superinterfaces */	index = jvmtiFindFieldStartingIndex_X(iCb, index, isStatic, processed,					    curBlk, pMax);	index += CVMcbFieldCount(iCb);        cbProcessed(curBlk, pMax, processed, iCb);    }    if (!CVMcbIs(fieldCb, INTERFACE) && CVMcbSuperclass(fieldCb) != NULL) {        /* count direct superclasses */	index = jvmtiFindFieldStartingIndex_X(CVMcbSuperclass(fieldCb), index,					    isStatic, processed,					    curBlk, pMax);	if (isStatic) {            /* Dumping a Class so we need to count fields to get the             * proper starting index.             */	    index += CVMcbFieldCount(CVMcbSuperclass(fieldCb));	}    }    return index;}static CVMInt32jvmtiFindFieldStartingIndex(const CVMClassBlock* fieldCb, int index,			    CVMBool isStatic){    CVMInt32 _pMax, _curBlk;    CVMClassBlock **_processed;    CVMInt32 retVal;    if (CVMjvmtiAllocate(sizeof(CVMClassBlock*) * NUM_ENTRIES,			 (unsigned char **)&_processed) != JVMTI_ERROR_NONE) {	return 0;    }    _pMax = NUM_ENTRIES;    _curBlk = 0;    retVal = jvmtiFindFieldStartingIndex_X(fieldCb, index, isStatic,					   &_processed, &_curBlk, &_pMax);    CVMjvmtiDeallocate((unsigned char*)_processed);    return retVal;}#define HASH_WITH_CB_BITS(cb, hash) \    ((hash) |								\     ((((CVMAddr)(cb) & ~0xf)<<(CVM_HASH_BITS - 4)) ^ ((hash)<<CVM_HASH_BITS)))/* An 'inline' version of CVMobjectSetHashBitsIfNeeded without any * GC safety checks/transitions/locking. Threads are suspended and all GC * locks are held. */static CVMInt32jvmtiObjectGetHash(CVMExecEnv *ee, CVMObject* obj){    CVMAddr bits;    CVMInt32 hashValue;    CVMassert(CVMjvmtiIsGCOwner());    do {	hashValue = CVMrandomNext();	hashValue &= CVM_OBJECT_HASH_MASK;    } while (hashValue == CVM_OBJECT_NO_HASH);    bits = obj->hdr.various32;    if (CVMhdrBitsSync(bits) == CVM_LOCKSTATE_MONITOR) {        CVMObjMonitor *mon = CVMobjMonitor(obj);        {            CVMUint32 h = CVMhdrBitsHashCode(mon->bits);            if (h == CVM_OBJECT_NO_HASH) {                CVMhdrSetHashCode(mon->bits, hashValue);            } else {                hashValue = h;            }        }    } else {#if CVM_FASTLOCK_TYPE != CVM_FASTLOCK_NONE        CVMAddr obits;        obits = obj->hdr.various32;        if (CVMhdrBitsSync(obits) == CVM_LOCKSTATE_LOCKED) {            CVMOwnedMonitor *o = (CVMOwnedMonitor *)CVMhdrBitsPtr(obits);            CVMUint32 h = CVMhdrBitsHashCode(o->u.fast.bits);#ifdef CVM_DEBUG            CVMassert(o->magic == CVM_OWNEDMON_MAGIC);#endif            CVMassert(o->type == CVM_OWNEDMON_FAST);            if (h == CVM_OBJECT_NO_HASH) {		CVMassert(!CVMobjectIsInROM(obj));		CVMhdrSetHashCode(o->u.fast.bits, hashValue);            } else {                hashValue = h;            }        } else             /* neither LOCKSTATE_MONITOR nor _LOCKED, must be _UNLOCKED if             * using FASTLOCK              */#endif        {            CVMUint32 h = CVMhdrBitsHashCode(obj->hdr.various32);            if (h == CVM_OBJECT_NO_HASH) {		CVMassert(!CVMobjectIsInROM(obj));		CVMhdrSetHashCode(obj->hdr.various32, hashValue);            } else {                hashValue = h;            }        }    }    return HASH_WITH_CB_BITS(CVMobjectGetClass(obj), hashValue);}static jint hashRef(jobject ref, CVMBool isGCOwner) {    CVMExecEnv *ee = CVMgetEE();    jint hashCode;    if (isGCOwner) {        CVMObject *obj = CVMjvmtiGetICellDirect(ee, ref);        hashCode = CVMobjectGetHashNoSet(ee, obj);        if (hashCode == CVM_OBJECT_NO_HASH) {            hashCode = jvmtiObjectGetHash(ee, obj);        }    } else {        hashCode = JVM_IHashCode(CVMexecEnv2JniEnv(CVMgetEE()), ref);    }    CVMassert(hashCode != CVM_OBJECT_NO_HASH);    if (hashCode < 0) {	hashCode = -hashCode;    }    return hashCode % HASH_SLOT_COUNT;}intCVMjvmtiGetObjectsWithTag(JNIEnv *env, const jlong *tags, jint tagCount,			  jobject **objPtr, jlong **tagPtr){    int i, j;    CVMJvmtiTagNode *node;    int count = 0;    CVMExecEnv *ee = CVMgetEE();    JVMTI_LOCK(ee);    for (i = 0; i < HASH_SLOT_COUNT; i++) {	node = CVMglobals.jvmti.statics.objectsByRef[i];	while (node != NULL) {	    for (j = 0; j < tagCount; j++) {		if (node->tag == tags[j]) {		    if (objPtr != NULL) {			(*objPtr)[count] = (*env)->NewLocalRef(env, node->ref);		    }		    if (tagPtr != NULL) {			(*tagPtr)[count] = node->tag;		    }		    count++;		}	    }	    node = node->next;	}    }    JVMTI_UNLOCK(ee);    return count;}void CVMjvmtiTagRehash() {    CVMJvmtiTagNode *node, *next, *prev;    int i;    CVMExecEnv *ee = CVMgetEE();    JVMTI_LOCK(ee);    for (i = 0; i < HASH_SLOT_COUNT; i++) {	node = CVMglobals.jvmti.statics.objectsByRef[i];	prev = NULL;	while (node != NULL) {	    next = node->next;	    if (node->ref == NULL || CVMID_icellIsNull(node->ref)) {		if (prev == NULL) {		    CVMglobals.jvmti.statics.objectsByRef[i] = node->next;		} else {		    prev->next = node->next;		}		CVMjvmtiDeallocate((unsigned char *)node);	    } else {		prev = node;	    }	    node = next;	}    }    JVMTI_UNLOCK(ee);}jvmtiErrorCVMjvmtiTagGetTag(jobject object, jlong* tagPtr,                  CVMBool isGCOwner) {    CVMJvmtiTagNode *node;    CVMJvmtiTagNode *prev;    JNIEnv *env;    CVMExecEnv *ee = CVMgetEE();    jint slot;    *tagPtr = CVMlongConstZero();    if (object == NULL || CVMID_icellIsNull(object)) {	return JVMTI_ERROR_NONE;    }    JVMTI_LOCK(ee);    CVMassert(CVMjvmtiIsGCOwner() || !isGCOwner);    slot = hashRef(object, isGCOwner);    env = CVMexecEnv2JniEnv(ee);    node = CVMglobals.jvmti.statics.objectsByRef[slot];    prev = NULL;    while (node != NULL) {        if (isGCOwner) {            if (CVMjvmtiGetICellDirect(ee, object) ==                CVMjvmtiGetICellDirect(ee, node->ref)) {                break;            }        } else {            if ((*env)->IsSameObject(env, object, node->ref)) {                break;            }        }	prev = node;	node = node->next;    }    if (node == NULL) {	*tagPtr = 0L;    } else {	*tagPtr = node->tag;    }    JVMTI_UNLOCK(ee);    return JVMTI_ERROR_NONE;}jvmtiErrorCVMjvmtiTagSetTag(jobject object, jlong tag,                  CVMBool isGCOwner){    JNIEnv *env;    jint slot;    CVMJvmtiTagNode *node, *prev;    CVMExecEnv *ee = CVMgetEE();    /*     * Add to reference hashtable      */    if (object == NULL || CVMID_icellIsNull(object)) {	return JVMTI_ERROR_INVALID_OBJECT;    }

⌨️ 快捷键说明

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