- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Re: scalac -optimise with surprising effect
Sun, 2011-08-21, 14:46
This is normal behaviour of the optimizer
because you are not using val a.
The not-optimized version does:
int a = this.$outer.ar()[this.$outer.x()];
while the optimized version does:
this.$outer.ar(); this.$outer.x();
which isn't doing much.
so it is not really accessing the array
if you add a line:
println(a)
then you get your out of bounds exception
Test$delayedInit$body.class
===========================
package err;
import scala.Array.;
import scala.Predef.;
import scala.ScalaObject;
import scala.reflect.Manifest.;
import scala.runtime.AbstractFunction0;
import scala.runtime.BoxedUnit;
import scala.runtime.BoxesRunTime;
public final class Test$delayedInit$body extends AbstractFunction0
implements ScalaObject
{
private final Test. $outer;
public final Object apply()
{
this.$outer.ar_$eq((int[])Array..MODULE$.ofDim(5, Manifest..MODULE
$.Int()));
this.$outer.x_$eq(0);
while (this.$outer.x() <= 5) {
Predef..MODULE$.println(BoxesRunTime.boxToInteger(this.
$outer.x()));
int a = this.$outer.ar()[this.$outer.x()];
this.$outer.x_$eq(this.$outer.x() + 1);
}
return BoxedUnit.UNIT;
}
public Test$delayedInit$body(Test. $outer)
{
}
}
Test$delayedInit$body.class
===========================
with -optimise
package err;
import scala.Array.;
import scala.Predef.;
import scala.ScalaObject;
import scala.reflect.Manifest.;
import scala.runtime.AbstractFunction0;
import scala.runtime.BoxedUnit;
import scala.runtime.BoxesRunTime;
public final class Test$delayedInit$body extends AbstractFunction0
implements ScalaObject
{
private final Test. $outer;
public final Object apply()
{
this.$outer.ar_$eq((int[])Array..MODULE$.ofDim(5, Manifest..MODULE
$.Int()));
this.$outer.x_$eq(0);
while (this.$outer.x() <= 5) {
Predef..MODULE$.println(BoxesRunTime.boxToInteger(this.
$outer.x()));
this.$outer.ar(); this.$outer.x();
this.$outer.x_$eq(this.$outer.x() + 1);
}
return BoxedUnit.UNIT;
}
public Test$delayedInit$body(Test. $outer)
{
}
}
On 21 aug, 15:38, HamsterofDeath wrote:
> decompile it and share the results
>
> Am 21.08.2011 15:09, schrieb Daniel D.:
>
>
>
> > object Test extends App{
> > val ar = Array.ofDim[Int](5)
>
> > var x = 0
> > while(x<=5){
> > println(x)
> > val a = ar(x)
> > x+=1
> > }
> > }
>
> > compiling this just with scalac gives an
> > ArrayIndexOutOfBoundsException, as expected.
>
> > with scalac -optimize it works. What is -optimize magically doing with
> > the code? Does it really check for IndexBounds?
> > The same holds true if using a for loop instead of a while.
>
> > I have to say I was surprised by this behavior...
>
> > Dan- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -
Sun, 2011-08-21, 18:57
#2
Re: scalac -optimise with surprising effect
This one was with JD-GUI (for windows).
On 21 aug, 16:05, "Daniel D."
wrote:
> Ahh, ok. So this was purely artificial.
> Thanks
>
> BTW: Which decompiler are you using?
>
> On 21 Aug., 15:46, Dave wrote:
>
>
>
> > This is normal behaviour of the optimizer
> > because you are not using val a.
>
> > The not-optimized version does:
> > int a = this.$outer.ar()[this.$outer.x()];
>
> > while the optimized version does:
> > this.$outer.ar(); this.$outer.x();
> > which isn't doing much.
>
> > so it is not really accessing the array
>
> > if you add a line:
> > println(a)
> > then you get your out of bounds exception
>
> > Test$delayedInit$body.class
> > ===========================
> > package err;
>
> > import scala.Array.;
> > import scala.Predef.;
> > import scala.ScalaObject;
> > import scala.reflect.Manifest.;
> > import scala.runtime.AbstractFunction0;
> > import scala.runtime.BoxedUnit;
> > import scala.runtime.BoxesRunTime;
>
> > public final class Test$delayedInit$body extends AbstractFunction0
> > implements ScalaObject
> > {
> > private final Test. $outer;
>
> > public final Object apply()
> > {
> > this.$outer.ar_$eq((int[])Array..MODULE$.ofDim(5, Manifest..MODULE
> > $.Int()));
>
> > this.$outer.x_$eq(0);
> > while (this.$outer.x() <= 5) {
> > Predef..MODULE$.println(BoxesRunTime.boxToInteger(this.
> > $outer.x()));
> > int a = this.$outer.ar()[this.$outer.x()];
> > this.$outer.x_$eq(this.$outer.x() + 1);
> > }
> > return BoxedUnit.UNIT;
> > }
>
> > public Test$delayedInit$body(Test. $outer)
> > {
> > }
>
> > }
>
> > Test$delayedInit$body.class
> > ===========================
> > with -optimise
>
> > package err;
>
> > import scala.Array.;
> > import scala.Predef.;
> > import scala.ScalaObject;
> > import scala.reflect.Manifest.;
> > import scala.runtime.AbstractFunction0;
> > import scala.runtime.BoxedUnit;
> > import scala.runtime.BoxesRunTime;
>
> > public final class Test$delayedInit$body extends AbstractFunction0
> > implements ScalaObject
> > {
> > private final Test. $outer;
>
> > public final Object apply()
> > {
> > this.$outer.ar_$eq((int[])Array..MODULE$.ofDim(5, Manifest..MODULE
> > $.Int()));
>
> > this.$outer.x_$eq(0);
> > while (this.$outer.x() <= 5) {
> > Predef..MODULE$.println(BoxesRunTime.boxToInteger(this.
> > $outer.x()));
> > this.$outer.ar(); this.$outer.x();
> > this.$outer.x_$eq(this.$outer.x() + 1);
> > }
> > return BoxedUnit.UNIT;
> > }
>
> > public Test$delayedInit$body(Test. $outer)
> > {
> > }
>
> > }
>
> > On 21 aug, 15:38, HamsterofDeath wrote:
>
> > > decompile it and share the results
>
> > > Am 21.08.2011 15:09, schrieb Daniel D.:
>
> > > > object Test extends App{
> > > > val ar = Array.ofDim[Int](5)
>
> > > > var x = 0
> > > > while(x<=5){
> > > > println(x)
> > > > val a = ar(x)
> > > > x+=1
> > > > }
> > > > }
>
> > > > compiling this just with scalac gives an
> > > > ArrayIndexOutOfBoundsException, as expected.
>
> > > > with scalac -optimize it works. What is -optimize magically doing with
> > > > the code? Does it really check for IndexBounds?
> > > > The same holds true if using a for loop instead of a while.
>
> > > > I have to say I was surprised by this behavior...
>
> > > > Dan- Tekst uit oorspronkelijk bericht niet weergeven -
>
> > > - Tekst uit oorspronkelijk bericht weergeven -- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -
Ahh, ok. So this was purely artificial.
Thanks
BTW: Which decompiler are you using?
On 21 Aug., 15:46, Dave wrote:
> This is normal behaviour of the optimizer
> because you are not using val a.
>
> The not-optimized version does:
> int a = this.$outer.ar()[this.$outer.x()];
>
> while the optimized version does:
> this.$outer.ar(); this.$outer.x();
> which isn't doing much.
>
> so it is not really accessing the array
>
> if you add a line:
> println(a)
> then you get your out of bounds exception
>
> Test$delayedInit$body.class
> ===========================
> package err;
>
> import scala.Array.;
> import scala.Predef.;
> import scala.ScalaObject;
> import scala.reflect.Manifest.;
> import scala.runtime.AbstractFunction0;
> import scala.runtime.BoxedUnit;
> import scala.runtime.BoxesRunTime;
>
> public final class Test$delayedInit$body extends AbstractFunction0
> implements ScalaObject
> {
> private final Test. $outer;
>
> public final Object apply()
> {
> this.$outer.ar_$eq((int[])Array..MODULE$.ofDim(5, Manifest..MODULE
> $.Int()));
>
> this.$outer.x_$eq(0);
> while (this.$outer.x() <= 5) {
> Predef..MODULE$.println(BoxesRunTime.boxToInteger(this.
> $outer.x()));
> int a = this.$outer.ar()[this.$outer.x()];
> this.$outer.x_$eq(this.$outer.x() + 1);
> }
> return BoxedUnit.UNIT;
> }
>
> public Test$delayedInit$body(Test. $outer)
> {
> }
>
> }
>
> Test$delayedInit$body.class
> ===========================
> with -optimise
>
> package err;
>
> import scala.Array.;
> import scala.Predef.;
> import scala.ScalaObject;
> import scala.reflect.Manifest.;
> import scala.runtime.AbstractFunction0;
> import scala.runtime.BoxedUnit;
> import scala.runtime.BoxesRunTime;
>
> public final class Test$delayedInit$body extends AbstractFunction0
> implements ScalaObject
> {
> private final Test. $outer;
>
> public final Object apply()
> {
> this.$outer.ar_$eq((int[])Array..MODULE$.ofDim(5, Manifest..MODULE
> $.Int()));
>
> this.$outer.x_$eq(0);
> while (this.$outer.x() <= 5) {
> Predef..MODULE$.println(BoxesRunTime.boxToInteger(this.
> $outer.x()));
> this.$outer.ar(); this.$outer.x();
> this.$outer.x_$eq(this.$outer.x() + 1);
> }
> return BoxedUnit.UNIT;
> }
>
> public Test$delayedInit$body(Test. $outer)
> {
> }
>
> }
>
> On 21 aug, 15:38, HamsterofDeath wrote:
>
>
>
>
>
>
>
> > decompile it and share the results
>
> > Am 21.08.2011 15:09, schrieb Daniel D.:
>
> > > object Test extends App{
> > > val ar = Array.ofDim[Int](5)
>
> > > var x = 0
> > > while(x<=5){
> > > println(x)
> > > val a = ar(x)
> > > x+=1
> > > }
> > > }
>
> > > compiling this just with scalac gives an
> > > ArrayIndexOutOfBoundsException, as expected.
>
> > > with scalac -optimize it works. What is -optimize magically doing with
> > > the code? Does it really check for IndexBounds?
> > > The same holds true if using a for loop instead of a while.
>
> > > I have to say I was surprised by this behavior...
>
> > > Dan- Tekst uit oorspronkelijk bericht niet weergeven -
>
> > - Tekst uit oorspronkelijk bericht weergeven -