My goal is to be able to completely omit classes from release builds when their only purpose is to define a bunch of constants. Usually, you only need a small number of the constants, so the rest of them bloat your app for no good reason.
I made a test project with a class that defines 100 Number constants. When combined this inline-constants option with a hacky tweak to the compiler that omitted the constant definitions from the output, it made the release build 4KB smaller. I still need to figure out how to do that in a non-hacky way, but that kind of reduction is really promising. -- Josh Tynjala Bowler Hat LLC <https://bowlerhat.dev> On Wed, Aug 7, 2019 at 2:47 PM Greg Dove <[email protected]> wrote: > Hey Josh, that sounds pretty cool. I'm not sure, but it might however be > duplicating some aspects of what GCC already does when it optimizes because > I expect it might do the same types of thing when it processes the @const > annotations in the debug code hints. > Also, for example, strings are only included once in the js-release build > if they are above a minimal length and then accessed by reference > irrespective of what inlining changes were made in the debug code output. > This ends up being similar conceptually to SWF's (and AMF) string tables I > think, although I did not check whether that changed since the ASC 2.0 > inlining support. > > fyi I have a local compiler branch from FlexJS days where I have bindings > for (static) primitive constants being converted to initialization value > assignments with inline values instead of *actual bindings*, similar to > what I assume you are doing here, but as a way to avoid running binding > code for simple static constant bindings. I will revisit that at some point > soon, It might help improve startup speed for some people. > > > > On Thu, Aug 8, 2019 at 9:09 AM <[email protected]> wrote: > > > This is an automated email from the ASF dual-hosted git repository. > > > > joshtynjala pushed a commit to branch develop > > in repository https://gitbox.apache.org/repos/asf/royale-compiler.git > > > > > > The following commit(s) were added to refs/heads/develop by this push: > > new 61479f5 compiler-jx: added inline-constants compiler option for > > JS builds to optionally inline the values of primitive constants (like > > Number, String, Boolean, int, and uint) instead of referencing them. > > 61479f5 is described below > > > > commit 61479f5cce3c4ea582a1a6a859f1e74ef9256a9f > > Author: Josh Tynjala <[email protected]> > > AuthorDate: Wed Aug 7 13:52:59 2019 -0700 > > > > compiler-jx: added inline-constants compiler option for JS builds to > > optionally inline the values of primitive constants (like Number, String, > > Boolean, int, and uint) instead of referencing them. > > > > Defaults to false. It may make sense to switch this to true in the > > future, but it's not stable yet. > > > > Does not yet skip unnecessary goog.require() calls, even though the > > classes may no longer be referenced. Figuring out how to do this should > > reduce the size of release builds. > > --- > > .../internal/codegen/js/jx/IdentifierEmitter.java | 37 > > +++++++++++++++++++++- > > .../driver/js/goog/JSGoogConfiguration.java | 19 +++++++++++ > > 2 files changed, 55 insertions(+), 1 deletion(-) > > > > diff --git > > > a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java > > > b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java > > index 4d42069..f6363ea 100644 > > --- > > > a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java > > +++ > > > b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java > > @@ -19,9 +19,12 @@ > > > > package org.apache.royale.compiler.internal.codegen.js.jx; > > > > +import org.apache.royale.abc.ABCConstants; > > import org.apache.royale.abc.semantics.Namespace; > > import org.apache.royale.compiler.codegen.ISubEmitter; > > import org.apache.royale.compiler.codegen.js.IJSEmitter; > > +import org.apache.royale.compiler.constants.IASLanguageConstants; > > +import org.apache.royale.compiler.definitions.IConstantDefinition; > > import org.apache.royale.compiler.definitions.IDefinition; > > import org.apache.royale.compiler.definitions.IFunctionDefinition; > > import > > > org.apache.royale.compiler.definitions.IFunctionDefinition.FunctionClassification; > > @@ -37,6 +40,7 @@ import > > org.apache.royale.compiler.internal.codegen.js.goog.JSGoogEmitterTokens; > > import > > > org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens; > > import > org.apache.royale.compiler.internal.codegen.js.utils.EmitterUtils; > > import org.apache.royale.compiler.internal.definitions.*; > > +import org.apache.royale.compiler.internal.projects.RoyaleJSProject; > > import org.apache.royale.compiler.internal.tree.as > > .BinaryOperatorAssignmentNode; > > import org.apache.royale.compiler.internal.tree.as > > .BinaryOperatorDivisionAssignmentNode; > > import org.apache.royale.compiler.internal.tree.as > > .MemberAccessExpressionNode; > > @@ -76,12 +80,43 @@ public class IdentifierEmitter extends JSSubEmitter > > implements > > && !identifierIsAccessorFunction; > > boolean emitName = true; > > JSRoyaleEmitter fjs = (JSRoyaleEmitter)getEmitter(); > > + RoyaleJSProject project = > > (RoyaleJSProject)getWalker().getProject(); > > boolean isCustomNamespace = false; > > boolean isStatic = nodeDef != null && nodeDef.isStatic(); > > if (nodeDef instanceof FunctionDefinition && > > fjs.isCustomNamespace((FunctionDefinition)nodeDef)) > > - isCustomNamespace = true; > > + isCustomNamespace = true; > > > > + if (isStatic > > + && nodeDef instanceof IConstantDefinition > > + && project != null && project.config != null > > + && project.config.getInlineConstants()) > > + { > > + IConstantDefinition constDef = (IConstantDefinition) > nodeDef; > > + Object initialValue = constDef.resolveInitialValue(project); > > + if (initialValue != null) > > + { > > + startMapping(parentNode); > > + if(initialValue instanceof String) > > + { > > + write("\"" + initialValue + "\""); > > + } > > + else if(initialValue == ABCConstants.UNDEFINED_VALUE) > > + { > > + write(IASLanguageConstants.UNDEFINED); > > + } > > + else if(initialValue == ABCConstants.NULL_VALUE) > > + { > > + write(IASLanguageConstants.NULL); > > + } > > + else > > + { > > + write(initialValue.toString()); > > + } > > + endMapping(parentNode); > > + return; > > + } > > + } > > if (isStatic) > > { > > String sname = nodeDef.getParent().getQualifiedName(); > > diff --git > > > a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/driver/js/goog/JSGoogConfiguration.java > > > b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/driver/js/goog/JSGoogConfiguration.java > > index 45af81c..d4e5328 100644 > > --- > > > a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/driver/js/goog/JSGoogConfiguration.java > > +++ > > > b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/driver/js/goog/JSGoogConfiguration.java > > @@ -512,4 +512,23 @@ public class JSGoogConfiguration extends > > JSConfiguration > > return ret; > > } > > > > + // > > + // 'inline-constants' > > + // > > + > > + private boolean inlineConstants = false; > > + > > + public boolean getInlineConstants() > > + { > > + return inlineConstants; > > + } > > + > > + @Config > > + @Mapping("inline-constants") > > + public void setInlineConstants(ConfigurationValue cv, boolean value) > > + throws ConfigurationException > > + { > > + inlineConstants = value; > > + } > > + > > } > > > > >
