Skip to content

Commit f3f9eb4

Browse files
committed
Address review feedback
- Rename CodeRepository to ByteCodeRepository - Scaladoc on OptimizerReporting - Scaladoc on ByteCodeRepository
1 parent afebcee commit f3f9eb4

File tree

4 files changed

+44
-19
lines changed

4 files changed

+44
-19
lines changed

src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ package backend.jvm
99
import scala.tools.asm
1010
import asm.Opcodes
1111
import scala.tools.asm.tree.{InnerClassNode, ClassNode}
12-
import opt.CodeRepository
12+
import opt.ByteCodeRepository
1313
import scala.collection.convert.decorateAsScala._
1414

1515
/**
@@ -32,7 +32,10 @@ abstract class BTypes {
3232
/**
3333
* Tools for parsing classfiles, used by the inliner.
3434
*/
35-
val codeRepository: CodeRepository
35+
val byteCodeRepository: ByteCodeRepository
36+
37+
// Allows to define per-run caches here and in the CallGraph component, which don't have a global
38+
def recordPerRunCache[T <: collection.generic.Clearable](cache: T): T
3639

3740
/**
3841
* A map from internal names to ClassBTypes. Every ClassBType is added to this map on its
@@ -45,13 +48,13 @@ abstract class BTypes {
4548
* Concurrent because stack map frames are computed when in the class writer, which might run
4649
* on multiple classes concurrently.
4750
*/
48-
val classBTypeFromInternalName: collection.concurrent.Map[InternalName, ClassBType]
51+
val classBTypeFromInternalName: collection.concurrent.Map[InternalName, ClassBType] = recordPerRunCache(collection.concurrent.TrieMap.empty[InternalName, ClassBType])
4952

5053
/**
5154
* Parse the classfile for `internalName` and construct the [[ClassBType]].
5255
*/
5356
def classBTypeFromParsedClassfile(internalName: InternalName): ClassBType = {
54-
classBTypeFromClassNode(codeRepository.classNode(internalName))
57+
classBTypeFromClassNode(byteCodeRepository.classNode(internalName))
5558
}
5659

5760
/**
@@ -90,7 +93,7 @@ abstract class BTypes {
9093
*/
9194
def nestedInCurrentClass(innerClassNode: InnerClassNode): Boolean = {
9295
(innerClassNode.outerName != null && innerClassNode.outerName == classNode.name) ||
93-
(innerClassNode.outerName == null && codeRepository.classNode(innerClassNode.name).outerClass == classNode.name)
96+
(innerClassNode.outerName == null && byteCodeRepository.classNode(innerClassNode.name).outerClass == classNode.name)
9497
}
9598

9699
val nestedClasses: List[ClassBType] = classNode.innerClasses.asScala.collect({

src/compiler/scala/tools/nsc/backend/jvm/BTypesFromSymbols.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ package scala.tools.nsc
77
package backend.jvm
88

99
import scala.tools.asm
10-
import opt.CodeRepository
10+
import opt.ByteCodeRepository
11+
import scala.tools.asm.tree.ClassNode
12+
import scala.tools.nsc.backend.jvm.opt.ByteCodeRepository.Source
1113
import BTypes.InternalName
1214

1315
/**
@@ -34,15 +36,13 @@ class BTypesFromSymbols[G <: Global](val global: G) extends BTypes {
3436
val coreBTypes = new CoreBTypesProxy[this.type](this)
3537
import coreBTypes._
3638

37-
val codeRepository = new CodeRepository(global.classPath)
39+
val byteCodeRepository = new ByteCodeRepository(global.classPath, recordPerRunCache(collection.concurrent.TrieMap.empty[InternalName, (ClassNode, Source)]))
3840

3941
final def initializeCoreBTypes(): Unit = {
4042
coreBTypes.setBTypes(new CoreBTypes[this.type](this))
4143
}
4244

43-
val classBTypeFromInternalName = {
44-
global.perRunCaches.recordCache(collection.concurrent.TrieMap.empty[InternalName, ClassBType])
45-
}
45+
def recordPerRunCache[T <: collection.generic.Clearable](cache: T): T = perRunCaches.recordCache(cache)
4646

4747
// helpers that need access to global.
4848
// TODO @lry create a separate component, they don't belong to BTypesFromSymbols

src/compiler/scala/tools/nsc/backend/jvm/opt/CodeRepository.scala renamed to src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,32 @@ import scala.collection.convert.decorateAsScala._
1313
import scala.tools.nsc.io.AbstractFile
1414
import scala.tools.nsc.util.ClassFileLookup
1515
import OptimizerReporting._
16+
import ByteCodeRepository._
17+
import BTypes.InternalName
1618

17-
class CodeRepository(val classPath: ClassFileLookup[AbstractFile]) {
18-
import BTypes.InternalName
19-
19+
/**
20+
* The ByteCodeRepository provides utilities to read the bytecode of classfiles from the compilation
21+
* classpath. Parsed classes are cached in the `classes` map.
22+
*
23+
* @param classPath The compiler classpath where classfiles are searched and read from.
24+
* @param classes Cache for parsed ClassNodes. Also stores the source of the bytecode:
25+
* [[Classfile]] if read from `classPath`, [[CompilationUnit]] if the bytecode
26+
* corresponds to a class being compiled.
27+
*/
28+
class ByteCodeRepository(val classPath: ClassFileLookup[AbstractFile], val classes: collection.concurrent.Map[InternalName, (ClassNode, Source)]) {
2029
/**
21-
* Cache for parsed ClassNodes.
30+
* The class node and source for an internal name. If the class node is not yet available, it is
31+
* parsed from the classfile on the compile classpath.
2232
*/
23-
val classes: collection.concurrent.Map[InternalName, ClassNode] = collection.concurrent.TrieMap.empty[InternalName, ClassNode]
33+
def classNodeAndSource(internalName: InternalName): (ClassNode, Source) = {
34+
classes.getOrElseUpdate(internalName, (parseClass(internalName), Classfile))
35+
}
2436

2537
/**
2638
* The class node for an internal name. If the class node is not yet available, it is parsed from
2739
* the classfile on the compile classpath.
2840
*/
29-
def classNode(internalName: InternalName): ClassNode = {
30-
classes.getOrElseUpdate(internalName, parseClass(internalName))
31-
}
41+
def classNode(internalName: InternalName) = classNodeAndSource(internalName)._1
3242

3343
/**
3444
* The field node for a field matching `name` and `descriptor`, accessed in class `classInternalName`.
@@ -74,7 +84,6 @@ class CodeRepository(val classPath: ClassFileLookup[AbstractFile]) {
7484
// http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.11
7585
// https://jcp.org/aboutJava/communityprocess/final/jsr045/index.html
7686
removeLineNumberNodes(classNode)
77-
classes(internalName) = classNode
7887
classNode
7988
} getOrElse {
8089
inlineFailure(s"Class file for class $fullName not found.")
@@ -91,3 +100,13 @@ class CodeRepository(val classPath: ClassFileLookup[AbstractFile]) {
91100
}
92101
}
93102
}
103+
104+
object ByteCodeRepository {
105+
/**
106+
* The source of a ClassNode in the ByteCodeRepository. Can be either [[CompilationUnit]] if the
107+
* class is being compiled or [[Classfile]] if the class was parsed from the compilation classpath.
108+
*/
109+
sealed trait Source
110+
object CompilationUnit extends Source
111+
object Classfile extends Source
112+
}

src/compiler/scala/tools/nsc/backend/jvm/opt/OptimizerReporting.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ package backend.jvm
99
import scala.tools.asm
1010
import asm.tree._
1111

12+
/**
13+
* Reporting utilities used in the optimizer.
14+
*/
1215
object OptimizerReporting {
1316
def methodSignature(className: String, methodName: String, methodDescriptor: String): String = {
1417
className + "::" + methodName + methodDescriptor

0 commit comments

Comments
 (0)