diff options
author | Adriaan Moors <adriaan@lightbend.com> | 2016-08-09 22:55:57 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan@lightbend.com> | 2016-08-29 09:50:39 +0200 |
commit | a3604707303e4b1f45b6afabccaf00510b281912 (patch) | |
tree | 3aabe0da13ae6cbb1e3d346b2c60228f76759e25 /src/compiler/scala/tools/nsc | |
parent | 7eb34a61ee1e08e95b983fe457307c24cfd76d3a (diff) | |
download | scala-a3604707303e4b1f45b6afabccaf00510b281912.tar.gz scala-a3604707303e4b1f45b6afabccaf00510b281912.tar.bz2 scala-a3604707303e4b1f45b6afabccaf00510b281912.zip |
asmutils
decompile classfiles in parallel to aid in diffing bytecode between quick & strap
```
mkdir class-repo
cd class-repo
git init .
( cd .. ; sbt publishLocal )
v="2.12.0-local-$(g rev-parse --short HEAD)" ( cd ~/git/scala-2 ; sbt -Dstarr.version=$v compile )
for i in compiler interactive junit library partest-extras partest-javaagent reflect repl repl-jline repl-jline-embedded scaladoc scalap
do
cp -a ~/git/scala/build/quick/classes/$i .
~/git/scala/build/quick/bin/scala scala.tools.nsc.backend.jvm.AsmUtils $(find $i -name "*.class" )
g add $(find $i -name "*.asm" )
done
g commit -m"quick"
for i in compiler interactive junit library partest-extras partest-javaagent reflect repl repl-jline repl-jline-embedded scaladoc scalap
do
cp -a ~/git/scala-2/build/quick/classes/$i/* $i/
~/git/scala/build/quick/bin/scala scala.tools.nsc.backend.jvm.AsmUtils $(find $i -name "*.class" )
done
git --no-pager diff | mate
```
Diffstat (limited to 'src/compiler/scala/tools/nsc')
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala | 46 |
1 files changed, 33 insertions, 13 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala index 630b2b6c7f..1982c7f643 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala @@ -5,11 +5,15 @@ package scala.tools.nsc.backend.jvm -import scala.tools.asm.tree.{InsnList, AbstractInsnNode, ClassNode, MethodNode} -import java.io.{StringWriter, PrintWriter} -import scala.tools.asm.util.{CheckClassAdapter, TraceClassVisitor, TraceMethodVisitor, Textifier} -import scala.tools.asm.{ClassReader, ClassWriter, Attribute} +import scala.tools.asm.tree.{AbstractInsnNode, ClassNode, FieldNode, InsnList, MethodNode} +import java.io.{PrintWriter, StringWriter} +import java.util + +import scala.tools.asm.util.{CheckClassAdapter, Textifier, TraceClassVisitor, TraceMethodVisitor} +import scala.tools.asm.{Attribute, ClassReader, ClassWriter} import scala.collection.JavaConverters._ +import scala.concurrent.duration.Duration +import scala.concurrent.{Await, Future} import scala.tools.nsc.backend.jvm.analysis.InitialProducer import scala.tools.nsc.backend.jvm.opt.InlineInfoAttributePrototype @@ -64,21 +68,37 @@ object AsmUtils { bytes } - def textifyClassStably(bytes: Array[Byte]): Unit = { + def classFromBytes(bytes: Array[Byte]): ClassNode = { val node = new ClassNode() new ClassReader(bytes).accept(node, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES) - node.fields = node.fields.asScala.sortBy(_.name).asJava - node.methods = node.methods.asScala.sortBy(_.name).asJava - node.visibleAnnotations = null - node.attrs = null - node.invisibleAnnotations = null + node + } + +// def main(args: Array[String]): Unit = println(textify(sortedClassRead(classBytes(args.head)))) + + def sortClassMembers(node: ClassNode): node.type = { + node.fields.sort(_.name compareTo _.name) + node.methods.sort(_.name compareTo _.name) + node + } + + // drop ScalaSig annotation and class attributes + def zapScalaClassAttrs(node: ClassNode): node.type = { + if (node.visibleAnnotations != null) + node.visibleAnnotations = node.visibleAnnotations.asScala.filterNot(a => a == null || a.desc.contains("Lscala/reflect/ScalaSignature")).asJava - println(textify(node)) + node.attrs = null + node } - def main(args: Array[String]): Unit = { - textifyClassStably(classBytes(args.head)) + def main(args: Array[String]): Unit = args.par.foreach { classFileName => + val node = zapScalaClassAttrs(sortClassMembers(classFromBytes(classBytes(classFileName)))) + + val pw = new PrintWriter(classFileName + ".asm") + val trace = new TraceClassVisitor(pw) + node.accept(trace) + pw.close() } /** |