From a3604707303e4b1f45b6afabccaf00510b281912 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Tue, 9 Aug 2016 22:55:57 -0700 Subject: 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 ``` --- .../scala/tools/nsc/backend/jvm/AsmUtils.scala | 46 ++++++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) (limited to 'src/compiler/scala/tools/nsc/backend') 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() } /** -- cgit v1.2.3