abstract class BackendUtils extends PerRunInit
This component hosts tools and utilities used in the backend that require access to a BTypes
instance.
One example is the AsmAnalyzer class, which runs computeMaxLocalsMaxStack
on the methodNode to
be analyzed. This method in turn lives inside the BTypes assembly because it queries the per-run
cache maxLocalsMaxStackComputed
defined in there.
TODO: move out of analysis
package?
- Source
- BackendUtils.scala
- Alphabetic
- By Inheritance
- BackendUtils
- PerRunInit
- AnyRef
- Any
- by any2stringadd
- by StringFormat
- by Ensuring
- by ArrowAssoc
- Hide All
- Show All
- Public
- All
Instance Constructors
- new BackendUtils()
Type Members
-
class
AsmAnalyzer[V <: Value] extends AnyRef
A wrapper to make ASM's Analyzer a bit easier to use.
- class NonLubbingTypeFlowAnalyzer extends AsmAnalyzer[BasicValue]
- class ProdConsAnalyzer extends AsmAnalyzer[SourceValue] with ProdConsAnalyzerImpl
Abstract Value Members
- abstract val postProcessor: PostProcessor
Concrete Value Members
- def addIndyLambdaImplMethod(hostClass: InternalName, handle: Handle): Boolean
-
def
addIndyLambdaImplMethod(hostClass: InternalName, handle: Seq[Handle]): Seq[Handle]
add methods
add methods
- returns
the added methods. Note the order is undefined
- final def addInnerClasses(jclass: ClassVisitor, refedInnerClasses: List[ClassBType]): Unit
- def addLambdaDeserialize(classNode: ClassNode, implMethods: Iterable[Handle]): Unit
- lazy val classfileVersion: LazyVar[Int]
-
def
cloneInstructions(methodNode: MethodNode, labelMap: Map[LabelNode, LabelNode], keepLineNumbers: Boolean): (InsnList, Map[AbstractInsnNode, AbstractInsnNode], List[Handle])
Clone the instructions in
methodNode
into a new InsnList, mapping labels according to thelabelMap
.Clone the instructions in
methodNode
into a new InsnList, mapping labels according to thelabelMap
. Returns the new instruction list and a map from old to new instructions, and a list of lambda implementation methods references by invokedynamic[LambdaMetafactory] for a serializable SAM types. -
def
collectNestedClasses(classNode: ClassNode): List[ClassBType]
Visit the class node and collect all referenced nested classes.
-
def
computeMaxLocalsMaxStack(method: MethodNode): Unit
In order to run an Analyzer, the maxLocals / maxStack fields need to be available.
In order to run an Analyzer, the maxLocals / maxStack fields need to be available. The ASM framework only computes these values during bytecode generation.
NOTE 1: as explained in the
analysis
package object, the maxStack value used by the Analyzer may be smaller than the correct maxStack value in the classfile (Analyzers only use a single slot for long / double values). The maxStack computed here are correct for running an analyzer, but not for writing in the classfile. We let the ClassWriter recompute max's.NOTE 2: the maxStack value computed here may be larger than the smallest correct value that would allow running an analyzer, see
InstructionStackEffect.forAsmAnalysis
andInstructionStackEffect.maxStackGrowth
.NOTE 3: the implementation doesn't look at instructions that cannot be reached, it computes the max local / stack size in the reachable code. These max's work just fine for running an Analyzer: its implementation also skips over unreachable code in the same way.
- lazy val emitStackMapFrame: LazyVar[Boolean]
- lazy val extraProc: LazyVar[Int]
- def getBoxedUnit: FieldInsnNode
- def getScalaBox(primitiveType: Type): MethodInsnNode
- def getScalaUnbox(primitiveType: Type): MethodInsnNode
- def hasAdaptedImplMethod(closureInit: (callGraph)#ClosureInstantiation): Boolean
-
def
initialize(): Unit
- Definition Classes
- PerRunInit
- def isBoxedUnit(insn: AbstractInsnNode): Boolean
- def isJavaBox(insn: MethodInsnNode): Boolean
- def isJavaUnbox(insn: MethodInsnNode): Boolean
- def isModuleLoad(insn: AbstractInsnNode, moduleName: InternalName): Boolean
- def isNewForSideEffectFreeConstructor(insn: AbstractInsnNode): Boolean
- def isNonNullMethodInvocation(mi: MethodInsnNode): Boolean
- def isPredefAutoBox(insn: MethodInsnNode): Boolean
- def isPredefAutoUnbox(insn: MethodInsnNode): Boolean
- def isPredefLoad(insn: AbstractInsnNode): Boolean
- def isPrimitiveBoxConstructor(insn: MethodInsnNode): Boolean
- def isRefCreate(insn: MethodInsnNode): Boolean
- def isRefZero(insn: MethodInsnNode): Boolean
- def isRuntimeRefConstructor(insn: MethodInsnNode): Boolean
- def isScalaBox(insn: MethodInsnNode): Boolean
- def isScalaUnbox(insn: MethodInsnNode): Boolean
- def isSideEffectFreeCall(insn: MethodInsnNode): Boolean
- def isSideEffectFreeConstructorCall(insn: MethodInsnNode): Boolean
- def isTupleConstructor(insn: MethodInsnNode): Boolean
- lazy val majorVersion: LazyVar[Int]
- def onIndyLambdaImplMethod[T](hostClass: InternalName)(action: (LinkedHashSet[Handle]) ⇒ T): T
- def onIndyLambdaImplMethodIfPresent(hostClass: InternalName)(action: (LinkedHashSet[Handle]) ⇒ Unit): Unit
-
def
perRunInit(init: ⇒ Unit): Unit
- Definition Classes
- PerRunInit
- def removeIndyLambdaImplMethod(hostClass: InternalName, handle: Seq[Handle]): Unit
- def runtimeRefClassBoxedType(refClass: InternalName): Type
-
object
AsmAnalyzer
See the doc comment on package object
analysis
for a discussion on performance.
The Scala compiler and reflection APIs.