Open Bug 1850344 Opened 1 year ago Updated 11 months ago

Use permanent atom for startup-related or frequently-used atoms, or all atoms used by bindings

Categories

(Core :: DOM: Bindings (WebIDL), task, P3)

task

Tracking

()

ASSIGNED

People

(Reporter: arai, Assigned: arai)

References

(Depends on 1 open bug, Blocks 1 open bug)

Details

(Whiteboard: [sp3])

Attachments

(13 files)

48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review

bug 1848278 is going to make the permanent atom extensible from embedder, and which allows optimizing CreateInterfaceObject and some other atom-related operation.
with speedometer 3, the 30% of the time taken by CreateInterfaceObject is atomization, and that part can be moved to compile-time (hash and length calculation, getter/setter name calculation) + startup (remaining atomization operation into permanent atoms)

Blocks: 1846110
Whiteboard: [sp3]

Before WebIDL bindings we used to selectively optimize a lot of the DOM bindings (cf. wrapper cache, slim wrappers, quickstubs, …). The problem is that that easily leads to performance cliffs, where once a new DOM API becomes popular the performance suddenly plummets because it wasn't optimized (because it used to be rarely used). These days we try to avoid that (even though we have some mechanisms like caching of attribute values that still are opt-in).

Did we evaluate not making this opt-in, but doing it for all interfaces/properties? It would avoid having another list to keep up-to-date when adding or removing interfaces, turning on prefs, … In my experience these kind of lists get quickly out-of-date.

the problem with the current implementation is that some part of atomization (allocation, putting into table) is done at startup instead of compile-time, while it had been lazily done when the interface is first used, so this can lead to slow startup if we have so much items.
I'll check how much it increases if we put all names into permanent atoms.
maybe we need to move more parts into compile-time and possibly optimize the JSAtom representation for this purpose.

Flags: needinfo?(arai.unmht)

Atomization at startup takes ~800us with 12409 entries (all WebIDL properties and interface names), that would be acceptable?
Also, the binary size increases by 360kB with the current representation.

Flags: needinfo?(arai.unmht)
Summary: Use permanent atom for startup-related or frequently-used atoms used by bindings → Use permanent atom for startup-related or frequently-used atoms, or all atoms used by bindings

360kB is a fair amount. Have you tried any kind of deduplication? That saved a lot of binary size for the XPIDL string constants (in xptcodegen.py).

deduplication isn't yet performed.

currently the getter name, setter name, and original property name are stored separately, but at least either getter or setter name and the original property name can be deduplicated:

get alignContent\0
^   ^
|   |
|   property name
getter name

or maybe the getter/setter name concatenation could be done at runtime, while still pre-calculating the hash at compile-time.
I'll look into deduplication, and also optimizing the storage

if we compress data and calculate some part at startup (accessor name etc), the essential increase from the current state would be length+hash+pointer or index, which would be ~100kB.
I'll look into the details of the trade off between the binary size and startup cost.

bug 1858040 solved the situation by making the accessor name calculation more lazy.
now the necessary static data is only for the property name, and the increased data is only its length and hash and pointer.
I'll update the statistics shortly.

With only property names (without the compression for length/index), the XUL file size increase is ~110kB.
There are 6782 items, and the increase matches to the length+hash+pointer which takes ~105kB.

Then, considering the compression, the method names and interface names are referred also from other places, for example from profiler marker code:

https://searchfox.org/mozilla-central/source/__GENERATED__/__macosx64__/dom/bindings/ChromeUtilsBinding.cpp#6493-6494

AUTO_PROFILER_LABEL_DYNAMIC_FAST(
  "ChromeUtils", "aliveUtilityProcesses", DOM, cx,

If we're to replace string pointer with "index into large string", we need to:

  • make sure the compiler's/linker's de-duplication works even between small string vs large string
    • at least the large string should be have null-terminator for each item
  • rewrite those other references to explicitly use the substring of the large string

otherwise we'll have duplicate text content for each method and interface name, and the binary size increases.

In order to simplify the codegen, stop using IF_* macro for well-knonw atoms
which is used by WebIDL.

Depends on D186329

Duplicate of this bug: 1847758
Duplicate of this bug: 1847862
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: