diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala | 6 | ||||
-rw-r--r-- | test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala | 17 |
2 files changed, 21 insertions, 2 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 3854bc840d..d7ef13cb9c 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/BytecodeUtils.scala @@ -461,15 +461,17 @@ object BytecodeUtils { private def buildFunctionTypes(base: String): Set[InternalName] = { def primitives = Iterator("B", "S", "I", "J", "C", "F", "D", "Z", "V") def ijfd = Iterator("I", "J", "F", "D") + def ijfdzv = Iterator("I", "J", "F", "D", "Z", "V") def ijd = Iterator("I", "J", "D") Set.empty[String] ++ { (0 to 22).map(base + _) } ++ { primitives.map(base + "0$mc" + _ + "$sp") // Function0 } ++ { - for (a <- ijfd; b <- ijfd) yield base + "1$mc" + a + b + "$sp" // Function1 + // return type specializations appear first in the name string (alphabetical sorting) + for (r <- ijfdzv; a <- ijfd) yield base + "1$mc" + r + a + "$sp" // Function1 } ++ { - for (a <- ijd; b <- ijd; c <- ijd) yield base + "2$mc" + a + b + c + "$sp" // Function2 + for (r <- ijfdzv; a <- ijd; b <- ijd) yield base + "2$mc" + r + a + b + "$sp" // Function2 } } diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala index 734b5d9172..3228d3de65 100644 --- a/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala +++ b/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala @@ -235,4 +235,21 @@ class MethodLevelOpts extends ClearAfterClass { VarOp(ILOAD, 3), Invoke(INVOKESTATIC, "C", "C$$$anonfun$1", "(III)I", false), Op(IRETURN))) } + + @Test + def rewriteSpecializedClosureCall(): Unit = { + val code = + """class C { + | def t = { + | val f1 = (x: Int) => println(x) // int-unit specialization + | val f2 = (x: Int, y: Long) => x == y // int-long-boolean + | f1(1) + | f2(3, 4) + | } + |} + """.stripMargin + val List(c) = compileClasses(methodOptCompiler)(code) + val t = getSingleMethod(c, "t") + assert(!t.instructions.exists(_.opcode == INVOKEDYNAMIC), t) + } } |