Title: [202955] trunk/Source/_javascript_Core
- Revision
- 202955
- Author
- [email protected]
- Date
- 2016-07-07 20:47:59 -0700 (Thu, 07 Jul 2016)
Log Message
REGRESSION(184445): Need to insert a StoreBarrier when we don't know child's epoch
https://bugs.webkit.org/show_bug.cgi?id=159537
Reviewed by Benjamin Poulain.
We weren't checking the case of a child node with a null epoch. The problem surfaces
when the base node of a PutByVal variant has a non-null epoch, because it represents an
allocation in the current function, while the child of the same node has an unknown epoch.
Added a check that the child node is not null before comparing the epochs of the base and
child nodes.
The added test creates the problem circumstance by doing a full GC to place an array in
remembered space, allocating a new object followed by an eden GC. The new object is
only referenced by the array and therefore won't be visited Without the store barrier.
The test may crash or more likely get the wrong answer with the bug.
* dfg/DFGStoreBarrierInsertionPhase.cpp:
* tests/stress/regress-159537.js: Added test.
(MyNumber):
(MyNumber.prototype.plusOne):
(bar):
(foo):
(test):
Modified Paths
Added Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (202954 => 202955)
--- trunk/Source/_javascript_Core/ChangeLog 2016-07-08 03:13:11 UTC (rev 202954)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-07-08 03:47:59 UTC (rev 202955)
@@ -1,3 +1,29 @@
+2016-07-07 Michael Saboff <[email protected]>
+
+ REGRESSION(184445): Need to insert a StoreBarrier when we don't know child's epoch
+ https://bugs.webkit.org/show_bug.cgi?id=159537
+
+ Reviewed by Benjamin Poulain.
+
+ We weren't checking the case of a child node with a null epoch. The problem surfaces
+ when the base node of a PutByVal variant has a non-null epoch, because it represents an
+ allocation in the current function, while the child of the same node has an unknown epoch.
+ Added a check that the child node is not null before comparing the epochs of the base and
+ child nodes.
+
+ The added test creates the problem circumstance by doing a full GC to place an array in
+ remembered space, allocating a new object followed by an eden GC. The new object is
+ only referenced by the array and therefore won't be visited Without the store barrier.
+ The test may crash or more likely get the wrong answer with the bug.
+
+ * dfg/DFGStoreBarrierInsertionPhase.cpp:
+ * tests/stress/regress-159537.js: Added test.
+ (MyNumber):
+ (MyNumber.prototype.plusOne):
+ (bar):
+ (foo):
+ (test):
+
2016-07-07 Joseph Pecoraro <[email protected]>
Unexpected "Out of memory" error for "x".repeat(-1)
Modified: trunk/Source/_javascript_Core/dfg/DFGStoreBarrierInsertionPhase.cpp (202954 => 202955)
--- trunk/Source/_javascript_Core/dfg/DFGStoreBarrierInsertionPhase.cpp 2016-07-08 03:13:11 UTC (rev 202954)
+++ trunk/Source/_javascript_Core/dfg/DFGStoreBarrierInsertionPhase.cpp 2016-07-08 03:47:59 UTC (rev 202955)
@@ -459,12 +459,12 @@
// Something we watch out for here is that the null epoch is a catch-all for objects
// allocated before we did any epoch tracking. Two objects being in the null epoch
// means that we don't know their epoch relationship.
- if (!!base->epoch() && base->epoch() >= child->epoch()) {
+ if (!!base->epoch() && !!child->epoch() && base->epoch() >= child->epoch()) {
if (verbose)
dataLog(" Rejecting because of epoch ordering.\n");
return;
}
-
+
considerBarrier(base);
}
Added: trunk/Source/_javascript_Core/tests/stress/regress-159537.js (0 => 202955)
--- trunk/Source/_javascript_Core/tests/stress/regress-159537.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/regress-159537.js 2016-07-08 03:47:59 UTC (rev 202955)
@@ -0,0 +1,62 @@
+// This test verifies that we don't crash in FTL generated code due to lack of a store barrier
+// for a put-by-val when we don't know when the value was allocated.
+
+class MyNumber
+{
+ constructor(v)
+ {
+ this._v = v;
+ }
+
+ plusOne()
+ {
+ return this._v + 1;
+ }
+}
+
+noDFG(MyNumber.plusOne);
+
+let count = 0;
+let bogus = null;
+
+function bar()
+{
+ count++;
+
+ if (!(count % 100))
+ fullGC();
+ return new MyNumber(count);
+}
+
+noDFG(bar);
+noInline(bar);
+
+function foo(index, arg)
+{
+ var result = [arg[0]];
+ if (arg.length > 1)
+ result[1] = bar();
+ return result;
+}
+
+noInline(foo);
+
+function test()
+{
+ for (let i = 0; i < 50000; i++)
+ {
+ let a = [1, i];
+ let x = foo(i, a);
+
+ if (!(count % 100))
+ edenGC();
+
+ for (let j = 0; j < 100; j++)
+ bogus = new MyNumber(-1);
+
+ if ((count + 1) != x[1].plusOne())
+ throw("Wrong value for count");
+ }
+}
+
+test();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes