Open Bug 1532556 Opened 5 years ago Updated 2 years ago

[meta] Optimize boxing of JS values for anyref

Categories

(Core :: JavaScript: WebAssembly, enhancement, P3)

enhancement

Tracking

()

People

(Reporter: lth, Unassigned)

References

(Blocks 2 open bugs)

Details

(Keywords: meta)

The current boxing scheme is correct but inefficient: when a JS string is passed to a wasm anyref, we box it, even though it is already an object (though it is a gc::Cell* not a JSObject*); when a small integer is passed, we box it, even though it could be represented as a tagged pointer.

There is (supposedly) a way to distinguish JSObject* from gc::Cell* without adding type information, so it would be good to start with not boxing string values.

With the stack map work we got a different MIR type for wasm object references, so we can use our own tagging scheme for references if we want; in particular, we can implement tagged pointers that are either references or small integers. And we can also choose whether to use tags to distinguish JSObject* from gc::Cell* or not.

On 32-bit platforms we realistically only have two tag bits available with 4-byte object alignment, and eventually wasm will want an i31ref type, so we need to keep this in mind too.

All of this interacts in some way with bug 1581572, in which we will need to handle at least some boxing/unboxing along the optimized call paths in stubs code.

One complication is that the super-fast path, which inlines any boxing into JS code that calls wasm by means of the usual MCallOptimize thing, will end up exposing MIRType::RefOrNull to JS. Long-term this may be right, but short-term probably not, so for initial work we should probably keep the guard in place here and not do this path for reftypes (perhaps unless we know the inputs are pointers).

We should still be able to do a fast path that goes through the optimized stub, where we control the frames and value flow more tightly.

[Update: The patches pending on bug 1581572 do indeed expose RefOrNull to JS on the path from JS into wasm, though not in any other situations.]

Another dimension here is how to represent the WasmValueBox object. At the moment it is a JSObject with a distinct class, and we test the class along the unboxing path to find out whether unboxing is needed or if the value represented is just a JSObject*. It's possible a gc::Cell would be more storage-efficient as the box.

No longer blocks: wasm-reftypes
Keywords: meta
Summary: Optimize boxing of JS values for anyref → [meta] Optimize boxing of JS values for anyref
Depends on: 1593640
Blocks: 1711412

A couple more data points here from bug 1711412, where there's also a useful test case:

  • We are calling deep into C++ to box return values from JS that are not objects or null. In this case they're probably numbers, cf Yury's observations on the cited bug. The boxing path is long and slow.
  • A lot of effort is being spent to hook the box into the JSObject machinery, yet these objects never escape to JS and most of that effort is pure overhead. See also comment 2.
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.