diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2015-01-16 22:36:49 +0100 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2015-01-16 23:21:52 +0100 |
commit | f3f9eb41aacc9731f8f00ed6c2bd52a30eb4ee76 (patch) | |
tree | e5062c86ef0474ebbac38e200596353035aab1ae | |
parent | afebceee78155c66564921eab7dd2170f820fdbf (diff) | |
download | scala-f3f9eb41aacc9731f8f00ed6c2bd52a30eb4ee76.tar.gz scala-f3f9eb41aacc9731f8f00ed6c2bd52a30eb4ee76.tar.bz2 scala-f3f9eb41aacc9731f8f00ed6c2bd52a30eb4ee76.zip |
Address review feedback
- Rename CodeRepository to ByteCodeRepository
- Scaladoc on OptimizerReporting
- Scaladoc on ByteCodeRepository
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala | 13 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala | 10 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala (renamed from src/compiler/scala/tools/nsc/backend/jvm/opt/CodeRepository.scala) | 37 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/opt/OptimizerReporting.scala | 3 |
4 files changed, 44 insertions, 19 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala index 11ee0d127b..a9bce82acd 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala @@ -9,7 +9,7 @@ package backend.jvm import scala.tools.asm import asm.Opcodes import scala.tools.asm.tree.{InnerClassNode, ClassNode} -import opt.CodeRepository +import opt.ByteCodeRepository import scala.collection.convert.decorateAsScala._ /** @@ -32,7 +32,10 @@ abstract class BTypes { /** * Tools for parsing classfiles, used by the inliner. */ - val codeRepository: CodeRepository + val byteCodeRepository: ByteCodeRepository + + // Allows to define per-run caches here and in the CallGraph component, which don't have a global + def recordPerRunCache[T <: collection.generic.Clearable](cache: T): T /** * A map from internal names to ClassBTypes. Every ClassBType is added to this map on its @@ -45,13 +48,13 @@ abstract class BTypes { * Concurrent because stack map frames are computed when in the class writer, which might run * on multiple classes concurrently. */ - val classBTypeFromInternalName: collection.concurrent.Map[InternalName, ClassBType] + val classBTypeFromInternalName: collection.concurrent.Map[InternalName, ClassBType] = recordPerRunCache(collection.concurrent.TrieMap.empty[InternalName, ClassBType]) /** * Parse the classfile for `internalName` and construct the [[ClassBType]]. */ def classBTypeFromParsedClassfile(internalName: InternalName): ClassBType = { - classBTypeFromClassNode(codeRepository.classNode(internalName)) + classBTypeFromClassNode(byteCodeRepository.classNode(internalName)) } /** @@ -90,7 +93,7 @@ abstract class BTypes { */ def nestedInCurrentClass(innerClassNode: InnerClassNode): Boolean = { (innerClassNode.outerName != null && innerClassNode.outerName == classNode.name) || - (innerClassNode.outerName == null && codeRepository.classNode(innerClassNode.name).outerClass == classNode.name) + (innerClassNode.outerName == null && byteCodeRepository.classNode(innerClassNode.name).outerClass == classNode.name) } val nestedClasses: List[ClassBType] = classNode.innerClasses.asScala.collect({ diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala index 9b8ac82340..94f9b585d9 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala @@ -7,7 +7,9 @@ package scala.tools.nsc package backend.jvm import scala.tools.asm -import opt.CodeRepository +import opt.ByteCodeRepository +import scala.tools.asm.tree.ClassNode +import scala.tools.nsc.backend.jvm.opt.ByteCodeRepository.Source import BTypes.InternalName /** @@ -34,15 +36,13 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes { val coreBTypes = new CoreBTypesProxy[this.type](this) import coreBTypes._ - val codeRepository = new CodeRepository(global.classPath) + val byteCodeRepository = new ByteCodeRepository(global.classPath, recordPerRunCache(collection.concurrent.TrieMap.empty[InternalName, (ClassNode, Source)])) final def initializeCoreBTypes(): Unit = { coreBTypes.setBTypes(new CoreBTypes[this.type](this)) } - val classBTypeFromInternalName = { - global.perRunCaches.recordCache(collection.concurrent.TrieMap.empty[InternalName, ClassBType]) - } + def recordPerRunCache[T <: collection.generic.Clearable](cache: T): T = perRunCaches.recordCache(cache) // helpers that need access to global. // TODO @lry create a separate component, they don't belong to BTypesFromSymbols diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/CodeRepository.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala index 285855d083..7b424d2107 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CodeRepository.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala @@ -13,22 +13,32 @@ import scala.collection.convert.decorateAsScala._ import scala.tools.nsc.io.AbstractFile import scala.tools.nsc.util.ClassFileLookup import OptimizerReporting._ +import ByteCodeRepository._ +import BTypes.InternalName -class CodeRepository(val classPath: ClassFileLookup[AbstractFile]) { - import BTypes.InternalName - +/** + * The ByteCodeRepository provides utilities to read the bytecode of classfiles from the compilation + * classpath. Parsed classes are cached in the `classes` map. + * + * @param classPath The compiler classpath where classfiles are searched and read from. + * @param classes Cache for parsed ClassNodes. Also stores the source of the bytecode: + * [[Classfile]] if read from `classPath`, [[CompilationUnit]] if the bytecode + * corresponds to a class being compiled. + */ +class ByteCodeRepository(val classPath: ClassFileLookup[AbstractFile], val classes: collection.concurrent.Map[InternalName, (ClassNode, Source)]) { /** - * Cache for parsed ClassNodes. + * The class node and source for an internal name. If the class node is not yet available, it is + * parsed from the classfile on the compile classpath. */ - val classes: collection.concurrent.Map[InternalName, ClassNode] = collection.concurrent.TrieMap.empty[InternalName, ClassNode] + def classNodeAndSource(internalName: InternalName): (ClassNode, Source) = { + classes.getOrElseUpdate(internalName, (parseClass(internalName), Classfile)) + } /** * The class node for an internal name. If the class node is not yet available, it is parsed from * the classfile on the compile classpath. */ - def classNode(internalName: InternalName): ClassNode = { - classes.getOrElseUpdate(internalName, parseClass(internalName)) - } + def classNode(internalName: InternalName) = classNodeAndSource(internalName)._1 /** * The field node for a field matching `name` and `descriptor`, accessed in class `classInternalName`. @@ -74,7 +84,6 @@ class CodeRepository(val classPath: ClassFileLookup[AbstractFile]) { // http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.11 // https://jcp.org/aboutJava/communityprocess/final/jsr045/index.html removeLineNumberNodes(classNode) - classes(internalName) = classNode classNode } getOrElse { inlineFailure(s"Class file for class $fullName not found.") @@ -91,3 +100,13 @@ class CodeRepository(val classPath: ClassFileLookup[AbstractFile]) { } } } + +object ByteCodeRepository { + /** + * The source of a ClassNode in the ByteCodeRepository. Can be either [[CompilationUnit]] if the + * class is being compiled or [[Classfile]] if the class was parsed from the compilation classpath. + */ + sealed trait Source + object CompilationUnit extends Source + object Classfile extends Source +} diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/OptimizerReporting.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/OptimizerReporting.scala index c07fda2bc5..7002e43d98 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/OptimizerReporting.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/OptimizerReporting.scala @@ -9,6 +9,9 @@ package backend.jvm import scala.tools.asm import asm.tree._ +/** + * Reporting utilities used in the optimizer. + */ object OptimizerReporting { def methodSignature(className: String, methodName: String, methodDescriptor: String): String = { className + "::" + methodName + methodDescriptor |