From 2aa44c230c96b0ceb8e2b84c8095620a1be5a77f Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 26 Apr 2012 07:02:55 -0700 Subject: 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 ()V // this one is weird, wonder why there's a generic signature 115 signature $div$colon$bslash (TA1;Lscala/Function2;)TA1; 105 signature applyOrElse (TA1;Lscala/Function1;)TB1; 103 signature view ()Ljava/lang/Object; 101 signature toSet ()Lscala/collection/immutable/Set; And the top five name/descriptor combinations. 11170 descriptor ()V 10155 descriptor serialVersionUID J 7130 descriptor apply (Ljava/lang/Object;)Ljava/lang/Object; 3028 descriptor apply ()Ljava/lang/Object; 2426 descriptor ()V --- test/files/run/inner-parse/J_1.java | 9 +++++++++ test/files/run/inner-parse/S_2.scala | 9 +++++++++ test/files/run/inner-parse/S_3.scala | 12 ++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 test/files/run/inner-parse/J_1.java create mode 100644 test/files/run/inner-parse/S_2.scala create mode 100644 test/files/run/inner-parse/S_3.scala (limited to 'test/files/run/inner-parse') 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) + } + } +} -- cgit v1.2.3