You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GWT version: GWT 2.11 and below Browser (with version): Any Operating System: Any
Background
GWT takes care to follow Java semantics in ways that users may not always expect or appreciate, especially around class initializers. In the JVM, a class must be initialized before it can be instantiated or its static members can be used, so in GWT, a $clinit function is created per class, roughly structured as
function$clinit_SomeClass(){$clinit_77=function(){};$clinit_SuperClass();// initialize static fields, run static initializer bodies...}
This ensures that if invoked more than once, the initializer won't replace already-initialized fields, etc. This will appear at the top of constructors and static methods, and will appear before references to static fields:
This often seems to generate unnecessary output, such as duplicate or pointless clinit calls. Some of these are due to non-obvious side effects from initializing classes, others are unoptimized cases where clinits were appropriately emitted for each individual reference/invocation, but inlining and dead code elimination has left duplicates or leftovers.
Potentially related issues to review when working on this: #9731 #9004 #6534
Proposal
Support a configuration property that takes a list of fully-qualified classes to initialize at startup. This would work somewhat like compiler.splitpoint.initial.sequence, where order matters, and users can add their own items to the list.
Items in this list would have their clinit invoked in order before any entrypoint is constructed. Each must not directly or indirectly cause any other class to be initialized, except those which have already been initialized.
Several built-in classes should be set to use this by default:
StackTraceCreator (resolves an early-startup cycle with Impl)
Double/String/Boolean. Potentially other boxed primitives as well, but those three are "always" used due to their relationship with their corresponding JS types. Impl, BigLongLib, other built-in types. Focusing on these should improve output and performance for most applications.
Consider automatically applying this to some enums (which define no non-constant static fields or static initializers), to both improve generated code size, and avoid changing program semantics. Some care must be taken to ensure that the enum wouldn't be optimized out to begin with.
Allow this configuration property to be further extended by application code, ensuring it can be disabled outright, have new classes added to it, and order specified.
The text was updated successfully, but these errors were encountered:
Hm I don't like introducing a compiler option right away. If some of the shortcomings in the compiler can be fixed, the property might not be worth it.
Making sure that empty clinits are removed
Maybe gather statistics about generated non-empty clinit function calls per class and give top contenders shorter obfuscated function names (might already be the case)
Given that GWT orders functions in a way that gzip works even better I am not sure if such an optimization would save a noticeable amount of download size.
Yep, I'm not saying this is definitely the right approach, but worth exploring. Compiled size is only one facet to this - Impl and StackTraceCreator also have a cyclical initialization dependency, and there are a few other classes (DomEvent is the only one I can find right now, but I thought there was another reference).
Additionally, clinits leave side effects in code that otherwise would have none, since they have their own "was I initialized or not" state - if the compiler can't prove that an otherwise pure function is being called on an already initialized class (like Double), it has to leave the clinit in place.
My limited experience with the compiler and the current contributors suggests that this approach is likely to be more fruitful. I have a very old draft of looking at handling these issues in this way, and definitely seemed to go better than my previous attacks on JsInliner and friends. But if you've got time/budget to try directly addressing in other ways, I'm all for it!
GWT version: GWT 2.11 and below
Browser (with version): Any
Operating System: Any
Background
GWT takes care to follow Java semantics in ways that users may not always expect or appreciate, especially around class initializers. In the JVM, a class must be initialized before it can be instantiated or its static members can be used, so in GWT, a
$clinit
function is created per class, roughly structured asThis ensures that if invoked more than once, the initializer won't replace already-initialized fields, etc. This will appear at the top of constructors and static methods, and will appear before references to static fields:
This often seems to generate unnecessary output, such as duplicate or pointless clinit calls. Some of these are due to non-obvious side effects from initializing classes, others are unoptimized cases where clinits were appropriately emitted for each individual reference/invocation, but inlining and dead code elimination has left duplicates or leftovers.
Potentially related issues to review when working on this:
#9731
#9004
#6534
Proposal
compiler.splitpoint.initial.sequence
, where order matters, and users can add their own items to the list.The text was updated successfully, but these errors were encountered: