summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/jvm
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2016-03-25 19:08:23 -0700
committerAdriaan Moors <adriaan.moors@typesafe.com>2016-03-28 17:48:23 -0700
commit3ae39036771acb107cbb4a37fe6113c243d89acc (patch)
tree31479991adc4552fb0b95800cf461b9b791900dd /src/compiler/scala/tools/nsc/backend/jvm
parenta17d247a8acea2daaddb39263ebf1dcf5673bcba (diff)
downloadscala-3ae39036771acb107cbb4a37fe6113c243d89acc.tar.gz
scala-3ae39036771acb107cbb4a37fe6113c243d89acc.tar.bz2
scala-3ae39036771acb107cbb4a37fe6113c243d89acc.zip
Target FunctionN, not scala/runtime/java8/JFunction.
We compile FunctionN to Java 8's idea of a function now, so no need to target the artisanal JFunction and friends, except when the function is specialized, as I don't yet see how we can use LMF with the way specialization handles FunctionN: First, the working status quo -- the hand-crafted specialized versions of JFunction0. Notice how `apply$mcB$sp` is looking pretty SAMmy: ``` @FunctionalInterface public interface JFunction0$mcB$sp extends JFunction0 { @Override public byte apply$mcB$sp(); @Override default public Object apply() { return BoxesRunTime.boxToByte(this.apply$mcB$sp()); } } ``` Contrast this with our specialized standard FunctionN: ``` public interface Function0<R> { public R apply(); default public byte apply$mcB$sp() { return BoxesRunTime.unboxToByte(this.apply()); } } public interface Function0$mcB$sp extends Function0<Object> { } ``` The single abstract method in `Function0$mcB$sp` is `apply`, and the method that would let us avoid boxing, if it were abstract, is `apply$mcB$sp`... TODO (after M4): - do same for specialized functions (issues with boxing?) - remove scala/runtime/java8/JFunction* (need new STARR?)
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala14
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala4
3 files changed, 10 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala
index 696a164c56..ab9fd94a93 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/CoreBTypes.scala
@@ -219,14 +219,12 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: Global]](val bTypes: BTFS) {
// 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 functionClasses(base: String): Set[Symbol] = {
- def primitives = Iterator("B", "S", "I", "J", "C", "F", "D", "Z", "V")
+ 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 = Set.empty[String] ++ {
- (0 to 22).map(base + _)
- } ++ {
+ val classNames = {
primitives.map(base + "0$mc" + _ + "$sp") // Function0
} ++ {
// return type specializations appear first in the name string (alphabetical sorting)
@@ -237,7 +235,7 @@ class CoreBTypes[BTFS <: BTypesFromSymbols[_ <: Global]](val bTypes: BTFS) {
classNames map getRequiredClass
}
- lazy val srJFunctionRefs: Set[InternalName] = functionClasses("scala.runtime.java8.JFunction").map(classBTypeFromSymbol(_).internalName)
+ lazy val functionRefs: Set[InternalName] = (FunctionClass.seq ++ specializedJFunctionSymbols("scala.runtime.java8.JFunction")).map(classBTypeFromSymbol(_).internalName).toSet
lazy val typeOfArrayOp: Map[Int, BType] = {
import scalaPrimitives._
@@ -343,7 +341,7 @@ trait CoreBTypesProxyGlobalIndependent[BTS <: BTypes] {
def srRefConstructors : Map[InternalName, MethodNameAndType]
def tupleClassConstructors : Map[InternalName, MethodNameAndType]
- def srJFunctionRefs: Set[InternalName]
+ def functionRefs: Set[InternalName]
def lambdaMetaFactoryBootstrapHandle : asm.Handle
def lambdaDeserializeBootstrapHandle : asm.Handle
@@ -410,7 +408,7 @@ final class CoreBTypesProxy[BTFS <: BTypesFromSymbols[_ <: Global]](val bTypes:
def srRefConstructors : Map[InternalName, MethodNameAndType] = _coreBTypes.srRefConstructors
def tupleClassConstructors : Map[InternalName, MethodNameAndType] = _coreBTypes.tupleClassConstructors
- def srJFunctionRefs: Set[InternalName] = _coreBTypes.srJFunctionRefs
+ def functionRefs: Set[InternalName] = _coreBTypes.functionRefs
def srSymbolLiteral : ClassBType = _coreBTypes.srSymbolLiteral
def srStructuralCallSite : ClassBType = _coreBTypes.srStructuralCallSite
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 bd7d5d2608..a6b9faa933 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala
@@ -125,7 +125,7 @@ class BackendUtils[BT <: BTypes](val btypes: BT) {
private val anonfunAdaptedName = """.*\$anonfun\$\d+\$adapted""".r
def hasAdaptedImplMethod(closureInit: ClosureInstantiation): Boolean = {
- isrJFunctionType(Type.getReturnType(closureInit.lambdaMetaFactoryCall.indy.desc).getInternalName) &&
+ isBuiltinFunctionType(Type.getReturnType(closureInit.lambdaMetaFactoryCall.indy.desc).getInternalName) &&
anonfunAdaptedName.pattern.matcher(closureInit.lambdaMetaFactoryCall.implMethod.getName).matches
}
@@ -250,7 +250,7 @@ class BackendUtils[BT <: BTypes](val btypes: BT) {
}
}
- def isrJFunctionType(internalName: InternalName): Boolean = srJFunctionRefs(internalName)
+ 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/CopyProp.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala
index f1eaebd27c..d28565b9bc 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala
@@ -296,11 +296,11 @@ 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/runtime/java8/JFunctionN), the `indy` and its inputs
+ * without side-effects (e.g. scala/FunctionN), the `indy` and its inputs
* are eliminated, otherwise a POP is inserted.
*/
def handleClosureInst(indy: InvokeDynamicInsnNode): Unit = {
- if (isrJFunctionType(Type.getReturnType(indy.desc).getInternalName)) {
+ if (isBuiltinFunctionType(Type.getReturnType(indy.desc).getInternalName)) {
toRemove += indy
callGraph.removeClosureInstantiation(indy, method)
handleInputs(indy, Type.getArgumentTypes(indy.desc).length)