abstract class CopyProp extends AnyRef
- Source
- CopyProp.scala
- Alphabetic
- By Inheritance
- CopyProp
- AnyRef
- Any
- by any2stringadd
- by StringFormat
- by Ensuring
- by ArrowAssoc
- Hide All
- Show All
- Public
- All
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( ... ) @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 eliminateStaleStores. -
def
eliminatePushPop(method: MethodNode, owner: InternalName): 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.
-
def
eliminateStaleStores(method: MethodNode, owner: InternalName): 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.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
. -
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 eliminateStaleStores.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: Any): Boolean
- Definition Classes
- AnyRef → Any
-
def
finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws( classOf[java.lang.Throwable] )
- def formatted(fmtstr: String): String
-
final
def
getClass(): Class[_]
- 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( ... )
-
final
def
wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... ) @native()
- def →[B](y: B): (CopyProp, B)
The Scala compiler and reflection APIs.