Closed Bug 1929125 Opened 3 months ago Closed 1 month ago

Add support for an ahead-of-time IC corpus compiled into SpiderMonkey

Categories

(Core :: JavaScript Engine, enhancement, P3)

enhancement

Tracking

()

RESOLVED FIXED
135 Branch
Tracking Status
firefox135 --- fixed

People

(Reporter: cfallin, Assigned: cfallin)

References

Details

Attachments

(1 file)

The SpiderMonkey CacheIR mechanism for inline caches (ICs) generates IC bodies dynamically based on observed cases invoked by the user program. Only these ICs will be compiled and exist at runtime. This is ideal from a flexibility standpoint: we have the ability to add new ICs without writing their bodies in full (and can, for example, programmatically generate parts of them). Also, it avoids the overhead of compilation until an IC is actually needed.

However, some environments require fully ahead-of-time code generation. In addition, in some environments, we may have ample compilation time available during a "preparation" phase, and wish to minimize latency for the first use of an IC instead. In these cases, it would be better to have a corpus of inline cache bodies, known ahead of time.

This bug tracks an "ahead-of-time ICs" feature that includes a corpus of IC bodies collected while running tests, builtin mechanisms to keep this corpus up-to-date, and a mechanism to load the corpus when a JitZone is created, so all ICs are ready.

The expectation is that any reasonable user program will likely only generate ICs that are in this corpus; thus, there is no need to compile ICs at first actual occurrence. In a system that can only AOT-compile ICs, this means we will have ICs available in more cases.

Because CacheIR still allows for programmatically-generated IC bodies of arbitrary content (e.g., due to arbitrarily long prototype chains), we may not always have an IC in the corpus when we encounter its CacheIR in the wild: that is, the corpus is not guaranteed to be "complete". However, because it includes all ICs observed during execution of all tests, we expect that any reasonable IC should be included. Note that this aligns the incentives of keeping IC generation tested and keeping the corpus close to complete.

In order to maintain the corpus, this feature includes an "enforcing" mode. This should ONLY be used during testing, and probably only in downstream users' repositories (e.g., in the SpiderMonkey tree that Bytecode Alliance maintains for StarlingMonkey). This mode aborts the shell process when an unknown (new) IC body is encountered, after dumping the file. For maintainence convenience, this file is in the format that we check into the tree: one must simply move it into js/src/ics/ and rebuild. The idea is that as one adds new IC bodies, one runs tests, sees these failures, and "blesses" the IC bodies as part of the corpus by adding the file(s) as needed. An environment variable AOT_ICS_KEEP_GOING is also recognized that dumps this file and continues the test; this way, we can add new ICs in bulk. Finally, a script to deduplicate dumped ICs is included.

Maintenance-wise, I am hoping to upstream these mechanisms, but not the corpus itself, and have no plans to ask for any of this "enforcing" mode to be enabled or tested upstream. My plan is to keep it on in our (BA's) tree, and regenerate the corpus whenever we update to a new SpiderMonkey version.

This functionality is a prerequisite for AOT compilation work, but is also potentially useful on its own.

Blocks: 1855321

The SpiderMonkey CacheIR mechanism for inline caches (ICs) generates IC
bodies dynamically based on observed cases invoked by the user program.
Only these ICs will be compiled and exist at runtime. This is ideal from
a flexibility standpoint: we have the ability to add new ICs without
writing their bodies in full (and can, for example, programmatically
generate parts of them). Also, it avoids the overhead of compilation
until an IC is actually needed.

However, some environments require fully ahead-of-time code generation.
In addition, in some environments, we may have ample compilation time
available during a "preparation" phase, and wish to minimize latency for
the first use of an IC instead. In these cases, it would be better to
have a corpus of inline cache bodies, known ahead of time.

This PR adds an "ahead-of-time ICs" feature that includes a corpus of IC
bodies collected while running tests, builtin mechanisms to keep this
corpus up-to-date, and a mechanism to load the corpus when a JitZone
is created, so all ICs are ready.

The expectation is that any reasonable user program will likely only
generate ICs that are in this corpus; thus, there is no need to compile
ICs at first actual occurrence. In a system that can only AOT-compile
ICs, this means we will have ICs available in more cases.

Because CacheIR still allows for programmatically-generated IC bodies of
arbitrary content (e.g., due to arbitrarily long prototype chains), we
may not always have an IC in the corpus when we encounter its CacheIR in
the wild: that is, the corpus is not guaranteed to be "complete".
However, because it includes all ICs observed during execution of all
tests, we expect that any reasonable IC should be included. Note that
this aligns the incentives of keeping IC generation tested and keeping
the corpus close to complete.

In order to maintain the corpus, this feature includes an "enforcing"
mode. This should ONLY be used during testing: it aborts the process
when an unknown (new) IC body is encountered, after dumping the file.
For maintainence convenience, this file is in the format that we check
into the tree: one must simply move it into js/src/ics/ and rebuild.
The idea is that as one adds new IC bodies, one runs tests, sees these
failures, and "blesses" the IC bodies as part of the corpus by adding
the file(s) as needed.

This functionality is a prerequisite for later AOT compilation work, but
is also potentially useful on its own.

Assignee: nobody → chris
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true

Here's a try run to ensure this doesn't break mainline SM or PBL builds.

Severity: -- → N/A
Priority: -- → P3

Ah, sorry about that -- I didn't do any try-runs on 32-bit systems. It looks like I had an ifdef issue from a diff that was leftover from my broader weval-branch changes -- reverted (removing the #ifdef JS_PUNBOX64/#endif conditionals -- two sets -- in my patch) and will resubmit.

Flags: needinfo?(chris)

Here's a try-run with the failing job above passing: link. I'll re-Lando this now.

Status: ASSIGNED → RESOLVED
Closed: 1 month ago
Resolution: --- → FIXED
Target Milestone: --- → 135 Branch
Regressions: 1941873
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: