internal TaggedReferenceTypeId TrackLocalClassReference(jclass classHandle, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, bool freeLocalReference) { if (classHandle == jclass.Null) { return(default(TaggedReferenceTypeId)); } bool isArrayClass; JvmtiErrorHandler.ThrowOnFailure(environment.IsArrayClass(classHandle, out isArrayClass)); bool isInterface; JvmtiErrorHandler.ThrowOnFailure(environment.IsInterface(classHandle, out isInterface)); TypeTag typeTag = isArrayClass ? TypeTag.Array : (isInterface ? TypeTag.Interface : TypeTag.Class); int hashCode; JvmtiErrorHandler.ThrowOnFailure(environment.GetObjectHashCode(classHandle, out hashCode)); ReferenceTypeId typeId = new ReferenceTypeId(hashCode); TaggedReferenceTypeId taggedTypeId = new TaggedReferenceTypeId(typeTag, typeId); lock (_classes) { if (!_classes.ContainsKey(typeId)) { jweak weak = nativeEnvironment.NewWeakGlobalReference(classHandle); bool added = false; if (!_classes.ContainsKey(typeId)) { _classes.Add(typeId, new jclass(weak.Handle)); added = true; } if (!added) { nativeEnvironment.DeleteWeakGlobalReference(weak); } } } if (freeLocalReference) { nativeEnvironment.DeleteLocalReference(classHandle); } return(taggedTypeId); }
internal ThreadId TrackLocalThreadReference(jthread thread, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, bool freeLocalReference) { if (thread == jthread.Null) { return(default(ThreadId)); } int hashCode; JvmtiErrorHandler.ThrowOnFailure(environment.RawInterface.GetObjectHashCode(environment, thread, out hashCode)); ThreadId threadId = new ThreadId(hashCode); lock (_threads) { if (!_threads.ContainsKey(threadId)) { jweak weak = nativeEnvironment.NewWeakGlobalReference(thread); bool added = false; if (!_threads.ContainsKey(threadId)) { _threads.Add(threadId, new jthread(weak.Handle)); added = true; } if (!added) { nativeEnvironment.DeleteWeakGlobalReference(weak); } } } if (freeLocalReference) { nativeEnvironment.DeleteLocalReference(thread); } return(threadId); }
internal TaggedObjectId TrackLocalObjectReference(jobject @object, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, bool freeLocalReference) { if (@object == jobject.Null) { return(new TaggedObjectId(Tag.Object, new ObjectId(0), default(TaggedReferenceTypeId))); } long tag; JvmtiErrorHandler.ThrowOnFailure(environment.GetTag(@object, out tag)); TaggedReferenceTypeId type = default(TaggedReferenceTypeId); Tag objectKind; if (tag == 0) { long uniqueTag = Interlocked.Increment(ref _nextTag); /* first figure out what type of object we're dealing with. could be: * - String * - Thread * - ThreadGroup * - ClassLoader * - ClassObject * - Array * - Object */ // check for array jclass objectClass = nativeEnvironment.GetObjectClass(@object); try { type = TrackLocalClassReference(objectClass, environment, nativeEnvironment, false); bool isArray = type.TypeTag == TypeTag.Array; if (isArray) { objectKind = Tag.Array; } else { if (_stringClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _stringClass)) { objectKind = Tag.String; } else if (_threadClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _threadClass)) { objectKind = Tag.Thread; } else if (_threadGroupClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _threadGroupClass)) { objectKind = Tag.ThreadGroup; } else if (_classClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _classClass)) { objectKind = Tag.ClassObject; } else if (_classLoaderClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _classLoaderClass)) { objectKind = Tag.ClassLoader; } else { objectKind = Tag.Object; } } } finally { nativeEnvironment.DeleteLocalReference(objectClass); } tag = (uniqueTag << 8) | (uint)objectKind; JvmtiErrorHandler.ThrowOnFailure(environment.SetTag(@object, tag)); lock (_objects) { _objects.Add(new ObjectId(tag), nativeEnvironment.NewWeakGlobalReference(@object)); } } else { jclass objectClass = nativeEnvironment.GetObjectClass(@object); type = TrackLocalClassReference(objectClass, environment, nativeEnvironment, true); } if (freeLocalReference) { nativeEnvironment.DeleteLocalReference(@object); } objectKind = (Tag)(tag & 0xFF); return(new TaggedObjectId(objectKind, new ObjectId(tag), type)); }