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;
> > +    }
> > +
> >  }
> >
> >
>

Reply via email to