diff options
author | James Iry <jamesiry@gmail.com> | 2013-01-23 16:01:59 -0800 |
---|---|---|
committer | James Iry <jamesiry@gmail.com> | 2013-01-28 21:47:54 -0800 |
commit | eab288442931f01b5bad2dcfa244a6183db0f4b6 (patch) | |
tree | 0f0d655e29c134f621ff2bc97c2f873c4d215a6a /test/files/run/t5313.scala | |
parent | cc3b9a23ebb453b827197e5ab5cba46a9e770f0c (diff) | |
download | scala-eab288442931f01b5bad2dcfa244a6183db0f4b6.tar.gz scala-eab288442931f01b5bad2dcfa244a6183db0f4b6.tar.bz2 scala-eab288442931f01b5bad2dcfa244a6183db0f4b6.zip |
SI-5313 Do not eliminate stores that potentially wipe referenes
Storing to local variables of reference or array type is indirectly
observable because it potentially allows gc to collect an object. So
this commit makes DeadCodeElimination mark a store necessary if it
assigns to a local that potentially stored by a previous necessary store.
Diffstat (limited to 'test/files/run/t5313.scala')
-rw-r--r-- | test/files/run/t5313.scala | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/test/files/run/t5313.scala b/test/files/run/t5313.scala new file mode 100644 index 0000000000..b65311622a --- /dev/null +++ b/test/files/run/t5313.scala @@ -0,0 +1,42 @@ +import scala.tools.partest.IcodeTest + +object Test extends IcodeTest { + override def printIcodeAfterPhase = "dce" + + override def extraSettings: String = super.extraSettings + " -optimize" + + override def code = + """class Foo { + def foo = true + def bar = { + var kept1 = new Object + val result = new java.lang.ref.WeakReference(kept1) + kept1 = null // we can't eliminate this assigment because result can observe + // when the object has no more references. See SI-5313 + var erased2 = null // we can eliminate this store because it's never used + val erased3 = erased2 // and this + var erased4 = erased2 // and this + val erased5 = erased4 // and this + var kept2: Object = new Object // ultimately can't be eliminated + while(foo) { + val kept3 = kept2 + kept2 = null // this can't, because it clobbers x, which is ultimately used + erased4 = null // safe to eliminate + println(kept3) + } + var kept4 = new Object // have to keep, it's used + try + println(kept4) + catch { + case _ : Throwable => kept4 = null // have to keep, it clobbers kept4 which is used + } + result + } + }""".stripMargin + + override def show() { + val storeLocal = "STORE_LOCAL" + val lines1 = collectIcode("") filter (_ contains storeLocal) map (x => x.drop(x.indexOf(storeLocal))) + println(lines1 mkString "\n") + } +} |