abstract class CopyProp extends AnyRef
- Alphabetic
- By Inheritance
- CopyProp
- AnyRef
- Any
- by any2stringadd
- by StringFormat
- by Ensuring
- by ArrowAssoc
- Hide All
- Show All
- Public
- Protected
Instance Constructors
- new CopyProp()
Type Members
- case class ProducedValue(producer: AbstractInsnNode, size: Int) extends Product with Serializable
Abstract Value Members
- abstract val postProcessor: PostProcessor
Concrete Value Members
- final def !=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def ##: Int
- Definition Classes
- AnyRef → Any
- def +(other: String): String
- def ->[B](y: B): (CopyProp, B)
- final def ==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def asInstanceOf[T0]: T0
- Definition Classes
- Any
- def clone(): AnyRef
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.CloneNotSupportedException]) @native()
- def copyPropagation(method: MethodNode, owner: InternalName): Boolean
For every
xLOAD n
, find all local variable slots that are aliases ofn
using an AliasingAnalyzer and change the instruction toxLOAD m
wherem
is the smallest alias.For every
xLOAD n
, find all local variable slots that are aliases ofn
using an AliasingAnalyzer and change the instruction toxLOAD m
wherem
is the smallest alias. This leaves behind potentially stalexSTORE n
instructions, which are then eliminated by eliminateStaleStoresAndRewriteSomeIntrinsics. - def eliminatePushPop(method: MethodNode, owner: InternalName): (Boolean, Boolean, Boolean)
When a POP instruction has a single producer, remove the POP and eliminate the producer by bubbling up the POPs.
When a POP instruction has a single producer, remove the POP and eliminate the producer by bubbling up the POPs. For example, given ILOAD 1; ILOAD 2; IADD; POP we first eliminate the POP, then the IADD, then its inputs, so the entire sequence goes away. If a producer cannot be eliminated (need to keep side-effects), a POP is inserted.
A special case eliminates the creation of unused objects with side-effect-free constructors: NEW scala/Tuple1; DUP; ALOAD 0; INVOKESPECIAL scala/Tuple1.<init>; POP The POP has a single producer (the DUP), it's easy to eliminate these two. A special case is needed to eliminate the INVOKESPECIAL and NEW.
Returns (pushPopChanged, castAdded, nullCheckAdded)
- def eliminateStaleStoresAndRewriteSomeIntrinsics(method: MethodNode, owner: InternalName): (Boolean, Boolean, Boolean)
Eliminate
xSTORE
instructions that have no consumer.Eliminate
xSTORE
instructions that have no consumer. If the instruction can be completely eliminated, it is replaced by a POP. The eliminatePushPop cleans up unnecessary POPs.Also rewrites some intrinsics (done here because a ProdCons analysis is available):
ClassTag(classOf[X]).newArray
is rewritten tonew Array[X]
Finally there's an interesting special case that complements the inliner heuristics. After the rewrite above, if the
new Array[X]
is used in aScalaRuntime.array_apply/update
call, inline that method. These methods have a big pattern match for all primitive array types, and we only inline them if we statically know the array type. In this case, all the non-matching branches are later eliminated byeliminateRedundantCastsAndRewriteSomeIntrinsics
.Note that an
ASOTRE
can not always be eliminated: it removes a reference to the object that is currently stored in that local, which potentially frees it for GC (scala/bug#5313). Therefore we replace such stores byPOP; ACONST_NULL; ASTORE x
- except if the store precedes anxRETURN
, in which case it can be removed.Returns (staleStoreRemoved, intrinsicRewritten, callInlined).
- def eliminateStoreLoad(method: MethodNode): Boolean
Remove
xSTORE n; xLOAD n
pairs ifRemove
xSTORE n; xLOAD n
pairs if- the local variable n is not used anywhere else in the method (1), and
- there are no executable instructions and no live labels (jump targets) between the two (2)
Note: store-load pairs that cannot be eliminated could be replaced by
DUP; xSTORE n
, but that's just cosmetic and doesn't help for anything.(1) This could be made more precise by running a prodCons analysis and checking that the load is the only user of the store. Then we could eliminate the pair even if the variable is live (except for ASTORE, scala/bug#5313). Not needing an analyzer is more efficient, and catches most cases.
(2) The implementation uses a conservative estimation for liveness (if some instruction uses local n, then n is considered live in the entire method). In return, it doesn't need to run an Analyzer on the method, making it more efficient.
This method also removes
ACONST_NULL; ASTORE n
if the local n is not live. This pattern is introduced by eliminateStaleStoresAndRewriteSomeIntrinsics.The implementation is a little tricky to support the following case: ISTORE 1; ISTORE 2; ILOAD 2; ACONST_NULL; ASTORE 3; ILOAD 1 The outer store-load pair can be removed if two the inner pairs can be.
- def ensuring(cond: (CopyProp) => Boolean, msg: => Any): CopyProp
- def ensuring(cond: (CopyProp) => Boolean): CopyProp
- def ensuring(cond: Boolean, msg: => Any): CopyProp
- def ensuring(cond: Boolean): CopyProp
- final def eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def equals(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef → Any
- def finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.Throwable])
- final def getClass(): Class[_ <: AnyRef]
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- def hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
- final def isInstanceOf[T0]: Boolean
- Definition Classes
- Any
- final def ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- final def notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- final def notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
- final def synchronized[T0](arg0: => T0): T0
- Definition Classes
- AnyRef
- def toString(): String
- Definition Classes
- AnyRef → Any
- final def wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException]) @native()
Deprecated Value Members
- def formatted(fmtstr: String): String
- Implicit
- This member is added by an implicit conversion from CopyProp toStringFormat[CopyProp] performed by method StringFormat in scala.Predef.
- Definition Classes
- StringFormat
- Annotations
- @deprecated @inline()
- Deprecated
(Since version 2.12.16) Use
formatString.format(value)
instead ofvalue.formatted(formatString)
, or use thef""
string interpolator. In Java 15 and later,formatted
resolves to the new method in String which has reversed parameters.
- def →[B](y: B): (CopyProp, B)
- Implicit
- This member is added by an implicit conversion from CopyProp toArrowAssoc[CopyProp] performed by method ArrowAssoc in scala.Predef.
- Definition Classes
- ArrowAssoc
- Annotations
- @deprecated
- Deprecated
(Since version 2.13.0) Use
->
instead. If you still wish to display it as one character, consider using a font with programming ligatures such as Fira Code.
The Scala compiler and reflection APIs.