This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Re: scalac -optimise with surprising effect

2 replies
DaveScala
Joined: 2011-03-18,
User offline. Last seen 1 year 21 weeks ago.

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 -

Daniel Degrandi
Joined: 2010-05-10,
User offline. Last seen 42 years 45 weeks ago.
Re: scalac -optimise with surprising effect

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 -

DaveScala
Joined: 2011-03-18,
User offline. Last seen 1 year 21 weeks ago.
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 -

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland