How Gwt runAsync decides to include code... be careful...?

258 views
Skip to first unread message

Ed

unread,
Dec 16, 2012, 7:15:21 AM12/16/12
to google-we...@googlegroups.com
(Using version 2.5.0)

I am a bit surprised the way gwt decide to include code in a split point, or left over.

Example: creation of a controller in a split point. (without the -XfragmentCount option)
1) Safe way that always works:  create controller in an anonymous RunAsyncCallback.onSuccess() method:
----
public void createSomeController(final AsyncCallback<MemberLoonController> callback, final Bla args) {
 final RunAsyncCallback async = new RunAsyncCallback() {
   public void onSuccess() {
callback.onSuccess(new SomeControllerDefault(args));
   }
   public void onFailure(Throwable ex) {
callback.onFailure(ex);
   }
 };
GWT.runAsync(async);
}
----
The above gives the same result when not creating  the async variable but passing the RunAsyncCallback directly to the GWT.runAsync() method. Which might sound logic, but nothing is like it seems...
Above results in my case in (Soyc report):
 Total code size: 1.1 MB
 Initial size: 350 KB
 left over: 550 KB

2) However when I replace the above line  "GWT.runAsync(async)" by the following:
---
if (GWT.isScript()) {
GWT.runAsync(async);
}
else {
   new CommandDeferred() { 
     public void execute() { 
         GWT.runAsync(callback); 
      } 
    }; 
}
----
I do the above because I want   the runAsync to be run decoupled when running in dev mode to get the exact same behavior as in script mode. This is due to an open issue (bug) that hasn't been solved yet, that is: in dev mode the behavior is different as it's not decoupled that can lead to strange app bugs..
Anyway: the point here is: that it will always run the "GWT.runAsync(async);" command just like above but then through an if statement...
Surprisingly however, the above results in a much bigger left over:
---
 Total code size: 1.1 MB
 Initial size: 350 KB
 left over: 750 KB
---
Interesting, so the GWT compiler doesn't use the runtime dependency path like you would expect...
BTW: this is a bumper so that I can never use this construction, such that my behavior in web and dev mode are (too) different... (mentioned above)

This is just one of the tests that was I was surprised of.
I another test I did:
3) Just like 1) but pass in a Creator method, like this: 
---
public void createSomeController(final AsyncCallback<SomeController> callback, final CreatorSimple<SomeController> creator) {
   final RunAsyncCallback async = new RunAsyncCallback() {
public void onSuccess() {
callback.onSuccess(creator.create());
}

public void onFailure(Throwable ex) {
callback.onFailure(ex);
}
  };
  GWT.runAsync(async);
}
---
I call the above code like this for example (the above usage makes it nice to share split points in case it works anyway):
---
final CreatorSimple<SomeController> creator = new CreatorSimple<SomeController>() {
   public SomeController create() {
return new SomeControllerDefault(args);
   }
};
getLazyLoader().createLoonController(callback, creator);
---
Also this results in the same big left over :(..
I am surprised about this as the creation of the controller is only called through the GWT.runAsync() and NEVER through another piece of code...
So why is my left over so big? Why is GWT deciding it's not included in it's own split point?
I don't understand the difference with construction 1), as besides it's another construction, it leads to the same result you would expect
I tried more constructions like putting the controller creation in it's own class instead of through an anonymous class, but it all results to the same big left over...

Idea's, your experience ?

My experience/advice: always use the less flexible construction 1) which makes it difficult to share split points and workaround the dev-mode-script-mode (bug) difference.. But at least that results in "correct" split points...

- Ed




Ed

unread,
Dec 18, 2012, 10:25:03 AM12/18/12
to google-we...@googlegroups.com
Can somebody tell me if the above is expected behavior or a bug?
So should I put it in the issue tracker?
Of should the doc be more specific about the above usage?

Please test it yourself ..
- Ed

Op zondag 16 december 2012 13:15:21 UTC+1 schreef Ed het volgende:

Jens

unread,
Dec 18, 2012, 10:54:40 AM12/18/12
to google-we...@googlegroups.com
Your compile report should tell you why your controller is now in the left over fragment. Its always hard to tell whats going on without knowing the whole code and the compile report.

For example a wild guess: In your second example you have two GWT.runAsync() calls with the same AsyncCallback (I assume that GWT.runAsync(callback) is a typo in your execute method and it should be GWT.runAsync(async)..). At first sight you have 2 possible paths now to load your controller. Maybe at the time the split points are calculated the GWT compiler has not yet optimized your IF statement to if(true) { .. } and pruned useless code and thus the CodeSplitter algorithm still sees two possible paths (although I think that its not the case, but I don't know the compiler flow).


-- J.

Ed

unread,
Dec 18, 2012, 11:13:24 AM12/18/12
to google-we...@googlegroups.com
Thanks Jens.

>Your compile report should tell you why your controller is now in the left over fragment.
I am aware of that, and that was exactly why I post this, as the soyc report shows a compiler-code path, and no "dependency path". Like mentioned, the controller creation code is ONLY called through the GWT.runAsnc(...) code but still the socy show like if it was called from "different" method. The report isn't very clear on these details, it just shows a list of methods even do they are not related, that is, they don't call each other direct or indirectly (even not when walking through the complete path or setting breakpoints).

> I assume that GWT.runAsync(callback) is a typo in your execute method and it should be GWT.runAsync(async)..)
Yes, thanks.

> and pruned useless code and thus the CodeSplitter algorithm still sees two possible paths
Good point, thanks for noticing...


Op dinsdag 18 december 2012 16:54:40 UTC+1 schreef Jens het volgende:

Matthew Dempsky

unread,
Dec 18, 2012, 12:11:55 PM12/18/12
to google-web-toolkit
On Tue, Dec 18, 2012 at 7:25 AM, Ed <post2...@gmail.com> wrote:
Can somebody tell me if the above is expected behavior or a bug?

We're aware there are issues with the current split-point algorithm that results in dead code being included in fragments.  It's on our list of higher priority issues to investigate and fix, but I'm not sure how far along that is.  Ray Cromwell and/or Roberto Lublinerman would know.

So should I put it in the issue tracker?

If you con put together a minimal and easy-to-reproduce test case, it wouldn't hurt.

Jens

unread,
Dec 18, 2012, 12:24:44 PM12/18/12
to google-we...@googlegroups.com

We're aware there are issues with the current split-point algorithm that results in dead code being included in fragments.  It's on our list of higher priority issues to investigate and fix, but I'm not sure how far along that is.  Ray Cromwell and/or Roberto Lublinerman would know.

Poor Ray, he already has a bad boy bug assigned where wrong code is generated in split points :)

-- J.

Ed Bras

unread,
Dec 18, 2012, 4:59:45 PM12/18/12
to google-we...@googlegroups.com
Thanks for your feedback.
I will open an issue these days and will links the issue and this topic.
I will put a minimum test-case on my "todo", I will do my best to add it in the comming weeks..  
- Ed

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-web-toolkit/-/cOpckcLFXFIJ.

To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

Ed Bras

unread,
Jun 9, 2013, 4:40:37 PM6/9/13
to google-we...@googlegroups.com
Thanks.... excellent work...


On Sat, Jun 8, 2013 at 12:03 AM, John Stalcup <sta...@google.com> wrote:
Goktug has commited a fix at https://gwt.googlesource.com/gwt/+/6d2ad61035607f4799301f0c0bc0991006a5f097 to make GWT.runAsync() act asynchronously in devmode as well.

Your work around should no longer be necessary if you work off a HEAD version of GWT.

--
You received this message because you are subscribed to a topic in the Google Groups "Google Web Toolkit" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-web-toolkit/aZD_dhldo54/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to google-web-tool...@googlegroups.com.

To post to this group, send email to google-we...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages