Closed Bug 1861434 Opened 1 year ago Closed 1 year ago

WebAssembly.instantiate sometimes rejects with string instead of Error when out of memory

Categories

(Core :: JavaScript: WebAssembly, defect, P2)

Firefox 119
defect

Tracking

()

RESOLVED FIXED
124 Branch
Tracking Status
firefox124 --- fixed

People

(Reporter: aswan, Assigned: rhunt)

Details

Attachments

(1 file)

I don't have specific steps to reproduce this, this is based on errors we're receiving from figma users in the field.
Sometimes the Promise returned from WebAssembly.instantiateStreaming() is rejecting with the string "out of memory" rather than with an Error instance with that string as the message. I'm not familiar enough with the specifications to know if this is technically in compliance or not, but it is inconsistent with other web apis, it would be handy if it return an Error instance...

And looking at more error data from the field, it appears this is happening with plain old WebAssembly.instantiate() in addition to instantiateStreaming

Summary: instantiateStreaming sometimes rejects string instead of Error → instantiate sometimes rejects with string instead of Error

The severity field is not set for this bug.
:rhunt, could you have a look please?

For more information, please visit BugBot documentation.

Flags: needinfo?(rhunt)
Severity: -- → S3
Flags: needinfo?(rhunt)
Priority: -- → P2

Thanks for the report! Looking at the Wasm JS-API spec [1], OOM errors are defined to match whatever JS does, which is itself implementation defined. It looks like SpiderMonkey's default behavior is to throw 'out of memory' as you're observing. I don't know if this is something we can change on our end, I'll check.

Do you get a different kind of OOM from other browsers? Or are you only getting OOM's in Firefox?

[1] https://webassembly.github.io/spec/js-api/index.html#out-of-memory

Flags: needinfo?(andrew.swan)
Summary: instantiate sometimes rejects with string instead of Error → instantiate sometimes rejects with string instead of Error when out of memory

I don't have an example of the message property on the Error that blink or webkit produces in this case readily available, but I can say for sure that they reject with an instance of Error (or at least something with a .message property, I just noticed this since we had some code that was roughly

try {
  await WebAssembly.instantiateStreaming(...);
} catch (err) {
  if (err.message.includes("something...")) { ... }
}

And the code in the catch block was throwing (since err.message is undefined), but only in Firefox.

Flags: needinfo?(andrew.swan)

It looks like SpiderMonkey's default behavior is to throw 'out of memory'

Oh interesting, I overlooked this at first, I guess maybe this is to try to avoid things that might require additional big allocations like gathering a stack trace to stuff into an Error?

Summary: instantiate sometimes rejects with string instead of Error when out of memory → WebAssembly.instantiate sometimes rejects with string instead of Error when out of memory

(In reply to Andrew Swan [:aswan] from comment #5)

It looks like SpiderMonkey's default behavior is to throw 'out of memory'

Oh interesting, I overlooked this at first, I guess maybe this is to try to avoid things that might require additional big allocations like gathering a stack trace to stuff into an Error?

That would be my guess as well.

Jan, have we had compatibility issues before with throwing out of memory instead of an Error? Is this something we can change?

Flags: needinfo?(jdemooij)

(In reply to Ryan Hunt [:rhunt] from comment #6)

Jan, have we had compatibility issues before with throwing out of memory instead of an Error? Is this something we can change?

OOM errors used to be uncatchable exceptions (similar to, for example, the slow script dialog stopping execution). This was changed in bug 865960 and that bug also has some discussion. Comment 5 is correct that we do this to avoid allocating an Error object etc. We also can't GC under ReportOutOfMemory because many callers depend on this.

If there's a case where OOM is more likely to happen, for example due to implementation limits instead of a real OOM, maybe we can change that to throw an actual InternalError?

Flags: needinfo?(jdemooij)

(In reply to Jan de Mooij [:jandem] from comment #7)

(In reply to Ryan Hunt [:rhunt] from comment #6)

Jan, have we had compatibility issues before with throwing out of memory instead of an Error? Is this something we can change?

OOM errors used to be uncatchable exceptions (similar to, for example, the slow script dialog stopping execution). This was changed in bug 865960 and that bug also has some discussion. Comment 5 is correct that we do this to avoid allocating an Error object etc. We also can't GC under ReportOutOfMemory because many callers depend on this.

If there's a case where OOM is more likely to happen, for example due to implementation limits instead of a real OOM, maybe we can change that to throw an actual InternalError?

I think in many cases with compiling modules, the OOM is due to there not being enough code memory, not due to lack of general heap memory. So throwing some actual error object might make sense here.

I also wonder if there is some last ditch GC'ing we could do to try to free up code memory in these cases.

(In reply to Ryan Hunt [:rhunt] from comment #8)

I think in many cases with compiling modules, the OOM is due to there not being enough code memory, not due to lack of general heap memory. So throwing some actual error object might make sense here.

Agreed. That would also let us use a more accurate error message.

I also wonder if there is some last ditch GC'ing we could do to try to free up code memory in these cases.

We do have some code here to call the large-allocation-failure callback which will trigger a GC.

Module compilation fails most frequently from large heap allocations or
not enough code memory. In these cases, we're very likely able to allocate
a proper error object. This commit switches module compilation to report
an InternalError now in these cases.

Assignee: nobody → rhunt
Status: NEW → ASSIGNED
Pushed by rhunt@eqrion.net: https://hg.mozilla.org/integration/autoland/rev/25e5c4ea04b1 wasm: Report OOM error instead of OOM string for module compilation. r=jandem
Status: ASSIGNED → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED
Target Milestone: --- → 124 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: