Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add custom closure compiler pass #2593

Merged
merged 2 commits into from
Apr 22, 2016
Merged

Conversation

erwinmombay
Copy link
Member

@erwinmombay erwinmombay commented Mar 15, 2016

Closes #2386

We add a custom closure compiler pass called AmpPass which allows us to do some optimizations like assert and logging elimination.


@Override
protected CompilerOptions createOptions() {
CompilerOptions options = super.createOptions();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we test this? Should we first try it w/o LOG_STRIP_TYPES and see if the result is equivalent?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dvoytenko absolutely. trying to get a local green test first before since local is super flakey right now =/. i also need to add its integration with the gulp build pipeline

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added JUnit tests.

@erwinmombay erwinmombay force-pushed the runner branch 6 times, most recently from 05a2417 to 5c5f91d Compare March 16, 2016 08:25
@erwinmombay erwinmombay changed the title [WIP] add custom closure compiler runner add custom closure compiler runner Mar 16, 2016
@erwinmombay erwinmombay force-pushed the runner branch 2 times, most recently from 5161682 to 0f71025 Compare March 16, 2016 23:37
@erwinmombay erwinmombay changed the title add custom closure compiler runner [WIP] add custom closure compiler runner Mar 16, 2016
@erwinmombay erwinmombay force-pushed the runner branch 4 times, most recently from 4555e6b to e5f0dff Compare March 16, 2016 23:40
@Override
protected CompilerOptions createOptions() {
CompilerOptions options = super.createOptions();
options.setStripTypes(Sets.newHashSet(LOG_STRIP_SUFFIX));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have 2 mechanisms to do DCE, setStripTypes/setStripTypePrefixes (option A) and setStripNameSuffixes/setStripNamePrefixes (option B). option A is more safer as we can declare an expression like dev.fine while option B seems to only allow fine or assert (no access operation, just bare method/property name).

the issue is that the strip operation seems to occur after the SIMPLE_PLUS_OPTIMIZATION has ran (only reason i can think of why it isn't working), meaning if you did setStripTypes('dev.fine') (option A), it wouldn't work, as the actual js code it operates on would be something like a.fine (after var renaming), this is also made worse by the output code for modules having the module name as the prefix of invocations, which means the output of dev.log is actually a.dev.log (where a is the log module). Now we could use option B, but option B is extremely unsafe since fine or assert are very generic and any other module/class could declare one, and to get around this we would need the log module to declare method names like devfine and devassert (even then it feels extremely unsafe).

One other option we can do is assign the log instances to the global AMP object since that is never renamed and an expression like AMP.dev.fine('hello world') would be stripped out if we do setStripTypes('AMP.dev.fine'). But this would also mean log has to be the very first module loaded since it would be needed by the other modules that uses logging.

/cc @cramforce @dvoytenko

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is crazy inconvenient. Ideally we'd find a way to do stripping before renaming/obfuscation. No idea why they thought it'd be a good idea. A stopgap option might be to disable dev/user obfuscation? Obviously that's a bit annoying too, but since we considering to doing them as globals, it doesn't really matter. And most of uses of these APIs are dev.fine and dev.assert - so it might be ok anyway.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, i might just invoke addCustomPass which i think allows me to walk the AST. will try it out

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so ive been researching it some more and its not that its running after optimization, its that it runs against the es6 -> es5 transpiled code (with module prefix symbols) meaning its walking through something that looks like the screenshot below (where its already been prefixed with the namespace):

screen shot 2016-03-17 at 1 17 30 am

@erwinmombay erwinmombay force-pushed the runner branch 2 times, most recently from 7408bba to 758b160 Compare March 17, 2016 11:33

boolean qualifiedNameEndsWithStripType(String name) {
if (name != null) {
return name.endsWith("log.dev.fine");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dvoytenko @cramforce this is what i came up with which is based on closure compilers' stripTypePrefixes code, this code is more or less a stripTypeSuffixes (which isnt implemented)

runner.run();
}
if (runner.hasErrors()) {
System.exit(-1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not 1? Do they get printed out?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is an exact copy of the main code in the super class, and in my testing the errors/warning do get printed out.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This library is on GitHub? Can we sprinkle links/references to the "standard" code here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, will do.

@cramforce
Copy link
Member

Looks great overall.

In a follow up we should take flags out of the JS config and instead set them in Java.

<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="/Users/erwinm/dev/amphtml/third_party/closure-compiler/compiler.jar"/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this file actually needed? If so - can we make this a local file path?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed, will clean up the project artifacts

@erwinmombay
Copy link
Member Author

erwinmombay commented Apr 19, 2016

@cramforce one slightly big issue is the addition of the 2 semi large jar files. runner.jar (5.9mb) and compiler-and-tests.jar (10.4mb, which is a redundant build of compiler.jar + tests, this is so i can inherit from base test classes for testing)

@erwinmombay erwinmombay force-pushed the runner branch 5 times, most recently from 87f9cdf to 0172e01 Compare April 19, 2016 08:26
return a;
}

function sideEffectAssert() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not actually a side effect. Ideally this would compile to
return 'wahhh'

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If that is not what you currently do it may be fine for now, but we should be correct on terminology.

For side effects I'd expects something like

dev.assert(document.body.appendChild(…))

to compile to

document.body.appendChild(…)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haha sorry, this file is really just for testing. i'll remove this

@erwinmombay erwinmombay force-pushed the runner branch 4 times, most recently from 4b18605 to 92f9f14 Compare April 22, 2016 17:49
}

public void testDevAssertPreserveFirstArg() throws Exception {
test(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent.

@erwinmombay
Copy link
Member Author

@cramforce PTAL

@erwinmombay erwinmombay force-pushed the runner branch 2 times, most recently from dd4cca2 to bf4fb11 Compare April 22, 2016 17:54
@cramforce
Copy link
Member

LGTM

@@ -1,38 +1,38 @@
max | min | gzip | file
--- | --- | --- | ---
612.52 kB | 178.05 kB | 49.15 kB | v0.js / amp.js
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/cc @dvoytenko for log elimination new sizes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice win.

@erwinmombay erwinmombay merged commit 656c3ec into ampproject:master Apr 22, 2016
@erwinmombay erwinmombay changed the title add custom closure compiler runner add custom closure compiler pass Apr 22, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants