summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala24
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala3
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala14
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala20
5 files changed, 25 insertions, 38 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala
index 1feca56923..d65380aa1f 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala
@@ -217,26 +217,6 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: Global]](val bTypes: BTFS) {
nonOverloadedConstructors(tupleClassSymbols)
}
- // enumeration of specialized classes is temporary, while we still use the java-defined JFunctionN.
- // once we switch to ordinary FunctionN, we can use specializedSubclasses just like for tuples.
- private def specializedJFunctionSymbols(base: String): Seq[Symbol] = {
- def primitives = Seq("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")
- val classNames = {
- primitives.map(base + "0$mc" + _ + "$sp") // Function0
- } ++ {
- // 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 (r <- ijfdzv; a <- ijd; b <- ijd) yield base + "2$mc" + r + a + b + "$sp" // Function2
- }
- classNames map getRequiredClass
- }
-
- lazy val functionRefs: Set[InternalName] = (FunctionClass.seq ++ specializedJFunctionSymbols("scala.runtime.java8.JFunction")).map(classBTypeFromSymbol(_).internalName).toSet
-
lazy val typeOfArrayOp: Map[Int, BType] = {
import scalaPrimitives._
Map(
@@ -342,8 +322,6 @@ trait CoreBTypesProxyGlobalIndependent[BTS <: BTypes] {
def srRefConstructors : Map[InternalName, MethodNameAndType]
def tupleClassConstructors : Map[InternalName, MethodNameAndType]
- def functionRefs: Set[InternalName]
-
def lambdaMetaFactoryBootstrapHandle : asm.Handle
def lambdaDeserializeBootstrapHandle : asm.Handle
}
@@ -410,8 +388,6 @@ final class CoreBTypesProxy[BTFS <: BTypesFromSymbols[_ <: Global]](val bTypes:
def srRefConstructors : Map[InternalName, MethodNameAndType] = _coreBTypes.srRefConstructors
def tupleClassConstructors : Map[InternalName, MethodNameAndType] = _coreBTypes.tupleClassConstructors
- def functionRefs: Set[InternalName] = _coreBTypes.functionRefs
-
def srSymbolLiteral : ClassBType = _coreBTypes.srSymbolLiteral
def srStructuralCallSite : ClassBType = _coreBTypes.srStructuralCallSite
def srLambdaDeserialize : ClassBType = _coreBTypes.srLambdaDeserialize
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala
index 539435a326..83615abc31 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala
@@ -131,7 +131,6 @@ class BackendUtils[BT <: BTypes](val btypes: BT) {
private val anonfunAdaptedName = """.*\$anonfun\$.*\$\d+\$adapted""".r
def hasAdaptedImplMethod(closureInit: ClosureInstantiation): Boolean = {
- isBuiltinFunctionType(Type.getReturnType(closureInit.lambdaMetaFactoryCall.indy.desc).getInternalName) &&
anonfunAdaptedName.pattern.matcher(closureInit.lambdaMetaFactoryCall.implMethod.getName).matches
}
@@ -256,8 +255,6 @@ class BackendUtils[BT <: BTypes](val btypes: BT) {
}
}
- def isBuiltinFunctionType(internalName: InternalName): Boolean = functionRefs(internalName)
-
/**
* Visit the class node and collect all referenced nested classes.
*/
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
index d6942d9ff9..5248183337 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
@@ -430,7 +430,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
def unapply(insn: AbstractInsnNode): Option[(InvokeDynamicInsnNode, Type, Handle, Type)] = insn match {
case indy: InvokeDynamicInsnNode if indy.bsm == metafactoryHandle || indy.bsm == altMetafactoryHandle =>
indy.bsmArgs match {
- case Array(samMethodType: Type, implMethod: Handle, instantiatedMethodType: Type, xs@_*) => // xs binding because IntelliJ gets confused about _@_*
+ case Array(samMethodType: Type, implMethod: Handle, instantiatedMethodType: Type, _@_*) =>
// LambdaMetaFactory performs a number of automatic adaptations when invoking the lambda
// implementation method (casting, boxing, unboxing, and primitive widening, see Javadoc).
//
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala
index 4163d62df7..b05669ce89 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala
@@ -295,18 +295,12 @@ class CopyProp[BT <: BTypes](val btypes: BT) {
}
/**
- * Eliminate the closure value produced by `indy`. If the SAM type is known to construct
- * without side-effects (e.g. scala/FunctionN), the `indy` and its inputs
- * are eliminated, otherwise a POP is inserted.
+ * Eliminate LMF `indy` and its inputs.
*/
def handleClosureInst(indy: InvokeDynamicInsnNode): Unit = {
- if (isBuiltinFunctionType(Type.getReturnType(indy.desc).getInternalName)) {
- toRemove += indy
- callGraph.removeClosureInstantiation(indy, method)
- handleInputs(indy, Type.getArgumentTypes(indy.desc).length)
- } else {
- toInsertAfter(indy) = getPop(1)
- }
+ toRemove += indy
+ callGraph.removeClosureInstantiation(indy, method)
+ handleInputs(indy, Type.getArgumentTypes(indy.desc).length)
}
def runQueue(): Unit = while (queue.nonEmpty) {
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala
index 938bc7b846..2c697bfe50 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOptsTest.scala
@@ -750,4 +750,24 @@ class MethodLevelOptsTest extends BytecodeTesting {
-1, LDC, ASTORE,
-1, ALOAD, ARETURN))
}
+
+ @Test
+ def elimSamLambda(): Unit = {
+ val code =
+ """class C {
+ | def t1(x: Int) = {
+ | val fun: java.util.function.IntFunction[Int] = y => y + 1
+ | fun(x)
+ | }
+ | def t2(x: Int) = {
+ | val fun: T = i => i + 1
+ | fun.f(x)
+ | }
+ |}
+ |trait T { def f(x: Int): Int }
+ """.stripMargin
+ val List(c, t) = compileClasses(code)
+ assertSameSummary(getMethod(c, "t1"), List(ILOAD, "$anonfun$t1$1", IRETURN))
+ assertSameSummary(getMethod(c, "t2"), List(ILOAD, "$anonfun$t2$1", IRETURN))
+ }
}