These are chat archives for opal/opal

15th
Nov 2018
Elia Schito
@elia
Nov 15 2018 00:05
@jscheid yeah, there's no one file, but single specs to make pass
image.png
Julian Scheid
@jscheid
Nov 15 2018 00:06
oh, right... missed that
Elia Schito
@elia
Nov 15 2018 00:06
sorry, didn't notice the class you were referring to is String πŸ€”
Julian Scheid
@jscheid
Nov 15 2018 00:07
I don't really need it at the moment... was more curious about missing features in general
do you have a moment to talk about something else, about google closure compiler?
I was experimenting with GCC ADVANCED_COMPILATION. it would be nice to be able to send opal output through that. preliminary results suggests that it can cut file size in half (compared to ~80% for uglifyjs) and it'll probably also help with performance, although I don't have benchmark results for it yet
are you interested in supporting this?
Julian Scheid
@jscheid
Nov 15 2018 00:11
oh, that's odd... I'll dig a bit deeper then. thanks for looking it up
Elia Schito
@elia
Nov 15 2018 00:11
@jscheid dead code elimination is something that should definitely being added, super open to anything that can tackle that
Julian Scheid
@jscheid
Nov 15 2018 00:12
well, so far it has nothing to do with dead code elimination. of course DCE would be awesome to have, but I think that's more difficult because of dynamic dispatch
so far this is only about applying all other optimizations that GCC offers... renaming variables, inlining functions, turning if/else into ?:, etc
Elia Schito
@elia
Nov 15 2018 00:13
then I mis-interpreted what GCC is doing, is it just compression/minification?
Julian Scheid
@jscheid
Nov 15 2018 00:13
no, GCC also does optimizations, including dead code elimination
Elia Schito
@elia
Nov 15 2018 00:13
πŸ‘ that's cool too, no problem supporting stuff that can work better with it
Julian Scheid
@jscheid
Nov 15 2018 00:13
I meant that applying DCE effectively to opal output will be difficult because of the nature of the generated code
but GCC does support it, and a host of other optimizations
Elia Schito
@elia
Nov 15 2018 00:14
πŸ‘πŸ‘πŸ‘
Julian Scheid
@jscheid
Nov 15 2018 00:14
so, the main issue I found is that the generated code uses X.y and X['y'] notation inconsistently
of course, they are equivalent in JS normally
Elia Schito
@elia
Nov 15 2018 00:15
about DCE I did some experiments in the past tracking a graph of called methods for each file and possibily skipping definition for methods that are never called (of course that would require explicitating or renouncing dynamic dispatch) but that is cool in some cases
Julian Scheid
@jscheid
Nov 15 2018 00:15
but GCC makes a distinction in ADVANCED_COMPILATION mode: the y in X.y is fair game for minification, but in X['y'] it is left unchanged
this is something I've worked around using an externs file (which is a GCC thing, where you specify which names should be left alone)... but doing so is cumbersome and brittle
Elia Schito
@elia
Nov 15 2018 00:16
go forth if you want to send in PRs fixing that kind of stuff
Julian Scheid
@jscheid
Nov 15 2018 00:16
so I was wondering if you were open to the idea to changing the code generation so that it will only generate X['y'], as a first step
Elia Schito
@elia
Nov 15 2018 00:16
we already track method calls for method missing support
Julian Scheid
@jscheid
Nov 15 2018 00:17
well I figured that you also need to switch to X['y'] when y contains non-alphanumerics
so there's probably (hopefully) just one place somewhere in the code to change?
Elia Schito
@elia
Nov 15 2018 00:17
that's already done in some parts of the compiler, so it's probably just a matter of identifying and fixing the remaining cases
Julian Scheid
@jscheid
Nov 15 2018 00:18
ok, TBH I don't think I can find the time to dig into the compiler anytime soon
I was hoping it could be a quick fix for you... never mind if it's more involved
anyway, once the X['y'] stuff is applied consistently, GCC should in theory just work (TM). the only other minor issue I've found is strict mode, but it's easy to tell GCC to omit the use strict header so not a showstopper
Elia Schito
@elia
Nov 15 2018 00:21
at the moment I have more pressing stuff to fix regarding prototypes and inheritance, if you get some spare time here's a starter that can be applied to other places https://github.com/opal/opal/blob/elia/cleanup-class-module-definition/lib/opal/nodes/helpers.rb#L16-L27
Julian Scheid
@jscheid
Nov 15 2018 00:22
so it's not just a matter of removing lines 22 and 24-26 in there?
Elia Schito
@elia
Nov 15 2018 00:24
hmmm, using […] is what causes problems to GCC then no, that method uses square brackets only when the id is not valid for .
wait, you mentioned using only []
is it the mix that trips GCC up?
Julian Scheid
@jscheid
Nov 15 2018 00:26
yes it's the mix
the same property should either always be accessed with X.y, or with X['y'], but not sometimes one and sometimes the other
as an aside: this actually ties into dead code elimination as well
as long as, say, String#to_r is assigned as some_module['to_r'] = function (...), GCC won't be able to eliminate it
but I think that is something for another day
tomorrow I'll try to fiddle with mid_to_jsid and see what results I get
it looks promising
is it the only place where a decision between . and [] is made?
Elia Schito
@elia
Nov 15 2018 00:32
nope, the plan, everything considered, should be this: always use . when possible and [] only when needed (i.e. it's not a valid JS id) so for example ary.empty? will become ary["$empty?"]() while ary.first will be ary.$first()
Julian Scheid
@jscheid
Nov 15 2018 00:33
well, that's how it works right now
that's not the plan, that's the status quo, correct?
Elia Schito
@elia
Nov 15 2018 00:33
that method already does that for method calls, we should expand that to other places
Julian Scheid
@jscheid
Nov 15 2018 00:34
I can see why you want to do it that way, but GCC is not happy about it
Elia Schito
@elia
Nov 15 2018 00:34
a search for [#{inside lib/opal probably gives you an initial hint of possible stuff to be fixed
Julian Scheid
@jscheid
Nov 15 2018 00:34
the problem is that ary.$first is defined with Opal.defn
so the code doesn't say: ary.$first = ..., it does effectively ary['$first'] = ...
and so then GCC can't handle it when later it's accessed as ary.$first
if that makes sense?
Elia Schito
@elia
Nov 15 2018 00:35
oh, yeah, so the problem includes when the method is assigned to the prototype…
Julian Scheid
@jscheid
Nov 15 2018 00:35
so what I'm proposing is to switch to always use [] here
the downside being a small increase in file size when it's not post-processed
however, pretty much everything can optimize that away (uglifyJS can as well, I'm 99.99% sure)
personally I think it's an acceptable trade-off if it buys the ability to run output through GCC
elia @elia looking at defn code again
Elia Schito
@elia
Nov 15 2018 00:36
$defineProperty(proto, jsid, body);
Julian Scheid
@jscheid
Nov 15 2018 00:37
ah ok... well, same difference
Elia Schito
@elia
Nov 15 2018 00:37
that's how the property is set, and for good reason, so it's a no go I think
Julian Scheid
@jscheid
Nov 15 2018 00:37
what is a no go?
Elia Schito
@elia
Nov 15 2018 00:37
switching it to proto[jsid] = body
Julian Scheid
@jscheid
Nov 15 2018 00:37
ah no that's not necessary
it's effectively the same
Elia Schito
@elia
Nov 15 2018 00:38
GCC can see trhu that?
Julian Scheid
@jscheid
Nov 15 2018 00:38
good question... I'm not sure now, but it doesn't really have to. the way it works is this:
let's say proto is foo and jsid is bar
when it sees foo['bar'] it leaves bar alone, and the expression will work regardless of how foo.bar was set (with foo[bar] or with defineProperty)
but when it sees foo.bar, it will mangle bar into something short, maybe into foo.y
and then it won't match anymore
does that make sense?
so at least in a first step, we don't have to change anything in how Opal.defn works
only in how the rest of the code accesses properties
Elia Schito
@elia
Nov 15 2018 00:42
oh I see, it's the reverse of what I thought, I was believing that you wanted to allow GCC to optimize method names, but really you want to prevent them from being touched, right?
Julian Scheid
@jscheid
Nov 15 2018 00:42
long term I think it would be great if we could let GCC optimize that stuff
the methods names would be nice if they were a little shorter, but the killer features of course is dead code elimination
I just think that's quite a bit of work, and so in the short term I'm suggesting to do it the other way around, as a quick fix that lets people use GCC with ADVANCED_OPTIMIZATIONS
Elia Schito
@elia
Nov 15 2018 00:44
question: is there a way to tell GCC not to touch some names?
Julian Scheid
@jscheid
Nov 15 2018 00:44
yes, with an externs file
that's how I have my test case working
it has lots of lines that look like this:
Opal.modules["corelib/module"].$class_variable_get = function() {};
it works -- it's just a PITA
and it only works for my case, I have lines like that for the code I'm compiling as well
obviously
Elia Schito
@elia
Nov 15 2018 00:47
hmm, asking because we have the list of method calls for each file, and maybe an externs file can be generated
elia @elia is looking up the docs
Julian Scheid
@jscheid
Nov 15 2018 00:48
hmm interesting thought... but why are you opposed to changing . to [] instead? the way I see it: people who care about file size will run the result through a compressor anyway, and that will turn it back into .s (or do something even smarter when it's GCC)
or is there another reason besides file size why you're not keen to make that change?
and it'll be a simpler system with fewer moving parts that way
Elia Schito
@elia
Nov 15 2018 00:52
Not opposed on principle, except for readability of the generated code (which is of course not a strong argument), I just need to be sure there's no hidden reason not to that I'm forgetting
right now I'm experimenting with uglily to see how it would handle it
Julian Scheid
@jscheid
Nov 15 2018 00:55
okie dokie
I gotta run but I'll pop back in tomorrow after doing some experiments with mid_to_jsid
but just to whet your appetite...
the lib I'm compiling with opal ends up as a 2 MB JS file
uglify gets it down to 1.6 MB
closure compiler down to 1 MB ... and that's without any DCE
maybe I'll have some performance benchmarks tomorrow as well
:wave:
Elia Schito
@elia
Nov 15 2018 00:57
πŸ‘πŸ‘πŸ‘ great stuff, see ya
Barrie Hadfield
@barriehadfield
Nov 15 2018 06:45
@jscheid @elia :clap: :thumbsup: