summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2015-10-29 09:59:51 +0100
committerLukas Rytz <lukas.rytz@gmail.com>2015-10-29 21:37:34 +0100
commit6ca9490b179533169da041e9af937f89485e05a1 (patch)
treeadd63bfd7625755bb407272072141e1a94bb8eee /src
parent8cd1f9566db60f06ab368fad32d474397ece90be (diff)
downloadscala-6ca9490b179533169da041e9af937f89485e05a1.tar.gz
scala-6ca9490b179533169da041e9af937f89485e05a1.tar.bz2
scala-6ca9490b179533169da041e9af937f89485e05a1.zip
[trivial] import Opcodes._ in two files, move a utility method
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala84
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala20
2 files changed, 51 insertions, 53 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala
index e543a8c3e0..c6f88a4c98 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala
@@ -12,7 +12,8 @@ import scala.collection.mutable
import scala.reflect.internal.util.Collections._
import scala.tools.asm.commons.CodeSizeEvaluator
import scala.tools.asm.tree.analysis._
-import scala.tools.asm.{MethodWriter, ClassWriter, Label, Opcodes, Type}
+import scala.tools.asm.{Label, Type}
+import scala.tools.asm.Opcodes._
import scala.tools.asm.tree._
import GenBCode._
import scala.collection.convert.decorateAsScala._
@@ -27,7 +28,7 @@ object BytecodeUtils {
object Goto {
def unapply(instruction: AbstractInsnNode): Option[JumpInsnNode] = {
- if (instruction.getOpcode == Opcodes.GOTO) Some(instruction.asInstanceOf[JumpInsnNode])
+ if (instruction.getOpcode == GOTO) Some(instruction.asInstanceOf[JumpInsnNode])
else None
}
}
@@ -57,27 +58,27 @@ object BytecodeUtils {
def isJumpNonJsr(instruction: AbstractInsnNode): Boolean = {
val op = instruction.getOpcode
// JSR is deprecated in classfile version 50, disallowed in 51. historically, it was used to implement finally.
- op == Opcodes.GOTO || isConditionalJump(instruction)
+ op == GOTO || isConditionalJump(instruction)
}
def isConditionalJump(instruction: AbstractInsnNode): Boolean = {
val op = instruction.getOpcode
- (op >= Opcodes.IFEQ && op <= Opcodes.IF_ACMPNE) || op == Opcodes.IFNULL || op == Opcodes.IFNONNULL
+ (op >= IFEQ && op <= IF_ACMPNE) || op == IFNULL || op == IFNONNULL
}
def isReturn(instruction: AbstractInsnNode): Boolean = {
val op = instruction.getOpcode
- op >= Opcodes.IRETURN && op <= Opcodes.RETURN
+ op >= IRETURN && op <= RETURN
}
def isLoad(instruction: AbstractInsnNode): Boolean = {
val op = instruction.getOpcode
- op >= Opcodes.ILOAD && op <= Opcodes.ALOAD
+ op >= ILOAD && op <= ALOAD
}
def isStore(instruction: AbstractInsnNode): Boolean = {
val op = instruction.getOpcode
- op >= Opcodes.ISTORE && op <= Opcodes.ASTORE
+ op >= ISTORE && op <= ASTORE
}
def isVarInstruction(instruction: AbstractInsnNode): Boolean = isLoad(instruction) || isStore(instruction)
@@ -88,21 +89,21 @@ object BytecodeUtils {
methodNode.name == INSTANCE_CONSTRUCTOR_NAME || methodNode.name == CLASS_CONSTRUCTOR_NAME
}
- def isStaticMethod(methodNode: MethodNode): Boolean = (methodNode.access & Opcodes.ACC_STATIC) != 0
+ def isStaticMethod(methodNode: MethodNode): Boolean = (methodNode.access & ACC_STATIC) != 0
- def isAbstractMethod(methodNode: MethodNode): Boolean = (methodNode.access & Opcodes.ACC_ABSTRACT) != 0
+ def isAbstractMethod(methodNode: MethodNode): Boolean = (methodNode.access & ACC_ABSTRACT) != 0
- def isSynchronizedMethod(methodNode: MethodNode): Boolean = (methodNode.access & Opcodes.ACC_SYNCHRONIZED) != 0
+ def isSynchronizedMethod(methodNode: MethodNode): Boolean = (methodNode.access & ACC_SYNCHRONIZED) != 0
- def isNativeMethod(methodNode: MethodNode): Boolean = (methodNode.access & Opcodes.ACC_NATIVE) != 0
+ def isNativeMethod(methodNode: MethodNode): Boolean = (methodNode.access & ACC_NATIVE) != 0
def hasCallerSensitiveAnnotation(methodNode: MethodNode) = methodNode.visibleAnnotations != null && methodNode.visibleAnnotations.asScala.exists(_.desc == "Lsun/reflect/CallerSensitive;")
- def isFinalClass(classNode: ClassNode): Boolean = (classNode.access & Opcodes.ACC_FINAL) != 0
+ def isFinalClass(classNode: ClassNode): Boolean = (classNode.access & ACC_FINAL) != 0
- def isFinalMethod(methodNode: MethodNode): Boolean = (methodNode.access & (Opcodes.ACC_FINAL | Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC)) != 0
+ def isFinalMethod(methodNode: MethodNode): Boolean = (methodNode.access & (ACC_FINAL | ACC_PRIVATE | ACC_STATIC)) != 0
- def isStrictfpMethod(methodNode: MethodNode): Boolean = (methodNode.access & Opcodes.ACC_STRICT) != 0
+ def isStrictfpMethod(methodNode: MethodNode): Boolean = (methodNode.access & ACC_STRICT) != 0
def isReference(t: Type) = t.getSort == Type.OBJECT || t.getSort == Type.ARRAY
@@ -124,14 +125,14 @@ object BytecodeUtils {
def removeJumpAndAdjustStack(method: MethodNode, jump: JumpInsnNode) {
val instructions = method.instructions
val op = jump.getOpcode
- if ((op >= Opcodes.IFEQ && op <= Opcodes.IFGE) || op == Opcodes.IFNULL || op == Opcodes.IFNONNULL) {
+ if ((op >= IFEQ && op <= IFGE) || op == IFNULL || op == IFNONNULL) {
instructions.insert(jump, getPop(1))
- } else if ((op >= Opcodes.IF_ICMPEQ && op <= Opcodes.IF_ICMPLE) || op == Opcodes.IF_ACMPEQ || op == Opcodes.IF_ACMPNE) {
+ } else if ((op >= IF_ICMPEQ && op <= IF_ICMPLE) || op == IF_ACMPEQ || op == IF_ACMPNE) {
instructions.insert(jump, getPop(1))
instructions.insert(jump, getPop(1))
} else {
// we can't remove JSR: its execution does not only jump, it also adds a return address to the stack
- assert(jump.getOpcode == Opcodes.GOTO)
+ assert(jump.getOpcode == GOTO)
}
instructions.remove(jump)
}
@@ -148,43 +149,50 @@ object BytecodeUtils {
}
def negateJumpOpcode(jumpOpcode: Int): Int = (jumpOpcode: @switch) match {
- case Opcodes.IFEQ => Opcodes.IFNE
- case Opcodes.IFNE => Opcodes.IFEQ
+ case IFEQ => IFNE
+ case IFNE => IFEQ
- case Opcodes.IFLT => Opcodes.IFGE
- case Opcodes.IFGE => Opcodes.IFLT
+ case IFLT => IFGE
+ case IFGE => IFLT
- case Opcodes.IFGT => Opcodes.IFLE
- case Opcodes.IFLE => Opcodes.IFGT
+ case IFGT => IFLE
+ case IFLE => IFGT
- case Opcodes.IF_ICMPEQ => Opcodes.IF_ICMPNE
- case Opcodes.IF_ICMPNE => Opcodes.IF_ICMPEQ
+ case IF_ICMPEQ => IF_ICMPNE
+ case IF_ICMPNE => IF_ICMPEQ
- case Opcodes.IF_ICMPLT => Opcodes.IF_ICMPGE
- case Opcodes.IF_ICMPGE => Opcodes.IF_ICMPLT
+ case IF_ICMPLT => IF_ICMPGE
+ case IF_ICMPGE => IF_ICMPLT
- case Opcodes.IF_ICMPGT => Opcodes.IF_ICMPLE
- case Opcodes.IF_ICMPLE => Opcodes.IF_ICMPGT
+ case IF_ICMPGT => IF_ICMPLE
+ case IF_ICMPLE => IF_ICMPGT
- case Opcodes.IF_ACMPEQ => Opcodes.IF_ACMPNE
- case Opcodes.IF_ACMPNE => Opcodes.IF_ACMPEQ
+ case IF_ACMPEQ => IF_ACMPNE
+ case IF_ACMPNE => IF_ACMPEQ
- case Opcodes.IFNULL => Opcodes.IFNONNULL
- case Opcodes.IFNONNULL => Opcodes.IFNULL
+ case IFNULL => IFNONNULL
+ case IFNONNULL => IFNULL
}
def isSize2LoadOrStore(opcode: Int): Boolean = (opcode: @switch) match {
- case Opcodes.LLOAD | Opcodes.DLOAD | Opcodes.LSTORE | Opcodes.DSTORE => true
+ case LLOAD | DLOAD | LSTORE | DSTORE => true
case _ => false
}
def getPop(size: Int): InsnNode = {
- val op = if (size == 1) Opcodes.POP else Opcodes.POP2
+ val op = if (size == 1) POP else POP2
new InsnNode(op)
}
def instructionResultSize(instruction: AbstractInsnNode) = InstructionResultSize(instruction)
+ /**
+ * The number of local variable slots used for parameters and for the `this` reference.
+ */
+ def parametersSize(methodNode: MethodNode): Int = {
+ (Type.getArgumentsAndReturnSizes(methodNode.desc) >> 2) - (if (isStaticMethod(methodNode)) 1 else 0)
+ }
+
def labelReferences(method: MethodNode): Map[LabelNode, Set[AnyRef]] = {
val res = mutable.Map.empty[LabelNode, Set[AnyRef]]
def add(l: LabelNode, ref: AnyRef) = if (res contains l) res(l) = res(l) + ref else res(l) = Set(ref)
@@ -311,10 +319,10 @@ object BytecodeUtils {
*/
def fixLoadedNothingOrNullValue(loadedType: Type, loadInstr: AbstractInsnNode, methodNode: MethodNode, bTypes: BTypes): Unit = {
if (loadedType == bTypes.coreBTypes.srNothingRef.toASMType) {
- methodNode.instructions.insert(loadInstr, new InsnNode(Opcodes.ATHROW))
+ methodNode.instructions.insert(loadInstr, new InsnNode(ATHROW))
} else if (loadedType == bTypes.coreBTypes.srNullRef.toASMType) {
- methodNode.instructions.insert(loadInstr, new InsnNode(Opcodes.ACONST_NULL))
- methodNode.instructions.insert(loadInstr, new InsnNode(Opcodes.POP))
+ methodNode.instructions.insert(loadInstr, new InsnNode(ACONST_NULL))
+ methodNode.instructions.insert(loadInstr, new InsnNode(POP))
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
index a80b3d0487..25e4bb1593 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
@@ -9,6 +9,7 @@ package opt
import scala.annotation.switch
import scala.tools.asm.{Type, ClassWriter, MethodWriter, Opcodes}
+import scala.tools.asm.Opcodes._
import scala.tools.asm.tree._
import scala.collection.convert.decorateAsScala._
import scala.tools.nsc.backend.jvm.BTypes.InternalName
@@ -193,7 +194,7 @@ class LocalOpt[BT <: BTypes](val btypes: BT) {
var i = 0
var liveLabels = Set.empty[LabelNode]
var removedInstructions = Set.empty[AbstractInsnNode]
- var maxLocals = (Type.getArgumentsAndReturnSizes(method.desc) >> 2) - (if (BytecodeUtils.isStaticMethod(method)) 1 else 0)
+ var maxLocals = parametersSize(method)
var maxStack = 0
val itr = method.instructions.iterator()
while (itr.hasNext) {
@@ -214,7 +215,7 @@ class LocalOpt[BT <: BTypes](val btypes: BT) {
maxLocals = math.max(maxLocals, i.`var` + 1)
case _ =>
- if (!isLive || insn.getOpcode == Opcodes.NOP) {
+ if (!isLive || insn.getOpcode == NOP) {
// Instruction iterators allow removing during iteration.
// Removing is O(1): instructions are doubly linked list elements.
itr.remove()
@@ -247,7 +248,7 @@ object LocalOptImpls {
def containsExecutableCode(start: AbstractInsnNode, end: LabelNode): Boolean = {
start != end && ((start.getOpcode : @switch) match {
// FrameNode, LabelNode and LineNumberNode have opcode == -1.
- case -1 | Opcodes.GOTO => containsExecutableCode(start.getNext, end)
+ case -1 | GOTO => containsExecutableCode(start.getNext, end)
case _ => true
})
}
@@ -295,17 +296,6 @@ object LocalOptImpls {
}
/**
- * The number of local variable slots used for parameters and for the `this` reference.
- */
- private def parametersSize(method: MethodNode): Int = {
- // Double / long fields occupy two slots, so we sum up the sizes. Since getSize returns 0 for
- // void, we have to add `max 1`.
- val paramsSize = scala.tools.asm.Type.getArgumentTypes(method.desc).iterator.map(_.getSize max 1).sum
- val thisSize = if ((method.access & Opcodes.ACC_STATIC) == 0) 1 else 0
- paramsSize + thisSize
- }
-
- /**
* Compact the local variable slots used in the method's implementation. This prevents having
* unused slots for example after eliminating unreachable code.
*
@@ -579,7 +569,7 @@ object LocalOptImpls {
case Goto(jump) =>
nextExecutableInstruction(jump.label) match {
case Some(target) =>
- if (isReturn(target) || target.getOpcode == Opcodes.ATHROW) {
+ if (isReturn(target) || target.getOpcode == ATHROW) {
method.instructions.set(jump, target.clone(null))
true
} else false