5 ms·
This sounds like blameshifting to me. Javascript is untrusted code, so it's on Firefox to make sure to handle any craziness gracefully. Stack probing is kind o
by im3w1l 3y ago
This sounds like blameshifting to me. Javascript is untrusted code, so it's on Firefox to make sure to handle any craziness gracefully.
Stack probing is kind of a weird thing though. I'm kind of surprised C++ compiler isn't doing that properly. Are they using inline assembly for speed?
- fathyb 3y agoAgreed that the problem here is Firefox, untrusted JS code should not cause a crash. For the probing, according to the code: // Can't push large frames blindly on windows, so we must touch frame memory // incrementally, with no more than 4096 - 1 bytes between touches. // // This is used across all platforms for simplicity. https://searchfox.org/mozilla-central/rev/c936f47f3a629ae49a4d528d3366bf29f2d4e4a7/js/src/jit/MacroAssembler.cpp#6585-6612 https://searchfox.org/mozilla-central/rev/c936f47f3a629ae49a...
- im3w1l 3y agoYeah I got that far but then I wasn't sure what exactly that was doing. Normal C++ doesn't directly move stack pointers around and do manual probing, so I was idly wondering whether those calls hid some inline assembly or how they worked. Edit: Or perhaps that is not the stack of the C++ program but rather than stack of the Javascript program.
- fathyb 3y agoIt does hide some assembly. Those calls are calling an assembler to generate native code at runtime for JIT compilation. The C++ compiler compiles an assembler, but this assembler runs at runtime. `MacroAssembler` itself is architecture independent, and calls into functions implemented in back-ends such as `MacroAssemblerARM` and `MacroAssemblerX64`. So the code in this function is not performing the stack-probing, it generates code to perform it instead.
- IainIreland 3y agoIn general, there's no difference between the stack of the C++ program and the stack of the JS program. When SpiderMonkey just-in-time compiles a JS function, the result is native code that creates a stack frame on the same stack as the C++ code that implements SpiderMonkey. JS code and C++ code can be semi-arbitrarily interleaved on the stack: JS calls C++ calls JS calls C++... The one exception about sharing the same stack is that the first few iterations of a function run in an interpreter implemented in C++, and that interpreter has its own stack that we heap-allocate. This particular bug occurred during the transition from the C++ interpreter to JIT code.
- usr1106 3y agoTechnically of course Firefox failed to live with an old kernel and insane JS code. Morally it's Google. Google is like Bitcoin. A huge natural ressource hog for a questionable benefit. Here the benefit is tracking users to make advertising billions. For that goal a billion of smart phones need several extra GB of memory an significantly larger batteries. What is the ecological footprint of that? Typing on a seven year old smart phone with 2 GB (SailfishOS, so yes it is maintained. Maybe not perfectly, but better than many Androids half as old). It works quite well on reasonable pages even without add blocking. Of course super heavy pages won't work and for Google search I haven't even consented. Occasionally I get reminded of that when some site embeds it. Well, a good reminder for me not to use them.
- fathyb 3y agoThis does not appear that crazy to me. In fact, today it's almost a recommended practice for large web applications and it's called "tree shaking". ECMAScript modules are inlined into the same scope. It makes the JIT work easier because it now works with symbols instead of `require(foo).bar` calls to speculate on. It makes most web apps run better, both in bandwidth and compute. It's very likely to have affected users on other websites, but Google is a common denominator for debugging. My uneducated guess: they're using the Google Closure Compiler to make smaller JavaScript bundles. It saves some bandwidth and allows for better optimizations. It seems like a reasonable engineering decision to ensure product decisions don't affect the user experience too negatively, something a lot of us are familiar with..
- usr1106 3y agoRight, optimization is good. But first building insanely heavy functionality and then optimizing it is not sustainable approach. The background is of course that increasingly heavy function is moved into the client. Technically and especially economically this makes sense for Google. But the environmental footprint is outsourced to client devices. Greenwashing in a way. Avoidance of computing is a better solution than all types of optimizations. Not everything that is technically feasible is good for the planet and mankind.
- 3y ago
- jandrese 3y agoI'm curious what Firefox could have done in this case beyond just killing off the tab. The issue was a check in old kernels that was being triggered by some insane code. This example had me remembering the discussion from earlier today about why modern code is so slow even though the machines are so fast. I doubt there were many Win32 programs that attempted to pass in 20,000 parameters to a function.
- db48x 3y agoIt would only be shifting the blame if they weren’t going to work around the problem in Firefox itself. The C++ compiler may or may not implement stack probing correctly, but this bug is in the Javascript JIT compiler. The fix is to make the JIT compiler update the stack pointer register each time through the loop so that if a page fault happens the kernel won’t see a huge amount of stack get allocated all in one go. Instead it’ll see several page faults each asking for a smaller amount which it is happy to grant. See https://phabricator.services.mozilla.com/rMOZILLACENTRAL304d01f5488b384023a1c647e8c5c2f5cee32a5b https://phabricator.services.mozilla.com/rMOZILLACENTRAL304d...
- deleted 3y ago[deleted]