diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2015-07-27 15:33:30 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2015-07-27 16:05:06 +1000 |
commit | 0c99742c51706ee4b60a56a8f5babb13682f9b10 (patch) | |
tree | 52ed40408595538c74da8f0fa8c8e6effc18875c /test/files/run/t9365.scala | |
parent | 0e9525aa618a2eca143a1c7379ff1e6efd23b86e (diff) | |
download | scala-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.scala | 18 |
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 + } +} |