Ignition/Turbofan is enabled as default without including a critical V8 fix for float32 numbers
Reported by
peter.si...@prezi.com,
Jun 14 2017
|
|||||||||
Issue descriptionUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.86 Safari/537.36 Steps to reproduce the problem: see https://bugs.chromium.org/p/v8/issues/detail?id=6077 What is the expected behavior? correctly executed JS code even when it is optimized What went wrong? https://bugs.chromium.org/p/v8/issues/detail?id=6077 is a critical issue in V8 causing JS code to run literally incorrect for float numbers. In practice, any arithmetic heavy JS applications can experience unexpected NaN injections to the numbers it uses (that are optimized to float32 registers), causing incorrect application behavior. This is not just theory, for example Prezi.com has two separate critical product regressions directly caused by this issue. The issues are confirmed to be fixed on Chrome 61, which includes the fix for V8 6077. It seems there's no simple workaround to prevent float32 register optimizations in the JS code in a general way, and it is not an option to ask end users to enable the classic JS pipeline in their browsers. Products and services experiencing regressions can basically refuse Chrome requests and advise to use other browsers at the moment. Hence I would like to ask for an immediate hotfix to Chrome 59, that either disables Ignition/TurboFan by default, or bumps V8 to a version that executes JS code correctly. Did this work before? Yes 58, it also works in 61 Chrome version: 59.0.3071.86 Channel: stable OS Version: OS X 10.12.5 Flash Version:
,
Jun 15 2017
Adding TF folks from the related bug linked in #1
,
Jun 15 2017
The bugfix (commit 798ffc9d67e25a0aa9b0be145892c27f2ac5391f) is included in the 5.9 branch, which is used by M59.
,
Jun 15 2017
,
Jun 15 2017
As @bmeurer already said, the fix for crbug.com/v8/6077 is in V8 since version 5.9.78, so it is in Chrome 59 (Chrome 59.0.3071.86 contains V8 5.9.211.31). Could you give us precise repro instructions for your problem?
,
Jun 15 2017
hm, maybe it is a variant then?
I can confirm that on 59.0.3071.86 we get random NaNs in our math, which disappear if we place console.log, breakpoint, or eval in the proper place in our code, in line with what the referenced V8 issue describes - that forcing deoptimization fixes the issue. Of course, it is a huge proprietary codebase, and I guess optimization also depends on call patterns as well (the issue happens ad-hoc, after our app is running for some time), so I cannot give you a short repro.
One of the affected codes looks something like this:
var Effect = (function () {
function Effect(camera, coeff) {
this.camera = camera;
this.coeff = coeff;
this.matrix = Geometry.createIdentity();
}
Effect.prototype.getTransform = function () {
return this.getMatrix().toTransform();
};
Effect.prototype.getMatrix = function () {
this.matrix = Geometry.createFromTransform(this.camera.getTransform());
var scale = this.camera.getScaleModifier(this.matrix.getScaleX(), this.coeff);
this.matrix.scale(scale);
return this.matrix;
};
return Effect;
}());
what seems to happen is that parts of this.matrix (which has a,b,c,d,x,y Number fields) become NaNs. If getMatrix method has console.log, breakpoint, or eval, then the issue is fixed. The codes runs a few times per requestAnimationFrame.
,
Jun 15 2017
Given that the fix is in, and there's no obvious Float32 involved (i.e. no Math.fround or Float32Array) in the code shown above, it appears to be a different issue.
,
Jun 15 2017
I understand that you might not have a short repro. Is there a way to get some repro? Since the issue is fixed in 61, it might be just a matter of bisecting which fix needs to be merged to 59.
,
Jun 15 2017
Not familiar with register optimizations, and how V8 implements doubles, maybe not float related then. Nevertheless, we could never reproduce on Chrome 61, so it is a bug that is fixed already in V8, either directly, or as a side-effect. I would argue that Chrome 59 should not roll out like this, the bug is as critical as the one I linked. We can give you pointers in our obf codebase, where it happens and how to reproduce. We also have a second case like the one above. These unexpected NaNs break down our whole app (objects are not rendered, hence the app is unusable = outage), we could fix them by forcing deoptimization, but since those are just local patches, new cases can pop up any time.
,
Jun 15 2017
,
Jun 19 2017
Using the supplied repro, I have found the fix that has not been merged, see below. In fact, it is only the drive-by fix part of that CL ("This also fixes incorrect type for fixed array accesses.") that fixes your problem. In the code, it is the one-line change in access-builder.cc (see https://codereview.chromium.org/2848583002/diff/1/src/compiler/access-builder.cc).
Since the other part of the CL is a bit risky, I will try to back-merge the one-liner to stable. The good news is that we have coverage in beta (M60), so we should be able to get the merge approval.
Thanks for the report and for make the repro accessible to us!
commit ff2109d53efccb2642df26ae2156f56285822885
Author: jarin <jarin@chromium.org>
Date: Thu Apr 27 04:35:15 2017 -0700
[turbofan] Fix impossible type handling for TypeGuard and BooleanNot.
This also fixes incorrect type for fixed array accesses.
BUG=chromium:715651, v8:6309 , chromium:715204
Review-Url: https://codereview.chromium.org/2848583002
Cr-Commit-Position: refs/heads/master@{#44926}
,
Jun 19 2017
That's great news! Thanks for following up on this and handling it fast!
,
Jun 19 2017
Based on email thread I am marking this as stable blocker to get into our radar and assuming this would be across the platforms(Please correct me if this is specific to Mac)
,
Jun 19 2017
,
Jun 19 2017
This is indeed platform-independent, I reproduced the issue on my Linux machine (where I also verified the fix).
,
Jun 19 2017
,
Jun 19 2017
For completeness, here is a simple repro case for d8:
// Flags: --allow-natives-syntax
function f() {}
// Create enough objects to trigger slack tracking.
for (let i = 0; i < 100; i++) {
new f();
}
function g(o) {
// Add more properties so that we trigger extension of out-ot-object
// property store.
o.y = 0.5;
o.u = 0.1;
o.v = 0.2;
o.z = 0.3;
// Return a field from the out-of-object-property store.
return o.y;
}
g(new f());
g(new f());
%OptimizeFunctionOnNextCall(g);
console.log(g(new f())); // Should print 0.5, prints NaN.
,
Jun 19 2017
Approved for M59. Please merge immediately.
,
Jun 19 2017
Merged to v8 stable branch: https://chromium.googlesource.com/v8/v8/+/376d3ae08e62591a0893768675f2dc35d98b7241
,
Jun 19 2017
New releases of Chrome for desktop and Android will be released shortly which will include the fix in c#19. Chrome OS is TBD though I'd assume they'll pick it up too. Marking as fixed, re-open if the next release for both platforms still contains the issue.
,
Jun 20 2017
|
|||||||||
►
Sign in to add a comment |
|||||||||
Comment 1 by manoranj...@chromium.org
, Jun 14 2017Components: -Blink Blink>JavaScript