summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2016-11-28 14:21:44 +0100
committerLukas Rytz <lukas.rytz@gmail.com>2016-11-28 14:22:09 +0100
commit1f7c74115e6699b6ebe8d1b5600ac439236a6568 (patch)
tree31954aa8a3ba121ec30c55adbcf3006ad3cf7ee1 /src/compiler/scala/tools/nsc/backend
parent8020cd66c8b30126bbba1dc1e87f7daafb3f2dd7 (diff)
downloadscala-1f7c74115e6699b6ebe8d1b5600ac439236a6568.tar.gz
scala-1f7c74115e6699b6ebe8d1b5600ac439236a6568.tar.bz2
scala-1f7c74115e6699b6ebe8d1b5600ac439236a6568.zip
Address review feedback
Rename `undoLog.run` to `rollback`, use java ArrayList instead of helper methods to copy to an array.
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala29
1 files changed, 14 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
index c520bb9d9e..a02debf14a 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
@@ -214,37 +214,33 @@ class Inliner[BT <: BTypes](val btypes: BT) {
}
class UndoLog(active: Boolean = true) {
+ import java.util.{ ArrayList => JArrayList }
+
private var actions = List.empty[() => Unit]
private var methodStateSaved = false
def apply(a: => Unit): Unit = if (active) actions = (() => a) :: actions
- def run(): Unit = if (active) actions.foreach(_.apply())
-
- private def arr[T: reflect.ClassTag](l: java.util.List[T]): Array[T] = {
- val a: Array[T] = new Array[T](l.size)
- l.toArray(a.asInstanceOf[Array[T with Object]]).asInstanceOf[Array[T]]
- }
- private def lst[T](a: Array[T]): java.util.List[T] = java.util.Arrays.asList(a: _*)
+ def rollback(): Unit = if (active) actions.foreach(_.apply())
def saveMethodState(methodNode: MethodNode): Unit = if (active && !methodStateSaved) {
methodStateSaved = true
val currentInstructions = methodNode.instructions.toArray
- val currentLocalVariables = arr(methodNode.localVariables)
- val currentTryCatchBlocks = arr(methodNode.tryCatchBlocks)
+ val currentLocalVariables = new JArrayList(methodNode.localVariables)
+ val currentTryCatchBlocks = new JArrayList(methodNode.tryCatchBlocks)
val currentMaxLocals = methodNode.maxLocals
val currentMaxStack = methodNode.maxStack
apply {
- // this doesn't work: it doesn't reset the `prev` / `next` / `index` of individual instruction nodes
- // methodNode.instructions.clear()
+ // `methodNode.instructions.clear()` doesn't work: it keeps the `prev` / `next` / `index` of
+ // instruction nodes. `instructions.removeAll(true)` would work, but is not public.
methodNode.instructions.iterator.asScala.toList.foreach(methodNode.instructions.remove)
for (i <- currentInstructions) methodNode.instructions.add(i)
methodNode.localVariables.clear()
- methodNode.localVariables.addAll(lst(currentLocalVariables))
+ methodNode.localVariables.addAll(currentLocalVariables)
methodNode.tryCatchBlocks.clear()
- methodNode.tryCatchBlocks.addAll(lst(currentTryCatchBlocks))
+ methodNode.tryCatchBlocks.addAll(currentTryCatchBlocks)
methodNode.maxLocals = currentMaxLocals
methodNode.maxStack = currentMaxStack
@@ -269,16 +265,19 @@ class Inliner[BT <: BTypes](val btypes: BT) {
postRequests.flatMap(inline(_, undo))
}
+ def inlinedByPost(insns: List[AbstractInsnNode]): Boolean =
+ insns.nonEmpty && insns.forall(ins => request.post.exists(_.callsite.callsiteInstruction == ins))
+
canInlineCallsite(request.callsite) match {
case None =>
doInline(undo)
- case Some((w, illegalAccessInsns)) if illegalAccessInsns.nonEmpty && illegalAccessInsns.forall(ins => request.post.exists(_.callsite.callsiteInstruction == ins)) =>
+ case Some((_, illegalAccessInsns)) if inlinedByPost(illegalAccessInsns) =>
// speculatively inline, roll back if an illegalAccessInsn cannot be eliminated
if (undo == NoUndoLogging) {
val undoLog = new UndoLog()
val warnings = doInline(undoLog)
- if (warnings.nonEmpty) undoLog.run()
+ if (warnings.nonEmpty) undoLog.rollback()
warnings
} else doInline(undo)