10000 Backend Refactoring by lrytz · Pull Request #6012 · scala/scala · GitHub
[go: up one dir, main page]

Skip to content

Backend Refactoring #6012

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Sep 1, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

8000
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Use LazyVar for CoreBTypes
Remove implicit conversion from LazyVar[T] to T
  • Loading branch information
lrytz committed Aug 11, 2017
commit 67a1693d665131e39f84bb5d416943e6959720c2
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ abstract class BCodeHelpers extends BCodeIdiomatic {
val bType = mirrorClassClassBType(moduleClass)
val mirrorClass = new asm.tree.ClassNode
mirrorClass.visit(
backendUtils.classfileVersion,
backendUtils.classfileVersion.get,
bType.info.get.flags,
bType.internalName,
null /* no java-generic-signature */,
Expand Down Expand Up @@ -1000,7 +1000,7 @@ abstract class BCodeHelpers extends BCodeIdiomatic {

val beanInfoClass = new asm.tree.ClassNode
beanInfoClass.visit(
backendUtils.classfileVersion,
backendUtils.classfileVersion.get,
beanInfoType.info.get.flags,
beanInfoType.internalName,
null, // no java-generic-signature
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ abstract class BCodeIdiomatic {
* can-multi-thread
*/
def genConcat(elemType: BType, pos: Position): Unit = {
val paramType = elemType match {
val paramType: BType = elemType match {
case ct: ClassBType if ct.isSubtypeOf(StringRef).get => StringRef
case ct: ClassBType if ct.isSubtypeOf(jlStringBufferRef).get => jlStringBufferRef
case ct: ClassBType if ct.isSubtypeOf(jlCharSequenceRef).get => jlCharSequenceRef
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ abstract class BCodeSkelBuilder extends BCodeHelpers {
val flags = javaFlags(claszSymbol)

val thisSignature = getGenericSignature(claszSymbol, claszSymbol.owner)
cnode.visit(backendUtils.classfileVersion, flags,
cnode.visit(backendUtils.classfileVersion.get, flags,
thisBType.internalName, thisSignature,
superClass, interfaceNames.toArray)

Expand Down
5 changes: 1 addition & 4 deletions src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ abstract class BTypes {
val postProcessorFrontendAccess: PostProcessorFrontendAccess
import postProcessorFrontendAccess.{frontendSynch, recordPerRunCache}

// Some core BTypes are required here, in class BType, where no Global instance is available.
// The Global is only available in the subclass BTypesFromSymbols. We cannot depend on the actual
// implementation (CoreBTypesProxy) here because it has members that refer to global.Symbol.
val coreBTypes: CoreBTypesProxyGlobalIndependent[this.type]
val coreBTypes: CoreBTypes { val bTypes: BTypes.this.type }
import coreBTypes._

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ class BTypesFromSymbols[G <: Global](val global: G, val postProcessorFrontendAcc
import codeGen.CodeGenImpl._
import postProcessor.{bTypesFromClassfile, byteCodeRepository}

// Why the proxy, see documentation of class [[CoreBTypes]].
val coreBTypes = new CoreBTypesProxy[this.type](this)
val coreBTypes = new CoreBTypesFromSymbols[G] {
val bTypes: BTypesFromSymbols.this.type = BTypesFromSymbols.this
}
import coreBTypes._

final def initialize(): Unit = {
Expand Down
8 changes: 4 additions & 4 deletions src/compiler/scala/tools/nsc/backend/jvm/CodeGen.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ abstract class CodeGen[G <: Global](val global: G) extends PerRunLazy {
private val caseInsensitively = perRunCaches.newMap[String, Symbol]()

// TODO: do we really need a new instance per run? Is there state that depends on the compiler frontend (symbols, types, settings)?
private val mirrorCodeGen: LazyVar[CodeGenImpl.JMirrorBuilder] = perRunLazy(new CodeGenImpl.JMirrorBuilder())
private[this] lazy val mirrorCodeGen: LazyVar[CodeGenImpl.JMirrorBuilder] = perRunLazy(new CodeGenImpl.JMirrorBuilder())

private val beanInfoCodeGen: LazyVar[CodeGenImpl.JBeanInfoBuilder] = perRunLazy(new CodeGenImpl.JBeanInfoBuilder())
private[this] lazy val beanInfoCodeGen: LazyVar[CodeGenImpl.JBeanInfoBuilder] = perRunLazy(new CodeGenImpl.JBeanInfoBuilder())

def genUnit(unit: CompilationUnit): Unit = {
import genBCode.postProcessor.generatedClasses
Expand Down Expand Up @@ -56,12 +56,12 @@ abstract class CodeGen[G <: Global](val global: G) extends PerRunLazy {
}

def genMirrorClass(classSym: Symbol, unit: CompilationUnit): ClassNode = {
mirrorCodeGen.genMirrorClass(classSym, unit)
mirrorCodeGen.get.genMirrorClass(classSym, unit)
}

def genBeanInfoClass(cd: ClassDef, unit: CompilationUnit): ClassNode = {
val sym = cd.symbol
beanInfoCodeGen.genBeanInfoClass(sym, unit, CodeGenImpl.fieldSymbols(sym), CodeGenImpl.methodSymbols(cd))
beanInfoCodeGen.get.genBeanInfoClass(sym, unit, CodeGenImpl.fieldSymbols(sym), CodeGenImpl.methodSymbols(cd))
}

private def warnCaseInsensitiveOverwrite(cd: ClassDef): Unit = {
Expand Down
455 changes: 215 additions & 240 deletions 6D4E src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala

Large diffs are not rendered by default.

11 changes: 3 additions & 8 deletions src/compiler/scala/tools/nsc/backend/jvm/PerRunLazy.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ trait PerRunLazy {
r
}

def initialize(): Unit = ls.foreach(_.reInit())
def initialize(): Unit = ls.foreach(_.reInitialize())
}

/**
Expand All @@ -30,7 +30,7 @@ class LazyVar[T](init: () => T) {
@volatile private[this] var isInit: Boolean = false
private[this] var v: T = _

def get = {
def get: T = {
if (isInit) v
else synchronized {
if (!isInit) v = init()
Expand All @@ -39,10 +39,5 @@ class LazyVar[T](init: () => T) {
}
}

def reInit(): Unit = synchronized(isInit = false)
def reInitialize(): Unit = synchronized(isInit = false)
}

object LazyVar {
import language.implicitConversions
implicit def lGet[T](l: LazyVar[T]): T = l.get
}
14 changes: 7 additions & 7 deletions src/compiler/scala/tools/nsc/backend/jvm/PostProcessor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ abstract class PostProcessor(val frontendAccess: PostProcessorFrontendAccess) ex
val bTypesFromClassfile = new { val postProcessor: PostProcessor.this.type = PostProcessor.this } with BTypesFromClassfile

// re-initialized per run because it reads compiler settings that might change
val classfileWriter: LazyVar[ClassfileWriter] = perRunLazy(new ClassfileWriter(frontendAccess))
lazy val classfileWriter: LazyVar[ClassfileWriter] = perRunLazy(new ClassfileWriter(frontendAccess))

val generatedClasses = recordPerRunCache(new ListBuffer[GeneratedClass])
lazy val generatedClasses = recordPerRunCache(new ListBuffer[GeneratedClass])

override def initialize(): Unit = {
super.initialize()
Expand Down Expand Up @@ -68,11 +68,11 @@ abstract class PostProcessor(val frontendAccess: PostProcessorFrontendAccess) ex
if (AsmUtils.traceSerializedClassEnabled && classNode.name.contains(AsmUtils.traceSerializedClassPattern))
AsmUtils.traceClass(bytes)

classfileWriter.write(classNode.name, bytes, sourceFile)
classfileWriter.get.write(classNode.name, bytes, sourceFile)
}
}

classfileWriter.close()
classfileWriter.get.close()
}

def runGlobalOptimizations(): Unit = {
Expand Down Expand Up @@ -101,7 +101,7 @@ abstract class PostProcessor(val frontendAccess: PostProcessorFrontendAccess) ex
}

def serializeClass(classNode: ClassNode): Array[Byte] = {
val cw = new ClassWriterWithBTypeLub(backendUtils.extraProc)
val cw = new ClassWriterWithBTypeLub(backendUtils.extraProc.get)
classNode.accept(cw)
cw.toByteArray
}
Expand Down Expand Up @@ -214,9 +214,9 @@ object PostProcessorFrontendAccess {
class PostProcessorFrontendAccessImpl(global: Global) extends PostProcessorFrontendAccess with PerRunLazy {
import global._

private[this] val _compilerSettings: LazyVar[CompilerSettings] = perRunLazy(buildCompilerSettings())
private[this] lazy val _compilerSettings: LazyVar[CompilerSettings] = perRunLazy(buildCompilerSettings())

def compilerSettings: CompilerSettings = _compilerSettings
def compilerSettings: CompilerSettings = _compilerSettings.get

private def buildCompilerSettings(): CompilerSettings = new CompilerSettings {
import global.{settings => s}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ abstract class BackendUtils extends PerRunLazy {
import frontendAccess.compilerSettings

// unused objects created by these constructors are eliminated by pushPop
private val sideEffectFreeConstructors: LazyVar[Set[(String, String)]] = perRunLazy {
private[this] lazy val sideEffectFreeConstructors: LazyVar[Set[(String, String)]] = perRunLazy {
val ownerDesc = (p: (InternalName, MethodNameAndType)) => (p._1, p._2.methodType.descriptor)
primitiveBoxConstructors.map(ownerDesc).toSet ++
srRefConstructors.map(ownerDesc) ++
Expand All @@ -49,20 +49,20 @@ abstract class BackendUtils extends PerRunLazy {
(StringRef.internalName, MethodBType(List(ArrayBType(CHAR)), UNIT).descriptor))
}

private val classesOfSideEffectFreeConstructors: LazyVar[Set[String]] = perRunLazy(sideEffectFreeConstructors.map(_._1))
private[this] lazy val classesOfSideEffectFreeConstructors: LazyVar[Set[String]] = perRunLazy(sideEffectFreeConstructors.get.map(_._1))

val classfileVersion: LazyVar[Int] = perRunLazy(compilerSettings.target match {
lazy val classfileVersion: LazyVar[Int] = perRunLazy(compilerSettings.target match {
case "jvm-1.8" => asm.Opcodes.V1_8
})


val majorVersion: LazyVar[Int] = perRunLazy(classfileVersion & 0xFF)
lazy val majorVersion: LazyVar[Int] = perRunLazy(classfileVersion.get & 0xFF)

val emitStackMapFrame: LazyVar[Boolean] = perRunLazy(majorVersion >= 50)
lazy val emitStackMapFrame: LazyVar[Boolean] = perRunLazy(majorVersion.get >= 50)

val extraProc: LazyVar[Int] = perRunLazy(GenBCode.mkFlags(
lazy val extraProc: LazyVar[Int] = perRunLazy(GenBCode.mkFlags(
asm.ClassWriter.COMPUTE_MAXS,
if (emitStackMapFrame) asm.ClassWriter.COMPUTE_FRAMES else 0
if (emitStackMapFrame.get) asm.ClassWriter.COMPUTE_FRAMES else 0
))

/**
Expand Down Expand Up @@ -293,13 +293,13 @@ abstract class BackendUtils extends PerRunLazy {


def isSideEffectFreeConstructorCall(insn: MethodInsnNode): Boolean = {
insn.name == INSTANCE_CONSTRUCTOR_NAME && sideEffectFreeConstructors((insn.owner, insn.desc))
insn.name == INSTANCE_CONSTRUCTOR_NAME && sideEffectFreeConstructors.get((insn.owner, insn.desc))
}

def isNewForSideEffectFreeConstructor(insn: AbstractInsnNode) = {
insn.getOpcode == NEW && {
val ti = insn.asInstanceOf[TypeInsnNode]
classesOfSideEffectFreeConstructors.contains(ti.desc)
classesOfSideEffectFreeConstructors.get.contains(ti.desc)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ abstract class InlinerHeuristics extends PerRunLazy {
import callGraph._
import frontendAccess.{backendReporting, compilerSettings}

val inlineSourceMatcher: LazyVar[InlineSourceMatcher] = perRunLazy(new InlineSourceMatcher(compilerSettings.optInlineFrom))
lazy val inlineSourceMatcher: LazyVar[InlineSourceMatcher] = perRunLazy(new InlineSourceMatcher(compilerSettings.optInlineFrom))

final case class InlineRequest(callsite: Callsite, post: List[InlineRequest], reason: String) {
// invariant: all post inline requests denote callsites in the callee of the main callsite
Expand All @@ -36,8 +36,8 @@ abstract class InlinerHeuristics extends PerRunLazy {
def canInlineFromSource(sourceFilePath: Option[String], calleeDeclarationClass: InternalName) = {
compilerSettings.optLClasspath ||
compilerSettings.optLProject && sourceFilePath.isDefined ||
inlineSourceMatcher.allowFromSources && sourceFilePath.isDefined ||
inlineSourceMatcher.allow(calleeDeclarationClass)
inlineSourceMatcher.get.allowFromSources && sourceFilePath.isDefined ||
inlineSourceMatcher.get.allow(calleeDeclarationClass)
}

/**
Expand Down
0