diff options
author | Paul Phillips <paulp@improving.org> | 2012-04-26 07:02:55 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-04-26 10:04:33 -0700 |
commit | 2aa44c230c96b0ceb8e2b84c8095620a1be5a77f (patch) | |
tree | 2b0d6e52c9d99bb8a90e9f7498e6cd6aee04f8ea /test/files | |
parent | 99388a81d42cde0cb0e8ecd57f290f6df25b9bdd (diff) | |
download | scala-2aa44c230c96b0ceb8e2b84c8095620a1be5a77f.tar.gz scala-2aa44c230c96b0ceb8e2b84c8095620a1be5a77f.tar.bz2 scala-2aa44c230c96b0ceb8e2b84c8095620a1be5a77f.zip |
A brand new, fast classfile parser.
Try it: ./tools/dump-class ./build/quick/classes
The output is intended to be easy to filter on the command line.
This is a starting point for lots of interesting bytecode analysis
for which we have waited too long.
Example. All generic signatures we produce.
// almost 20K classfiles
% find build/quick/classes -name '*.class' |wc -l
18519
// fully parsed in 6 seconds
tools/dump-class build/quick/classes |grep "^ signature" | wc -l
50802
real 0m6.230s
It's designed to be easy to make faster if you don't care about
particular classfile bits; you can override those methods to jump
forward in the input stream rather than building a structure.
For just a little sampling, here are our most frequently
repeated name/signature combinations.
194 signature <init> ()V // this one is weird, wonder why there's a generic signature
115 signature $div$colon$bslash <A1:Ljava/lang/Object;>(TA1;Lscala/Function2<TA1;TA1;TA1;>;)TA1;
105 signature applyOrElse <A1:Ljava/lang/Object;B1:Ljava/lang/Object;>(TA1;Lscala/Function1<TA1;TB1;>;)TB1;
103 signature view ()Ljava/lang/Object;
101 signature toSet <B:Ljava/lang/Object;>()Lscala/collection/immutable/Set<TB;>;
And the top five name/descriptor combinations.
11170 descriptor <clinit> ()V
10155 descriptor serialVersionUID J
7130 descriptor apply (Ljava/lang/Object;)Ljava/lang/Object;
3028 descriptor apply ()Ljava/lang/Object;
2426 descriptor <init> ()V
Diffstat (limited to 'test/files')
-rw-r--r-- | test/files/run/inner-parse.check | 86 | ||||
-rw-r--r-- | test/files/run/inner-parse/J_1.java | 9 | ||||
-rw-r--r-- | test/files/run/inner-parse/S_2.scala | 9 | ||||
-rw-r--r-- | test/files/run/inner-parse/S_3.scala | 12 |
4 files changed, 116 insertions, 0 deletions
diff --git a/test/files/run/inner-parse.check b/test/files/run/inner-parse.check new file mode 100644 index 0000000000..87ea9ddeb5 --- /dev/null +++ b/test/files/run/inner-parse.check @@ -0,0 +1,86 @@ +file Test$$anonfun$main$1.class +class Test$$anonfun$main$1 extends scala.runtime.AbstractFunction1$mcVL$sp + interface scala.Serializable + inner/anon anonymous class: Test$$anonfun$main$1 + descriptor <clinit> ()V + descriptor apply (Lscala/Tuple2;)V + descriptor apply (Ljava/lang/Object;)Ljava/lang/Object; + descriptor cwd$1 Ljava/lang/String; + descriptor serialVersionUID J + descriptor <init> (Ljava/lang/String;)V + signature apply (Lscala/Tuple2<Ljava/lang/String;Lscala/reflect/internal/JvmClassInfo;>;)V + +file Test$.class +class Test$ extends java.lang.Object + inner/anon anonymous class: Test$$anonfun$main$1 + descriptor <clinit> ()V + descriptor MODULE$ LTest$; + descriptor main ([Ljava/lang/String;)V + descriptor <init> ()V + +file Test.class +class Test extends java.lang.Object + inner/anon anonymous class: Test$$anonfun$main$1 + descriptor main ([Ljava/lang/String;)V + +file j/J_1$B$C$D.class +class j.J_1$B$C$D extends java.lang.Object + inner B j.J_1$B in j.J_1 + inner C j.J_1$B$C in j.J_1$B + inner/enclosing D enclosing class: j.J_1$B$C + descriptor <init> (Lj/J_1$B$C;)V + descriptor this$2 Lj/J_1$B$C; + +file j/J_1$B$C.class +class j.J_1$B$C extends java.lang.Object + inner B j.J_1$B in j.J_1 + inner/enclosing C enclosing class: j.J_1$B + inner/nested D member class: j.J_1$B$C$D + descriptor <init> (Lj/J_1$B;)V + descriptor this$1 Lj/J_1$B; + +file j/J_1$B.class +class j.J_1$B extends java.lang.Object + inner/enclosing B enclosing class: j.J_1 + inner/nested C member class: j.J_1$B$C + descriptor <init> (Lj/J_1;)V + descriptor this$0 Lj/J_1; + +file j/J_1.class +class j.J_1 extends java.lang.Object + interface java.util.RandomAccess + inner/nested B member class: j.J_1$B + descriptor <init> ()V + +file s/J_1$B$C$D.class +class s.J_1$B$C$D extends java.lang.Object + inner B s.J_1$B in s.J_1 + inner C s.J_1$B$C in s.J_1$B + inner/enclosing D enclosing class: s.J_1$B$C + descriptor $outer Ls/J_1$B$C; + descriptor s$J_1$B$C$D$$$outer ()Ls/J_1$B$C; + descriptor <init> (Ls/J_1$B$C;)V + +file s/J_1$B$C.class +class s.J_1$B$C extends java.lang.Object + inner B s.J_1$B in s.J_1 + inner/enclosing C enclosing class: s.J_1$B + inner/nested D member class: s.J_1$B$C$D + descriptor $outer Ls/J_1$B; + descriptor s$J_1$B$C$$$outer ()Ls/J_1$B; + descriptor <init> (Ls/J_1$B;)V + +file s/J_1$B.class +class s.J_1$B extends java.lang.Object + inner/enclosing B enclosing class: s.J_1 + inner/nested C member class: s.J_1$B$C + descriptor $outer Ls/J_1; + descriptor s$J_1$B$$$outer ()Ls/J_1; + descriptor <init> (Ls/J_1;)V + +file s/J_1.class +class s.J_1 extends java.lang.Object + interface java.util.RandomAccess + inner/nested B member class: s.J_1$B + descriptor <init> ()V + diff --git a/test/files/run/inner-parse/J_1.java b/test/files/run/inner-parse/J_1.java new file mode 100644 index 0000000000..920ab951ab --- /dev/null +++ b/test/files/run/inner-parse/J_1.java @@ -0,0 +1,9 @@ +package j; + +public class J_1 implements java.util.RandomAccess { // "random" marker interface + class B { + class C { + class D { } + } + } +} diff --git a/test/files/run/inner-parse/S_2.scala b/test/files/run/inner-parse/S_2.scala new file mode 100644 index 0000000000..fd144a40b7 --- /dev/null +++ b/test/files/run/inner-parse/S_2.scala @@ -0,0 +1,9 @@ +package s; + +class J_1 extends java.util.RandomAccess { + class B { + class C { + class D { } + } + } +} diff --git a/test/files/run/inner-parse/S_3.scala b/test/files/run/inner-parse/S_3.scala new file mode 100644 index 0000000000..296a651460 --- /dev/null +++ b/test/files/run/inner-parse/S_3.scala @@ -0,0 +1,12 @@ +import scala.reflect.internal.JvmClassInfo + +object Test { + def main(args: Array[String]): Unit = { + val cwd = sys.props("partest.output") + + for ((f, info) <- JvmClassInfo.classInfoList(cwd)) { + println("file " + f.stripPrefix(cwd + "/")) + println(info) + } + } +} |