/* Prevent garbage collection of an object */ jvmtiError commonRef_pin(jlong id) { JNIEnv *env = getEnv(); jvmtiError error = JVMTI_ERROR_NONE; RefNode *node; if (id == NULL_OBJECT_ID) { return JNI_FALSE; } debugMonitorEnter(refLock); node = findNodeByID(env, id); if (node == NULL) { error = JVMTI_ERROR_INVALID_OBJECT; } else { jobject strongRef = strengthenNode(env, node); if (strongRef == NULL) { /* * Referent has been collected, clean up now. */ error = JVMTI_ERROR_INVALID_OBJECT; deleteNodeByID(env, id, ALL_REFS); } } debugMonitorExit(refLock); return error; }
void commonRef_releaseMultiple(JNIEnv *env, jlong id, jint refCount) { debugMonitorEnter(gdata->refLock); { deleteNodeByID(env, id, refCount); } debugMonitorExit(gdata->refLock); }
/* Release tracking of an object by ID */ void commonRef_release(JNIEnv *env, jlong id) { debugMonitorEnter(gdata->refLock); { deleteNodeByID(env, id, 1); } debugMonitorExit(gdata->refLock); }
/* * Given an object ID obtained from the debugger front end, return a * strong, global reference to that object (or NULL if the object * has been collected). The reference can then be used for JNI and * JVMTI calls. Caller is resposible for deleting the returned reference. */ jobject commonRef_idToRef(JNIEnv *env, jlong id) { jobject ref; ref = NULL; debugMonitorEnter(gdata->refLock); { RefNode *node; node = findNodeByID(env, id); if (node != NULL) { if (node->isStrong) { saveGlobalRef(env, node->ref, &ref); } else { jobject lref; lref = JNI_FUNC_PTR(env,NewLocalRef)(env, node->ref); if ( lref == NULL ) { /* Object was GC'd shortly after we found the node */ deleteNodeByID(env, node->seqNum, ALL_REFS); } else { saveGlobalRef(env, node->ref, &ref); JNI_FUNC_PTR(env,DeleteLocalRef)(env, lref); } } } } debugMonitorExit(gdata->refLock); return ref; }
void commonRef_releaseMultiple(jlong id, jint refCount) { JNIEnv *env = getEnv(); debugMonitorEnter(refLock); deleteNodeByID(env, id, refCount); debugMonitorExit(refLock); }
void commonRef_release(jlong id) { JNIEnv *env = getEnv(); debugMonitorEnter(refLock); deleteNodeByID(env, id, 1); debugMonitorExit(refLock); }
/* * Returns the node stored in the object hash table for the given object * id. The id should be a value previously returned by * commonRef_refToID. */ static RefNode * findNodeByID(JNIEnv *env, jlong id) { jint slot = hashID(id); RefNode *node = objectsByID[slot]; while (node != NULL) { /* * Use this opportunity to clean up any nodes for weak * references that have been garbage collected. */ if (isSameObject(env, node->ref, NULL)) { jlong collectedID = OBJECT_ID(node); node = node->nextByID; deleteNodeByID(env, collectedID, ALL_REFS); } else if (id == OBJECT_ID(node)) { break; /* found it */ } else { node = node->nextByID; } } return node; }