in modules/jpda/src/main/native/jdwp/common/agent/core/ObjectManager.cpp [66:148]
ObjectID ObjectManager::MapToObjectID(JNIEnv* JNIEnvPtr, jobject jvmObject) throw (AgentException) {
JDWP_TRACE_ENTRY("MapToObjectID(" << JNIEnvPtr << ',' << jvmObject << ')');
if (jvmObject == NULL) {
JDWP_TRACE_MAP("## MapToObjectID: map NULL jobject");
return JDWP_OBJECT_ID_NULL;
}
// get object HASH CODE
jint hashCode = -1;
if (GetObjectHashCode(jvmObject, &hashCode) != JVMTI_ERROR_NONE) {
JDWP_TRACE_MAP("## MapToObjectID: GetObjectHashCode failed");
throw AgentException(JDWP_ERROR_INVALID_OBJECT);
}
// get HASH INDEX
size_t idx = size_t(hashCode) & HASH_TABLE_MSK;
ObjectID objectID = 0;
{ // LOCK objectID table
MonitorAutoLock objectIDTableLock(m_objectIDTableMonitor JDWP_FILE_LINE);
// find EXISTING objectID
ObjectIDItem* objectIDItem = m_objectIDTable[idx];
ObjectIDItem* objectIDItemEnd = objectIDItem + m_maxAllocatedObjectID[idx];
while (objectIDItem != objectIDItemEnd) {
if (objectIDItem->objectID != FREE_OBJECTID_SIGN &&
JNIEnvPtr->IsSameObject(objectIDItem->mapObjectIDItem.jvmObject, jvmObject) == JNI_TRUE) {
objectID = objectIDItem->objectID;
break;
}
objectIDItem++;
}
// map NEW objectID if not found existing
if (objectID == 0) {
JNIEnvPtr->ExceptionClear();
jobject newWeakGlobRef = JNIEnvPtr->NewWeakGlobalRef(jvmObject);
if (newWeakGlobRef == NULL) {
/* NewWeakGlobalRef() returns NULL for two cases:
* - requested jobject is garbage collected: here it is not possibly,
* as passed jvmObject is local reference and jvmObject can NOT be
* garbage collected as long as "live" local reference exists.
* - the VM runs out of memory and OutOfMemoryExceptionError is thrown -
* suppose just this case is here
*/
JNIEnvPtr->ExceptionClear();
JDWP_TRACE_MAP("## MapToObjectID: NewWeakGlobalRef returned NULL");
throw OutOfMemoryException();
}
if (m_freeObjectIDItems[idx] == NULL) {
// expand table
size_t objectIDTableOldSize = m_objectIDTableSize[idx];
m_objectIDTableSize[idx]+= HASH_TABLE_GROW;
m_objectIDTable[idx] = reinterpret_cast<ObjectIDItem*>
(AgentBase::GetMemoryManager().Reallocate(m_objectIDTable[idx],
OBJECTID_ITEM_SIZE * objectIDTableOldSize,
OBJECTID_ITEM_SIZE * m_objectIDTableSize[idx] JDWP_FILE_LINE));
objectIDItem = m_freeObjectIDItems[idx] = m_objectIDTable[idx] + objectIDTableOldSize;
objectIDItemEnd = objectIDItem + HASH_TABLE_GROW - 1;
while (objectIDItem != objectIDItemEnd) {
objectIDItem->objectID = FREE_OBJECTID_SIGN;
objectIDItem->nextFreeObjectIDItem = objectIDItem + 1;
objectIDItem++;
}
objectIDItem->objectID = FREE_OBJECTID_SIGN;
objectIDItem->nextFreeObjectIDItem = NULL;
}
objectIDItem = m_freeObjectIDItems[idx];
m_freeObjectIDItems[idx] = objectIDItem->nextFreeObjectIDItem;
objectID = objectIDItem - m_objectIDTable[idx] + 1;
m_maxAllocatedObjectID[idx] = objectID > m_maxAllocatedObjectID[idx] ? objectID : m_maxAllocatedObjectID[idx];
objectIDItem->objectID = objectID = (objectID << HASH_TABLE_IDX) | idx;
objectIDItem->mapObjectIDItem.globalRefKind = WEAK_GLOBAL_REF;
objectIDItem->mapObjectIDItem.jvmObject = newWeakGlobRef;
objectIDItem->mapObjectIDItem.referencesCount = 0;
}
} // UNLOCK objectID table
return objectID;
} // MapToObjectID()