Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-13 Thread Chris Plummer

  
  
Thanks Staffan! And I really appreciate
  all your reviews. Also thanks to Mikael for the DCMD test review.
  
  Cheers,
  
  Chris
  
  On 2/12/15 1:19 AM, Staffan Larsen wrote:


  
  Looks good! 
  
  
  Thanks for providing incremental webrevs - very
helpful!
  
  
  
  
  Thanks,
  /Staffan
  
  
  
  
  
  
  

  On 12 feb 2015, at 09:31, Chris Plummer chris.plum...@oracle.com
wrote:
  
  


  I suppose it would be nice if
I included links to the webrevs:

http://cr.openjdk.java.net/~cjplummer/8054888/webrev.02-03/
http://cr.openjdk.java.net/~cjplummer/8054888/webrev.03/

First one is just the latest changes described in the
previous email. 2nd one includes all changes.

thanks,

Chris

On 2/12/15 12:28 AM, Chris Plummer wrote:
  
  

Ok, hopefully the last
  webrev. :)
  
  -JPRT found a compiler error on Solaris.
  
  classfile/systemDictionary.hpp needed to be included
  due to the reference to
  
  SystemDictionary::Object_klass(). I assume this turned
  up on Solaris because it doesn't use precompiled
  headers.
  
  -I noticed I had inadvertently removed a ResourceMark
  in KlassInfoHisto::print_class_stats(). I think maybe
  I had done a cut-n-paste rather than copy-n-paste.
  This was in webrev.01 but was pretty inconspicuous in
  the webrev so went noticed.
  
  -I changed another WARNING to ERROR as Staffan
  requested.
  
  -I updated to the latest JDK9 sources and made the
  needed changes to the DCMD test as Mikael requested.
  
  thanks,
  
  Chris
  
  On 2/11/15 9:38 AM, Chris Plummer wrote:

On 2/11/15 2:12 AM, Mikael Auno
  wrote: 
  On 2015-02-11 04:13,
Chris Plummer wrote: 

  In general I
think this looks very good. Simple and
well-commented 
code to follow. I am missing a test, though.
Please look at the 
hotspot/test/serviceability/dcmd set of tests. 
  
  Added. 

Your test is based on DcmdUtil.java which was
removed last week (see 
[0]). If you pull new changes from hs-rt/hotspot,
you'll see plenty of 
tests using the new DCMD utility classes in
testlibrary. Also, the new 
tests are divided in different subdirectories
depending on the commands, 
so as your test exercises VM.class_hierarchy it
should go in 
.../dcmd/vm/ as opposed to just .../dcmd/. 

Thanks, 
Mikael 

  [0] 
http://hg.openjdk.java.net/jdk9/hs-rt/hotspot/file/tip/test/serviceability/dcmd

  
  Ok. I'll pull the latest hs-rt and update the test.
  Thanks for pointing that out. 
  
  Chris 


  
  

  

  
  


  




Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-12 Thread Chris Plummer

  
  
Ok, hopefully the last webrev. :)
  
  -JPRT found a compiler error on Solaris.
  
  classfile/systemDictionary.hpp needed to be included due to the
  reference to
  
  SystemDictionary::Object_klass(). I assume this turned up on
  Solaris because it doesn't use precompiled headers.
  
  -I noticed I had inadvertently removed a ResourceMark in
  KlassInfoHisto::print_class_stats(). I think maybe I had done a
  cut-n-paste rather than copy-n-paste. This was in webrev.01 but
  was pretty inconspicuous in the webrev so went noticed.
  
  -I changed another WARNING to ERROR as Staffan requested.
  
  -I updated to the latest JDK9 sources and made the needed changes
  to the DCMD test as Mikael requested.
  
  thanks,
  
  Chris
  
  On 2/11/15 9:38 AM, Chris Plummer wrote:

On
  2/11/15 2:12 AM, Mikael Auno wrote:
  
  On 2015-02-11 04:13, Chris Plummer wrote:


  In general I think this looks very
good. Simple and well-commented

code to follow. I am missing a test, though. Please look at
the

hotspot/test/serviceability/dcmd set of tests.

  
  Added.
  

Your test is based on DcmdUtil.java which was removed last week
(see

[0]). If you pull new changes from hs-rt/hotspot, you'll see
plenty of

tests using the new DCMD utility classes in testlibrary. Also,
the new

tests are divided in different subdirectories depending on the
commands,

so as your test exercises VM.class_hierarchy it should go in

.../dcmd/vm/ as opposed to just .../dcmd/.


Thanks,

Mikael


  [0]

http://hg.openjdk.java.net/jdk9/hs-rt/hotspot/file/tip/test/serviceability/dcmd

  
  Ok. I'll pull the latest hs-rt and update the test. Thanks for
  pointing that out.
  
  
  Chris
  


  




Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-12 Thread Chris Plummer

  
  
I suppose it would be nice if I
  included links to the webrevs:
  
  http://cr.openjdk.java.net/~cjplummer/8054888/webrev.02-03/
  http://cr.openjdk.java.net/~cjplummer/8054888/webrev.03/
  
  First one is just the latest changes described in the previous
  email. 2nd one includes all changes.
  
  thanks,
  
  Chris
  
  On 2/12/15 12:28 AM, Chris Plummer wrote:


  
  Ok, hopefully the last webrev. :)

-JPRT found a compiler error on Solaris.

classfile/systemDictionary.hpp needed to be included due to the
reference to

SystemDictionary::Object_klass(). I assume this turned up on
Solaris because it doesn't use precompiled headers.

-I noticed I had inadvertently removed a ResourceMark in
KlassInfoHisto::print_class_stats(). I think maybe I had done a
cut-n-paste rather than copy-n-paste. This was in webrev.01 but
was pretty inconspicuous in the webrev so went noticed.

-I changed another WARNING to ERROR as Staffan requested.

-I updated to the latest JDK9 sources and made the needed
changes to the DCMD test as Mikael requested.

thanks,

Chris

On 2/11/15 9:38 AM, Chris Plummer wrote:
  
  On
2/11/15 2:12 AM, Mikael Auno wrote: 
On 2015-02-11 04:13, Chris Plummer
  wrote: 
  
In general I think this looks very
  good. Simple and well-commented 
  code to follow. I am missing a test, though. Please look
  at the 
  hotspot/test/serviceability/dcmd set of tests. 

Added. 
  
  Your test is based on DcmdUtil.java which was removed last
  week (see 
  [0]). If you pull new changes from hs-rt/hotspot, you'll see
  plenty of 
  tests using the new DCMD utility classes in testlibrary. Also,
  the new 
  tests are divided in different subdirectories depending on the
  commands, 
  so as your test exercises VM.class_hierarchy it should go in 
  .../dcmd/vm/ as opposed to just .../dcmd/. 
  
  Thanks, 
  Mikael 
  
    [0] 
  http://hg.openjdk.java.net/jdk9/hs-rt/hotspot/file/tip/test/serviceability/dcmd
  

Ok. I'll pull the latest hs-rt and update the test. Thanks for
pointing that out. 

Chris 
  
  


  




Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-12 Thread Staffan Larsen
Looks good! 

Thanks for providing incremental webrevs - very helpful!


Thanks,
/Staffan



 On 12 feb 2015, at 09:31, Chris Plummer chris.plum...@oracle.com wrote:
 
 I suppose it would be nice if I included links to the webrevs:
 
 http://cr.openjdk.java.net/~cjplummer/8054888/webrev.02-03/ 
 http://cr.openjdk.java.net/~cjplummer/8054888/webrev.02-03/
 http://cr.openjdk.java.net/~cjplummer/8054888/webrev.03/ 
 http://cr.openjdk.java.net/~cjplummer/8054888/webrev.03/
 
 First one is just the latest changes described in the previous email. 2nd one 
 includes all changes.
 
 thanks,
 
 Chris
 
 On 2/12/15 12:28 AM, Chris Plummer wrote:
 Ok, hopefully the last webrev. :)
 
 -JPRT found a compiler error on Solaris. classfile/systemDictionary.hpp 
 needed to be included due to the reference to 
 SystemDictionary::Object_klass(). I assume this turned up on Solaris because 
 it doesn't use precompiled headers.
 
 -I noticed I had inadvertently removed a ResourceMark in 
 KlassInfoHisto::print_class_stats(). I think maybe I had done a cut-n-paste 
 rather than copy-n-paste. This was in webrev.01 but was pretty inconspicuous 
 in the webrev so went noticed.
 
 -I changed another WARNING to ERROR as Staffan requested.
 
 -I updated to the latest JDK9 sources and made the needed changes to the 
 DCMD test as Mikael requested.
 
 thanks,
 
 Chris
 
 On 2/11/15 9:38 AM, Chris Plummer wrote:
 On 2/11/15 2:12 AM, Mikael Auno wrote: 
 On 2015-02-11 04:13, Chris Plummer wrote: 
 In general I think this looks very good. Simple and well-commented 
 code to follow. I am missing a test, though. Please look at the 
 hotspot/test/serviceability/dcmd set of tests. 
 Added. 
 Your test is based on DcmdUtil.java which was removed last week (see 
 [0]). If you pull new changes from hs-rt/hotspot, you'll see plenty of 
 tests using the new DCMD utility classes in testlibrary. Also, the new 
 tests are divided in different subdirectories depending on the commands, 
 so as your test exercises VM.class_hierarchy it should go in 
 .../dcmd/vm/ as opposed to just .../dcmd/. 
 
 Thanks, 
 Mikael 
 
   [0] 
 http://hg.openjdk.java.net/jdk9/hs-rt/hotspot/file/tip/test/serviceability/dcmd
  
 http://hg.openjdk.java.net/jdk9/hs-rt/hotspot/file/tip/test/serviceability/dcmd
  
 Ok. I'll pull the latest hs-rt and update the test. Thanks for pointing 
 that out. 
 
 Chris 
 
 



Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-11 Thread Chris Plummer

On 2/11/15 2:12 AM, Mikael Auno wrote:

On 2015-02-11 04:13, Chris Plummer wrote:

In general I think this looks very good. Simple and well-commented
code to follow. I am missing a test, though. Please look at the
hotspot/test/serviceability/dcmd set of tests.

Added.

Your test is based on DcmdUtil.java which was removed last week (see
[0]). If you pull new changes from hs-rt/hotspot, you'll see plenty of
tests using the new DCMD utility classes in testlibrary. Also, the new
tests are divided in different subdirectories depending on the commands,
so as your test exercises VM.class_hierarchy it should go in
.../dcmd/vm/ as opposed to just .../dcmd/.

Thanks,
Mikael

  [0]
http://hg.openjdk.java.net/jdk9/hs-rt/hotspot/file/tip/test/serviceability/dcmd
Ok. I'll pull the latest hs-rt and update the test. Thanks for pointing 
that out.


Chris


Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-11 Thread Chris Plummer

  
  
Yes, so I reverted back to the CLD*.
  Seems to be the only thing that is unique per ClassLoader instance
  and does not move.
  
  Chris
  
  On 2/11/15 2:11 PM, Karen Kinnear wrote:

Chris,
  
  
  Just saw this. I was thinking the instance in the heap since
you might have multiple instances of a single subclass.
  Good point that it might change and so the correlation would
be gone.
  
  
  thanks,
  Karen
  

  On Feb 6, 2015, at 5:09 PM, Chris Plummer wrote:
  
  


  Hi Karen,

Can you clarify what you mean by "address of the
j.l.ClassLoader class". Is that the Klass* for the
ClassLoader subclass, or the actual address of the
ClassLoader instance in the heap, which can change.

Chris

On 2/6/15 1:21 PM, Karen Kinnear wrote:
  
  Chris,


So I was curious - I was thinking you would
  printing the hex address of the j.l.ClassLoader class
  rather than the cld so that if folks were to look
at a heap dump later it might be meaningful to
  them. Is it unlikely that they would ever want to
  correlate those?



  
On Feb 6, 2015, at 3:15 PM, Chris Plummer
  wrote:


  
  
I was also thinking
  it might be a good idea to indicate what the
  hex value is, although still have figured out
  the best way of doing this. Maybe just a
  simple comment before the output. Keep in mind
  that eventually other DCMDS will also include
  the cld to help uniquiely identify classes
  across dcmd output. Also keep in mind your
  earlier suggestion:
  
  
  
java.lang.Object/0x12345600
|--java.io.Serializable/0x12345601
|--java.util.RandomAccess/0x12345602
|--java.lang.Iterable/0x12345603
|
|--java.util.Collection/0x12345604
|
| |--java.util.List/0x12345605
|--java.util.AbstractCollection/0x12345606
|
|  implements java.util.Collection/0x12345604
|
|  implements java.lang.Iterable/0x12345603
|
|--java.util.AbstractList/0x12345607
|
|    implements java.util.List/0x12345605
|
| |--java.util.Arrays$ArrayList/0x12345608
|
| |    implements java.io.Serializable/0x12345601
|
| |    implements java.util.RandomAccess/0x12345602
  
  

  
With additions to
  GC.class_stats:
  
  
  
  
Index

Super ClassLoader        ClassName
 
  1    -1 0x0007c0034c48 java.lang.Object/0x12345600

      2     1
  0x0007c0034c48 java.util.List/0x12345605


      3  
   31 0x0007c0034c48 java.util.AbstractList/0x12345607



  
  
And GC.class_histogram:
  
  
  
  
 num
    #instances         #bytes  class
name

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-11 Thread Karen Kinnear
Chris,

Just saw this. I was thinking the instance in the heap since you might have 
multiple instances of a single subclass.
Good point that it might change and so the correlation would be gone.

thanks,
Karen

On Feb 6, 2015, at 5:09 PM, Chris Plummer wrote:

 Hi Karen,
 
 Can you clarify what you mean by address of the j.l.ClassLoader class. Is 
 that the Klass* for the ClassLoader subclass, or the actual address of the 
 ClassLoader instance in the heap, which can change.
 
 Chris
 
 On 2/6/15 1:21 PM, Karen Kinnear wrote:
 Chris,
 
 So I was curious - I was thinking you would printing the hex address of the 
 j.l.ClassLoader class rather than the cld so that if folks were to look
 at a heap dump later it might be meaningful to them. Is it unlikely that 
 they would ever want to correlate those?
 
 
 On Feb 6, 2015, at 3:15 PM, Chris Plummer wrote:
 
 I was also thinking it might be a good idea to indicate what the hex value 
 is, although still have figured out the best way of doing 
 this. Maybe just a simple comment before the output. Keep in mind that 
 eventually other DCMDS will also include the cld to help uniquiely identify 
 classes across dcmd output. Also keep in mind your earlier suggestion:
 
 java.lang.Object/0x12345600
 |--java.io.Serializable/0x12345601
 |--java.util.RandomAccess/0x12345602
 |--java.lang.Iterable/0x12345603
 | |--java.util.Collection/0x12345604
 | | |--java.util.List/0x12345605
 |--java.util.AbstractCollection/0x12345606
 | |  implements java.util.Collection/0x12345604
 | |  implements java.lang.Iterable/0x12345603
 | |--java.util.AbstractList/0x12345607
 | |implements java.util.List/0x12345605
 | | |--java.util.Arrays$ArrayList/0x12345608
 | | |implements java.io.Serializable/0x12345601
 | | |implements java.util.RandomAccess/0x12345602
 
 With additions to GC.class_stats:
 
 Index Super ClassLoaderClassName
 1-1 0x0007c0034c48 java.lang.Object/0x12345600
 2 1 0x0007c0034c48 java.util.List/0x12345605
 331 0x0007c0034c48 java.util.AbstractList/0x12345607
 
 And GC.class_histogram:
 
  num #instances #bytes  class name
 --
1:   945 117736  java.lang.Object/0x12345600
2:   442  50352  java.util.List/0x12345605
3:   499  25288  java.util.AbstractList/0x12345607
 
 I think in your case you assumed we would create a unique identifier for 
 each class, but then we settled on just classname + ClassLoader identifier 
 of some sort, and the CLD* works for that. So replace your hex class ID in 
 the above with the hex CLD*.
 
 Also something Karen had said is just now starting to sink in and make 
 sense to me:
 
 |-sun.misc.Launcher$AppClassLoader/null (0xyyy)
 |-myapp/0xyyy
 
 I think the idea here is that when printing a ClassLoader subclass, you 
 include two CLDs. The first is for the ClassLoader that loaded the class, 
 and the second is the CLD for the ClassLoader subclass itself. Thus the 
 above indicates that myapp was loaded by 0xyyy, which is the 
 sun.misc.Launcher$AppClassLoader, which was loaded by the null ClassLoader. 
 I apologize - I don't remember what I said. But I am not sure we need that 
 level of complexity. I think I was asking that one of the dcmds that gives
 information could print information like 0xabc a 
 sun.misc.Launcher$AppClassLoader or a WLS.blah.GenericClassLoader if we 
 don't want to include
 that everywhere. Mostly people want to know the name of the class loader. 
 Since they don't yet have names, they want to know the type of the
 classloader. So that string a MyClassLoader would be more meaningful than 
 the 0xabc - except that if they
 have 5 of those they need the uniqueness. So personally I think I was 
 proposing the 
   java.base, 0xA/a MyClassLoader, iface).
 
 But I would defer to Staffan if he suggests something else.
 
 thanks for your patience,
 Karen
 
 With regard to the '/' format, keep in mind that we also need an indicator 
 of whether or not it's an interface, and there's also a request to include 
 the module name when that becomes available. At one point you requested the 
 following, which is what I was aiming for:
 
 java.lang.Object
 |--java.io.Serializable (java.base, 0x0007c00375f8, iface)
 |--java.util.RandomAccess (java.base, 0x0007c00375f8, iface)
 
 So maybe I can do:
 
 java.lang.Object
 |--java.io.Serializable/0x0007c00375f8 (java.base, intf)
 |--java.util.RandomAccess/0x0007c00375f8 (java.base, intf)
 ...
 |-sun.misc.Launcher$AppClassLoader/0x0007c00375f8 (java.base, 
 CLD=0x00087654320)
 |-myapp/0x00087654320
 
 So now the classname and its classloader id (which is the CLD*)  are 
 grouped together to make it easy to strip out or to search for in more than 
 one dcmd output. I think this is probably what you were striving when you 
 proposed using '/', and other DCMDs can eventually be changed 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-11 Thread Karen Kinnear
So I am in agreement on the CLD* - sorry for the earlier suggestion.

thanks,
Karen

On Feb 11, 2015, at 3:04 AM, Staffan Larsen wrote:

 This version looks good to me!
 
 Small comments inline.
 
 On 11 feb 2015, at 04:13, Chris Plummer chris.plum...@oracle.com wrote:
 
 Hi Staffan,
 
 Thanks for your feedback. A new incremental webrev can be found at:
 
 http://cr.openjdk.java.net/~cjplummer/8054888/webrev.01-02/
 
 Most changes are discussed inline below. Here are a couple of additional 
 changes:
 
 - Changed transitive interface to inherited interface in the output.
 - Went back to using the CLD* instead of the Klass*, except still use null 
 for the bootstrap ClassLoader.
 
 Good. 
 
 
 On 2/10/15 4:19 AM, Staffan Larsen wrote:
 Chris,
 
 In general I think this looks very good. Simple and well-commented code to 
 follow. I am missing a test, though. Please look at the 
 hotspot/test/serviceability/dcmd set of tests.
 Added.
 
 Thanks!
 
 
 
 A couple of smaller comments:
 
 
 Are Unsafe.defineAnonymousClass classes included? Should they be?
 I didn't really understand what you were talking about at first, but then 
 when I started looking at ClassLoaderStatsTest.java, I saw the following:
 
 class TestClass {
   static {
   // force creation of anonymous class (for the lambdaform)
   Runnable r = () - System.out.println(Hello);
   r.run();
   }
 }
 
 I added something similar to my test case and found a whole bunch of lines 
 like the following are suddenly added to the output:
 
 |--java.lang.invoke.LambdaForm$MH/11440528/null
 
 And there is one that seems specifically for the test case:
 
 |--DcmdTestClass$$Lambda$1/4081552/0xa529fbb0
 
 So I think they answer is yes they are added. As for whether or not they 
 should be, I really don't know. That's probably up to you. GC.class_stats 
 does include them however.
 
 I like to include them.
 
 
 BTW, I do not include array classes. They are intentionally stripped out 
 since they don't really have relevance in a Class hierarchy analysis. I can 
 easily add them back in if you want.
 
 I’m fine with skipping array classes.
 
 I think ClassHierarchyDCmd should include this code as well to restrict 
 remote access:
static const JavaPermission permission() {
  JavaPermission p = {java.lang.management.ManagementPermission,
  monitor, NULL};
  return p;
}
 Ok. I was a bit unclear as to when this was really needed.
 diagnosticCommand.hpp:278: Missing �if� in the comment
 Ok.
 vm_operations.hpp: Spelling error in �VM_PrintClassHierachry� and 
 �PrintClassHierachry�
 Ok.
 vm_operations.hpp:461: Should the complete class be surrounded by #if 
 INCLUDE_SERVICES� ?
 Yes, but I can't do anything about the reference in the VM_OPS_DO macro, at 
 least not in a straight forward manner. I think that part is benign, but 
 will find out when I do a minimal VM build.
 heapInspection.hpp:272: The constructor and destructor does not seem to be 
 used. Because of that you should also change it to a AllStatic class.
 Yeah, old code copied from HeapInspection class. I made it AllStatic and 
 removed the constructor and destructor. However, my lack of C++ experience 
 is showing here, and I haven't been happy about the existence of this 
 KlassHierarchy class. It's static with just one public API. It's purpose in 
 life is just to allow a VM operation to call that public method, but it just 
 as easily could have been a regular C function call. Likewise the two 
 private static methods in KlassHierarchy could have been C functions. There 
 is no encapsulation or subclassing going on here. If you have 
 recommendations for further improvement I'm open to suggestions. Otherwise 
 I'll leave it with just the changes mentioned.
 
 I come from a C background as well, so I don’t have much to add here. I think 
 this looks reasonable.
 
 heapInspection.cpp:339: Shouldn�t this be labeled as an �error�?
 That would probably be better. I had copied it from line 742. Should I make 
 that one an ERROR also to be consistent?
 
 Yes, please.
 
 Thanks,
 /Staffan
 
 
 thanks,
 
 Chris
 
 Thanks,
 /Staffan
 
 
 
 
 On 10 feb 2015, at 03:00, Chris Plummerchris.plum...@oracle.com  wrote:
 
 [Once again the attachment went out but the main body was stripped. Not 
 too sure what's going on, but here it is again. Sorry if you are getting 
 this twice.]
 
 I've attached updated output:
 
 � I now use the Klass* of the ClassLoader instead of the CLD*, and this 
 is documented in the help output.
 � The Klass* of the ClassLoader now immediately follows the class name, 
 and is also included when printing interface names.
 
 The webrevs can be found at:
 
 http://cr.openjdk.java.net/~cjplummer/8054888/webrev.01/
 http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00-01/
 
 The first is the full webrev. The 2nd is what's changed since the last 
 webrev that was reviewed. Changes since then include:
 
 � Support for 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-11 Thread Mikael Auno
On 2015-02-11 04:13, Chris Plummer wrote:
 In general I think this looks very good. Simple and well-commented
 code to follow. I am missing a test, though. Please look at the
 hotspot/test/serviceability/dcmd set of tests.
 Added.

Your test is based on DcmdUtil.java which was removed last week (see
[0]). If you pull new changes from hs-rt/hotspot, you'll see plenty of
tests using the new DCMD utility classes in testlibrary. Also, the new
tests are divided in different subdirectories depending on the commands,
so as your test exercises VM.class_hierarchy it should go in
.../dcmd/vm/ as opposed to just .../dcmd/.

Thanks,
Mikael

 [0]
http://hg.openjdk.java.net/jdk9/hs-rt/hotspot/file/tip/test/serviceability/dcmd


Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-11 Thread Staffan Larsen
This version looks good to me!

Small comments inline.

 On 11 feb 2015, at 04:13, Chris Plummer chris.plum...@oracle.com wrote:
 
 Hi Staffan,
 
 Thanks for your feedback. A new incremental webrev can be found at:
 
 http://cr.openjdk.java.net/~cjplummer/8054888/webrev.01-02/
 
 Most changes are discussed inline below. Here are a couple of additional 
 changes:
 
 - Changed transitive interface to inherited interface in the output.
 - Went back to using the CLD* instead of the Klass*, except still use null 
 for the bootstrap ClassLoader.

Good. 

 
 On 2/10/15 4:19 AM, Staffan Larsen wrote:
 Chris,
 
 In general I think this looks very good. Simple and well-commented code to 
 follow. I am missing a test, though. Please look at the 
 hotspot/test/serviceability/dcmd set of tests.
 Added.

Thanks!

 
 
 A couple of smaller comments:
 
 
 Are Unsafe.defineAnonymousClass classes included? Should they be?
 I didn't really understand what you were talking about at first, but then 
 when I started looking at ClassLoaderStatsTest.java, I saw the following:
 
 class TestClass {
static {
// force creation of anonymous class (for the lambdaform)
Runnable r = () - System.out.println(Hello);
r.run();
}
 }
 
 I added something similar to my test case and found a whole bunch of lines 
 like the following are suddenly added to the output:
 
 |--java.lang.invoke.LambdaForm$MH/11440528/null
 
 And there is one that seems specifically for the test case:
 
 |--DcmdTestClass$$Lambda$1/4081552/0xa529fbb0
 
 So I think they answer is yes they are added. As for whether or not they 
 should be, I really don't know. That's probably up to you. GC.class_stats 
 does include them however.

I like to include them.

 
 BTW, I do not include array classes. They are intentionally stripped out 
 since they don't really have relevance in a Class hierarchy analysis. I can 
 easily add them back in if you want.

I’m fine with skipping array classes.

 I think ClassHierarchyDCmd should include this code as well to restrict 
 remote access:
 static const JavaPermission permission() {
   JavaPermission p = {java.lang.management.ManagementPermission,
   monitor, NULL};
   return p;
 }
 Ok. I was a bit unclear as to when this was really needed.
 diagnosticCommand.hpp:278: Missing �if� in the comment
 Ok.
 vm_operations.hpp: Spelling error in �VM_PrintClassHierachry� and 
 �PrintClassHierachry�
 Ok.
 vm_operations.hpp:461: Should the complete class be surrounded by #if 
 INCLUDE_SERVICES� ?
 Yes, but I can't do anything about the reference in the VM_OPS_DO macro, at 
 least not in a straight forward manner. I think that part is benign, but will 
 find out when I do a minimal VM build.
 heapInspection.hpp:272: The constructor and destructor does not seem to be 
 used. Because of that you should also change it to a AllStatic class.
 Yeah, old code copied from HeapInspection class. I made it AllStatic and 
 removed the constructor and destructor. However, my lack of C++ experience is 
 showing here, and I haven't been happy about the existence of this 
 KlassHierarchy class. It's static with just one public API. It's purpose in 
 life is just to allow a VM operation to call that public method, but it just 
 as easily could have been a regular C function call. Likewise the two private 
 static methods in KlassHierarchy could have been C functions. There is no 
 encapsulation or subclassing going on here. If you have recommendations for 
 further improvement I'm open to suggestions. Otherwise I'll leave it with 
 just the changes mentioned.

I come from a C background as well, so I don’t have much to add here. I think 
this looks reasonable.

 heapInspection.cpp:339: Shouldn�t this be labeled as an �error�?
 That would probably be better. I had copied it from line 742. Should I make 
 that one an ERROR also to be consistent?

Yes, please.

Thanks,
/Staffan

 
 thanks,
 
 Chris
 
 Thanks,
 /Staffan
 
 
 
  
 On 10 feb 2015, at 03:00, Chris Plummerchris.plum...@oracle.com  wrote:
 
 [Once again the attachment went out but the main body was stripped. Not too 
 sure what's going on, but here it is again. Sorry if you are getting this 
 twice.]
 
 I've attached updated output:
 
 � I now use the Klass* of the ClassLoader instead of the CLD*, and this 
 is documented in the help output.
 � The Klass* of the ClassLoader now immediately follows the class name, 
 and is also included when printing interface names.
 
 The webrevs can be found at:
 
 http://cr.openjdk.java.net/~cjplummer/8054888/webrev.01/
 http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00-01/
 
 The first is the full webrev. The 2nd is what's changed since the last 
 webrev that was reviewed. Changes since then include:
 
 � Support for printing the hierarchy of just one class.
 � -s option for optionally including subclasses when printing one class.
 � -i option for optionally 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-10 Thread Chris Plummer

Hi Staffan,

Thanks for your feedback. A new incremental webrev can be found at:

http://cr.openjdk.java.net/~cjplummer/8054888/webrev.01-02/

Most changes are discussed inline below. Here are a couple of additional 
changes:


 - Changed transitive interface to inherited interface in the output.
 - Went back to using the CLD* instead of the Klass*, except still use 
null for the bootstrap ClassLoader.


On 2/10/15 4:19 AM, Staffan Larsen wrote:

Chris,

In general I think this looks very good. Simple and well-commented code to 
follow. I am missing a test, though. Please look at the 
hotspot/test/serviceability/dcmd set of tests.

Added.



A couple of smaller comments:


Are Unsafe.defineAnonymousClass classes included? Should they be?
I didn't really understand what you were talking about at first, but 
then when I started looking at ClassLoaderStatsTest.java, I saw the 
following:


class TestClass {
static {
// force creation of anonymous class (for the lambdaform)
Runnable r = () - System.out.println(Hello);
r.run();
}
}

I added something similar to my test case and found a whole bunch of 
lines like the following are suddenly added to the output:


|--java.lang.invoke.LambdaForm$MH/11440528/null

And there is one that seems specifically for the test case:

|--DcmdTestClass$$Lambda$1/4081552/0xa529fbb0

So I think they answer is yes they are added. As for whether or not they 
should be, I really don't know. That's probably up to you. 
GC.class_stats does include them however.


BTW, I do not include array classes. They are intentionally stripped out 
since they don't really have relevance in a Class hierarchy analysis. I 
can easily add them back in if you want.

I think ClassHierarchyDCmd should include this code as well to restrict remote 
access:
 static const JavaPermission permission() {
   JavaPermission p = {java.lang.management.ManagementPermission,
   monitor, NULL};
   return p;
 }

Ok. I was a bit unclear as to when this was really needed.

diagnosticCommand.hpp:278: Missing �if� in the comment

Ok.

vm_operations.hpp: Spelling error in �VM_PrintClassHierachry� and 
�PrintClassHierachry�

Ok.

vm_operations.hpp:461: Should the complete class be surrounded by #if 
INCLUDE_SERVICES� ?
Yes, but I can't do anything about the reference in the VM_OPS_DO macro, 
at least not in a straight forward manner. I think that part is benign, 
but will find out when I do a minimal VM build.

heapInspection.hpp:272: The constructor and destructor does not seem to be 
used. Because of that you should also change it to a AllStatic class.
Yeah, old code copied from HeapInspection class. I made it AllStatic and 
removed the constructor and destructor. However, my lack of C++ 
experience is showing here, and I haven't been happy about the existence 
of this KlassHierarchy class. It's static with just one public API. It's 
purpose in life is just to allow a VM operation to call that public 
method, but it just as easily could have been a regular C function call. 
Likewise the two private static methods in KlassHierarchy could have 
been C functions. There is no encapsulation or subclassing going on 
here. If you have recommendations for further improvement I'm open to 
suggestions. Otherwise I'll leave it with just the changes mentioned.

heapInspection.cpp:339: Shouldn�t this be labeled as an �error�?
That would probably be better. I had copied it from line 742. Should I 
make that one an ERROR also to be consistent?


thanks,

Chris


Thanks,
/Staffan



  

On 10 feb 2015, at 03:00, Chris Plummerchris.plum...@oracle.com  wrote:

[Once again the attachment went out but the main body was stripped. Not too 
sure what's going on, but here it is again. Sorry if you are getting this 
twice.]

I've attached updated output:

� I now use the Klass* of the ClassLoader instead of the CLD*, and this is 
documented in the help output.
� The Klass* of the ClassLoader now immediately follows the class name, and 
is also included when printing interface names.

The webrevs can be found at:

http://cr.openjdk.java.net/~cjplummer/8054888/webrev.01/
http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00-01/

The first is the full webrev. The 2nd is what's changed since the last webrev 
that was reviewed. Changes since then include:

� Support for printing the hierarchy of just one class.
� -s option for optionally including subclasses when printing one class.
� -i option for optionally including interfaces implemented by a class.
� Output formatting changes.
� Fixed some comment typos as requested.
� I moved a couple of KlassInfoEntry methods out of the .hpp file and into 
the .cpp file as requested.
� No longer keep track of the stack of superclasses when processing all the 
classes as requested. This also means the super_index field I added is no 
longer needed.
� Moved some code within an already existing  #if 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-10 Thread Staffan Larsen
Chris,

In general I think this looks very good. Simple and well-commented code to 
follow. I am missing a test, though. Please look at the 
hotspot/test/serviceability/dcmd set of tests.


A couple of smaller comments:


Are Unsafe.defineAnonymousClass classes included? Should they be?

I think ClassHierarchyDCmd should include this code as well to restrict remote 
access:
static const JavaPermission permission() {
  JavaPermission p = {java.lang.management.ManagementPermission,
  monitor, NULL};
  return p;
}

diagnosticCommand.hpp:278: Missing “if” in the comment

vm_operations.hpp: Spelling error in “VM_PrintClassHierachry” and 
“PrintClassHierachry”

vm_operations.hpp:461: Should the complete class be surrounded by #if 
INCLUDE_SERVICES” ?

heapInspection.hpp:272: The constructor and destructor does not seem to be 
used. Because of that you should also change it to a AllStatic class.

heapInspection.cpp:339: Shouldn’t this be labeled as an “error”?


Thanks,
/Staffan



 
 On 10 feb 2015, at 03:00, Chris Plummer chris.plum...@oracle.com wrote:
 
 [Once again the attachment went out but the main body was stripped. Not too 
 sure what's going on, but here it is again. Sorry if you are getting this 
 twice.]
 
 I've attached updated output:
 
 • I now use the Klass* of the ClassLoader instead of the CLD*, and this is 
 documented in the help output.
 • The Klass* of the ClassLoader now immediately follows the class name, and 
 is also included when printing interface names.
 
 The webrevs can be found at:
 
 http://cr.openjdk.java.net/~cjplummer/8054888/webrev.01/
 http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00-01/
 
 The first is the full webrev. The 2nd is what's changed since the last webrev 
 that was reviewed. Changes since then include:
 
 • Support for printing the hierarchy of just one class.
 • -s option for optionally including subclasses when printing one class.
 • -i option for optionally including interfaces implemented by a class.
 • Output formatting changes.
 • Fixed some comment typos as requested.
 • I moved a couple of KlassInfoEntry methods out of the .hpp file and into 
 the .cpp file as requested.
 • No longer keep track of the stack of superclasses when processing all the 
 classes as requested. This also means the super_index field I added is no 
 longer needed.
 • Moved some code within an already existing  #if INCLUDE_SERVICES block as 
 requested.
 
 thanks,
 
 Chris
 



Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-09 Thread Staffan Larsen

 On 6 feb 2015, at 21:15, Chris Plummer chris.plum...@oracle.com wrote:
 
 I was also thinking it might be a good idea to indicate what the hex value 
 is, although still have figured out the best way of doing this. Maybe just a 
 simple comment before the output. Keep in mind that eventually other DCMDS 
 will also include the cld to help uniquiely identify classes across dcmd 
 output. Also keep in mind your earlier suggestion:
 
 java.lang.Object/0x12345600
 |--java.io.Serializable/0x12345601
 |--java.util.RandomAccess/0x12345602
 |--java.lang.Iterable/0x12345603
 | |--java.util.Collection/0x12345604
 | | |--java.util.List/0x12345605
 |--java.util.AbstractCollection/0x12345606
 | |  implements java.util.Collection/0x12345604
 | |  implements java.lang.Iterable/0x12345603
 | |--java.util.AbstractList/0x12345607
 | |implements java.util.List/0x12345605
 | | |--java.util.Arrays$ArrayList/0x12345608
 | | |implements java.io.Serializable/0x12345601
 | | |implements java.util.RandomAccess/0x12345602
 
 With additions to GC.class_stats:
 
 Index Super ClassLoaderClassName
 1-1 0x0007c0034c48 java.lang.Object/0x12345600
 2 1 0x0007c0034c48 java.util.List/0x12345605
 331 0x0007c0034c48 java.util.AbstractList/0x12345607
 
 And GC.class_histogram:
 
  num #instances #bytes  class name
 --
1:   945 117736  java.lang.Object/0x12345600
2:   442  50352  java.util.List/0x12345605
3:   499  25288  java.util.AbstractList/0x12345607
 
 I think in your case you assumed we would create a unique identifier for each 
 class, but then we settled on just classname + ClassLoader identifier of some 
 sort, and the CLD* works for that. So replace your hex class ID in the above 
 with the hex CLD*.
 
 Also something Karen had said is just now starting to sink in and make sense 
 to me:
 
 |-sun.misc.Launcher$AppClassLoader/null (0xyyy)
 |-myapp/0xyyy
 
 I think the idea here is that when printing a ClassLoader subclass, you 
 include two CLDs. The first is for the ClassLoader that loaded the class, and 
 the second is the CLD for the ClassLoader subclass itself. Thus the above 
 indicates that myapp was loaded by 0xyyy, which is the 
 sun.misc.Launcher$AppClassLoader, which was loaded by the null ClassLoader. 
 
 With regard to the '/' format, keep in mind that we also need an indicator of 
 whether or not it's an interface, and there's also a request to include the 
 module name when that becomes available. At one point you requested the 
 following, which is what I was aiming for:
 
 java.lang.Object
 |--java.io.Serializable (java.base, 0x0007c00375f8, iface)
 |--java.util.RandomAccess (java.base, 0x0007c00375f8, iface)
 
 So maybe I can do:
 
 java.lang.Object
 |--java.io.Serializable/0x0007c00375f8 (java.base, intf)
 |--java.util.RandomAccess/0x0007c00375f8 (java.base, intf)

This looks good to me.

 ...
 |-sun.misc.Launcher$AppClassLoader/0x0007c00375f8 (java.base, 
 CLD=0x00087654320)
 |-myapp/0x00087654320
 
 So now the classname and its classloader id (which is the CLD*)  are grouped 
 together to make it easy to strip out or to search for in more than one dcmd 
 output. I think this is probably what you were striving when you proposed 
 using '/', and other DCMDs can eventually be changed to do the same. Also, 
 once you know the CLD of the ClassLoader, you can find out the name of the 
 ClassLoader class by looking for CLD=classloaderID
 
 I can go with null for the null ClassLoader if you want. I used it's 
 ClassLoaderData* to be consistent with the other ClassLoaders. Just let me 
 know which you prefer.

If we change the CLD* to the “Klass of the j.l.ClassLoader”, then it will 
become “null”. If someone wants to find the CLD* for the null ClassLoader, then 
the VM.classloader_stats command will get that.

/Staffan

 
 thanks,
 
 Chris
 
 On 2/6/15 12:52 AM, Staffan Larsen wrote:
 I think this looks good! Perhaps we should give a hint as to what the hex 
 value is? I don�t know if it is best to print this as part of a �header� 
 printed before the rest of the output or if we should include it as part of 
 each line �(classloaderdata*=0x080609c8)�.
 
 /Staffan
 
 On 6 feb 2015, at 05:49, Chris Plummer chris.plum...@oracle.com 
 mailto:chris.plum...@oracle.com wrote:
 
 [Hmm. My previous email somehow included the attachment with the dcmd 
 output, but not the body of the message, so here it is again.]
 
 Hey Folks,
 
 Sorry about the delay in getting the next webrev for this out. I was 
 sidetracked by a few other things, including being out sick of almost a 
 week, and there were also quite a few changes to make.
 
 I'm ready for review with an updated webrev, but thought first I'd have you 
 look at and comment on the output. Please see the attached file. It now 
 supports:
 
printing the hierarchy for a single 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-09 Thread Staffan Larsen

 On 6 feb 2015, at 22:21, Karen Kinnear karen.kinn...@oracle.com wrote:
 
 Chris,
 
 So I was curious - I was thinking you would printing the hex address of the 
 j.l.ClassLoader class rather than the cld so that if folks were to look
 at a heap dump later it might be meaningful to them. Is it unlikely that they 
 would ever want to correlate those?
 
 
 On Feb 6, 2015, at 3:15 PM, Chris Plummer wrote:
 
 I was also thinking it might be a good idea to indicate what the hex value 
 is, although still have figured out the best way of doing this. Maybe just a 
 simple comment before the output. Keep in mind that eventually other DCMDS 
 will also include the cld to help uniquiely identify classes across dcmd 
 output. Also keep in mind your earlier suggestion:
 
 java.lang.Object/0x12345600
 |--java.io.Serializable/0x12345601
 |--java.util.RandomAccess/0x12345602
 |--java.lang.Iterable/0x12345603
 | |--java.util.Collection/0x12345604
 | | |--java.util.List/0x12345605
 |--java.util.AbstractCollection/0x12345606
 | |  implements java.util.Collection/0x12345604
 | |  implements java.lang.Iterable/0x12345603
 | |--java.util.AbstractList/0x12345607
 | |implements java.util.List/0x12345605
 | | |--java.util.Arrays$ArrayList/0x12345608
 | | |implements java.io.Serializable/0x12345601
 | | |implements java.util.RandomAccess/0x12345602
 
 With additions to GC.class_stats:
 
 Index Super ClassLoaderClassName
 1-1 0x0007c0034c48 java.lang.Object/0x12345600
 2 1 0x0007c0034c48 java.util.List/0x12345605
 331 0x0007c0034c48 java.util.AbstractList/0x12345607
 
 And GC.class_histogram:
 
  num #instances #bytes  class name
 --
1:   945 117736  java.lang.Object/0x12345600
2:   442  50352  java.util.List/0x12345605
3:   499  25288  java.util.AbstractList/0x12345607
 
 I think in your case you assumed we would create a unique identifier for 
 each class, but then we settled on just classname + ClassLoader identifier 
 of some sort, and the CLD* works for that. So replace your hex class ID in 
 the above with the hex CLD*.
 
 Also something Karen had said is just now starting to sink in and make sense 
 to me:
 
 |-sun.misc.Launcher$AppClassLoader/null (0xyyy)
 |-myapp/0xyyy
 
 I think the idea here is that when printing a ClassLoader subclass, you 
 include two CLDs. The first is for the ClassLoader that loaded the class, 
 and the second is the CLD for the ClassLoader subclass itself. Thus the 
 above indicates that myapp was loaded by 0xyyy, which is the 
 sun.misc.Launcher$AppClassLoader, which was loaded by the null ClassLoader. 
 I apologize - I don't remember what I said. But I am not sure we need that 
 level of complexity. I think I was asking that one of the dcmds that gives
 information could print information like 0xabc a 
 sun.misc.Launcher$AppClassLoader or a WLS.blah.GenericClassLoader if we 
 don't want to include
 that everywhere. Mostly people want to know the name of the class loader. 
 Since they don't yet have names, they want to know the type of the
 classloader. So that string a MyClassLoader would be more meaningful than 
 the 0xabc - except that if they
 have 5 of those they need the uniqueness. So personally I think I was 
 proposing the 
   java.base, 0xA/a MyClassLoader, iface).
 
 But I would defer to Staffan if he suggests something else.

The mapping from “Klass of the j.l.ClassLoader” to “type of the ClassLoader” is 
available in the VM.classloader_stats command:

ClassLoader Parent  CLD*   Classes   ChunkSz   
BlockSz  Type
0x0007c0038d10  0x0007c0036240  0x7faf7843d8f0   1  6144
  1496  sun.misc.Launcher$AppClassLoader
0x0007c0036240  0x  0x   0 0
 0  sun.misc.Launcher$ExtClassLoader
0x  0x  0x7faf7852ffd0 432   4587520   
2851696  boot class loader
Total = 3  433   4593664   
2853192
ChunkSz: Total size of all allocated metaspace chunks
BlockSz: Total size of all allocated metaspace blocks (each chunk has several 
blocks)

I think that having the mapping in one place is enough.

/Staffan

 
 thanks for your patience,
 Karen
 
 With regard to the '/' format, keep in mind that we also need an indicator 
 of whether or not it's an interface, and there's also a request to include 
 the module name when that becomes available. At one point you requested the 
 following, which is what I was aiming for:
 
 java.lang.Object
 |--java.io.Serializable (java.base, 0x0007c00375f8, iface)
 |--java.util.RandomAccess (java.base, 0x0007c00375f8, iface)
 
 So maybe I can do:
 
 java.lang.Object
 |--java.io.Serializable/0x0007c00375f8 (java.base, intf)
 |--java.util.RandomAccess/0x0007c00375f8 (java.base, intf)
 ...
 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-09 Thread Chris Plummer

  
  
I've attached updated output:

  I now use the Klass* of the ClassLoader instead of the CLD*,
and this is documented in the help output.
  
  The Klass* of the ClassLoader now immediately follows the
class name, and is also included when printing interface names.

The webrevs can be found at:

http://cr.openjdk.java.net/~cjplummer/8054888/webrev.01/
  http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00-01/

The first is the full webrev. The 2nd is what's changed since the
last webrev that was reviewed. Changes since then include:

  Support for printing the hierarchy of just one class.
  -s option for optionally including subclasses when printing
one class.
  -i option for optionally including interfaces implemented by a
class.
  Output formatting changes.
  Fixed some comment typos as requested.
  
  I moved a couple of KlassInfoEntry methods out of the .hpp
file and into the .cpp file as requested.
  No longer keep track of the stack of superclasses when
processing all the classes as requested. This also means the
super_index field I added is no longer needed.
  Moved some code within an already existing "

#if INCLUDE_SERVICES" block as requested.
  

thanks,
Chris

On 2/5/15 6:49 PM, Chris Plummer wrote:
 Hey Folks,

 Sorry about the delay in getting the next webrev for this out.
I was sidetracked by a few other things, including being out sick of
almost a week, and there were also quite a few changes to make.

 I'm ready for review with an updated webrev, but thought first
I'd have you look at and comment on the output. Please see the
attached file. It now supports:

 printing the hierarchy for a single class
 optionally including all subclasses of the specified class
(-s)
 for each class, also list all of its interfaces (-i)

 The hex value in the output is the address of the
ClassLoaderData for the ClassLoader of the class. I did not include
the address of the Klass, but could if you think it would be useful.
Changing the format of what comes after the classname is easy. Just
let me know what you think is best.

 I have not updated any other dcmds to be consistent with how
classes are uniquely identified. A separate bug should be filed for
that. Actually I thought one was, but I looked through this thread's
history and could not find mention of it. I also have not
implemented the reverse hierarchy dcmd. JDK-8068830 has already been
filed for that, but there are no plans to work on it in the near
term.

 thanks,

 Chris

 On 1/7/15 3:29 PM, Chris Plummer wrote:
 Hi,

 Please review the following changes for the addition of the
VM.class_hierarchy DCMD. Please read the bug first for some
background information.

 Webrev:
http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00/
 Bug: https://bugs.openjdk.java.net/browse/JDK-8054888

 I expect there will be further restructuring or additional
feature work. More discussion on that below. I'm not sure if that
additional work will be done later with a separately bug filed or
with this initial commit. That's one thing I want to work out with
this review.

 Currently the bulk of the DCMD is implemented in
heapInspection.cpp. The  main purpose of this file is to implement
the GC.class_stats and GC.class_histogram DCMDs. Both of them
require walking the java heap to count live objects of each type,
thus the name "heapInspection.cpp". This new VM.class_hierarchy DCMD
does not require walking the heap, but is implemented in this file
because it leverages the existing KlassInfoTable and related classes
(KlassInfoEntry, KlassInfoBucket, and KlassClosure).

 KlassInfoTable makes it easy to build a database of all
loaded classes, save additional info gathered for each class,
iterate over them quickly, and also do quick lookups. This exactly
what I needed for this DCMD, thus the reuse. There is some downside
to this. For starters, heapInspection.cpp is not the proper place
for a DCMD that has nothing to do with heap inspection. Also,
KlassInfoEntry is being overloaded now to support 3 different DCMDs,
as is KlassInfoTable. As a result each has a few fields and methods
that are not used for all 3 DCMDs. Some subclassing might be in
order here, but I'm not sure if it's worth it. Opinions welcomed. If
I am going to refactor, I would prefer that be done as a next step
so I'm not disturbing the existing DCMDs with this first
implementation.

 I added some comments to code only used for GC.class_stats
and GC.class_histogram. I did this when trying to figure them out so
   

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-09 Thread Chris Plummer
[Once again the attachment went out but the main body was stripped. Not 
too sure what's going on, but here it is again. Sorry if you are getting 
this twice.]


I've attached updated output:

• I now use the Klass* of the ClassLoader instead of the CLD*, and this 
is documented in the help output.
• The Klass* of the ClassLoader now immediately follows the class name, 
and is also included when printing interface names.


The webrevs can be found at:

http://cr.openjdk.java.net/~cjplummer/8054888/webrev.01/
http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00-01/

The first is the full webrev. The 2nd is what's changed since the last 
webrev that was reviewed. Changes since then include:


• Support for printing the hierarchy of just one class.
• -s option for optionally including subclasses when printing one class.
• -i option for optionally including interfaces implemented by a class.
• Output formatting changes.
• Fixed some comment typos as requested.
• I moved a couple of KlassInfoEntry methods out of the .hpp file and 
into the .cpp file as requested.
• No longer keep track of the stack of superclasses when processing all 
the classes as requested. This also means the super_index field I added 
is no longer needed.
• Moved some code within an already existing  #if INCLUDE_SERVICES 
block as requested.


thanks,

Chris



Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-09 Thread Chris Plummer
Arrg. Just noticed these emails after I sent my webrev. They got snagged 
by my openjdk filter for later viewing. I had been expecting all replies 
to CC me and be in my inbox. serviceability-dev@openjdk.java.net also 
got removed, so they've been re-added.


Anyway, good point on both j.l.ClassLoader address suffering from 
objects moving (which is why I went with Klass*), and good point that 
more than one ClassLoader instance can have the same Klass*. I will 
change back to using the CLD*, but still use null for the bootstrap 
classloader since that makes it easier to read the output.


Please still review the webrev I just sent out. The change to CLD* will 
be pretty simple and not impact the existing logic. I can send out an 
incremental webrev to cover changes for it and any addition work that 
may still be needed.


thanks,

Chris

On 2/9/15 11:33 AM, Staffan Larsen wrote:

Very good point! Let’s go with ClassLoaderData.

/Staffan


On 9 feb 2015, at 18:35, Ioi Lam ioi@oracle.com wrote:

Hmm, you may have two instances of the same j.l.ClassLoader type, and their 
Klass will have the same value. This means you can't distinguish between the 
ClassLoader instances.

So, maybe we should change all the jcmd code to print a unique identifier for 
each ClassLoader instance. ClassLoaderData seems a good choice :-)

- Ioi


On 2/9/15, 1:40 AM, Staffan Larsen wrote:

Using the address of the Klass of the j.l.ClassLoader is good. It is also 
printed by VM.classloader_stats so allows for correlation there too. (Note that 
printing address of the j.l.ClassLoader itself is not a good idea since that 
can change during the lifetime of the JVM).

/Staffan


On 9 feb 2015, at 06:47, Ioi Lam ioi@oracle.com wrote:

I agree that we should use the address of the j.l.ClassLoader. This way, we can 
match the output with that of GC.class_stats, which prints out the class loader 
as:

class loader 0x7fc09c11d3d0a 'sun/misc/Launcher$AppClassLoader'

Thanks
- Ioi

On 2/6/15, 1:21 PM, Karen Kinnear wrote:

Chris,

So I was curious - I was thinking you would printing the hex address of the 
j.l.ClassLoader class rather than the cld so that if folks were to look
at a heap dump later it might be meaningful to them. Is it unlikely that they 
would ever want to correlate those?


On Feb 6, 2015, at 3:15 PM, Chris Plummer wrote:


I was also thinking it might be a good idea to indicate what the hex value is, 
although still have figured out the best way of doing this. Maybe just a simple 
comment before the output. Keep in mind that eventually other DCMDS will also 
include the cld to help uniquiely identify classes across dcmd output. Also 
keep in mind your earlier suggestion:

java.lang.Object/0x12345600
|--java.io.Serializable/0x12345601
|--java.util.RandomAccess/0x12345602
|--java.lang.Iterable/0x12345603
| |--java.util.Collection/0x12345604
| | |--java.util.List/0x12345605
|--java.util.AbstractCollection/0x12345606
| |  implements java.util.Collection/0x12345604
| |  implements java.lang.Iterable/0x12345603
| |--java.util.AbstractList/0x12345607
| |implements java.util.List/0x12345605
| | |--java.util.Arrays$ArrayList/0x12345608
| | |implements java.io.Serializable/0x12345601
| | |implements java.util.RandomAccess/0x12345602

With additions to GC.class_stats:

Index Super ClassLoaderClassName
 1-1 0x0007c0034c48 java.lang.Object/0x12345600
 2 1 0x0007c0034c48 java.util.List/0x12345605
 331 0x0007c0034c48 java.util.AbstractList/0x12345607

And GC.class_histogram:

  num #instances #bytes  class name
--
1:   945 117736  java.lang.Object/0x12345600
2:   442  50352  java.util.List/0x12345605
3:   499  25288  java.util.AbstractList/0x12345607

I think in your case you assumed we would create a unique identifier for each 
class, but then we settled on just classname + ClassLoader identifier of some 
sort, and the CLD* works for that. So replace your hex class ID in the above 
with the hex CLD*.

Also something Karen had said is just now starting to sink in and make sense to 
me:

|-sun.misc.Launcher$AppClassLoader/null (0xyyy)
|-myapp/0xyyy

I think the idea here is that when printing a ClassLoader subclass, you include 
two CLDs. The first is for the ClassLoader that loaded the class, and the 
second is the CLD for the ClassLoader subclass itself. Thus the above indicates 
that myapp was loaded by 0xyyy, which is the sun.misc.Launcher$AppClassLoader, 
which was loaded by the null ClassLoader.

I apologize - I don't remember what I said. But I am not sure we need that 
level of complexity. I think I was asking that one of the dcmds that gives
information could print information like 0xabc a sun.misc.Launcher$AppClassLoader or 
a WLS.blah.GenericClassLoader if we don't want to include
that everywhere. Mostly people want to know the name of the 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-06 Thread Chris Plummer

  
  
I was also thinking it might be a good
  idea to indicate what the hex value is, although still have
  figured out the best way of doing this. Maybe just a simple
  comment before the output. Keep in mind that eventually other
  DCMDS will also include the cld to help uniquiely identify classes
  across dcmd output. Also keep in mind your earlier suggestion:
  
  
  
java.lang.Object/0x12345600
|--java.io.Serializable/0x12345601
|--java.util.RandomAccess/0x12345602
|--java.lang.Iterable/0x12345603
|
|--java.util.Collection/0x12345604
| |
|--java.util.List/0x12345605
|--java.util.AbstractCollection/0x12345606
| |  implements
java.util.Collection/0x12345604
| |  implements java.lang.Iterable/0x12345603
|
|--java.util.AbstractList/0x12345607
| |    implements java.util.List/0x12345605
| |
|--java.util.Arrays$ArrayList/0x12345608
| | |    implements java.io.Serializable/0x12345601
| | |    implements java.util.RandomAccess/0x12345602
  
  

  
With additions to GC.class_stats:
  
  
  
  
Index Super
ClassLoader        ClassName
    1    -1
0x0007c0034c48 java.lang.Object/0x12345600

      2     1
  0x0007c0034c48 java.util.List/0x12345605


      3  
   31 0x0007c0034c48 java.util.AbstractList/0x12345607



  
  
And GC.class_histogram:
  
  
  
  
 num     #instances
        #bytes  class name
--
   1:           945
        117736  java.lang.Object/0x12345600
   2:           442
         50352  java.util.List/0x12345605
   3:           499
         25288  java.util.AbstractList/0x12345607
  
  
  
  I think in your case you assumed we would create a unique
  identifier for each class, but then we settled on just classname +
  ClassLoader identifier of some sort, and the CLD* works for that.
  So replace your hex class ID in the above with the hex CLD*.
  
  Also something Karen had said is just now starting to sink in and
  make sense to me:
  
  |-sun.misc.Launcher$AppClassLoader/null (0xyyy)
  |-myapp/0xyyy
  
  I think the idea here is that when printing a ClassLoader
  subclass, you include two CLDs. The first is for the ClassLoader
  that loaded the class, and the second is the CLD for the
  ClassLoader subclass itself. Thus the above indicates that myapp
  was loaded by 0xyyy, which is the
  sun.misc.Launcher$AppClassLoader, which was loaded by the null
  ClassLoader. 
  
  With regard to the '/' format, keep in mind that we also need an
  indicator of whether or not it's an interface, and there's also a
  request to include the module name when that becomes available. At
  one point you requested the following, which is what I was aiming
  for:
  
  java.lang.Object
  |--java.io.Serializable (java.base,
  0x0007c00375f8, iface)
  |--java.util.RandomAccess (java.base,
  0x0007c00375f8, iface)
  
  So maybe I can do:
  
  
java.lang.Object
|--java.io.Serializable/0x0007c00375f8
(java.base, intf)
|--java.util.RandomAccess/0x0007c00375f8
(java.base, intf)
...
  
|-sun.misc.Launcher$AppClassLoader/0x0007c00375f8
(java.base, CLD=0x00087654320)
  |-myapp/0x00087654320

So now the classname and its classloader id (which is the
CLD*)  are grouped together to make it easy to strip out or
to search for in more than one dcmd output. I think this is
probably what you were striving when you proposed using '/',
and other DCMDs can eventually be changed to do the same.
Also, once you know the CLD of the ClassLoader, you can find
out the name of the ClassLoader class by looking for
CLD=classloaderID

I can go with "null" for the null ClassLoader if you want. I
used it's ClassLoaderData* to be consistent with the other
ClassLoaders. Just let me know which you prefer.

thanks,

Chris
  
  
  On 2/6/15 12:52 AM, Staffan Larsen wrote:


  I think this looks good! Perhaps we should give a hint as to what the hex value is? I don�t know if it is best to print this as part of a �header� printed before the rest of the output or if we should include it as part of each line 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-06 Thread Karen Kinnear
Chris,

So I was curious - I was thinking you would printing the hex address of the 
j.l.ClassLoader class rather than the cld so that if folks were to look
at a heap dump later it might be meaningful to them. Is it unlikely that they 
would ever want to correlate those?


On Feb 6, 2015, at 3:15 PM, Chris Plummer wrote:

 I was also thinking it might be a good idea to indicate what the hex value 
 is, although still have figured out the best way of doing this. Maybe just a 
 simple comment before the output. Keep in mind that eventually other DCMDS 
 will also include the cld to help uniquiely identify classes across dcmd 
 output. Also keep in mind your earlier suggestion:
 
 java.lang.Object/0x12345600
 |--java.io.Serializable/0x12345601
 |--java.util.RandomAccess/0x12345602
 |--java.lang.Iterable/0x12345603
 | |--java.util.Collection/0x12345604
 | | |--java.util.List/0x12345605
 |--java.util.AbstractCollection/0x12345606
 | |  implements java.util.Collection/0x12345604
 | |  implements java.lang.Iterable/0x12345603
 | |--java.util.AbstractList/0x12345607
 | |implements java.util.List/0x12345605
 | | |--java.util.Arrays$ArrayList/0x12345608
 | | |implements java.io.Serializable/0x12345601
 | | |implements java.util.RandomAccess/0x12345602
 
 With additions to GC.class_stats:
 
 Index Super ClassLoaderClassName
 1-1 0x0007c0034c48 java.lang.Object/0x12345600
 2 1 0x0007c0034c48 java.util.List/0x12345605
 331 0x0007c0034c48 java.util.AbstractList/0x12345607
 
 And GC.class_histogram:
 
  num #instances #bytes  class name
 --
1:   945 117736  java.lang.Object/0x12345600
2:   442  50352  java.util.List/0x12345605
3:   499  25288  java.util.AbstractList/0x12345607
 
 I think in your case you assumed we would create a unique identifier for each 
 class, but then we settled on just classname + ClassLoader identifier of some 
 sort, and the CLD* works for that. So replace your hex class ID in the above 
 with the hex CLD*.
 
 Also something Karen had said is just now starting to sink in and make sense 
 to me:
 
 |-sun.misc.Launcher$AppClassLoader/null (0xyyy)
 |-myapp/0xyyy
 
 I think the idea here is that when printing a ClassLoader subclass, you 
 include two CLDs. The first is for the ClassLoader that loaded the class, and 
 the second is the CLD for the ClassLoader subclass itself. Thus the above 
 indicates that myapp was loaded by 0xyyy, which is the 
 sun.misc.Launcher$AppClassLoader, which was loaded by the null ClassLoader. 
I apologize - I don't remember what I said. But I am not sure we need that 
level of complexity. I think I was asking that one of the dcmds that gives
information could print information like 0xabc a 
sun.misc.Launcher$AppClassLoader or a WLS.blah.GenericClassLoader if we 
don't want to include
that everywhere. Mostly people want to know the name of the class loader. Since 
they don't yet have names, they want to know the type of the
classloader. So that string a MyClassLoader would be more meaningful than the 
0xabc - except that if they
have 5 of those they need the uniqueness. So personally I think I was proposing 
the 
  java.base, 0xA/a MyClassLoader, iface).

But I would defer to Staffan if he suggests something else.

thanks for your patience,
Karen
 
 With regard to the '/' format, keep in mind that we also need an indicator of 
 whether or not it's an interface, and there's also a request to include the 
 module name when that becomes available. At one point you requested the 
 following, which is what I was aiming for:
 
 java.lang.Object
 |--java.io.Serializable (java.base, 0x0007c00375f8, iface)
 |--java.util.RandomAccess (java.base, 0x0007c00375f8, iface)
 
 So maybe I can do:
 
 java.lang.Object
 |--java.io.Serializable/0x0007c00375f8 (java.base, intf)
 |--java.util.RandomAccess/0x0007c00375f8 (java.base, intf)
 ...
 |-sun.misc.Launcher$AppClassLoader/0x0007c00375f8 (java.base, 
 CLD=0x00087654320)
 |-myapp/0x00087654320
 
 So now the classname and its classloader id (which is the CLD*)  are grouped 
 together to make it easy to strip out or to search for in more than one dcmd 
 output. I think this is probably what you were striving when you proposed 
 using '/', and other DCMDs can eventually be changed to do the same. Also, 
 once you know the CLD of the ClassLoader, you can find out the name of the 
 ClassLoader class by looking for CLD=classloaderID
 
 I can go with null for the null ClassLoader if you want. I used it's 
 ClassLoaderData* to be consistent with the other ClassLoaders. Just let me 
 know which you prefer.
 
 thanks,
 
 Chris
 
 On 2/6/15 12:52 AM, Staffan Larsen wrote:
 I think this looks good! Perhaps we should give a hint as to what the hex 
 value is? I don�t know if it is best to print this as part of a �header� 
 printed before the rest of the 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-06 Thread Chris Plummer

  
  
Hi Karen,
  
  Can you clarify what you mean by "address of the j.l.ClassLoader
  class". Is that the Klass* for the ClassLoader subclass, or the
  actual address of the ClassLoader instance in the heap, which can
  change.
  
  Chris
  
  On 2/6/15 1:21 PM, Karen Kinnear wrote:

Chris,
  
  
  So I was curious - I was thinking you would printing the hex
address of the j.l.ClassLoader class rather than the cld so that
if folks were to look
  at a heap dump later it might be meaningful to them. Is it
unlikely that they would ever want to correlate those?
  
  
  

  On Feb 6, 2015, at 3:15 PM, Chris Plummer wrote:
  
  


  I was also thinking it might
be a good idea to indicate what the hex value is,
although still have figured out the best way of doing
this. Maybe just a simple comment before the output.
Keep in mind that eventually other DCMDS will also
include the cld to help uniquiely identify classes
across dcmd output. Also keep in mind your earlier
suggestion:



  java.lang.Object/0x12345600
  |--java.io.Serializable/0x12345601
  |--java.util.RandomAccess/0x12345602
  |--java.lang.Iterable/0x12345603
  |
  |--java.util.Collection/0x12345604
  | |
  |--java.util.List/0x12345605
  |--java.util.AbstractCollection/0x12345606
  | |
   implements java.util.Collection/0x12345604
  | |  implements java.lang.Iterable/0x12345603
  |
  |--java.util.AbstractList/0x12345607
  | |    implements java.util.List/0x12345605
  | |
  |--java.util.Arrays$ArrayList/0x12345608
  | | |    implements java.io.Serializable/0x12345601
  | | |    implements java.util.RandomAccess/0x12345602


  

  With additions to GC.class_stats:




  Index
  Super ClassLoader        ClassName
      1  
   -1 0x0007c0034c48 java.lang.Object/0x12345600
  
    2  
  1 0x0007c0034c48 java.util.List/0x12345605
  
  
    3  
 31 0x0007c0034c48 java.util.AbstractList/0x12345607
  
  
  


  And GC.class_histogram:




   num    
  #instances         #bytes  class name
  --
     1:    
        945         117736  java.lang.Object/0x12345600
     2:    
        442          50352  java.util.List/0x12345605
     3:    
        499          25288  java.util.AbstractList/0x12345607



I think in your case you assumed we would create a
unique identifier for each class, but then we settled on
just classname + ClassLoader identifier of some sort,
and the CLD* works for that. So replace your hex class
ID in the above with the hex CLD*.

Also something Karen had said is just now starting to
sink in and make sense to me:

|-sun.misc.Launcher$AppClassLoader/null (0xyyy)
|-myapp/0xyyy

I think the idea here is that when printing a
ClassLoader subclass, you include two CLDs. The first is
for the ClassLoader that loaded the class, and the
second is the CLD for the ClassLoader subclass itself.
Thus the above indicates that myapp was loaded by 0xyyy,
which is the sun.misc.Launcher$AppClassLoader, which was
loaded by the null ClassLoader. 
  

  
  I apologize - I don't remember what I said. But I am not sure
  we need that level of complexity. I think I was asking that
  one of the dcmds that gives
information could print information like 0xabc "a
  sun.misc.Launcher$AppClassLoader" or 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-06 Thread Staffan Larsen
I think this looks good! Perhaps we should give a hint as to what the hex value 
is? I don’t know if it is best to print this as part of a “header” printed 
before the rest of the output or if we should include it as part of each line 
“(classloaderdata*=0x080609c8)”.

/Staffan

 On 6 feb 2015, at 05:49, Chris Plummer chris.plum...@oracle.com wrote:
 
 [Hmm. My previous email somehow included the attachment with the dcmd output, 
 but not the body of the message, so here it is again.]
 
 Hey Folks,
 
 Sorry about the delay in getting the next webrev for this out. I was 
 sidetracked by a few other things, including being out sick of almost a week, 
 and there were also quite a few changes to make.
 
 I'm ready for review with an updated webrev, but thought first I'd have you 
 look at and comment on the output. Please see the attached file. It now 
 supports:
 
printing the hierarchy for a single class
optionally including all subclasses of the specified class (-s)
for each class, also list all of its interfaces (-i)
 
 The hex value in the output is the address of the ClassLoaderData for the 
 ClassLoader of the class. I did not include the address of the Klass, but 
 could if you think it would be useful. Changing the format of what comes 
 after the classname is easy. Just let me know what you think is best.
 
 I have not updated any other dcmds to be consistent with how classes are 
 uniquely identified. A separate bug should be filed for that. Actually I 
 thought one was, but I looked through this thread's history and could not 
 find mention of it. I also have not implemented the reverse hierarchy dcmd. 
 JDK-8068830 has already been filed for that, but there are no plans to work 
 on it in the near term.
 
 thanks,
 
 Chris



Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-05 Thread Chris Plummer
[Hmm. My previous email somehow included the attachment with the dcmd 
output, but not the body of the message, so here it is again.]


Hey Folks,

Sorry about the delay in getting the next webrev for this out. I was 
sidetracked by a few other things, including being out sick of almost a 
week, and there were also quite a few changes to make.


I'm ready for review with an updated webrev, but thought first I'd have 
you look at and comment on the output. Please see the attached file. It 
now supports:


printing the hierarchy for a single class
optionally including all subclasses of the specified class (-s)
for each class, also list all of its interfaces (-i)

The hex value in the output is the address of the ClassLoaderData for 
the ClassLoader of the class. I did not include the address of the 
Klass, but could if you think it would be useful. Changing the format of 
what comes after the classname is easy. Just let me know what you think 
is best.


I have not updated any other dcmds to be consistent with how classes are 
uniquely identified. A separate bug should be filed for that. Actually I 
thought one was, but I looked through this thread's history and could 
not find mention of it. I also have not implemented the reverse 
hierarchy dcmd. JDK-8068830 has already been filed for that, but there 
are no plans to work on it in the near term.


thanks,

Chris


Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-05 Thread Chris Plummer

  
  
Hey Folks,
  
  Sorry about the delay in getting the next webrev for this out. I
  was sidetracked by a few other things, including being out sick of
  almost a week, and there were also quite a few changes to make.
  
  I'm ready for review with an updated webrev, but thought first I'd
  have you look at and comment on the output. Please see the
  attached file. It now supports:
  
printing the hierarchy for a single class
optionally including all subclasses of the specified class
  (-s)
for each class, also list all of its interfaces (-i)
  
  The hex value in the output is the address of the ClassLoaderData
  for the ClassLoader of the class. I did not include the address of
  the Klass, but could if you think it would be useful. Changing the
  format of what comes after the classname is easy. Just let me know
  what you think is best.
  
  I have not updated any other dcmds to be consistent with how
  classes are uniquely identified. A separate bug should be filed
  for that. Actually I thought one was, but I looked through this
  thread's history and could not find mention of it. I also have not
  implemented the reverse hierarchy dcmd.
  
  JDK-8068830
  has already been filed for that, but there are no plans to work on
  it in the near term.
  
  thanks,
  
  Chris
  
  On 1/7/15 3:29 PM, Chris Plummer wrote:

Hi,
  
  
  Please review the following changes for the addition of the
  VM.class_hierarchy DCMD. Please read the bug first for some
  background information.
  
  
  Webrev: http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00/
  
  Bug: https://bugs.openjdk.java.net/browse/JDK-8054888
  
  
  I expect there will be further restructuring or additional feature
  work. More discussion on that below. I'm not sure if that
  additional work will be done later with a separately bug filed or
  with this initial commit. That's one thing I want to work out with
  this review.
  
  
  Currently the bulk of the DCMD is implemented in
  heapInspection.cpp. The  main purpose of this file is to implement
  the GC.class_stats and GC.class_histogram DCMDs. Both of them
  require walking the java heap to count live objects of each type,
  thus the name "heapInspection.cpp". This new VM.class_hierarchy
  DCMD does not require walking the heap, but is implemented in this
  file because it leverages the existing KlassInfoTable and related
  classes (KlassInfoEntry, KlassInfoBucket, and KlassClosure).
  
  
  KlassInfoTable makes it easy to build a database of all loaded
  classes, save additional info gathered for each class, iterate
  over them quickly, and also do quick lookups. This exactly what I
  needed for this DCMD, thus the reuse. There is some downside to
  this. For starters, heapInspection.cpp is not the proper place for
  a DCMD that has nothing to do with heap inspection. Also,
  KlassInfoEntry is being overloaded now to support 3 different
  DCMDs, as is KlassInfoTable. As a result each has a few fields and
  methods that are not used for all 3 DCMDs. Some subclassing might
  be in order here, but I'm not sure if it's worth it. Opinions
  welcomed. If I am going to refactor, I would prefer that be done
  as a next step so I'm not disturbing the existing DCMDs with this
  first implementation.
  
  
  I added some comments to code only used for GC.class_stats and
  GC.class_histogram. I did this when trying to figure them out so I
  could better understand how to implement VM.class_hierarchy. I can
  take them out if you think they are not appropriate for this
  commit.
  
  
  One other item I like to discuss is whether it is worth adding a
  class name argument to this DCMD. That would cause just the
  superclasses and subclasses of the named class to be printed. If
  you think that is useful, I think it can be added without too much
  trouble.
  
  
  At the moment not much testing has been done other than running
  the DCMD and looking at the output. I'll do more once it's clear
  the code has "settled". I would like to know if there are any
  existing tests for GC.class_stats and GC.class_histogram (there
  are none in the "test" directory). If so, possibly one could serve
  as the basis for a new test for VM.class_hierarchy.
  
  
  thanks,
  
  
  Chris
  


  

$ jcmd NeverExit help VM.class_hierarchy
25101:
VM.class_hierarchy
Print a list of all loaded classes, indented to show the class hiearchy.

Impact: Medium: Depends on number of loaded classes.

Syntax : VM.class_hierarchy [options] [classname]

Arguments:

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-02-05 Thread Chris Plummer

  
  
[Hmm. My previous email somehow included the attachment, but not the
body of the message, so here it is again.]

Hey Folks,

Sorry about the delay in getting the next webrev for this out. I was
sidetracked by a few other things, including being out sick of
almost a week, and there were also quite a few changes to make.

I'm ready for review with an updated webrev, but thought first I'd
have you look at and comment on the output. Please see the attached
file. It now supports:

  printing the hierarchy for a single class
  optionally including all subclasses of the specified class
(-s)
  for each class, also list all of its interfaces (-i)

The hex value in the output is the address of the ClassLoaderData
for the ClassLoader of the class. I did not include the address of
the Klass, but could if you think it would be useful. Changing the
format of what comes after the classname is easy. Just let me know
what you think is best.

I have not updated any other dcmds to be consistent with how classes
are uniquely identified. A separate bug should be filed for that.
Actually I thought one was, but I looked through this thread's
history and could not find mention of it. I also have not
implemented the reverse hierarchy dcmd. JDK-8068830
has already been filed for that, but there are no plans to work on
it in the near term.

thanks,

Chris
  



Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-01-12 Thread Staffan Larsen

 On 9 jan 2015, at 21:08, Chris Plummer chris.plum...@oracle.com wrote:
 
 On 1/9/15 4:38 AM, Staffan Larsen wrote:
 It�s getting difficult to get all the information into the same output: 
 hierarchy, interfaces, class loaders and modules. I took a stab at it and it 
 could look like this:
 
 java.lang.Object
 |--java.io.Serializable (java.base, 0x0007c00375f8, iface)
 |--java.util.RandomAccess (java.base, 0x0007c00375f8, iface)
 |--java.lang.Iterable (java.base, 0x0007c00375f8, iface)
 | |--java.util.Collection (java.base, 0x0007c00375f8, iface)
 | | |--java.util.List (java.base, 0x0007c00375f8, iface)
 |--java.util.AbstractCollection  (java.base, 0x0007c00375f8)
 | |  implements java.util.Collection
 | |  implements java.lang.Iterable
 | |--java.util.AbstractList (java.base, 0x0007c00375f8)
 | |implements java.util.List
 | | |--java.util.Arrays$ArrayList (java.base, 0x0007c00375f8)
 | | |implements java.io.Serializable
 | | |implements java.util.RandomAccess
 For the most part I like this. The one part I'm not too fond of is hex long 
 which I assume represents the ClassLoader. Maybe we could just use a simple 
 index, and at the end of the dump include a table of the referenced 
 ClassLoaders. Possibly just hijack what VM.classloader_stats outputs, but 
 include the simple index in the first column.
  
 
 But this is pushing what can be visualized in one place.
 
 We will need to add module and class loader information somehow to all the 
 Diagnostic Commands that list classes. In addition we will need a way to see 
 how modules relate to one another. Perhaps it isn�t possible to have all the 
 information in one place, but instead make it possible to cross reference 
 between different diagnostic commands. For example, GC.class_stats could 
 have the module and class loader information, and GC.class_hierarchy would 
 not have to include it. What is missing from making that possible is a 
 unique way of identifying a class (since the name is not unique). All output 
 would need to include that unique identifier and it would be possible to 
 cross reference. The identifier has to be stable during a JVM run, but not 
 between runs.
 I don't know if there is some sort of simple stable ID for a class other than 
 the address of the Klass instance. And of course this assumes there isn't any 
 class unloading going on that could result in reuse of the address. Is that 
 acceptable?

Yeah, I was thinking about the Klass*, but as you say it isn’t guaranteed to be 
unique over time. Karen suggested using {class loader, class} which has the 
same problem, but includes more useful information, so I think that is 
preferable. (Ideally we should have a unique id assigned to classes and class 
loaders when they are created).

 
 The above would then become:
 
 java.lang.Object/0x12345600
 |--java.io.Serializable/0x12345601
 |--java.util.RandomAccess/0x12345602
 |--java.lang.Iterable/0x12345603
 | |--java.util.Collection/0x12345604
 | | |--java.util.List/0x12345605
 |--java.util.AbstractCollection/0x12345606
 | |  implements java.util.Collection/0x12345604
 | |  implements java.lang.Iterable/0x12345603
 | |--java.util.AbstractList/0x12345607
 | |implements java.util.List/0x12345605
 | | |--java.util.Arrays$ArrayList/0x12345608
 | | |implements java.io.Serializable/0x12345601
 | | |implements java.util.RandomAccess/0x12345602
 
 With additions to GC.class_stats:
 
 Index Super ClassLoaderClassName
 1-1 0x0007c0034c48 java.lang.Object/0x12345600
 2 1 0x0007c0034c48 java.util.List/0x12345605
 331 0x0007c0034c48 java.util.AbstractList/0x12345607
 
 And GC.class_histogram:
 
  num #instances #bytes  class name
 --
1:   945 117736  java.lang.Object/0x12345600
2:   442  50352  java.util.List/0x12345605
3:   499  25288  java.util.AbstractList/0x12345607
 Would it be better for the class identifier to be in a separate column from 
 the class name, or is combining them intentional? In any case, it's easy 
 enough to add to all of the above assuming we are talking about an existing 
 value such as the address of the Klass instance.

Perhaps better to separate them, yes.

/Staffan

 
 Chris
 
 
 
 /Staffan
 
 On 9 jan 2015, at 09:53, Frederic Parain frederic.par...@oracle.com 
 mailto:frederic.par...@oracle.com wrote:
 
 
 
 On 01/08/2015 10:29 PM, Chris Plummer wrote:
 Hi Karen,
 
 Comments inline.
 
 On 1/8/15 8:07 AM, Karen Kinnear wrote:
 Chris,
 
 Thank you for doing this. I had a couple of questions/comments.
 
 I like your idea of being able to start with a specific class to show
 all subclasses of.
 Ok. I'll add that.
 
 I think the way I read the code this shows the superclass hierarchy,
 not the superinterfaces. With the addition
 of default methods in interfaces, I think we have increased the value
 in 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-01-12 Thread Karen Kinnear
Chris,

I filed JDK-8068830 to capture the request I had to print the super types of
a given class - so you don't have to deal with that as part of this exercise.

thanks,
Karen

On Jan 9, 2015, at 12:53 PM, Karen Kinnear wrote:

 Thanks Frederic for suggesting two different dcmds - they could
 share a lot of the code logic.
 
 If folks generally prefer these as separate dcmds - I can file an
 rfe to add the inverted one - i.e. start at a given class/interface and
 tell me its supertypes.
 
 thanks,
 Karen
 
 On Jan 9, 2015, at 3:53 AM, Frederic Parain wrote:
 
 
 
 On 01/08/2015 10:29 PM, Chris Plummer wrote:
 Hi Karen,
 
 Comments inline.
 
 On 1/8/15 8:07 AM, Karen Kinnear wrote:
 Chris,
 
 Thank you for doing this. I had a couple of questions/comments.
 
 I like your idea of being able to start with a specific class to show
 all subclasses of.
 Ok. I'll add that.
 
 I think the way I read the code this shows the superclass hierarchy,
 not the superinterfaces. With the addition
 of default methods in interfaces, I think we have increased the value
 in seeing superinterfaces.
 It does include interfaces in the output, but not as part of any class
 hierarchy. Interfaces are just shown as regular classes that inherit
 from Object. This is the case if one interface extends another, I
 suppose because extends is just interpreted as implements in this case.
 
 So what I personally would find useful would be to be able to start
 with a specific class and
 find the superclasses and superinterfaces of that class - for the
 debugging I do, I usually am
 trying to look up and need both sets of information. Today if you run
 -XX:+TraceDefaultMethods
 there is one sample way to display all the supertypes of a single
 type, all the way up. I don't know the
 best way to make that consistent with the current output approach,
 e.g. using the |- syntax.
 
 e.g.
 Class java.util.Arrays$ArrayList requires default method processing
 java/util/Arrays$ArrayList
  java/util/AbstractList
java/util/AbstractCollection
  java/lang/Object
  java/util/Collection
java/lang/Object
java/lang/Iterable
  java/lang/Object
java/util/List
  java/lang/Object
  java/util/Collection
java/lang/Object
java/lang/Iterable
  java/lang/Object
  java/util/RandomAccess
java/lang/Object
  java/io/Serializable
java/lang/Object
 
 Do you think there could be value to others in the ability to walk up
 the hierarchy as well as to
 see superclasses and superinterfaces at least from that perspective?
 This is a inverted from how my dcmd prints the hierarchy, plus also
 includes interfaces. Inverting the hierarchy means a class is listed
 with every subclass of the class, which I don't think is desirable.
 Including interfaces has the same issue, but introduces a new issue even
 when not inverting the hierarchy. The same interface can be in more than
 one location in the hierarchy, so there is no avoiding printing it more
 than once, so we need to decide how to best include interfaces in the
 output.
 
 It seems to me that we have two very different use cases here, each one
 best served with a different output format:
 
 1 - Listing of all classes/interfaces hierarchy when the dcmd is
invoked without arguments:
   - Chris' output format as described below (with interfaces)
 2 - Investigation on a particular class or interface when a class
or interface is passed in argument to the dcmd
   - Karen's output format, much easier to work with to
  track default methods. Because the output is limited to the
  hierarchy from a single class, there's no class duplication
  in output (single parent class inheritance) and limited
  interfaces duplication.
 
 If the implementations of the two features are too different, we could
 consider having two different dcmds.
 
 My 2 cents,
 
 Fred
 
 The could just be a simple list right after the class that
 implements them:
 
 java.lang.Object
 | ...
 |--MyBaseClass
 | |  implements - MyInterface1
 | |  implements - MyInterface2
 | |--MySubClass
 |  implements - MyInterface1
 |  implements - MyInterface2
 | ...
 |--MyInterface1
 |--MyInterface2
 
 The implements  lines could be optional.
 
 I know cvm would distinguish between interfaces the Class declared it
 implemented, and those it inherited from the interfaces it declared it
 implemented. This was necessary for reflection, and I think also to
 properly build up interfaces tables. I assume hotspot does something
 similar. Is there any need for this information to be conveyed in the
 above output, or just list out every interface implemented, and not
 worry about how the class acquired it.
 Is there value in printing the defining class loader for each class -
 maybe optionally?
 This is already available with GC.class_stats, although not in the
 default output. I suppose the reality is that it might be better handled
 by this DCMD. The main 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-01-09 Thread Frederic Parain



On 01/08/2015 10:29 PM, Chris Plummer wrote:

Hi Karen,

Comments inline.

On 1/8/15 8:07 AM, Karen Kinnear wrote:

Chris,

Thank you for doing this. I had a couple of questions/comments.

I like your idea of being able to start with a specific class to show
all subclasses of.

Ok. I'll add that.


I think the way I read the code this shows the superclass hierarchy,
not the superinterfaces. With the addition
of default methods in interfaces, I think we have increased the value
in seeing superinterfaces.

It does include interfaces in the output, but not as part of any class
hierarchy. Interfaces are just shown as regular classes that inherit
from Object. This is the case if one interface extends another, I
suppose because extends is just interpreted as implements in this case.


So what I personally would find useful would be to be able to start
with a specific class and
find the superclasses and superinterfaces of that class - for the
debugging I do, I usually am
trying to look up and need both sets of information. Today if you run
-XX:+TraceDefaultMethods
there is one sample way to display all the supertypes of a single
type, all the way up. I don't know the
best way to make that consistent with the current output approach,
e.g. using the |- syntax.

e.g.
Class java.util.Arrays$ArrayList requires default method processing
java/util/Arrays$ArrayList
   java/util/AbstractList
 java/util/AbstractCollection
   java/lang/Object
   java/util/Collection
 java/lang/Object
 java/lang/Iterable
   java/lang/Object
 java/util/List
   java/lang/Object
   java/util/Collection
 java/lang/Object
 java/lang/Iterable
   java/lang/Object
   java/util/RandomAccess
 java/lang/Object
   java/io/Serializable
 java/lang/Object

Do you think there could be value to others in the ability to walk up
the hierarchy as well as to
see superclasses and superinterfaces at least from that perspective?

This is a inverted from how my dcmd prints the hierarchy, plus also
includes interfaces. Inverting the hierarchy means a class is listed
with every subclass of the class, which I don't think is desirable.
Including interfaces has the same issue, but introduces a new issue even
when not inverting the hierarchy. The same interface can be in more than
one location in the hierarchy, so there is no avoiding printing it more
than once, so we need to decide how to best include interfaces in the
output.


It seems to me that we have two very different use cases here, each one
best served with a different output format:

 1 - Listing of all classes/interfaces hierarchy when the dcmd is
 invoked without arguments:
- Chris' output format as described below (with interfaces)
 2 - Investigation on a particular class or interface when a class
 or interface is passed in argument to the dcmd
- Karen's output format, much easier to work with to
   track default methods. Because the output is limited to the
   hierarchy from a single class, there's no class duplication
   in output (single parent class inheritance) and limited
   interfaces duplication.

If the implementations of the two features are too different, we could
consider having two different dcmds.

My 2 cents,

Fred


The could just be a simple list right after the class that
implements them:

java.lang.Object
| ...
|--MyBaseClass
| |  implements - MyInterface1
| |  implements - MyInterface2
| |--MySubClass
|  implements - MyInterface1
|  implements - MyInterface2
| ...
|--MyInterface1
|--MyInterface2

The implements  lines could be optional.

I know cvm would distinguish between interfaces the Class declared it
implemented, and those it inherited from the interfaces it declared it
implemented. This was necessary for reflection, and I think also to
properly build up interfaces tables. I assume hotspot does something
similar. Is there any need for this information to be conveyed in the
above output, or just list out every interface implemented, and not
worry about how the class acquired it.

Is there value in printing the defining class loader for each class -
maybe optionally?

This is already available with GC.class_stats, although not in the
default output. I suppose the reality is that it might be better handled
by this DCMD. The main puprose of GC.class_stats is to print statistics
(counts and sizes), so printing the ClassLoader name there is probably
not appropriate, but then it's not really appropriate for
VM.class_hierarchy either. I'm not sure how best to handle this. One or
both DCMDs possibly should be re-purposed and more clearly define what
type of data it displays.

If so, I'm wondering if there might be value in future for the jigsaw
project adding the module for each class - maybe optionally as well?

This relates to my above statement. We need to figure out what type of
data is useful, and which dcmds should handle them.

Love 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-01-09 Thread Karen Kinnear
Staffan,

On Jan 9, 2015, at 7:38 AM, Staffan Larsen wrote:

 It’s getting difficult to get all the information into the same output: 
 hierarchy, interfaces, class loaders and modules. I took a stab at it and it 
 could look like this:
 
 java.lang.Object
 |--java.io.Serializable (java.base, 0x0007c00375f8, iface)
 |--java.util.RandomAccess (java.base, 0x0007c00375f8, iface)
 |--java.lang.Iterable (java.base, 0x0007c00375f8, iface)
 | |--java.util.Collection (java.base, 0x0007c00375f8, iface)
 | | |--java.util.List (java.base, 0x0007c00375f8, iface)
 |--java.util.AbstractCollection  (java.base, 0x0007c00375f8)
 | |  implements java.util.Collection
 | |  implements java.lang.Iterable
 | |--java.util.AbstractList (java.base, 0x0007c00375f8)
 | |implements java.util.List
 | | |--java.util.Arrays$ArrayList (java.base, 0x0007c00375f8)
 | | |implements java.io.Serializable
 | | |implements java.util.RandomAccess
  
 
 But this is pushing what can be visualized in one place.
 
 We will need to add module and class loader information somehow to all the 
 Diagnostic Commands that list classes. In addition we will need a way to see 
 how modules relate to one another. Perhaps it isn’t possible to have all the 
 information in one place, but instead make it possible to cross reference 
 between different diagnostic commands. For example, GC.class_stats could have 
 the module and class loader information, and GC.class_hierarchy would not 
 have to include it. What is missing from making that possible is a unique way 
 of identifying a class (since the name is not unique). All output would need 
 to include that unique identifier and it would be possible to cross 
 reference. The identifier has to be stable during a JVM run, but not between 
 runs.
I like where you are going with this. Since a given module is within a class 
loader, putting the the loader/module/class  information in class_stats would 
be helpful and then having
other dcmds just need the class/class loader pair for uniqueness. 

Not sure what you are using below for unique identifier.
I would be tempted to use the class loader hex value since otherwise you are 
introducing hex values that have no meaning other than as
cross-references. And the class/class loader pair is guaranteed uniqueness.
For any class loader you could list its hex value thereby giving the 
information in a single command that gives meaning to the loader value. 

java.lang.Object/null
...
|-sun.misc.Launcher$AppClassLoader/null (0xyyy)
|-myapp/0xyyy

Just a thought. If you are not enthused - I am ok with your proposal.

thanks,
Karen

 
 The above would then become:
 
 java.lang.Object/0x12345600
 |--java.io.Serializable/0x12345601
 |--java.util.RandomAccess/0x12345602
 |--java.lang.Iterable/0x12345603
 | |--java.util.Collection/0x12345604
 | | |--java.util.List/0x12345605
 |--java.util.AbstractCollection/0x12345606
 | |  implements java.util.Collection/0x12345604
 | |  implements java.lang.Iterable/0x12345603
 | |--java.util.AbstractList/0x12345607
 | |implements java.util.List/0x12345605
 | | |--java.util.Arrays$ArrayList/0x12345608
 | | |implements java.io.Serializable/0x12345601
 | | |implements java.util.RandomAccess/0x12345602
 
 With additions to GC.class_stats:
 
 Index Super ClassLoaderClassName
 1-1 0x0007c0034c48 java.lang.Object/0x12345600
 2 1 0x0007c0034c48 java.util.List/0x12345605
 331 0x0007c0034c48 java.util.AbstractList/0x12345607
 
 And GC.class_histogram:
 
  num #instances #bytes  class name
 --
1:   945 117736  java.lang.Object/0x12345600
2:   442  50352  java.util.List/0x12345605
3:   499  25288  java.util.AbstractList/0x12345607
 
 
 
 /Staffan
 
 On 9 jan 2015, at 09:53, Frederic Parain frederic.par...@oracle.com wrote:
 
 
 
 On 01/08/2015 10:29 PM, Chris Plummer wrote:
 Hi Karen,
 
 Comments inline.
 
 On 1/8/15 8:07 AM, Karen Kinnear wrote:
 Chris,
 
 Thank you for doing this. I had a couple of questions/comments.
 
 I like your idea of being able to start with a specific class to show
 all subclasses of.
 Ok. I'll add that.
 
 I think the way I read the code this shows the superclass hierarchy,
 not the superinterfaces. With the addition
 of default methods in interfaces, I think we have increased the value
 in seeing superinterfaces.
 It does include interfaces in the output, but not as part of any class
 hierarchy. Interfaces are just shown as regular classes that inherit
 from Object. This is the case if one interface extends another, I
 suppose because extends is just interpreted as implements in this case.
 
 So what I personally would find useful would be to be able to start
 with a specific class and
 find the superclasses and superinterfaces of that class - for the
 debugging I do, I usually am
 trying to look up and need both 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-01-09 Thread Staffan Larsen

 On 9 jan 2015, at 18:49, Karen Kinnear karen.kinn...@oracle.com wrote:
 
 Staffan,
 
 On Jan 9, 2015, at 7:38 AM, Staffan Larsen wrote:
 
 It’s getting difficult to get all the information into the same output: 
 hierarchy, interfaces, class loaders and modules. I took a stab at it and it 
 could look like this:
 
 java.lang.Object
 |--java.io.Serializable (java.base, 0x0007c00375f8, iface)
 |--java.util.RandomAccess (java.base, 0x0007c00375f8, iface)
 |--java.lang.Iterable (java.base, 0x0007c00375f8, iface)
 | |--java.util.Collection (java.base, 0x0007c00375f8, iface)
 | | |--java.util.List (java.base, 0x0007c00375f8, iface)
 |--java.util.AbstractCollection  (java.base, 0x0007c00375f8)
 | |  implements java.util.Collection
 | |  implements java.lang.Iterable
 | |--java.util.AbstractList (java.base, 0x0007c00375f8)
 | |implements java.util.List
 | | |--java.util.Arrays$ArrayList (java.base, 0x0007c00375f8)
 | | |implements java.io.Serializable
 | | |implements java.util.RandomAccess
  
 
 But this is pushing what can be visualized in one place.
 
 We will need to add module and class loader information somehow to all the 
 Diagnostic Commands that list classes. In addition we will need a way to see 
 how modules relate to one another. Perhaps it isn’t possible to have all the 
 information in one place, but instead make it possible to cross reference 
 between different diagnostic commands. For example, GC.class_stats could 
 have the module and class loader information, and GC.class_hierarchy would 
 not have to include it. What is missing from making that possible is a 
 unique way of identifying a class (since the name is not unique). All output 
 would need to include that unique identifier and it would be possible to 
 cross reference. The identifier has to be stable during a JVM run, but not 
 between runs.
 I like where you are going with this. Since a given module is within a class 
 loader, putting the the loader/module/class  information in class_stats would 
 be helpful and then having
 other dcmds just need the class/class loader pair for uniqueness. 
 
 Not sure what you are using below for unique identifier.
 I would be tempted to use the class loader hex value since otherwise you are 
 introducing hex values that have no meaning other than as
 cross-references. And the class/class loader pair is guaranteed uniqueness.

I was actually thinking of a unique identifier for a class (the Klass* for 
example), not a {class name, class loader} combo, but as you say, the {class 
name, class loader} combo is also unique and gives more useful information.


 For any class loader you could list its hex value thereby giving the 
 information in a single command that gives meaning to the loader value. 
 
 java.lang.Object/null
 ...
 |-sun.misc.Launcher$AppClassLoader/null (0xyyy)
 |-myapp/0xyyy
 
 Just a thought. If you are not enthused - I am ok with your proposal.

This looks good to me.

/Staffan

 
 thanks,
 Karen
 
 
 The above would then become:
 
 java.lang.Object/0x12345600
 |--java.io.Serializable/0x12345601
 |--java.util.RandomAccess/0x12345602
 |--java.lang.Iterable/0x12345603
 | |--java.util.Collection/0x12345604
 | | |--java.util.List/0x12345605
 |--java.util.AbstractCollection/0x12345606
 | |  implements java.util.Collection/0x12345604
 | |  implements java.lang.Iterable/0x12345603
 | |--java.util.AbstractList/0x12345607
 | |implements java.util.List/0x12345605
 | | |--java.util.Arrays$ArrayList/0x12345608
 | | |implements java.io.Serializable/0x12345601
 | | |implements java.util.RandomAccess/0x12345602
 
 With additions to GC.class_stats:
 
 Index Super ClassLoaderClassName
 1-1 0x0007c0034c48 java.lang.Object/0x12345600
 2 1 0x0007c0034c48 java.util.List/0x12345605
 331 0x0007c0034c48 java.util.AbstractList/0x12345607
 
 And GC.class_histogram:
 
  num #instances #bytes  class name
 --
1:   945 117736  java.lang.Object/0x12345600
2:   442  50352  java.util.List/0x12345605
3:   499  25288  java.util.AbstractList/0x12345607
 
 
 
 /Staffan
 
 On 9 jan 2015, at 09:53, Frederic Parain frederic.par...@oracle.com 
 mailto:frederic.par...@oracle.com wrote:
 
 
 
 On 01/08/2015 10:29 PM, Chris Plummer wrote:
 Hi Karen,
 
 Comments inline.
 
 On 1/8/15 8:07 AM, Karen Kinnear wrote:
 Chris,
 
 Thank you for doing this. I had a couple of questions/comments.
 
 I like your idea of being able to start with a specific class to show
 all subclasses of.
 Ok. I'll add that.
 
 I think the way I read the code this shows the superclass hierarchy,
 not the superinterfaces. With the addition
 of default methods in interfaces, I think we have increased the value
 in seeing superinterfaces.
 It does include interfaces in the output, but not as part of any class
 hierarchy. Interfaces are just 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-01-09 Thread Karen Kinnear
Thanks Frederic for suggesting two different dcmds - they could
share a lot of the code logic.

If folks generally prefer these as separate dcmds - I can file an
rfe to add the inverted one - i.e. start at a given class/interface and
tell me its supertypes.

thanks,
Karen

On Jan 9, 2015, at 3:53 AM, Frederic Parain wrote:

 
 
 On 01/08/2015 10:29 PM, Chris Plummer wrote:
 Hi Karen,
 
 Comments inline.
 
 On 1/8/15 8:07 AM, Karen Kinnear wrote:
 Chris,
 
 Thank you for doing this. I had a couple of questions/comments.
 
 I like your idea of being able to start with a specific class to show
 all subclasses of.
 Ok. I'll add that.
 
 I think the way I read the code this shows the superclass hierarchy,
 not the superinterfaces. With the addition
 of default methods in interfaces, I think we have increased the value
 in seeing superinterfaces.
 It does include interfaces in the output, but not as part of any class
 hierarchy. Interfaces are just shown as regular classes that inherit
 from Object. This is the case if one interface extends another, I
 suppose because extends is just interpreted as implements in this case.
 
 So what I personally would find useful would be to be able to start
 with a specific class and
 find the superclasses and superinterfaces of that class - for the
 debugging I do, I usually am
 trying to look up and need both sets of information. Today if you run
 -XX:+TraceDefaultMethods
 there is one sample way to display all the supertypes of a single
 type, all the way up. I don't know the
 best way to make that consistent with the current output approach,
 e.g. using the |- syntax.
 
 e.g.
 Class java.util.Arrays$ArrayList requires default method processing
 java/util/Arrays$ArrayList
   java/util/AbstractList
 java/util/AbstractCollection
   java/lang/Object
   java/util/Collection
 java/lang/Object
 java/lang/Iterable
   java/lang/Object
 java/util/List
   java/lang/Object
   java/util/Collection
 java/lang/Object
 java/lang/Iterable
   java/lang/Object
   java/util/RandomAccess
 java/lang/Object
   java/io/Serializable
 java/lang/Object
 
 Do you think there could be value to others in the ability to walk up
 the hierarchy as well as to
 see superclasses and superinterfaces at least from that perspective?
 This is a inverted from how my dcmd prints the hierarchy, plus also
 includes interfaces. Inverting the hierarchy means a class is listed
 with every subclass of the class, which I don't think is desirable.
 Including interfaces has the same issue, but introduces a new issue even
 when not inverting the hierarchy. The same interface can be in more than
 one location in the hierarchy, so there is no avoiding printing it more
 than once, so we need to decide how to best include interfaces in the
 output.
 
 It seems to me that we have two very different use cases here, each one
 best served with a different output format:
 
 1 - Listing of all classes/interfaces hierarchy when the dcmd is
 invoked without arguments:
- Chris' output format as described below (with interfaces)
 2 - Investigation on a particular class or interface when a class
 or interface is passed in argument to the dcmd
- Karen's output format, much easier to work with to
   track default methods. Because the output is limited to the
   hierarchy from a single class, there's no class duplication
   in output (single parent class inheritance) and limited
   interfaces duplication.
 
 If the implementations of the two features are too different, we could
 consider having two different dcmds.
 
 My 2 cents,
 
 Fred
 
 The could just be a simple list right after the class that
 implements them:
 
 java.lang.Object
 | ...
 |--MyBaseClass
 | |  implements - MyInterface1
 | |  implements - MyInterface2
 | |--MySubClass
 |  implements - MyInterface1
 |  implements - MyInterface2
 | ...
 |--MyInterface1
 |--MyInterface2
 
 The implements  lines could be optional.
 
 I know cvm would distinguish between interfaces the Class declared it
 implemented, and those it inherited from the interfaces it declared it
 implemented. This was necessary for reflection, and I think also to
 properly build up interfaces tables. I assume hotspot does something
 similar. Is there any need for this information to be conveyed in the
 above output, or just list out every interface implemented, and not
 worry about how the class acquired it.
 Is there value in printing the defining class loader for each class -
 maybe optionally?
 This is already available with GC.class_stats, although not in the
 default output. I suppose the reality is that it might be better handled
 by this DCMD. The main puprose of GC.class_stats is to print statistics
 (counts and sizes), so printing the ClassLoader name there is probably
 not appropriate, but then it's not really appropriate for
 VM.class_hierarchy either. I'm not 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-01-09 Thread Chris Plummer

  
  
On 1/9/15 4:38 AM, Staffan Larsen
  wrote:


  
  It�s getting difficult to get all the information into the same
  output: hierarchy, interfaces, class loaders and modules. I took a
  stab at it and it could look like this:
  
  
  
java.lang.Object
|--java.io.Serializable
(java.base, 0x0007c00375f8, iface)
|--java.util.RandomAccess
(java.base, 0x0007c00375f8, iface)
|--java.lang.Iterable
(java.base, 0x0007c00375f8, iface)
|
|--java.util.Collection (java.base, 0x0007c00375f8,
iface)
| |
|--java.util.List (java.base, 0x0007c00375f8, iface)
|--java.util.AbstractCollection
 (java.base, 0x0007c00375f8)
| |  implements
java.util.Collection
| |  implements java.lang.Iterable
|
|--java.util.AbstractList (java.base, 0x0007c00375f8)
| |    implements java.util.List
| |
|--java.util.Arrays$ArrayList (java.base,
0x0007c00375f8)
| | |    implements java.io.Serializable
| | |    implements java.util.RandomAccess
  

For the most part I like this. The one part I'm
  not too fond of is hex long which I assume represents the
  ClassLoader. Maybe we could just use a simple index, and at the
  end of the dump include a table of the referenced ClassLoaders.
  Possibly just hijack what VM.classloader_stats outputs, but
  include the simple index in the first column.

  
 


But this is pushing what can be visualized in one
  place.


We will need to add module and class loader
  information somehow to all the Diagnostic Commands that list
  classes. In addition we will need a way to see how modules
  relate to one another. Perhaps it isn�t possible to have all
  the information in one place, but instead make it possible to
  cross reference between different diagnostic commands. For
  example, GC.class_stats could have the module and class loader
  information, and GC.class_hierarchy would not have to include
  it. What is missing from making that possible is a unique way
  of identifying a class (since the name is not unique). All
  output would need to include that unique identifier and it
  would be possible to cross reference. The identifier has to be
  stable during a JVM run, but not between runs.
  

I don't know if there is some sort of simple stable ID for a class
other than the address of the Klass instance. And of course this
assumes there isn't any class unloading going on that could result
in reuse of the address. Is that acceptable?

  


The above would then become:



  java.lang.Object/0x12345600
  |--java.io.Serializable/0x12345601
  |--java.util.RandomAccess/0x12345602
  |--java.lang.Iterable/0x12345603
  |
  |--java.util.Collection/0x12345604
  | |
  |--java.util.List/0x12345605
  |--java.util.AbstractCollection/0x12345606
  | |  implements
  java.util.Collection/0x12345604
  | |  implements java.lang.Iterable/0x12345603
  |
  |--java.util.AbstractList/0x12345607
  | |    implements java.util.List/0x12345605
  | |
  |--java.util.Arrays$ArrayList/0x12345608
  | | |    implements java.io.Serializable/0x12345601
  | | |    implements java.util.RandomAccess/0x12345602


  

  With additions to GC.class_stats:




  Index Super
  ClassLoader        ClassName
      1    -1
  0x0007c0034c48 java.lang.Object/0x12345600
  
    2     1
0x0007c0034c48 java.util.List/0x12345605
  
  
    3  
 31 0x0007c0034c48 java.util.AbstractList/0x12345607
  

  


  

  
  


  And GC.class_histogram:




   num    
  #instances         #bytes  class name
  --
     1:          
  945         117736  java.lang.Object/0x12345600
     2:          
  442          50352  java.util.List/0x12345605
     3:          
  499          25288  java.util.AbstractList/0x12345607

  

Would it be better for the class identifier to be in a separate
column from the class name, or is combining them intentional? In any
  

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-01-09 Thread Chris Plummer

  
  
On 1/9/15 4:38 AM, Staffan Larsen
  wrote:


  
  It�s getting difficult to get all the information into the same
  output: hierarchy, interfaces, class loaders and modules. I took a
  stab at it and it could look like this:
  
  
  
java.lang.Object
|--java.io.Serializable
(java.base, 0x0007c00375f8, iface)
|--java.util.RandomAccess
(java.base, 0x0007c00375f8, iface)
|--java.lang.Iterable
(java.base, 0x0007c00375f8, iface)
|
|--java.util.Collection (java.base, 0x0007c00375f8,
iface)
| |
|--java.util.List (java.base, 0x0007c00375f8, iface)
|--java.util.AbstractCollection
 (java.base, 0x0007c00375f8)
| |  implements
java.util.Collection
| |  implements java.lang.Iterable
|
|--java.util.AbstractList (java.base, 0x0007c00375f8)
| |    implements java.util.List
| |
|--java.util.Arrays$ArrayList (java.base,
0x0007c00375f8)
| | |    implements java.io.Serializable
| | |    implements java.util.RandomAccess
  

For the most part I like this. The one part I'm
  not too fond of is hex long which I assume represents the
  ClassLoader. Maybe we could just use a simple index, and at the
  end of the dump include a table of the referenced ClassLoaders.
  Possibly just hijack what VM.classloader_stats outputs, but
  include the simple index in the first column.

  
 


But this is pushing what can be visualized in one
  place.


We will need to add module and class loader
  information somehow to all the Diagnostic Commands that list
  classes. In addition we will need a way to see how modules
  relate to one another. Perhaps it isn�t possible to have all
  the information in one place, but instead make it possible to
  cross reference between different diagnostic commands. For
  example, GC.class_stats could have the module and class loader
  information, and GC.class_hierarchy would not have to include
  it. What is missing from making that possible is a unique way
  of identifying a class (since the name is not unique). All
  output would need to include that unique identifier and it
  would be possible to cross reference. The identifier has to be
  stable during a JVM run, but not between runs.
  

I don't know if there is some sort of simple stable ID for a class
other than the address of the Klass instance. And of course this
assumes there isn't any class unloading going on that could result
in reuse of the address. Is that acceptable?

  


The above would then become:



  java.lang.Object/0x12345600
  |--java.io.Serializable/0x12345601
  |--java.util.RandomAccess/0x12345602
  |--java.lang.Iterable/0x12345603
  |
  |--java.util.Collection/0x12345604
  | |
  |--java.util.List/0x12345605
  |--java.util.AbstractCollection/0x12345606
  | |  implements
  java.util.Collection/0x12345604
  | |  implements java.lang.Iterable/0x12345603
  |
  |--java.util.AbstractList/0x12345607
  | |    implements java.util.List/0x12345605
  | |
  |--java.util.Arrays$ArrayList/0x12345608
  | | |    implements java.io.Serializable/0x12345601
  | | |    implements java.util.RandomAccess/0x12345602


  

  With additions to GC.class_stats:




  Index Super
  ClassLoader        ClassName
      1    -1
  0x0007c0034c48 java.lang.Object/0x12345600
  
    2     1
0x0007c0034c48 java.util.List/0x12345605
  
  
    3  
 31 0x0007c0034c48 java.util.AbstractList/0x12345607
  

  


  

  
  


  And GC.class_histogram:




   num    
  #instances         #bytes  class name
  --
     1:          
  945         117736  java.lang.Object/0x12345600
     2:          
  442          50352  java.util.List/0x12345605
     3:          
  499          25288  java.util.AbstractList/0x12345607

  

Would it be better for the class identifier to be in a separate
column from the class name, or is combining them intentional? In any
  

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-01-09 Thread Stefan Karlsson


On 2015-01-08 20:15, Chris Plummer wrote:

Hi Stefan,

Comments inline below:

On 1/8/15 2:50 AM, Stefan Karlsson wrote:

Hi Chris,

On 2015-01-08 00:29, Chris Plummer wrote:

Hi,

Please review the following changes for the addition of the 
VM.class_hierarchy DCMD. Please read the bug first for some 
background information.


Webrev: http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00/
Bug: https://bugs.openjdk.java.net/browse/JDK-8054888


This looks like a nice feature. I think your suggestion about 
supporting a class name argument as the root of the hierarchy would 
be a nice addition.



Some comments:

Why do you need / use the super_stack? To me it seems like you could 
simplify the could if you get rid of the super_stack and walk the 
Klass::super() chain instead.
The initial implementation actually printed the superclass index as 
the indentation, which required the super_stack, and I just ended up 
keeping it. It looks like I could get rid of all the superclass 
maintenance done in print_class_hierarchy()  if I walk Klass:super() 
in print_class(). I'll make that change.


Why did you add this side-effect to KlassInfoHisto::print_class_state?:

-  super_index = super_e-index();
+  e-set_super_index(super_e-index());


AFAICT, you are not using KlassInfoHisto::print_class_stats to 
implement the VM.class_hierarchy DCMD, right? Or am I missing 
something in your patch?
Originally I did overload print_class_stats to also handle 
VM.class_hierarchy, but in the end decided not to due to the overhead 
of it causing the java heap to be walked. So the above is a remnant, 
but is also consistent with how print_class_hierarchy() sets the 
super_index field of the KlassInfoEntry. However, it may not be 
necessary anymore to maintain the super_index if I make the change 
above to no longer maintain the super_stack. I'll look into that.




A side-note, if it were not for the AnonymousClasses (created by 
Unsafe_DefineAnonymousClass), then this could have be implemented 
with less resources by just walking the Klass::subclass() and 
Klass::next_sibling() links. Which means that you wouldn't have to 
use any of the classes or functionality in heapInspection.hpp/cpp. 
But the anonymous classes is unfortunately not present in the 
subclass/next_sibling hierarchy.
I didn't not realize subclass info was being maintained by Klass. 
Still had CVM stuck in my head, which does not do that. I'm not sure 
what the AnonymousClasses issue is. Can you explain more?


The AnonymousClasses are supposed to be lightweight classes used by 
JSR292. They have a different lifecycle than ordinary Klasses, and are 
not registered in some of the data structures where the ordinary Klasses 
are registered, and one example is the subclass/next_sibling tree. 
Because these classes treated differently, they are a constant source of 
bugs. If you visit Klasses by iterating over a data structure in the 
JVM, you need to know if the AnonymousClasses are present our not. Your 
current code is safe because you walk the ClassLoaderDataGraph, which 
contains the AnonymousKlasses. But a simplified version relying on the 
subclass/next_sibling tree would unfortunately be broken. The 
SystemDictionary is another place where the AnonymousClasses are not 
registered.


Note, that the term anonymous class is an overloaded term and I'm not 
referring to this kind of anonymous classes:

http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html




And some style comments:

http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00/src/share/vm/services/diagnosticCommand.cpp.frames.html 



Maybe it would be nice to move:

  66 #if INCLUDE_SERVICES
  67   DCmdFactory::register_DCmdFactory(new 
DCmdFactoryImplClassHierarchyDCmd(full_export, true, false));

  68 #endif

into the already existing INCLUDE_SERVICE block:

  55 #if INCLUDE_SERVICES // Heap dumping/inspection supported
  56   DCmdFactory::register_DCmdFactory(new 
DCmdFactoryImplHeapDumpDCmd(DCmd_Source_Internal | 
DCmd_Source_AttachAPI, true, false));
  57   DCmdFactory::register_DCmdFactory(new 
DCmdFactoryImplClassHistogramDCmd(full_export, true, false));
  58   DCmdFactory::register_DCmdFactory(new 
DCmdFactoryImplClassStatsDCmd(full_export, true, false));

  59 #endif // INCLUDE_SERVICES

Ok.



http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00/src/share/vm/memory/heapInspection.hpp.frames.html 




I would prefer if you moved the following implementation to the cpp 
file, so that we can keep our includes in our hpp files to a minimal. 
That helps lowering our include complexity.


 218 inline void KlassInfoEntry::add_subclass(KlassInfoEntry* cie) {
 219   if (_subclasses == NULL) {
 220 _subclasses = new  (ResourceObj::C_HEAP, mtInternal) 
GrowableArrayKlassInfoEntry*(4, true);

 221   }
 222   _subclasses-append(cie);
 223 }
 224
 225 inline KlassInfoEntry::~KlassInfoEntry() {
 226   if (_subclasses != NULL) {
 227 delete 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-01-09 Thread Staffan Larsen
It’s getting difficult to get all the information into the same output: 
hierarchy, interfaces, class loaders and modules. I took a stab at it and it 
could look like this:

java.lang.Object
|--java.io.Serializable (java.base, 0x0007c00375f8, iface)
|--java.util.RandomAccess (java.base, 0x0007c00375f8, iface)
|--java.lang.Iterable (java.base, 0x0007c00375f8, iface)
| |--java.util.Collection (java.base, 0x0007c00375f8, iface)
| | |--java.util.List (java.base, 0x0007c00375f8, iface)
|--java.util.AbstractCollection  (java.base, 0x0007c00375f8)
| |  implements java.util.Collection
| |  implements java.lang.Iterable
| |--java.util.AbstractList (java.base, 0x0007c00375f8)
| |implements java.util.List
| | |--java.util.Arrays$ArrayList (java.base, 0x0007c00375f8)
| | |implements java.io.Serializable
| | |implements java.util.RandomAccess
 

But this is pushing what can be visualized in one place.

We will need to add module and class loader information somehow to all the 
Diagnostic Commands that list classes. In addition we will need a way to see 
how modules relate to one another. Perhaps it isn’t possible to have all the 
information in one place, but instead make it possible to cross reference 
between different diagnostic commands. For example, GC.class_stats could have 
the module and class loader information, and GC.class_hierarchy would not have 
to include it. What is missing from making that possible is a unique way of 
identifying a class (since the name is not unique). All output would need to 
include that unique identifier and it would be possible to cross reference. The 
identifier has to be stable during a JVM run, but not between runs.

The above would then become:

java.lang.Object/0x12345600
|--java.io.Serializable/0x12345601
|--java.util.RandomAccess/0x12345602
|--java.lang.Iterable/0x12345603
| |--java.util.Collection/0x12345604
| | |--java.util.List/0x12345605
|--java.util.AbstractCollection/0x12345606
| |  implements java.util.Collection/0x12345604
| |  implements java.lang.Iterable/0x12345603
| |--java.util.AbstractList/0x12345607
| |implements java.util.List/0x12345605
| | |--java.util.Arrays$ArrayList/0x12345608
| | |implements java.io.Serializable/0x12345601
| | |implements java.util.RandomAccess/0x12345602

With additions to GC.class_stats:

Index Super ClassLoaderClassName
1-1 0x0007c0034c48 java.lang.Object/0x12345600
2 1 0x0007c0034c48 java.util.List/0x12345605
331 0x0007c0034c48 java.util.AbstractList/0x12345607

And GC.class_histogram:

 num #instances #bytes  class name
--
   1:   945 117736  java.lang.Object/0x12345600
   2:   442  50352  java.util.List/0x12345605
   3:   499  25288  java.util.AbstractList/0x12345607



/Staffan

 On 9 jan 2015, at 09:53, Frederic Parain frederic.par...@oracle.com wrote:
 
 
 
 On 01/08/2015 10:29 PM, Chris Plummer wrote:
 Hi Karen,
 
 Comments inline.
 
 On 1/8/15 8:07 AM, Karen Kinnear wrote:
 Chris,
 
 Thank you for doing this. I had a couple of questions/comments.
 
 I like your idea of being able to start with a specific class to show
 all subclasses of.
 Ok. I'll add that.
 
 I think the way I read the code this shows the superclass hierarchy,
 not the superinterfaces. With the addition
 of default methods in interfaces, I think we have increased the value
 in seeing superinterfaces.
 It does include interfaces in the output, but not as part of any class
 hierarchy. Interfaces are just shown as regular classes that inherit
 from Object. This is the case if one interface extends another, I
 suppose because extends is just interpreted as implements in this case.
 
 So what I personally would find useful would be to be able to start
 with a specific class and
 find the superclasses and superinterfaces of that class - for the
 debugging I do, I usually am
 trying to look up and need both sets of information. Today if you run
 -XX:+TraceDefaultMethods
 there is one sample way to display all the supertypes of a single
 type, all the way up. I don't know the
 best way to make that consistent with the current output approach,
 e.g. using the |- syntax.
 
 e.g.
 Class java.util.Arrays$ArrayList requires default method processing
 java/util/Arrays$ArrayList
   java/util/AbstractList
 java/util/AbstractCollection
   java/lang/Object
   java/util/Collection
 java/lang/Object
 java/lang/Iterable
   java/lang/Object
 java/util/List
   java/lang/Object
   java/util/Collection
 java/lang/Object
 java/lang/Iterable
   java/lang/Object
   java/util/RandomAccess
 java/lang/Object
   java/io/Serializable
 java/lang/Object
 
 Do you think there could be value to others in the ability to walk up
 the hierarchy as well as to
 see superclasses and superinterfaces at least from that 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-01-08 Thread Mikael Auno
On 2015-01-08 00:29, Chris Plummer wrote:
 At the moment not much testing has been done other than running the DCMD
 and looking at the output. I'll do more once it's clear the code has
 settled. I would like to know if there are any existing tests for
 GC.class_stats and GC.class_histogram (there are none in the test
 directory). If so, possibly one could serve as the basis for a new test
 for VM.class_hierarchy.

Unfortunately, there are no open tests either of them as of yet. There
are, however, internal ones. I can give you the details offline.

Mikael


Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-01-08 Thread Stefan Karlsson

Hi Chris,

On 2015-01-08 00:29, Chris Plummer wrote:

Hi,

Please review the following changes for the addition of the 
VM.class_hierarchy DCMD. Please read the bug first for some background 
information.


Webrev: http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00/
Bug: https://bugs.openjdk.java.net/browse/JDK-8054888


This looks like a nice feature. I think your suggestion about supporting 
a class name argument as the root of the hierarchy would be a nice addition.



Some comments:

Why do you need / use the super_stack? To me it seems like you could 
simplify the could if you get rid of the super_stack and walk the 
Klass::super() chain instead.


Why did you add this side-effect to KlassInfoHisto::print_class_state?:

-  super_index = super_e-index();
+  e-set_super_index(super_e-index());


AFAICT, you are not using KlassInfoHisto::print_class_stats to implement 
the VM.class_hierarchy DCMD, right? Or am I missing something in your patch?


A side-note, if it were not for the AnonymousClasses (created by 
Unsafe_DefineAnonymousClass), then this could have be implemented with 
less resources by just walking the Klass::subclass() and 
Klass::next_sibling() links. Which means that you wouldn't have to use 
any of the classes or functionality in heapInspection.hpp/cpp. But the 
anonymous classes is unfortunately not present in the 
subclass/next_sibling hierarchy.



And some style comments:

http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00/src/share/vm/services/diagnosticCommand.cpp.frames.html

Maybe it would be nice to move:

  66 #if INCLUDE_SERVICES
  67   DCmdFactory::register_DCmdFactory(new 
DCmdFactoryImplClassHierarchyDCmd(full_export, true, false));
  68 #endif

into the already existing INCLUDE_SERVICE block:

  55 #if INCLUDE_SERVICES // Heap dumping/inspection supported
  56   DCmdFactory::register_DCmdFactory(new 
DCmdFactoryImplHeapDumpDCmd(DCmd_Source_Internal | DCmd_Source_AttachAPI, 
true, false));
  57   DCmdFactory::register_DCmdFactory(new 
DCmdFactoryImplClassHistogramDCmd(full_export, true, false));
  58   DCmdFactory::register_DCmdFactory(new 
DCmdFactoryImplClassStatsDCmd(full_export, true, false));
  59 #endif // INCLUDE_SERVICES


http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00/src/share/vm/memory/heapInspection.hpp.frames.html


I would prefer if you moved the following implementation to the cpp 
file, so that we can keep our includes in our hpp files to a minimal. 
That helps lowering our include complexity.


 218 inline void KlassInfoEntry::add_subclass(KlassInfoEntry* cie) {
 219   if (_subclasses == NULL) {
 220 _subclasses = new  (ResourceObj::C_HEAP, mtInternal) 
GrowableArrayKlassInfoEntry*(4, true);
 221   }
 222   _subclasses-append(cie);
 223 }
 224
 225 inline KlassInfoEntry::~KlassInfoEntry() {
 226   if (_subclasses != NULL) {
 227 delete _subclasses;
 228   }
 229 }


http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00/src/share/vm/memory/heapInspection.cpp.frames.html

Could you move the local variables to where they are used:

 316 void KlassHierarchy::print_class_hierarchy(outputStream* st) {
 317   ResourceMark rm;
 318   int i;
 319   Stack KlassInfoEntry*, mtClass class_stack;
 320   Stack KlassInfoEntry*, mtClass super_stack;
 321   GrowableArrayKlassInfoEntry* elements;
 322


For example, 'int i' into the for statements:

 336   // Set the index for each class
 337   for(i=0; i  elements.length(); i++) {
 338 elements.at(i)-set_index(i+1);
 339   }


Could you add spaces around the operators (= and +):

 337   for(i=0; i  elements.length(); i++) {
 338 elements.at(i)-set_index(i+1);


Some of your new comments are not capitalized and some lack a period. 
Example:


 399   // print indentation with proper indicators of superclass.

 454 // Add the stats for this class to the overall totals


Thanks,
StefanK



I expect there will be further restructuring or additional feature 
work. More discussion on that below. I'm not sure if that additional 
work will be done later with a separately bug filed or with this 
initial commit. That's one thing I want to work out with this review.


Currently the bulk of the DCMD is implemented in heapInspection.cpp. 
The  main purpose of this file is to implement the GC.class_stats and 
GC.class_histogram DCMDs. Both of them require walking the java heap 
to count live objects of each type, thus the name 
heapInspection.cpp. This new VM.class_hierarchy DCMD does not 
require walking the heap, but is implemented in this file because it 
leverages the existing KlassInfoTable and related classes 
(KlassInfoEntry, KlassInfoBucket, and KlassClosure).


KlassInfoTable makes it easy to build a database of all loaded 
classes, save additional info gathered for each class, iterate over 
them quickly, and also do quick lookups. This exactly what I needed 
for this DCMD, thus the reuse. There is some downside to this. For 
starters, heapInspection.cpp is 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-01-08 Thread Karen Kinnear
Chris,

Thank you for doing this. I had a couple of questions/comments.

I like your idea of being able to start with a specific class to show all 
subclasses of.

I think the way I read the code this shows the superclass hierarchy, not the 
superinterfaces. With the addition
of default methods in interfaces, I think we have increased the value in seeing 
superinterfaces.

So what I personally would find useful would be to be able to start with a 
specific class and
find the superclasses and superinterfaces of that class - for the debugging I 
do, I usually am
trying to look up and need both sets of information. Today if you run 
-XX:+TraceDefaultMethods
there is one sample way to display all the supertypes of a single type, all the 
way up. I don't know the
best way to make that consistent with the current output approach, e.g. using 
the |- syntax.

e.g.
Class java.util.Arrays$ArrayList requires default method processing
java/util/Arrays$ArrayList
  java/util/AbstractList
java/util/AbstractCollection
  java/lang/Object
  java/util/Collection
java/lang/Object
java/lang/Iterable
  java/lang/Object
java/util/List
  java/lang/Object
  java/util/Collection
java/lang/Object
java/lang/Iterable
  java/lang/Object
  java/util/RandomAccess
java/lang/Object
  java/io/Serializable
java/lang/Object

Do you think there could be value to others in the ability to walk up the 
hierarchy as well as to
see superclasses and superinterfaces at least from that perspective? 

Is there value in printing the defining class loader for each class - maybe 
optionally?
If so, I'm wondering if there might be value in future for the jigsaw project 
adding the module for each class - maybe optionally as well?
Love opinions on that  - especially from the serviceability folks 

thanks,
Karen


On Jan 7, 2015, at 6:29 PM, Chris Plummer wrote:

 Hi,
 
 Please review the following changes for the addition of the 
 VM.class_hierarchy DCMD. Please read the bug first for some background 
 information.
 
 Webrev: http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00/
 Bug: https://bugs.openjdk.java.net/browse/JDK-8054888
 
 I expect there will be further restructuring or additional feature work. More 
 discussion on that below. I'm not sure if that additional work will be done 
 later with a separately bug filed or with this initial commit. That's one 
 thing I want to work out with this review.
 
 Currently the bulk of the DCMD is implemented in heapInspection.cpp. The  
 main purpose of this file is to implement the GC.class_stats and 
 GC.class_histogram DCMDs. Both of them require walking the java heap to count 
 live objects of each type, thus the name heapInspection.cpp. This new 
 VM.class_hierarchy DCMD does not require walking the heap, but is implemented 
 in this file because it leverages the existing KlassInfoTable and related 
 classes (KlassInfoEntry, KlassInfoBucket, and KlassClosure).
 
 KlassInfoTable makes it easy to build a database of all loaded classes, save 
 additional info gathered for each class, iterate over them quickly, and also 
 do quick lookups. This exactly what I needed for this DCMD, thus the reuse. 
 There is some downside to this. For starters, heapInspection.cpp is not the 
 proper place for a DCMD that has nothing to do with heap inspection. Also, 
 KlassInfoEntry is being overloaded now to support 3 different DCMDs, as is 
 KlassInfoTable. As a result each has a few fields and methods that are not 
 used for all 3 DCMDs. Some subclassing might be in order here, but I'm not 
 sure if it's worth it. Opinions welcomed. If I am going to refactor, I would 
 prefer that be done as a next step so I'm not disturbing the existing DCMDs 
 with this first implementation.
 
 I added some comments to code only used for GC.class_stats and 
 GC.class_histogram. I did this when trying to figure them out so I could 
 better understand how to implement VM.class_hierarchy. I can take them out if 
 you think they are not appropriate for this commit.
 
 One other item I like to discuss is whether it is worth adding a class name 
 argument to this DCMD. That would cause just the superclasses and subclasses 
 of the named class to be printed. If you think that is useful, I think it can 
 be added without too much trouble.
 
 At the moment not much testing has been done other than running the DCMD and 
 looking at the output. I'll do more once it's clear the code has settled. I 
 would like to know if there are any existing tests for GC.class_stats and 
 GC.class_histogram (there are none in the test directory). If so, possibly 
 one could serve as the basis for a new test for VM.class_hierarchy.
 
 thanks,
 
 Chris



Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-01-08 Thread Chris Plummer

  
  
Hi Stefan,
  
  Comments inline below:
  
  On 1/8/15 2:50 AM, Stefan Karlsson wrote:

Hi
  Chris,
  
  
  On 2015-01-08 00:29, Chris Plummer wrote:
  
  Hi,


Please review the following changes for the addition of the
VM.class_hierarchy DCMD. Please read the bug first for some
background information.


Webrev: http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00/

Bug: https://bugs.openjdk.java.net/browse/JDK-8054888

  
  
  This looks like a nice feature. I think your suggestion about
  supporting a class name argument as the root of the hierarchy
  would be a nice addition.
  
  
  
  Some comments:
  
  
  Why do you need / use the super_stack? To me it seems like you
  could simplify the could if you get rid of the super_stack and
  walk the Klass::super() chain instead.
  

The initial implementation actually printed the superclass index as
the indentation, which required the super_stack, and I just ended up
keeping it. It looks like I could get rid of all the superclass
maintenance done in

print_class_hierarchy()  if I walk Klass:super() in print_class().
I'll make that change.

  
  Why did you add this side-effect to
  KlassInfoHisto::print_class_state?:
  
  
  -  super_index = super_e-index();
  
  +  e-set_super_index(super_e-index());
  


  
  
  AFAICT, you are not using KlassInfoHisto::print_class_stats to
  implement the VM.class_hierarchy DCMD, right? Or am I missing
  something in your patch?
  

Originally I did overload print_class_stats to also handle
VM.class_hierarchy, but in the end decided not to due to the
overhead of it causing the java heap to be walked. So the above is a
remnant, but is also consistent with how print_class_hierarchy()
sets the super_index field of the KlassInfoEntry. However, it may
not be necessary anymore to maintain the super_index if I make the
change above to no longer maintain the super_stack. I'll look into
that.


  
  A side-note, if it were not for the AnonymousClasses (created by
  Unsafe_DefineAnonymousClass), then this could have be implemented
  with less resources by just walking the Klass::subclass() and
  Klass::next_sibling() links. Which means that you wouldn't have to
  use any of the classes or functionality in heapInspection.hpp/cpp.
  But the anonymous classes is unfortunately not present in the
  subclass/next_sibling hierarchy.
  

I didn't not realize subclass info was being maintained by Klass.
Still had CVM stuck in my head, which does not do that. I'm not sure
what the AnonymousClasses issue is. Can you explain more?

  
  
  And some style comments:
  
  
http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00/src/share/vm/services/diagnosticCommand.cpp.frames.html
  
  
  Maybe it would be nice to move:
  
  
    66 #if INCLUDE_SERVICES
  
    67   DCmdFactory::register_DCmdFactory(new
  DCmdFactoryImplClassHierarchyDCmd(full_export, true,
  false));
  
    68 #endif
  
  
  into the already existing INCLUDE_SERVICE block:
  
  
    55 #if INCLUDE_SERVICES // Heap dumping/inspection supported
  
    56   DCmdFactory::register_DCmdFactory(new
  DCmdFactoryImplHeapDumpDCmd(DCmd_Source_Internal |
  DCmd_Source_AttachAPI, true, false));
  
    57   DCmdFactory::register_DCmdFactory(new
  DCmdFactoryImplClassHistogramDCmd(full_export, true,
  false));
  
    58   DCmdFactory::register_DCmdFactory(new
  DCmdFactoryImplClassStatsDCmd(full_export, true, false));
  
    59 #endif // INCLUDE_SERVICES
  

Ok.

  
  
http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00/src/share/vm/memory/heapInspection.hpp.frames.html
  
  
  
  I would prefer if you moved the following implementation to the
  cpp file, so that we can keep our includes in our hpp files to a
  minimal. That helps lowering our include complexity.
  
  
   218 inline void KlassInfoEntry::add_subclass(KlassInfoEntry* cie)
  {
  
   219   if (_subclasses == NULL) {
  
   220 _subclasses = new  (ResourceObj::C_HEAP, mtInternal)
  GrowableArrayKlassInfoEntry*(4, true);
  
   221   }
  
   222   _subclasses-append(cie);
  
   223 }
  
   224
  
   225 inline KlassInfoEntry::~KlassInfoEntry() {
  
   226   if (_subclasses != NULL) {
  
   227 delete _subclasses;
  
   228   }
  
   229 }
  
  

I guess I'm a bit unclear on this, 

Re: [9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-01-08 Thread Chris Plummer

Hi Karen,

Comments inline.

On 1/8/15 8:07 AM, Karen Kinnear wrote:

Chris,

Thank you for doing this. I had a couple of questions/comments.

I like your idea of being able to start with a specific class to show all 
subclasses of.

Ok. I'll add that.


I think the way I read the code this shows the superclass hierarchy, not the 
superinterfaces. With the addition
of default methods in interfaces, I think we have increased the value in seeing 
superinterfaces.
It does include interfaces in the output, but not as part of any class 
hierarchy. Interfaces are just shown as regular classes that inherit 
from Object. This is the case if one interface extends another, I 
suppose because extends is just interpreted as implements in this case.


So what I personally would find useful would be to be able to start with a 
specific class and
find the superclasses and superinterfaces of that class - for the debugging I 
do, I usually am
trying to look up and need both sets of information. Today if you run 
-XX:+TraceDefaultMethods
there is one sample way to display all the supertypes of a single type, all the 
way up. I don't know the
best way to make that consistent with the current output approach, e.g. using 
the |- syntax.

e.g.
Class java.util.Arrays$ArrayList requires default method processing
java/util/Arrays$ArrayList
   java/util/AbstractList
 java/util/AbstractCollection
   java/lang/Object
   java/util/Collection
 java/lang/Object
 java/lang/Iterable
   java/lang/Object
 java/util/List
   java/lang/Object
   java/util/Collection
 java/lang/Object
 java/lang/Iterable
   java/lang/Object
   java/util/RandomAccess
 java/lang/Object
   java/io/Serializable
 java/lang/Object

Do you think there could be value to others in the ability to walk up the 
hierarchy as well as to
see superclasses and superinterfaces at least from that perspective?
This is a inverted from how my dcmd prints the hierarchy, plus also 
includes interfaces. Inverting the hierarchy means a class is listed 
with every subclass of the class, which I don't think is desirable. 
Including interfaces has the same issue, but introduces a new issue even 
when not inverting the hierarchy. The same interface can be in more than 
one location in the hierarchy, so there is no avoiding printing it more 
than once, so we need to decide how to best include interfaces in the 
output. The could just be a simple list right after the class that 
implements them:


java.lang.Object
| ...
|--MyBaseClass
| |  implements - MyInterface1
| |  implements - MyInterface2
| |--MySubClass
|  implements - MyInterface1
|  implements - MyInterface2
| ...
|--MyInterface1
|--MyInterface2

The implements  lines could be optional.

I know cvm would distinguish between interfaces the Class declared it 
implemented, and those it inherited from the interfaces it declared it 
implemented. This was necessary for reflection, and I think also to 
properly build up interfaces tables. I assume hotspot does something 
similar. Is there any need for this information to be conveyed in the 
above output, or just list out every interface implemented, and not 
worry about how the class acquired it.

Is there value in printing the defining class loader for each class - maybe 
optionally?
This is already available with GC.class_stats, although not in the 
default output. I suppose the reality is that it might be better handled 
by this DCMD. The main puprose of GC.class_stats is to print statistics 
(counts and sizes), so printing the ClassLoader name there is probably 
not appropriate, but then it's not really appropriate for 
VM.class_hierarchy either. I'm not sure how best to handle this. One or 
both DCMDs possibly should be re-purposed and more clearly define what 
type of data it displays.

If so, I'm wondering if there might be value in future for the jigsaw project 
adding the module for each class - maybe optionally as well?
This relates to my above statement. We need to figure out what type of 
data is useful, and which dcmds should handle them.

Love opinions on that  - especially from the serviceability folks

thanks,
Karen

Thanks for the input.

Chris



On Jan 7, 2015, at 6:29 PM, Chris Plummer wrote:


Hi,

Please review the following changes for the addition of the VM.class_hierarchy 
DCMD. Please read the bug first for some background information.

Webrev: http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00/
Bug: https://bugs.openjdk.java.net/browse/JDK-8054888

I expect there will be further restructuring or additional feature work. More 
discussion on that below. I'm not sure if that additional work will be done 
later with a separately bug filed or with this initial commit. That's one thing 
I want to work out with this review.

Currently the bulk of the DCMD is implemented in heapInspection.cpp. The  main purpose of 
this file is to implement the GC.class_stats and 

[9] RFR (M) 8054888: Runtime: Add Diagnostic Command that prints the class hierarchy

2015-01-07 Thread Chris Plummer

Hi,

Please review the following changes for the addition of the 
VM.class_hierarchy DCMD. Please read the bug first for some background 
information.


Webrev: http://cr.openjdk.java.net/~cjplummer/8054888/webrev.00/
Bug: https://bugs.openjdk.java.net/browse/JDK-8054888

I expect there will be further restructuring or additional feature work. 
More discussion on that below. I'm not sure if that additional work will 
be done later with a separately bug filed or with this initial commit. 
That's one thing I want to work out with this review.


Currently the bulk of the DCMD is implemented in heapInspection.cpp. 
The  main purpose of this file is to implement the GC.class_stats and 
GC.class_histogram DCMDs. Both of them require walking the java heap to 
count live objects of each type, thus the name heapInspection.cpp. 
This new VM.class_hierarchy DCMD does not require walking the heap, but 
is implemented in this file because it leverages the existing 
KlassInfoTable and related classes (KlassInfoEntry, KlassInfoBucket, and 
KlassClosure).


KlassInfoTable makes it easy to build a database of all loaded classes, 
save additional info gathered for each class, iterate over them quickly, 
and also do quick lookups. This exactly what I needed for this DCMD, 
thus the reuse. There is some downside to this. For starters, 
heapInspection.cpp is not the proper place for a DCMD that has nothing 
to do with heap inspection. Also, KlassInfoEntry is being overloaded now 
to support 3 different DCMDs, as is KlassInfoTable. As a result each has 
a few fields and methods that are not used for all 3 DCMDs. Some 
subclassing might be in order here, but I'm not sure if it's worth it. 
Opinions welcomed. If I am going to refactor, I would prefer that be 
done as a next step so I'm not disturbing the existing DCMDs with this 
first implementation.


I added some comments to code only used for GC.class_stats and 
GC.class_histogram. I did this when trying to figure them out so I could 
better understand how to implement VM.class_hierarchy. I can take them 
out if you think they are not appropriate for this commit.


One other item I like to discuss is whether it is worth adding a class 
name argument to this DCMD. That would cause just the superclasses and 
subclasses of the named class to be printed. If you think that is 
useful, I think it can be added without too much trouble.


At the moment not much testing has been done other than running the DCMD 
and looking at the output. I'll do more once it's clear the code has 
settled. I would like to know if there are any existing tests for 
GC.class_stats and GC.class_histogram (there are none in the test 
directory). If so, possibly one could serve as the basis for a new test 
for VM.class_hierarchy.


thanks,

Chris