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

dart2js: smaller, faster, and correct map literals #17417

Closed
rakudrama opened this issue Mar 11, 2014 · 2 comments
Closed

dart2js: smaller, faster, and correct map literals #17417

rakudrama opened this issue Mar 11, 2014 · 2 comments
Assignees
Labels
type-enhancement A request for a change that isn't a bug web-dart2js

Comments

@rakudrama
Copy link
Member

Map literals are large and have incorrect type checks (issue #12891)

For

    <String,int>{"a": 1, "b": x}

we currently generate:

    H.setRuntimeTypeInfo(H.fillLiteralMap(["a", 1, "b", x], P.LinkedHashMap_LinkedHashMap(null, null, null, null, null)), [J.JSString, J.JSInt])

The smallest this can be (counting all identifiers as length=1, except "null") is 66 characters.

Is is orginally generated as

    H.setRuntimeTypeInfo(H.makeLiteralMap(["a", 1, "b", x]), [J.JSString, J.JSInt])

and then makeMapLiteral is inlined. The incorrect type checks (issue #12891) is because makeLiteralMap creates a LinkedHashMap<dynamic,dynamic>, calls fillLiteralMap to insert the values (missing the required checks) and returns the map.
The attaching of runtime type info is done on the result of makeLiteralMap by code specially emitted in the builder, which adds more code than necessary at each literal.

Suggestion


What we should do instead is generate code that calls a factory constructor.

Add a factory constructor...

    LinkedHashMap._literal(keysAndValues) {
      var map = new LinkedHashMap<K, V>();
      return fillLiteralMap(keysAndValues, map);
    }

... then generate <T1,T2>{e1: e2, e3: e3, ...} exactly as if it had been written:

    new LinkedHashMap<T1,T2>._literal([e1, e2, e3, e4, ...])

If the factory constructor is not inlined, the generated code for the would look like:

    P.LinkedHashMap_LinkedHashMap$_literal(["a", 1, "b", x], J.JSString, J.JSInt)

... which could minify to 25 characters.

Smaller improvements


We could make code slightly smaller and avoid allocating temporary arrays by having some extra constructors for common small sizes:

    LinkedHashMap._literal2(k1, v1, k2, v2) {
      var map = new LinkedHashMap<K, V>();
      map[k1] = v1;
      map[k2] = v2;
      return map;
    }

    new LinkedHashMap<String, int>._literal2("a", 1, "b", x)
    

In some programs there are many map literals with the same keys (but different values). This can be handled by splitting the keys and values in the constructor. The keys list could be shared by converting it to a const List where possible. Our running example would then be generated as if it had been written

     new LinkedHashMap<String, int>._literal(const ["a", "b"], [1, x])

@rakudrama
Copy link
Member Author

https://codereview.chromium.org/228063002/


Set owner to @rakudrama.
Added Started label.

@rakudrama
Copy link
Member Author

Done in r34836


Added Fixed label.

@rakudrama rakudrama self-assigned this Jun 16, 2014
@kevmoo kevmoo added type-enhancement A request for a change that isn't a bug and removed priority-unassigned labels Mar 1, 2016
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-enhancement A request for a change that isn't a bug web-dart2js
Projects
None yet
Development

No branches or pull requests

2 participants