From ea61b3f66007b1a0029a5f22a7de334924390f7c Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Mon, 2 Jun 2014 13:20:58 +0200 Subject: Disable -Ydelambdafy:method for specialized FunctionN The Delambdafy phase generates its `FunctionN` subclasses after the specialization phase. As such, `((x: Int) => x).apply(42)` incurs boxing. This commit falls back to the `-Ydelambdafy:inline` in this case. This is done by running the specialization type map over the type of the function, and seeing if anything changes. To make this work robustly, we first need to ensure that the specialization info transformer has processed all the function types. This is not a fundamental limitation; we could in principle generate the specialized code. A followup change will use `-Ydelambdafy:method` as the basis for invokedymnamic lambdas. As part of that stream of work, we will synthesize specialization-aware lambdas, and remove the fallback to `-Ydelambdafy:inline`. I have updated some tests that intend to test the delambdafy transform to avoid use of specialized function types. --- test/files/run/delambdafy_t6028.check | 51 ++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 18 deletions(-) (limited to 'test/files/run/delambdafy_t6028.check') diff --git a/test/files/run/delambdafy_t6028.check b/test/files/run/delambdafy_t6028.check index 7bd8cd7202..419e7043a3 100644 --- a/test/files/run/delambdafy_t6028.check +++ b/test/files/run/delambdafy_t6028.check @@ -1,35 +1,35 @@ [[syntax trees at end of lambdalift]] // newSource1.scala package { class T extends Object { - private[this] val classParam: Int = _; - def (classParam: Int): T = { + private[this] val classParam: String = _; + def (classParam: String): T = { T.super.(); () }; - private[this] val field: Int = 0; - def field(): Int = T.this.field; - def foo(methodParam: Int): Function0 = { - val methodLocal: Int = 0; + private[this] val field: String = ""; + def field(): String = T.this.field; + def foo(methodParam: String): Function0 = { + val methodLocal: String = ""; { (() => T.this.$anonfun$1(methodParam, methodLocal)).$asInstanceOf[Function0]() } }; - def bar(barParam: Int): Object = { + def bar(barParam: String): Object = { @volatile var MethodLocalObject$module: runtime.VolatileObjectRef = scala.runtime.VolatileObjectRef.zero(); T.this.MethodLocalObject$1(barParam, MethodLocalObject$module) }; - def tryy(tryyParam: Int): Function0 = { - var tryyLocal: runtime.IntRef = scala.runtime.IntRef.create(0); + def tryy(tryyParam: String): Function0 = { + var tryyLocal: runtime.ObjectRef = scala.runtime.ObjectRef.create(""); { - (() => T.this.$anonfun$2(tryyParam, tryyLocal)).$asInstanceOf[Function0]() + (new <$anon: Function0>(T.this, tryyParam, tryyLocal): Function0) } }; - final private[this] def $anonfun$1(methodParam$1: Int, methodLocal$1: Int): Int = T.this.classParam.+(T.this.field()).+(methodParam$1).+(methodLocal$1); + final private[this] def $anonfun$1(methodParam$1: String, methodLocal$1: String): String = T.this.classParam.+(T.this.field()).+(methodParam$1).+(methodLocal$1); abstract trait MethodLocalTrait$1 extends Object { def $outer(): T }; object MethodLocalObject$2 extends Object with T#MethodLocalTrait$1 { - def ($outer: T, barParam$1: Int): T#MethodLocalObject$2.type = { + def ($outer: T, barParam$1: String): T#MethodLocalObject$2.type = { MethodLocalObject$2.super.(); MethodLocalObject$2.this.$asInstanceOf[T#MethodLocalTrait$1$class]()./*MethodLocalTrait$1$class*/$init$(barParam$1); () @@ -38,19 +38,34 @@ package { def $outer(): T = MethodLocalObject$2.this.$outer; def $outer(): T = MethodLocalObject$2.this.$outer }; - final private[this] def MethodLocalObject$1(barParam$1: Int, MethodLocalObject$module$1: runtime.VolatileObjectRef): T#MethodLocalObject$2.type = { + final private[this] def MethodLocalObject$1(barParam$1: String, MethodLocalObject$module$1: runtime.VolatileObjectRef): T#MethodLocalObject$2.type = { MethodLocalObject$module$1.elem = new T#MethodLocalObject$2.type(T.this, barParam$1); MethodLocalObject$module$1.elem.$asInstanceOf[T#MethodLocalObject$2.type]() }; abstract trait MethodLocalTrait$1$class extends Object with T#MethodLocalTrait$1 { - def /*MethodLocalTrait$1$class*/$init$(barParam$1: Int): Unit = { + def /*MethodLocalTrait$1$class*/$init$(barParam$1: String): Unit = { () }; - scala.this.Predef.print(scala.Int.box(barParam$1)) + scala.this.Predef.print(barParam$1) }; - final private[this] def $anonfun$2(tryyParam$1: Int, tryyLocal$1: runtime.IntRef): Unit = try { - tryyLocal$1.elem = tryyParam$1 - } finally () + @SerialVersionUID(value = 0) final class $anonfun$tryy$1 extends scala.runtime.AbstractFunction0$mcV$sp with Serializable { + def ($outer: T, tryyParam$1: String, tryyLocal$1: runtime.ObjectRef): <$anon: Function0> = { + $anonfun$tryy$1.super.(); + () + }; + final def apply(): Unit = $anonfun$tryy$1.this.apply$mcV$sp(); + def apply$mcV$sp(): Unit = try { + $anonfun$tryy$1.this.tryyLocal$1.elem = $anonfun$tryy$1.this.tryyParam$1 + } finally (); + private[this] val $outer: T = _; + def $outer(): T = $anonfun$tryy$1.this.$outer; + final def apply(): Object = { + $anonfun$tryy$1.this.apply(); + scala.runtime.BoxedUnit.UNIT + }; + private[this] val tryyParam$1: String = _; + private[this] val tryyLocal$1: runtime.ObjectRef = _ + } } } -- cgit v1.2.3