summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/transform/Fields.scala6
-rw-r--r--test/files/run/delambdafy_t6028.check5
-rw-r--r--test/files/run/t6028.check5
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala4
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala9
5 files changed, 20 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Fields.scala b/src/compiler/scala/tools/nsc/transform/Fields.scala
index a383b65192..45741eb391 100644
--- a/src/compiler/scala/tools/nsc/transform/Fields.scala
+++ b/src/compiler/scala/tools/nsc/transform/Fields.scala
@@ -22,7 +22,7 @@ import symtab.Flags._
* in the first (closest in the subclassing lattice) subclass (not a trait) of a trait.
*
* For lazy vals and modules, we emit accessors that using double-checked locking (DCL) to balance thread safety
- * and performance. A lazy val gets a compute method for the DCL's slow path, for a module it's all done in the accessor.
+ * and performance. For both lazy vals and modules, the a compute method contains the DCL's slow path.
*
* Local lazy vals do not receive bitmaps, but use a Lazy*Holder that has the volatile init bit and the computed value.
* See `mkLazyLocalDef`.
@@ -236,7 +236,9 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
*
* TODO: optimize using local variable?
*/
- Block(If(needsInit, gen.mkSynchronized(monitorHolder)(If(needsInit, init, EmptyTree)), EmptyTree) :: Nil, moduleVarRef)
+ val computeName = nme.newLazyValSlowComputeName(module.name)
+ val computeMethod = DefDef(NoMods, computeName, Nil, ListOfNil, TypeTree(UnitTpe), gen.mkSynchronized(monitorHolder)(If(needsInit, init, EmptyTree)))
+ Block(computeMethod :: If(needsInit, Apply(Ident(computeName), Nil), EmptyTree) :: Nil, moduleVarRef)
}
// NoSymbol for lazy accessor sym with unit result type
diff --git a/test/files/run/delambdafy_t6028.check b/test/files/run/delambdafy_t6028.check
index eaba70ee1a..6a15b3b003 100644
--- a/test/files/run/delambdafy_t6028.check
+++ b/test/files/run/delambdafy_t6028.check
@@ -42,10 +42,11 @@ package <empty> {
<synthetic> <stable> <artifact> def $outer(): T = MethodLocalObject$2.this.$outer;
<synthetic> <stable> <artifact> def $outer(): T = MethodLocalObject$2.this.$outer
};
+ final private[this] def MethodLocalObject$lzycompute$1(barParam$1: String, MethodLocalObject$module$1: runtime.VolatileObjectRef): Unit = T.this.synchronized[Unit](if (MethodLocalObject$module$1.elem.$asInstanceOf[T#MethodLocalObject$2.type]().eq(null))
+ MethodLocalObject$module$1.elem = new T#MethodLocalObject$2.type(T.this, barParam$1));
final <stable> private[this] def MethodLocalObject$1(barParam$1: String, MethodLocalObject$module$1: runtime.VolatileObjectRef): T#MethodLocalObject$2.type = {
if (MethodLocalObject$module$1.elem.$asInstanceOf[T#MethodLocalObject$2.type]().eq(null))
- T.this.synchronized[Unit](if (MethodLocalObject$module$1.elem.$asInstanceOf[T#MethodLocalObject$2.type]().eq(null))
- MethodLocalObject$module$1.elem = new T#MethodLocalObject$2.type(T.this, barParam$1));
+ T.this.MethodLocalObject$lzycompute$1(barParam$1, MethodLocalObject$module$1);
MethodLocalObject$module$1.elem.$asInstanceOf[T#MethodLocalObject$2.type]()
};
final <artifact> private[this] def $anonfun$tryy$1(tryyParam$1: String, tryyLocal$1: runtime.ObjectRef): Unit = try {
diff --git a/test/files/run/t6028.check b/test/files/run/t6028.check
index d6cc452bbf..80f8698ecf 100644
--- a/test/files/run/t6028.check
+++ b/test/files/run/t6028.check
@@ -54,10 +54,11 @@ package <empty> {
<synthetic> <stable> <artifact> def $outer(): T = MethodLocalObject$2.this.$outer;
<synthetic> <stable> <artifact> def $outer(): T = MethodLocalObject$2.this.$outer
};
+ final private[this] def MethodLocalObject$lzycompute$1(barParam$1: Int, MethodLocalObject$module$1: runtime.VolatileObjectRef): Unit = T.this.synchronized[Unit](if (MethodLocalObject$module$1.elem.$asInstanceOf[T#MethodLocalObject$2.type]().eq(null))
+ MethodLocalObject$module$1.elem = new T#MethodLocalObject$2.type(T.this, barParam$1));
final <stable> private[this] def MethodLocalObject$1(barParam$1: Int, MethodLocalObject$module$1: runtime.VolatileObjectRef): T#MethodLocalObject$2.type = {
if (MethodLocalObject$module$1.elem.$asInstanceOf[T#MethodLocalObject$2.type]().eq(null))
- T.this.synchronized[Unit](if (MethodLocalObject$module$1.elem.$asInstanceOf[T#MethodLocalObject$2.type]().eq(null))
- MethodLocalObject$module$1.elem = new T#MethodLocalObject$2.type(T.this, barParam$1));
+ T.this.MethodLocalObject$lzycompute$1(barParam$1, MethodLocalObject$module$1);
MethodLocalObject$module$1.elem.$asInstanceOf[T#MethodLocalObject$2.type]()
};
@SerialVersionUID(value = 0) final <synthetic> class $anonfun$tryy$1 extends scala.runtime.AbstractFunction0$mcV$sp with Serializable {
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala
index 85b44d9fa0..95b47f7d04 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlineWarningTest.scala
@@ -198,7 +198,9 @@ class InlineWarningTest extends BytecodeTesting {
|Note that class A is defined in a Java source (mixed compilation), no bytecode is available.""".stripMargin
)
var c = 0
- compileClasses(sCode, javaCode = List((jCode, "A.java")), allowMessage = i => { c += 1; warns.exists(i.msg.contains)})
+ compileClasses(sCode, javaCode = List((jCode, "A.java")), allowMessage = i => { c += 1;
+ warns.exists(i.msg.contains)
+ })
assert(c == 2)
}
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala
index eae5385147..8861577366 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/ScalaInlineInfoTest.scala
@@ -107,7 +107,9 @@ class ScalaInlineInfoTest extends BytecodeTesting {
("x5$(LT;)I", MethodInlineInfo(true ,false,false)),
("L$1(Lscala/runtime/VolatileObjectRef;)LT$L$2$;", MethodInlineInfo(true, false,false)),
("nest$1()I", MethodInlineInfo(true, false,false)),
- ("$init$(LT;)V", MethodInlineInfo(true,false,false))),
+ ("$init$(LT;)V", MethodInlineInfo(true,false,false)),
+ ("L$lzycompute$1(Lscala/runtime/VolatileObjectRef;)V", MethodInlineInfo(true,false,false))
+ ),
None // warning
)
@@ -128,7 +130,9 @@ class ScalaInlineInfoTest extends BytecodeTesting {
"x4()I" -> MethodInlineInfo(false,false,false),
// "x5()I" -> MethodInlineInfo(true ,false,false), -- there is no x5 in the class as it's implemented fully in the interface
"T$$super$toString()Ljava/lang/String;" -> MethodInlineInfo(true ,false,false),
- "<init>()V" -> MethodInlineInfo(false,false,false)),
+ "<init>()V" -> MethodInlineInfo(false,false,false),
+ "O$lzycompute$1()V" -> MethodInlineInfo(true,false,false)
+ ),
None)
assert(infoC == expectC, mapDiff(expectC.methodInfos, infoC.methodInfos) + infoC)
@@ -179,6 +183,7 @@ class ScalaInlineInfoTest extends BytecodeTesting {
val infoC = inlineInfo(c)
val expected = Map(
"<init>()V" -> MethodInlineInfo(false,false,false),
+ "O$lzycompute$1()V" -> MethodInlineInfo(true,false,false),
"O()LC$O$;" -> MethodInlineInfo(true,false,false))
assert(infoC.methodInfos == expected, mapDiff(infoC.methodInfos, expected))
assertSameMethods(c, expected.keySet)