[RFA] JVMTI/JDWP GetAllLoadedClasses
Keith Seitz
keiths@redhat.com
Sat Apr 28 00:20:00 GMT 2007
A couple of comments...
Kyle Galloway wrote:
> Index: java/lang/natClassLoader.cc
> ===================================================================
> --- java/lang/natClassLoader.cc (revision 124192)
> +++ java/lang/natClassLoader.cc (working copy)
> @@ -380,6 +392,19 @@
> void
> _Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::SystemClassLoader *loader)
> {
> + using namespace ::java::lang;
> +
> + // Add any classes loaded before this point to the loaded classes list for
> + // JVMTI. As this is done, the memory used by the list is freed.
> + for (struct _Jv_TempClassListElement *ptr = jvmti_class_list_head;
> + ptr;
> + ptr = ptr->next)
> + {
> + VMClassLoader::loaded_classes->add (new ref::WeakReference (ptr->klass));
> + _Jv_Free (jvmti_class_list_head);
> + jvmti_class_list_head = ptr;
> + }
> +
> for (jclass klass = system_class_list;
> klass;
> klass = klass->next_or_version)
In order to minimize the impact of this on startup times for the
non-debug case, please wrap all this so that it does nothing when JVMTI
is not active. You can check JVMTI::enabled to do this.
> @@ -655,6 +680,33 @@
> _Jv_PushClass (jclass k)
> {
> JvSynchronize sync (&java::lang::Class::class$);
> +
> + using namespace ::java::lang;
> +
> + // Build a list of loaded classes for JVMTI.
> + if (system_class_list == SYSTEM_LOADER_INITIALIZED)
> + VMClassLoader::loaded_classes->add (new ref::WeakReference (k));
> + else
> + {
> + if (!jvmti_class_list_head)
> + {
> + jvmti_class_list_head
> + = reinterpret_cast<struct _Jv_TempClassListElement *>
> + (_Jv_MallocUnchecked (sizeof (struct _Jv_TempClassListElement)));
> + jvmti_class_list_head->next = NULL;
> + }
> + else
> + {
> + struct _Jv_TempClassListElement *tmp
> + = reinterpret_cast<struct _Jv_TempClassListElement *>
> + (_Jv_MallocUnchecked (sizeof (struct _Jv_TempClassListElement)));
> + tmp->next = jvmti_class_list_head;
> + jvmti_class_list_head = tmp;
> + }
> +
> + jvmti_class_list_head->klass = k;
> + }
> +
> jclass tmp = stack_head;
> stack_head = k;
> k->chain = tmp;
Likewise with JVMTI::enabled.
> Index: java/lang/VMClassLoader.h
> ===================================================================
> --- java/lang/VMClassLoader.h (revision 124192)
> +++ java/lang/VMClassLoader.h (working copy)
This header is regenerated by the build, right? I don't think you need
to post a patch for it in that case. We all know it is regenerated. (And
your ChangeLog told us it was regenerated. [Ditto the class files.] :-)
> Index: java/lang/VMClassLoader.java
> ===================================================================
> --- java/lang/VMClassLoader.java (revision 124192)
> +++ java/lang/VMClassLoader.java (working copy)
> @@ -345,4 +350,24 @@
>
> return default_sys;
> }
> +
> + /**
> + * First check if any of the classes in the list have been collected, and if
> + * they have, remove them from the list. It then returns the modified list.
> + *
> + * @return The <code>HashSet</code> of loaded classes.
> + */
> + public static HashSet getAllLoadedClasses()
> + {
> + Iterator it = loaded_classes.iterator();
> +
> + while (it.hasNext())
> + {
> + WeakReference ref = (WeakReference) it.next();
> + if (ref.get() == null)
> + it.remove();
> + }
> +
> + return loaded_classes;
> + }
> }
I have one concern about this... If another class is loaded by another
thread at this time, your iterating functions
(_Jv_JVMTI_GetLoadedClasses and getAllLoadedClasses) are going to throw
a ConcurrentModificationException.
While this seems pretty unlikely today, sometime in the future it is
conceivable that someone might run multiple JVMTI agents or have
multiple threads running through JDWP (all suspended/running
asynchronously). I would throw in a lock just to be sure. [I'm sure
there are other parts around JDWP where this is an issue, but we have to
start somewhere.]
Keith
More information about the Java-patches
mailing list