summaryrefslogtreecommitdiff
path: root/test/files/run/t9365.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2015-07-27 15:33:30 +1000
committerJason Zaugg <jzaugg@gmail.com>2015-07-27 16:05:06 +1000
commit0c99742c51706ee4b60a56a8f5babb13682f9b10 (patch)
tree52ed40408595538c74da8f0fa8c8e6effc18875c /test/files/run/t9365.scala
parent0e9525aa618a2eca143a1c7379ff1e6efd23b86e (diff)
downloadscala-0c99742c51706ee4b60a56a8f5babb13682f9b10.tar.gz
scala-0c99742c51706ee4b60a56a8f5babb13682f9b10.tar.bz2
scala-0c99742c51706ee4b60a56a8f5babb13682f9b10.zip
SI-9365 Don't null out dependencies of transient lazy vals
As per Iulian's analysis: > When lazy vals are transient, the optimization in SI-720 is invalid, > leading to NPEs. These NPEs appear when recomputing the lazy val when deserializaing the object. This commit disables the field nulling if the lazy val is marked transient. The post-mixin tree in the enclosed test changes as follows: ``` --- sandbox/old.log 2015-07-27 15:48:03.000000000 +1000 +++ sandbox/new.log 2015-07-27 15:47:56.000000000 +1000 @@ -1,61 +1,54 @@ [[syntax trees at end of mixin]] // t9365.scala package <empty> { class Test extends Object with Serializable { @transient @volatile private[this] var bitmap$trans$0: Boolean = false; private def foo$lzycompute(): Object = { { Test.this.synchronized({ if (Test.this.bitmap$trans$0.unary_!()) { Test.this.foo = Test.this.x.apply(); Test.this.bitmap$trans$0 = true; () }; scala.runtime.BoxedUnit.UNIT }); - Test.this.x = null + () }; Test.this.foo }; ``` In addition to the test from the ticket, I've added a reflection based test that directly tests the nulling. This complements the test added in 449f2a7473, the fix for SI-720, which passes by virtue of not exhausting the heap.
Diffstat (limited to 'test/files/run/t9365.scala')
-rw-r--r--test/files/run/t9365.scala18
1 files changed, 18 insertions, 0 deletions
diff --git a/test/files/run/t9365.scala b/test/files/run/t9365.scala
new file mode 100644
index 0000000000..0c4477dda9
--- /dev/null
+++ b/test/files/run/t9365.scala
@@ -0,0 +1,18 @@
+class Test(x: => Object) extends Serializable {
+ @transient lazy val foo = x
+}
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ import java.io._
+ val t = new Test("foo")
+ println(t.foo)
+ val baos = new ByteArrayOutputStream
+ val dos = new ObjectOutputStream(baos)
+ dos.writeObject(t)
+ dos.close()
+ val dis = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))
+ val t1 = dis.readObject().asInstanceOf[Test]
+ println(t1.foo) // was NPE
+ }
+}