As I said, I hadn't looked at all into how feasible this was... but I was
hoping to do it by jiggering the Java AST, really, and not the JS one.  That
is, I was looking to rewrite the Java from a chained
builder.setA().setB().setC() to multi-statement
builder.setA();builder.setB();builder.setC(), effectively unwinding any call
on the return value of a method returning "this" as a special-case pattern,
and let the Java-to-JavaScript compiler run from that.



On Tue, Jun 16, 2009 at 11:59 AM, Ray Cromwell <[email protected]>wrote:

>
> Even before the inliner gets it, a JSO chained expression like
> a().b().c() is going to look like c(b(a())) so the inliner can only
> inline the first call.
>
> Automatically introducing temporaries would seem a lot harder. You'd
> have to teach the compiler that 'this' is effectively final, and
> therefore any method returning this, effectively always returns the
> same value, regardless of side effects. Then, you'd have to introduce
> the idea that the compiler can introduce temporaries (speculatively),
> and later use common subexpression elimination to detect multiple
> identical ones and hoist them out.
>
> e.g.
>
> c(b(a()))
>
> becomes
>
> var t1, t2, t3;
> t1 = c(t2 = b(t3 = a()))
>
> then, recognizing the that t1=t2=t3=builder=a() with copy propagation
> t1 = builder
> a(t1)
> b(t1)
> c(t1)
>
> and now they can be inlined.
>
> This just seems hard to me, since introducing temporaries is
> speculative and you'd have introduce another pass to remove them in
> the cases where they provided no benefit. However, this could end up
> leading to infinite loops if you're not careful.
>
> -Ray
>
>
>
> On Mon, Jun 15, 2009 at 6:11 PM, Brian Stoler<[email protected]> wrote:
> >
> > Hi gwtc,
> >
> > I was playing with using super-source to emulate some existing code
> > that uses a builder pattern and make it efficient in GWT as a
> > JavaScriptObject. I was hoping that the I could make the Builder just
> > compile away, but that doesn't seem to be happening. I started
> > debugging in JsInliner but started to get a bit lost. This is using
> > svn r5557 on trunk FYI (very recent).
> >
> > What I am seeing is that if you use a chaining call pattern, the
> > inliner doesn't realize some of the optimization it can do.
> >
> > Example usage code:
> >
> >    void example() {
> >        MyData myData = MyData.Builder.create()
> >            .setBar("a")
> >            .setFoo("b").build();
> >
> >        Window.alert(myData.getBar());
> >        Window.alert(myData.getFoo());
> >    }
> >
> >
> > Output I get (extraneous bits removed, PRETTY mode):
> >
> >    function init(){
> >      var myData;
> >      myData = $setFoo($setBar(new Object(), 'a'), 'b');
> >      $wnd.alert(myData.bar);
> >      $wnd.alert(myData.foo);
> >    }
> >
> >    function $setBar(this$static, s){
> >      this$static.bar = s;
> >      return this$static;
> >    }
> >
> >    function $setFoo(this$static, s){
> >      this$static.foo = s;
> >      return this$static;
> >    }
> >
> >
> > However, with this similar code:
> >
> >    void example2() {
> >        MyData.Builder builder = MyData.Builder.create();
> >        builder.setBar("a");
> >        builder.setFoo("b");
> >
> >        MyData myData = builder.build();
> >
> >        Window.alert(myData.getBar());
> >        Window.alert(myData.getFoo());
> >    }
> >
> >
> > The code compiles better (no setters):
> >
> >      builder = new Object();
> >      builder.bar = 'a';
> >      builder.foo = 'b';
> >      myData = builder;
> >      $wnd.alert(myData.bar);
> >      $wnd.alert(myData.foo);
> >
> >
> > The biggest issue seemed to be that the inliner didn't introduce a
> > local variable for "new Object()", and because of that, it correctly
> > concluded it couldn't keep copying that expression around. (I traced
> > through it having issues due to "new" having side effects.) Even if I
> > manually create a variable for the Builder at the outset, it still
> > doesn't help. (FYI, I am using new Object() instead of {} to work
> > around http://code.google.com/p/google-web-toolkit/issues/detail?id=3568
> )
> >
> > I was going to try to dig some more in to the inliner, but any ideas
> > how to improve this?
> >
> > Will a later pass remove useless variable aliasing? (Seems like not
> > from my other example?) If so, I was thinking it might work to have
> > the inliner introduce a local all the time when it is trying to inline
> > a non-void function. Smarter methods are of course possible, but I
> > thought that might be worth a shot.
> >
> > Any other ideas welcome. MyData class attached below. I tried a
> > variety of small tweaks to the MyData class and nothing made a
> > difference.
> >
> > FYI, my eventual goal is:
> >
> > var myData = {bar:'a',foo:'b'};
> >
> > But that seems like an orthogonal optimization (and perhaps
> > generically useful).
> >
> > Thanks for your interest, if you read this far,
> > -brian
> >
> > PS: I am open to any changes to the MyData code below that a) preserve
> > the JSO-ness and b) leave the external API the same.
> >
> >  public static interface MyData {
> >    String getFoo();
> >    String getBar();
> >
> >    public static final class Builder extends JavaScriptObject
> > implements MyData {
> >      protected Builder() {}
> >
> >      public static native Builder create() /*-{
> >        return new Object();
> >      }-*/;
> >
> >      public native String getFoo() /*-{
> >        return this.foo;
> >      }-*/;
> >
> >      public native String getBar() /*-{
> >        return this.bar;
> >      }-*/;
> >
> >      public Builder setFoo(String s) {
> >        setFooImpl(s);
> >        return this;
> >      }
> >
> >      private native void setFooImpl(String s) /*-{
> >        this.foo = s;
> >      }-*/;
> >
> >      public Builder setBar(String s) {
> >        setBarImpl(s);
> >        return this;
> >      }
> >
> >      private native void setBarImpl(String s) /*-{
> >        this.bar = s;
> >      }-*/;
> >
> >      public MyData build() {
> >        return this;
> >      }
> >    }
> >  }
> >
> > >
> >
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to