Closed Bug 1698791 Opened 4 years ago Closed 4 years ago

Add an is-index flag to atoms

Categories

(Core :: JavaScript Engine, task, P3)

task

Tracking

()

RESOLVED FIXED
89 Branch
Tracking Status
firefox89 --- fixed

People

(Reporter: jandem, Assigned: jandem)

References

Details

Attachments

(3 files)

JSLinearString::isIndex is very hot, it's used for megamorphic GetElem lookups for example (to convert an atom to a jsid).

Non-index strings are the common case there, but we need at least 6 branches to figure that out: hasIndexValue, length == 0, length > UINT32_CHAR_BUFFER_LENGTH, inline vs non-inline chars, Latin1 vs TwoByte chars, IsAsciiDigit.

If we instead determine isIndex when we allocate a new JSAtom, we can reduce this to a single flag check. Furthermore, it makes the index-value stored in the upper 16 flag bits more effective, because we will set it for all index-atoms <= UINT16_MAX.

I collected some data on the number of isIndexSlow (or equivalent) calls before/after this change. When browsing some popular websites, it goes from 2-3 million to 0.1-0.2 million, so it's a good trade-off.

StringIsArrayIndex is almost identical to isIndex/CheckStringIsIndex, but it's
limited to UINT32_MAX - 2 instead of UINT32_MAX.

This patch de-duplicates this with an explicit check for the smaller max length.
This ensures we can benefit from the index-value optimization and the ATOM_IS_INDEX
flag added in the next patch.

The difference in maximum length is still confusing and should probably be cleaned
up separately.

Depends on D108741

This lets us speed up JSAtom to PropertyKey conversions. This matters for example
for megamorphic GetElem lookups (a very hot code path for modern JS frameworks).

Although this calls isIndexSlow for each atom we create, it still results in a lot
less calls to that method compared to before, when browsing some popular websites.

Depends on D108742

Blocks: 1700034
Pushed by jdemooij@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/48b921d8aeee part 1 - Replace JSLinearString::isIndexSlow with CheckStringIsIndex. r=evilpie https://hg.mozilla.org/integration/autoland/rev/467a7afcdd3d part 2 - Use isIndex/CheckStringIsIndex for StringIsArrayIndex. r=evilpie https://hg.mozilla.org/integration/autoland/rev/1bd16d8959e5 part 3 - Add an is-index flag to JS atoms. r=evilpie

This is likely a false positive. In GetIndexFromString I changed the first line here to uint32_t index;:

  uint32_t index = UINT32_MAX;
  if (!str->asLinear().isIndex(&index) || index > INT32_MAX) {
    return -1;
  }

But looking at the history of that code that was a workaround for Valgrind (bug 1481670) :/

Pushed by jdemooij@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/d1c00e47dfce part 1 - Replace JSLinearString::isIndexSlow with CheckStringIsIndex. r=evilpie https://hg.mozilla.org/integration/autoland/rev/190e231ffdeb part 2 - Use isIndex/CheckStringIsIndex for StringIsArrayIndex. r=evilpie https://hg.mozilla.org/integration/autoland/rev/ab1644a7b0ee part 3 - Add an is-index flag to JS atoms. r=evilpie
Flags: needinfo?(jdemooij)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: