Optimisation of obfuscated mode

10 views
Skip to first unread message

Elias Martenson

unread,
May 5, 2009, 3:50:13 AM5/5/09
to Google Web Toolkit
When looking at the generated Javascript code in obfuscated mode, I
can see a lot of functions that, after obfuscation, has become
identical to eachother. For example, here is a real example from my
application:

function yLc(a,b,g,f,e,c,d){return 0}
function zLc(a,b,g,f,e,c,d){return 0}
function kMc(a,b,g,f,e,c,d){return 0}
function lMc(a,b,g,f,e,c,d){return 0}

Obviously, before obfuscation these functions are distinctly different
entities, probably coming from wildely different parts of the code
base. However, after obfuscation, these functions are identical and
they can safely be replaced by a single function.

My question is: are there any plans to do this? Perhaps in 1.7?

My second issue is with the large number of functions that do nothing
except for calling another function. Here's another example from my
application:

function p3b(b,a){z3b(b,a)}
function q3b(b,a){A3b(b,a)}
function D3b(b,a){p4b(b,a)}
function E3b(b,a){q4b(b,a)}

Is there a technical reason why these are not inlined?

Salvador Diaz

unread,
May 5, 2009, 4:19:11 AM5/5/09
to Google Web Toolkit
I'm curious about this, could you compile in pretty or detailed and
show us this duplicate functions ?

Thanks,

Salvador

Elias Martenson

unread,
May 5, 2009, 4:50:40 AM5/5/09
to Google Web Toolkit
On May 5, 4:19 pm, Salvador Diaz <diaz.salva...@gmail.com> wrote:

> I'm curious about this, could you compile in pretty or detailed and
> show us this duplicate functions ?

I think that would be hard, since it's quite difficult to map a
function to the actual method when looking at the obfuscated output.

However, my point was that wildly different methods gets converted to
the exact same obfuscated javascript code, and is therefore only
needed once. Take as an example the following two classes:

public class Foo {
private String name;
public String getName() { return name; }
}

public class Bar {
private int size;
public int getSize() { return size; }
}

In this case, both of these methods would be converted into something
like the following:

function xyz(b) { return b.a; }
function xyz(a) { return a.a; }

This is because the first member of a class is always called "a".
However, thanks to the fact that there are no types in Javascript, the
functions are interchangeable.

What I'm asking is whether the GWT compiler will take advantage of
this in later versions.

X

unread,
May 5, 2009, 10:18:18 PM5/5/09
to Google-We...@googlegroups.com
public interface Bax{
    public String getValue();
}
public class Bar implements Bax{
    String size;
    public String getValue(){return size;}
}

public class Foo implements Ba...  OH WAIT!!

You have one class returning String, and another returning int. 

I was going to say you need to use interfaces more, and the compiler WILL generate singleton functions and add them to prototypes as needed, but you have different data types.

Just because it's the same in javascript to return x.a, does NOT make it the same in Java, and like it or not, the strength of GWT is that it is hierarchial, object-oriented javascript.  You CAN'T inline these functions, because when you just call getSize() or getName(), it will just return the variable, but it you add more functions to Bar like

public int OR(Bar a){
   return a.size()|this.size();
}

The compliler can generate function xYz(b){ return this$static.a | b.a;}

This is NOT legal for Strings anywhere, and any prototypes inline to take advantage of compiler naming conventions would result in HUGE permutation chains to determine what areas of javascript can be melted into single functions, but this is not a worthwhile price to pay for file sizes today...

...Cos in the world of tomorrow, next gen browsers like Firefox and Chrome actual use class-based internal optimizations to make your typeless javascript take advantage of the strongly-typed applications by relaxing how they treat data.  In old JS, any data could be any other data, and the browser's got to perform type-checking for every + operation, for every new and every x.apply(y);...  In new JS, when your app uses a certain expando for numbers-only, or string-only or jsObjects only, it will adapt and stop running redundant checks when data will never be anything but an int...

Trust me, an old JS library I wrote in FF2 would run slow for a while, but after a few page reloads, my animations actually speeded up, and benchmarks reported slight but noticeable improvements around 15% after the first run...

--
"He whose desires are drawn toward knowledge in every form will be absorbed in the pleasures of the soul, and will hardly feel bodily pleasure --I mean, if he be a true philosopher and not a sham one." - Plato
"Wise Words Woven With Will Wakes Worlds" - Alyxandor Artistocles

X

unread,
May 5, 2009, 10:18:28 PM5/5/09
to Google-We...@googlegroups.com

Elias Martenson

unread,
May 6, 2009, 2:17:37 AM5/6/09
to Google Web Toolkit
On May 6, 10:18 am, X <a.revolution.ultra.b...@gmail.com> wrote:
> public interface Bax{
>     public String getValue();}
>
> public class Bar implements Bax{
>     String size;
>     public String getValue(){return size;}
>
> }
>
> public class Foo implements Ba...  OH WAIT!!
>
> You have one class returning String, and another returning int.

I know what you are saying, but given the fact that all of the
Javascript is regenerated on every compile, and that dynamic
classloading is not available in GWT, there is no reason why the
compiler itself can't share these functions.

What you are saying is that "if the circumstances where changed
somehow, the optimisation won't work anymore". Well, if that happens,
the GWT compiler wouldn't generate the optimisation anymore.

If dynamic classloading was supported, this wouldn't work of course,
but dynamic classloading was not included in GWT for exactly this
reason; to give the compiler better ability to do optimisations.

Alyxandor

unread,
May 6, 2009, 10:00:48 AM5/6/09
to Google Web Toolkit
This is true,

I was thinking of this later, and saw that in many cases, this COULD
be done,
And it can be done outside of the gwt compiler, if you like.

Some fancy regexp to find functions with EXACT method bodies and
renaming+deletion could potentially decrease file sizes dramatically,
but only for Obfuscated code... Possibly a fourth compiler option
"PRODUCTION" which would do all the extra permutations for final
builds, using text functions after the Java->JavaScript magic
happens. One look at the logic trees from the compiler is enough to
scare a stone into cold sweat, so to me, it seems easier to just use
RegExp; capture the argument names, back-reference them in the method
bodies, create generic method signatures, search for equalities, and
then replace them down to a minimum.

If someone who actually works on the compiler has any input, I'd love
to hear it.

/Starring this issue now...

Elias Martenson

unread,
May 6, 2009, 12:53:25 PM5/6/09
to Google Web Toolkit
Ah, that's not a bad idea actually. Using a regex that is… I might
actually try that.

I haven't actually looked at the compiler source yet, but I think I'll
do that tomorrow. I'll update if I come up with anything.

luke

unread,
Nov 23, 2011, 10:22:59 AM11/23/11
to google-we...@googlegroups.com, Google Web Toolkit
There's an even simpler example of the same optmisiation question. In compiled obfuscated code, I'm seeing lots of functions that do exactly nothing. e.g. :

function Id(){}
function Od(){}
function Hd(){}
function Qd(){}
... etc

Why are these here at all? Surely they could be optimised away
Reply all
Reply to author
Forward
0 new messages