diff options
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala index af962c4ce0..65bd62a413 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenBCode.scala @@ -14,6 +14,7 @@ import scala.reflect.internal.util.Statistics import scala.tools.asm import scala.tools.asm.tree.ClassNode +import scala.tools.nsc.backend.jvm.opt.ByteCodeRepository /* * Prepare in-memory representations of classfiles using the ASM Tree API, and serialize them to disk. @@ -186,7 +187,7 @@ abstract class GenBCode extends BCodeSyncAndTry { // -------------- "plain" class -------------- val pcb = new PlainClassBuilder(cunit) pcb.genPlainClass(cd) - val outF = if (needsOutFolder) getOutFolder(claszSymbol, pcb.thisName, cunit) else null; + val outF = if (needsOutFolder) getOutFolder(claszSymbol, pcb.thisBType.internalName, cunit) else null val plainC = pcb.cnode // -------------- bean info class, if needed -------------- @@ -221,16 +222,22 @@ abstract class GenBCode extends BCodeSyncAndTry { class Worker2 { def runGlobalOptimizations(): Unit = { import scala.collection.convert.decorateAsScala._ - if (settings.YoptBuildCallGraph) { - q2.asScala foreach { - case Item2(_, _, plain, _, _) => - // skip mirror / bean: wd don't inline into tem, and they are not used in the plain class - if (plain != null) callGraph.addClass(plain) - } + + // add classes to the bytecode repo before building the call graph: the latter needs to + // look up classes and methods in the code repo. + if (settings.YoptAddToBytecodeRepository) q2.asScala foreach { + case Item2(_, mirror, plain, bean, _) => + if (mirror != null) byteCodeRepository.add(mirror, ByteCodeRepository.CompilationUnit) + if (plain != null) byteCodeRepository.add(plain, ByteCodeRepository.CompilationUnit) + if (bean != null) byteCodeRepository.add(bean, ByteCodeRepository.CompilationUnit) + } + if (settings.YoptBuildCallGraph) q2.asScala foreach { item => + // skip call graph for mirror / bean: wd don't inline into tem, and they are not used in the plain class + if (item.plain != null) callGraph.addClass(item.plain) } if (settings.YoptInlinerEnabled) bTypes.inliner.runInliner() - if (settings.YoptClosureElimination) + if (settings.YoptClosureInvocations) closureOptimizer.rewriteClosureApplyInvocations() } @@ -238,6 +245,11 @@ abstract class GenBCode extends BCodeSyncAndTry { BackendStats.timed(BackendStats.methodOptTimer)(localOpt.methodOptimizations(classNode)) } + def setInnerClasses(classNode: ClassNode): Unit = if (classNode != null) { + classNode.innerClasses.clear() + addInnerClasses(classNode, bTypes.backendUtils.collectNestedClasses(classNode)) + } + def run() { runGlobalOptimizations() @@ -250,8 +262,14 @@ abstract class GenBCode extends BCodeSyncAndTry { else { try { localOptimizations(item.plain) + setInnerClasses(item.plain) + setInnerClasses(item.mirror) + setInnerClasses(item.bean) addToQ3(item) } catch { + case e: java.lang.RuntimeException if e.getMessage != null && (e.getMessage contains "too large!") => + reporter.error(NoPosition, + s"Could not write class ${item.plain.name} because it exceeds JVM code size limits. ${e.getMessage}") case ex: Throwable => ex.printStackTrace() error(s"Error while emitting ${item.plain.name}\n${ex.getMessage}") |