diff --git a/implementation-contributed/javascriptcore/stress/activation-sink-default-value-tdz-error.js b/implementation-contributed/javascriptcore/stress/activation-sink-default-value-tdz-error.js
new file mode 100644
index 0000000000000000000000000000000000000000..c780b38732c4b37e5ade201fc2a14cff2f67843f
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/activation-sink-default-value-tdz-error.js
@@ -0,0 +1,46 @@
+//@ skip if $buildType == "debug" or $architecture == "x86"
+
+"use strict";
+
+var n = 10000000;
+
+function shouldThrowTDZ(func) {
+    var hasThrown = false;
+    try {
+        func();
+    } catch(e) {
+        if (e.name.indexOf("ReferenceError") !== -1)
+            hasThrown = true;
+    }
+    if (!hasThrown)
+        throw new Error("Did not throw TDZ error");
+}
+noInline(shouldThrowTDZ);
+
+function bar(f) { f(10); }
+
+function foo(b) {
+    let result = 0;
+    var set = function (x) { result = x; }
+    var cap = function() { return tdzPerpetrator; }
+    if (b) {
+        bar(set);
+        return tdzPerpetrator;
+    }
+    let tdzPerpetrator;
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+
+for (var i = 0; i < n; i++) {
+    var bool = !(i % 100);
+    if (bool)
+        shouldThrowTDZ(function() { foo(bool); });
+    else {
+        var result = foo(bool);
+        if (result != 0)
+            throw "Error: bad result: " + result;
+    }
+}
diff --git a/implementation-contributed/javascriptcore/stress/activation-sink-default-value.js b/implementation-contributed/javascriptcore/stress/activation-sink-default-value.js
new file mode 100644
index 0000000000000000000000000000000000000000..4bb5277f98d8e95e491b7cbbbe29ae7c048f19db
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/activation-sink-default-value.js
@@ -0,0 +1,33 @@
+//@ skip if $architecture == "x86"
+
+var n = 10000000;
+
+function bar(f) { f(10); }
+
+function foo(b) {
+    var result = 0;
+    var imUndefined;
+    var baz;
+    var set = function (x) { result = x; return (imUndefined, baz); }
+    baz = 40;
+    if (b) {
+        bar(set);
+        if (result != 10)
+            throw "Error: bad: " + result;
+        if (baz !== 40)
+            throw "Error: bad: " + baz;
+        if (imUndefined !== void 0)
+            throw "Error: bad value: " + imUndefined;
+        return 0;
+    }
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+
+for (var i = 0; i < n; i++) {
+    var result = foo(!(i % 100));
+    if (result != 0)
+        throw "Error: bad result: " + result;
+}
diff --git a/implementation-contributed/javascriptcore/stress/activation-sink-osrexit-default-value-tdz-error.js b/implementation-contributed/javascriptcore/stress/activation-sink-osrexit-default-value-tdz-error.js
new file mode 100644
index 0000000000000000000000000000000000000000..4ca18e3d16bee2edddef969f7653a742f505b977
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/activation-sink-osrexit-default-value-tdz-error.js
@@ -0,0 +1,48 @@
+//@ skip if $architecture == "x86"
+
+"use strict";
+
+var n = 10000000;
+
+function shouldThrowTDZ(func) {
+    var hasThrown = false;
+    try {
+        func();
+    } catch(e) {
+        if (e.name.indexOf("ReferenceError") !== -1)
+            hasThrown = true;
+    }
+    if (!hasThrown)
+        throw new Error("Did not throw TDZ error");
+}
+
+function bar(f) { }
+
+function foo(b) {
+    let result = 0;
+    var set = function (x) { result = x; return tdzPerpetrator; }
+    if (b) {
+        OSRExit();
+        if (b) {
+            bar(set);
+            return tdzPerpetrator;
+        }
+    }
+    let tdzPerpetrator;
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+noInline(shouldThrowTDZ);
+
+for (var i = 0; i < n; i++) {
+    var bool = !(i % 100);
+    if (bool)
+        shouldThrowTDZ(function() { foo(bool); });
+    else {
+        var result = foo(bool);
+        if (result != 0)
+            throw "Error: bad result: " + result;
+    }
+}
diff --git a/implementation-contributed/javascriptcore/stress/activation-sink-osrexit-default-value.js b/implementation-contributed/javascriptcore/stress/activation-sink-osrexit-default-value.js
new file mode 100644
index 0000000000000000000000000000000000000000..60623ad1a74d29b30050dcf02f79905a7ea1ac4b
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/activation-sink-osrexit-default-value.js
@@ -0,0 +1,39 @@
+//@ skip if $architecture == "x86"
+
+var n = 10000000;
+
+function bar(set) { 
+    var result = set(0);
+    if (result !== void 0)
+        throw "Error: bad value: " + result;
+}
+
+function foo(b) {
+    var result = 0;
+    var imUndefined;
+    var baz;
+    var set = function (x) { 
+        result = x; 
+        if (baz !== 50)
+            throw "Error: bad value: " + baz;
+        return imUndefined;
+    }
+    baz = 50;
+    if (b) {
+        OSRExit();
+        if (b) {
+            bar(set);
+        }
+        return 0;
+    }
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+
+for (var i = 0; i < n; i++) {
+    var result = foo(!(i % 100));
+    if (result != 0)
+        throw "Error: bad result: " + result;
+}
diff --git a/implementation-contributed/javascriptcore/stress/activation-sink-osrexit.js b/implementation-contributed/javascriptcore/stress/activation-sink-osrexit.js
new file mode 100644
index 0000000000000000000000000000000000000000..bd5a2af47e8d3618c170f281086cc02dd2c7299e
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/activation-sink-osrexit.js
@@ -0,0 +1,27 @@
+//@ skip if $architecture == "x86"
+
+var n = 10000000;
+
+function bar() { }
+
+function foo(b) {
+    var result = 0;
+    var set = function (x) { result = x; }
+    if (b) {
+        OSRExit();
+        if (b) {
+            bar(set);
+        }
+        return 0;
+    }
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+
+for (var i = 0; i < n; i++) {
+    var result = foo(!(i % 100));
+    if (result != 0)
+        throw "Error: bad result: " + result;
+}
diff --git a/implementation-contributed/javascriptcore/stress/activation-sink.js b/implementation-contributed/javascriptcore/stress/activation-sink.js
new file mode 100644
index 0000000000000000000000000000000000000000..ccde211447adf2e9606f63e6a835ecec7be37bcf
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/activation-sink.js
@@ -0,0 +1,26 @@
+//@ skip if $architecture == "x86"
+
+var n = 10000000;
+
+function bar(f) { f(10); }
+
+function foo(b) {
+    var result = 0;
+    var set = function (x) { result = x; }
+    if (b) {
+        bar(set);
+        if (result != 10)
+            throw "Error: bad: " + result;
+        return 0;
+    }
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+
+for (var i = 0; i < n; i++) {
+    var result = foo(!(i % 100));
+    if (result != 0)
+        throw "Error: bad result: " + result;
+}
diff --git a/implementation-contributed/javascriptcore/stress/allow-math-ic-b3-code-duplication.js b/implementation-contributed/javascriptcore/stress/allow-math-ic-b3-code-duplication.js
index 92213ac3489a91b00087fa06559d462c1fb62bf9..0dc18276cf803cbd10487350d3a4c9568dd03267 100644
--- a/implementation-contributed/javascriptcore/stress/allow-math-ic-b3-code-duplication.js
+++ b/implementation-contributed/javascriptcore/stress/allow-math-ic-b3-code-duplication.js
@@ -1,4 +1,5 @@
-// Reviewed
+//@ skip if $architecture == "x86"
+
 function test1() {
     var o1;
     for (let i = 0; i < 1000000; ++i) {
diff --git a/implementation-contributed/javascriptcore/stress/array-push-multiple-int32.js b/implementation-contributed/javascriptcore/stress/array-push-multiple-int32.js
new file mode 100644
index 0000000000000000000000000000000000000000..f4164d8989ddc1139c99dce3389915e773d1a606
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/array-push-multiple-int32.js
@@ -0,0 +1,26 @@
+//@ skip if $architecture == "x86"
+
+function shouldBe(actual, expected)
+{
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function test(array, val1, val2, val3)
+{
+    return array.push(val1, val2, val3);
+}
+noInline(test);
+
+for (var i = 0; i < 1e7; ++i) {
+    var array = [];
+    shouldBe(test(array, 1, 2, 3), 3);
+    shouldBe(array[0], 1);
+    shouldBe(array[1], 2);
+    shouldBe(array[2], 3);
+}
+var array = [];
+shouldBe(test(array, 1, 2, 3.3), 3);
+shouldBe(array[0], 1);
+shouldBe(array[1], 2);
+shouldBe(array[2], 3.3);
diff --git a/implementation-contributed/javascriptcore/stress/arrowfunction-activation-sink-osrexit-default-value-tdz-error.js b/implementation-contributed/javascriptcore/stress/arrowfunction-activation-sink-osrexit-default-value-tdz-error.js
new file mode 100644
index 0000000000000000000000000000000000000000..905073e998f0a00b261825a9de65eac347f48f5b
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/arrowfunction-activation-sink-osrexit-default-value-tdz-error.js
@@ -0,0 +1,48 @@
+//@ skip if $architecture == "x86"
+
+"use strict";
+
+var n = 1000000;
+
+function shouldThrowTDZ(func) {
+    var hasThrown = false;
+    try {
+        func();
+    } catch(e) {
+        if (e.name.indexOf("ReferenceError") !== -1)
+            hasThrown = true;
+    }
+    if (!hasThrown)
+        throw new Error("Did not throw TDZ error");
+}
+
+function bar(f) { }
+
+function foo(b) {
+    let result = 0;
+    var set =  (x) => { result = x; return tdzPerpetrator; }
+    if (b) {
+        OSRExit();
+        if (b) {
+            bar(set);
+            return tdzPerpetrator;
+        }
+    }
+    let tdzPerpetrator;
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+noInline(shouldThrowTDZ);
+
+for (var i = 0; i < n; i++) {
+    var bool = !(i % 100);
+    if (bool)
+        shouldThrowTDZ(()=> { foo(bool); });
+    else {
+        var result = foo(bool);
+        if (result != 0)
+            throw "Error: bad result: " + result;
+    }
+}
diff --git a/implementation-contributed/javascriptcore/stress/arrowfunction-lexical-this-activation-sink-osrexit.js b/implementation-contributed/javascriptcore/stress/arrowfunction-lexical-this-activation-sink-osrexit.js
new file mode 100644
index 0000000000000000000000000000000000000000..d7a322e4bf43441bbef7148bfed6b753acf9104d
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/arrowfunction-lexical-this-activation-sink-osrexit.js
@@ -0,0 +1,36 @@
+//@ skip if $architecture == "x86"
+
+var n = 10000000;
+
+var newContext = {
+  id : 'new-context'
+};
+
+function bar() { }
+
+function foo(b) {
+    var result = 0;
+    var set = (x) => {
+      // Check if arrow function store context
+      if (this != newContext || this.id != newContext.id)
+          throw 'Wrong context of arrow function';
+      result = x;
+    }
+    if (b) {
+        OSRExit();
+        if (b) {
+            bar(set);
+        }
+        return result;
+    }
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+
+for (var i = 0; i < n; i++) {
+    var result = foo.call(newContext, !(i % 100));
+    if (result != 0)
+        throw "Error: bad result: " + result;
+}
diff --git a/implementation-contributed/javascriptcore/stress/arrowfunction-lexical-this-activation-sink.js b/implementation-contributed/javascriptcore/stress/arrowfunction-lexical-this-activation-sink.js
new file mode 100644
index 0000000000000000000000000000000000000000..92655f4faf9e335e0528dc21bc4c9d4932d8119d
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/arrowfunction-lexical-this-activation-sink.js
@@ -0,0 +1,40 @@
+//@ skip if $architecture == "x86"
+
+var n = 10000000;
+
+var newContext = {
+  id : 'new-context'
+};
+
+function bar(f) {
+    if (this == newContext)
+        throw 'Wrong context of nesting function';
+    f(10);
+}
+
+function foo(b) {
+    var result = 0;
+    var set = (x) => {
+      result = x;
+      // Check if arrow function store context
+      if (this != newContext || this.id != newContext.id)
+          throw 'Wrong context of arrow function';
+    };
+
+    if (b) {
+        bar(set);
+        if (result != 10)
+            throw "Error: bad: " + result;
+        return 0;
+    }
+    return result;
+}
+
+noInline(bar);
+noInline(foo);
+
+for (var i = 0; i < n; i++) {
+    var result = foo.call(newContext, !(i % 100));
+    if (result != 0)
+        throw "Error: bad result: " + result;
+}
diff --git a/implementation-contributed/javascriptcore/stress/dont-crash-on-stack-overflow-when-parsing-builtin.js b/implementation-contributed/javascriptcore/stress/dont-crash-on-stack-overflow-when-parsing-builtin.js
new file mode 100644
index 0000000000000000000000000000000000000000..4254ec86865e585d759bfa384f76fa3960aff643
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/dont-crash-on-stack-overflow-when-parsing-builtin.js
@@ -0,0 +1,13 @@
+//@ runDefault("--softReservedZoneSize=16384", "--reservedZoneSize=0", "--useJIT=0", "--validateBytecode=1", "--maxPerThreadStackUsage=499712")
+
+function f() {
+    try {
+        f();
+    } catch (e) {
+        try {
+            Map.prototype.forEach.call('', {});
+        } catch (e) {}
+    }
+}
+
+f()
diff --git a/implementation-contributed/javascriptcore/stress/dont-crash-on-stack-overflow-when-parsing-default-constructor.js b/implementation-contributed/javascriptcore/stress/dont-crash-on-stack-overflow-when-parsing-default-constructor.js
new file mode 100644
index 0000000000000000000000000000000000000000..55454418a316d5d9017396532f47b3b88dcfb14e
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/dont-crash-on-stack-overflow-when-parsing-default-constructor.js
@@ -0,0 +1,17 @@
+//@ runDefault("--softReservedZoneSize=16384", "--reservedZoneSize=0", "--useJIT=0", "--validateBytecode=1", "--maxPerThreadStackUsage=499712")
+
+function runNearStackLimit(f) {
+    function t() {
+        try {
+            return t();
+        } catch (e) {
+            new class extends (class {}) {}();
+            return f();
+        }
+    }
+    return t();
+}
+function foo() {
+    new class extends (class {}) {}();
+}
+runNearStackLimit(() => { return foo(); });
diff --git a/implementation-contributed/javascriptcore/stress/elide-new-object-dag-then-exit.js b/implementation-contributed/javascriptcore/stress/elide-new-object-dag-then-exit.js
new file mode 100644
index 0000000000000000000000000000000000000000..a2ed594082cfc2ed94e27cb5a061bc4bedced8c8
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/elide-new-object-dag-then-exit.js
@@ -0,0 +1,45 @@
+//@ skip if $architecture == "x86"
+
+function sumOfArithSeries(limit) {
+    return limit * (limit + 1) / 2;
+}
+
+var n = 10000000;
+
+function bar() { }
+
+function verify(q, i) {
+    if (q.f == q.g)
+        throw "Error: q.f == q.g";
+    if (q.f.f != q.g.f)
+        throw "Error: q.f.f != q.g.f";
+    if (q.f.f.f != i)
+        throw "Error: q.f.f.f != i";
+}
+
+function foo() {
+    var result = 0;
+    for (var i = 0; i < n; ++i) {
+        var leaf = {f:i};
+        var o = {f:leaf};
+        var p = {f:leaf};
+        var q = {f:o, g:p};
+        result += q.f.f.f;
+        if (i >= n - 100) {
+            // We want the materialization to happen in the exit. So, before calling the thing that
+            // causes the materialization, we call bar(). We've never profiled this call at the time
+            // of FTL compilation, so this should be an exit.
+            bar();
+            verify(q, i);
+        }
+    }
+    return result;
+}
+
+noInline(foo);
+noInline(verify);
+noInline(bar);
+
+var result = foo();
+if (result != sumOfArithSeries(n - 1))
+    throw "Error: bad result: " + result;
diff --git a/implementation-contributed/javascriptcore/stress/materialize-regexp-cyclic.js b/implementation-contributed/javascriptcore/stress/materialize-regexp-cyclic.js
new file mode 100644
index 0000000000000000000000000000000000000000..1787639a117faa86b8acade324fa1d0e24a7ee00
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/materialize-regexp-cyclic.js
@@ -0,0 +1,41 @@
+//@ slow!
+
+function shouldBe(actual, expected)
+{
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function test(num)
+{
+    var regexp = /hello world/;
+    regexp.lastIndex = { ok: regexp, value: 42 };
+    if (num === 0)
+        return regexp;
+    if (num === 1)
+        return regexp.lastIndex;
+    return regexp.lastIndex.value;
+}
+noInline(test);
+
+for (var i = 0; i < 1e6; ++i) {
+    var num = i % 3;
+    switch (num) {
+    case 0:
+        var regexp = test(num);
+        shouldBe(regexp instanceof RegExp, true);
+        shouldBe(typeof regexp.lastIndex, "object");
+        shouldBe(regexp.lastIndex.ok, regexp);
+        break;
+    case 1:
+        var object = test(num);
+        shouldBe(object.value, 42);
+        shouldBe(object.ok instanceof RegExp, true);
+        shouldBe(object.ok.lastIndex, object);
+        break;
+    case 2:
+        var value = test(num);
+        shouldBe(value, 42);
+        break;
+    }
+}
diff --git a/implementation-contributed/javascriptcore/stress/new-regex-inline.js b/implementation-contributed/javascriptcore/stress/new-regex-inline.js
new file mode 100644
index 0000000000000000000000000000000000000000..53d80477b41818ddf88edd2b55c587077458db7f
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/new-regex-inline.js
@@ -0,0 +1,84 @@
+//@ skip if $architecture == "x86"
+
+function assert(a) {
+    if (!a)
+        throw Error("bad assertion");
+}
+
+function testRegexpInline(functor) {
+    for (let i = 0; i < 100000; i++) {
+        functor();
+    }
+
+    gc();
+
+    // Create objects to force collected objects be reused
+    for (let i = 0; i < 10000000; i++) {
+        let a = {value: i};
+    }
+
+    // Checking if RegExp were collected
+    for (let i = 0; i < 100; i++) {
+        functor();
+    }
+}
+
+function toInlineGlobal() {
+    var re = /cc+/;
+
+    assert(re.test("ccc"));
+    assert(!re.test("abc"));
+    return 0;
+}
+
+function withRegexp() {
+    toInlineGlobal();
+    var re = /(ab)+/;
+    assert(re.test("ab"));
+    assert(!re.test("ba"));
+    return 0;
+}
+
+noInline(withRegexp);
+
+testRegexpInline(withRegexp);
+
+function inlineRegexpNotGlobal() {
+    let toInline = () => {
+        let re = /a+/;
+
+        assert(re.test("aaaaaa"));
+        assert(!re.test("bc"));
+    }
+
+    toInline();
+}
+
+noInline(inlineRegexpNotGlobal);
+
+testRegexpInline(inlineRegexpNotGlobal);
+
+function toInlineRecursive(depth) {
+    if (depth == 5) {
+        return;
+    }
+
+    var re = /(ef)+/;
+
+    assert(re.test("efef"));
+    assert(!re.test("abc"));
+    
+    toInlineRecursive(depth + 1);
+}
+
+function regexpContainsRecursive() {
+    var re = /r+/;
+    toInlineRecursive(0);
+
+    assert(re.test("r"));
+    assert(!re.test("ab"));
+}
+noInline(regexpContainsRecursive);
+
+testRegexpInline(regexpContainsRecursive);
+
diff --git a/implementation-contributed/javascriptcore/stress/op_add.js b/implementation-contributed/javascriptcore/stress/op_add.js
index 65679b43aec5939a642ca82ea09510227df19ddc..c6290406cc662bb9291f6aedb9bd26fdb55bf2f0 100644
--- a/implementation-contributed/javascriptcore/stress/op_add.js
+++ b/implementation-contributed/javascriptcore/stress/op_add.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_bitand.js b/implementation-contributed/javascriptcore/stress/op_bitand.js
index 1bc61a00eb42fe4751fd1a637847a949728fc6c3..a4586034d31687e229a4263f4414cb748e3f2e5c 100644
--- a/implementation-contributed/javascriptcore/stress/op_bitand.js
+++ b/implementation-contributed/javascriptcore/stress/op_bitand.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_bitor.js b/implementation-contributed/javascriptcore/stress/op_bitor.js
index 685e2362412fc63a869fa174aa1bf51cb4780494..2668a999970e0764cd2ea4a43e3a24d26eb235f2 100644
--- a/implementation-contributed/javascriptcore/stress/op_bitor.js
+++ b/implementation-contributed/javascriptcore/stress/op_bitor.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_bitxor.js b/implementation-contributed/javascriptcore/stress/op_bitxor.js
index e05fa5d78a8e683a52a8845e98ead66915836eb8..769c5520ec4e248f3ab17fb16c553672cc176297 100644
--- a/implementation-contributed/javascriptcore/stress/op_bitxor.js
+++ b/implementation-contributed/javascriptcore/stress/op_bitxor.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_div-ConstVar.js b/implementation-contributed/javascriptcore/stress/op_div-ConstVar.js
new file mode 100644
index 0000000000000000000000000000000000000000..45086543ad612bc44760bcc37e6545c7de797f95
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/op_div-ConstVar.js
@@ -0,0 +1,20 @@
+//@ skip if $architecture == "x86"
+//@ runFTLNoCJIT("--timeoutMultiplier=2.0")
+
+// If all goes well, this test module will terminate silently. If not, it will print
+// errors. See binary-op-test.js for debugging options if needed.
+
+load("./resources/binary-op-test.js");
+
+//============================================================================
+// Test configuration data:
+
+var opName = "div";
+var op = "/";
+
+load("./resources/binary-op-values.js");
+
+tests = [];
+generateBinaryTests(tests, opName, op, "ConstVar", values, values);
+
+run();
diff --git a/implementation-contributed/javascriptcore/stress/op_div-VarConst.js b/implementation-contributed/javascriptcore/stress/op_div-VarConst.js
new file mode 100644
index 0000000000000000000000000000000000000000..91ff2f14ad8977e7d04e55aa9102b476cff1239b
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/op_div-VarConst.js
@@ -0,0 +1,20 @@
+//@ skip if $architecture == "x86"
+//@ runFTLNoCJIT("--timeoutMultiplier=2.0")
+
+// If all goes well, this test module will terminate silently. If not, it will print
+// errors. See binary-op-test.js for debugging options if needed.
+
+load("./resources/binary-op-test.js");
+
+//============================================================================
+// Test configuration data:
+
+var opName = "div";
+var op = "/";
+
+load("./resources/binary-op-values.js");
+
+tests = [];
+generateBinaryTests(tests, opName, op, "VarConst", values, values);
+
+run();
diff --git a/implementation-contributed/javascriptcore/stress/op_div-VarVar.js b/implementation-contributed/javascriptcore/stress/op_div-VarVar.js
new file mode 100644
index 0000000000000000000000000000000000000000..828a203045d1cedeeb0e94424ddfb2ea388ea16e
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/op_div-VarVar.js
@@ -0,0 +1,20 @@
+//@ skip if $architecture == "x86"
+//@ runFTLNoCJIT("--timeoutMultiplier=2.0")
+
+// If all goes well, this test module will terminate silently. If not, it will print
+// errors. See binary-op-test.js for debugging options if needed.
+
+load("./resources/binary-op-test.js");
+
+//============================================================================
+// Test configuration data:
+
+var opName = "div";
+var op = "/";
+
+load("./resources/binary-op-values.js");
+
+tests = [];
+generateBinaryTests(tests, opName, op, "VarVar", values, values);
+
+run();
diff --git a/implementation-contributed/javascriptcore/stress/op_lshift-ConstVar.js b/implementation-contributed/javascriptcore/stress/op_lshift-ConstVar.js
index 0feac842b0f605555db74065f2c0456b54def540..79b46c11d48a469a20277f23a854ff9bb0b0516e 100644
--- a/implementation-contributed/javascriptcore/stress/op_lshift-ConstVar.js
+++ b/implementation-contributed/javascriptcore/stress/op_lshift-ConstVar.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_lshift-VarConst.js b/implementation-contributed/javascriptcore/stress/op_lshift-VarConst.js
index 3345eee26b489d657f85341ae6d063b482846ca0..da7e06f10eabe3a8d68b39b59127b21cf868bc29 100644
--- a/implementation-contributed/javascriptcore/stress/op_lshift-VarConst.js
+++ b/implementation-contributed/javascriptcore/stress/op_lshift-VarConst.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_lshift-VarVar.js b/implementation-contributed/javascriptcore/stress/op_lshift-VarVar.js
index 5c20cc3b79d9718e617e363044fe29e1e5d9e997..26b8688d1a7aeaffdfd53766f35c0f0224e3db5e 100644
--- a/implementation-contributed/javascriptcore/stress/op_lshift-VarVar.js
+++ b/implementation-contributed/javascriptcore/stress/op_lshift-VarVar.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_mod-ConstVar.js b/implementation-contributed/javascriptcore/stress/op_mod-ConstVar.js
index f7d439f82abf2d5aaad55bb5e309a3f61c84ee0a..6052bb2a76807b9cb9d790a5c981bdd87f270a6e 100644
--- a/implementation-contributed/javascriptcore/stress/op_mod-ConstVar.js
+++ b/implementation-contributed/javascriptcore/stress/op_mod-ConstVar.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT("--timeoutMultiplier=1.5")
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_mod-VarConst.js b/implementation-contributed/javascriptcore/stress/op_mod-VarConst.js
index 97bdcf26faf3802569dbd7bf05667bd244cb5087..3ecc67dc707f267eed221fd1ea8612fa9d419e76 100644
--- a/implementation-contributed/javascriptcore/stress/op_mod-VarConst.js
+++ b/implementation-contributed/javascriptcore/stress/op_mod-VarConst.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT("--timeoutMultiplier=1.5")
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_mod-VarVar.js b/implementation-contributed/javascriptcore/stress/op_mod-VarVar.js
index 4d321700f883cfcc4abaa789661a068f7d44b619..1f09be897ccb4939df3fe339350b8cedaf2cd8e3 100644
--- a/implementation-contributed/javascriptcore/stress/op_mod-VarVar.js
+++ b/implementation-contributed/javascriptcore/stress/op_mod-VarVar.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT("--timeoutMultiplier=1.5")
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_mul-ConstVar.js b/implementation-contributed/javascriptcore/stress/op_mul-ConstVar.js
index 934926afb91f1580bee9bc4a3aec4e52dbef828f..f1ca9b55e7b0a1d6ba3559fdf7c71e1b7af07492 100644
--- a/implementation-contributed/javascriptcore/stress/op_mul-ConstVar.js
+++ b/implementation-contributed/javascriptcore/stress/op_mul-ConstVar.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_mul-VarConst.js b/implementation-contributed/javascriptcore/stress/op_mul-VarConst.js
index e7c617bfd170167282bef712af66cbca671d6b73..1de41fed68d5b9f4a52c1118774ead4b34936206 100644
--- a/implementation-contributed/javascriptcore/stress/op_mul-VarConst.js
+++ b/implementation-contributed/javascriptcore/stress/op_mul-VarConst.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_mul-VarVar.js b/implementation-contributed/javascriptcore/stress/op_mul-VarVar.js
index ec1225bca2bb7fe2282442e1700144a70f7ccab1..fd9f1d0eebbb1f760dd6d67b8c6c270c3c374110 100644
--- a/implementation-contributed/javascriptcore/stress/op_mul-VarVar.js
+++ b/implementation-contributed/javascriptcore/stress/op_mul-VarVar.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_rshift-ConstVar.js b/implementation-contributed/javascriptcore/stress/op_rshift-ConstVar.js
index b6d65bccd713a6d24dd097518f1c69ed4f78efbb..721856c2423dbd8c892d3680eb554bfefac55245 100644
--- a/implementation-contributed/javascriptcore/stress/op_rshift-ConstVar.js
+++ b/implementation-contributed/javascriptcore/stress/op_rshift-ConstVar.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_rshift-VarConst.js b/implementation-contributed/javascriptcore/stress/op_rshift-VarConst.js
index ab46fcdb3476b02db6127577ac22333f3d233486..b2bf2da248ae166a80c9e73ef318015c49a15d96 100644
--- a/implementation-contributed/javascriptcore/stress/op_rshift-VarConst.js
+++ b/implementation-contributed/javascriptcore/stress/op_rshift-VarConst.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_rshift-VarVar.js b/implementation-contributed/javascriptcore/stress/op_rshift-VarVar.js
index 02c5b4112bd363c850edc4d13d74e366234bfb7b..a6a1bfc87a4196ea4f2747b33f706a0a4225de6a 100644
--- a/implementation-contributed/javascriptcore/stress/op_rshift-VarVar.js
+++ b/implementation-contributed/javascriptcore/stress/op_rshift-VarVar.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_sub-ConstVar.js b/implementation-contributed/javascriptcore/stress/op_sub-ConstVar.js
index 9e94c2b0ce62770c9797e2e562c836010fe746ca..f651df2e655f4244e4f768e3e451866c59010b5d 100644
--- a/implementation-contributed/javascriptcore/stress/op_sub-ConstVar.js
+++ b/implementation-contributed/javascriptcore/stress/op_sub-ConstVar.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_sub-VarConst.js b/implementation-contributed/javascriptcore/stress/op_sub-VarConst.js
index 5223846d688b18663f01d7d9b1d605aac2d18a90..f590d0ed8e4852a9e11783fadb8dd738d4a96a8e 100644
--- a/implementation-contributed/javascriptcore/stress/op_sub-VarConst.js
+++ b/implementation-contributed/javascriptcore/stress/op_sub-VarConst.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_sub-VarVar.js b/implementation-contributed/javascriptcore/stress/op_sub-VarVar.js
index e8bbc154005114230ab04cc1fb1f6cfd0928ec23..f194861e6bdb81f906e0b8c697e40dadd068681f 100644
--- a/implementation-contributed/javascriptcore/stress/op_sub-VarVar.js
+++ b/implementation-contributed/javascriptcore/stress/op_sub-VarVar.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_urshift-ConstVar.js b/implementation-contributed/javascriptcore/stress/op_urshift-ConstVar.js
index 82312fe5c862ce0c5aeab7b1340ccf35259d3b87..d427c1f294b8718b7995925547de2788a67b926c 100644
--- a/implementation-contributed/javascriptcore/stress/op_urshift-ConstVar.js
+++ b/implementation-contributed/javascriptcore/stress/op_urshift-ConstVar.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_urshift-VarConst.js b/implementation-contributed/javascriptcore/stress/op_urshift-VarConst.js
index 491153b43adea5c69d31d7ad567af208b8ff1140..1bf063c5457088b5f494329da13f9677865f5bba 100644
--- a/implementation-contributed/javascriptcore/stress/op_urshift-VarConst.js
+++ b/implementation-contributed/javascriptcore/stress/op_urshift-VarConst.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/op_urshift-VarVar.js b/implementation-contributed/javascriptcore/stress/op_urshift-VarVar.js
index 5b6f5cb739e84a70413a97c997421cba91f07c04..bc22b997e692edb491607f29e55c4aa720634290 100644
--- a/implementation-contributed/javascriptcore/stress/op_urshift-VarVar.js
+++ b/implementation-contributed/javascriptcore/stress/op_urshift-VarVar.js
@@ -1,6 +1,6 @@
 // FIXME: unskip when this is solved
 // https://bugs.webkit.org/show_bug.cgi?id=191163
-//@ skip if $architecture == "arm"
+//@ skip if $architecture == "arm" or $architecture == "x86"
 //@ runFTLNoCJIT
 
 // If all goes well, this test module will terminate silently. If not, it will print
diff --git a/implementation-contributed/javascriptcore/stress/proxy-get-set-correct-receiver.js b/implementation-contributed/javascriptcore/stress/proxy-get-set-correct-receiver.js
new file mode 100644
index 0000000000000000000000000000000000000000..6708ab185dd281c0f0acbf5a95530d70a28d2d33
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/proxy-get-set-correct-receiver.js
@@ -0,0 +1,117 @@
+"use strict";
+
+function assert(b) {
+    if (!b)
+        throw new Error("Bad")
+}
+
+function test(f, count = 1000) {
+    noInline(f);
+    for (let i = 0; i < count; ++i)
+        f();
+}
+
+test(function() {
+    let called = false;
+    let target = {
+        set prop(x)
+        {
+            assert(x === 20);
+            called = true;
+            assert(this === proxy)
+        }
+    }
+
+    let proxy = new Proxy(target, {})
+    proxy.prop = 20;
+    assert(called);
+});
+
+test(function() {
+    let called = false;
+    let target = {
+        get prop()
+        {
+            called = true;
+            assert(this === proxy)
+        }
+    }
+
+    let proxy = new Proxy(target, {})
+    proxy.prop
+    assert(called);
+});
+
+test(function() {
+    let target = {
+        get prop()
+        {
+            called = true;
+            assert(this === proxy)
+        }
+    }
+    let p1 = new Proxy(target, {});
+
+    let called = false;
+    let proxy = new Proxy(p1, {});
+    proxy.prop
+    assert(called);
+});
+
+test(function() {
+    let t = {};
+    let p1 = new Proxy(t, {
+        get(target, prop, receiver) {
+            called = true;
+            assert(target === t);
+            assert(receiver === proxy);
+            assert(prop === "prop");
+        }
+    });
+
+    let called = false;
+    let proxy = new Proxy(p1, {});
+    proxy.prop
+    assert(called);
+});
+
+test(function() {
+    let t = {};
+    let callCount = 0;
+    let handler = {
+        get(target, prop, receiver) {
+            if (callCount === 100)
+                assert(target === t);
+            ++callCount;
+            assert(receiver === proxy);
+            assert(prop === "prop");
+            return Reflect.get(target, prop, receiver);
+        }
+    };
+    let proxy = new Proxy(t, handler);
+    for (let i = 0; i < 100; ++i)
+        proxy = new Proxy(proxy, handler);
+    proxy.prop
+    assert(callCount === 101);
+}, 10);
+
+test(function() {
+    let t = {};
+    let callCount = 0;
+    let handler = {
+        set(target, prop, value, receiver) {
+            if (callCount === 100)
+                assert(target === t);
+            ++callCount;
+            assert(receiver === proxy);
+            assert(prop === "prop");
+            assert(value === 20);
+            return Reflect.set(target, prop, value, receiver);
+        }
+    };
+    let proxy = new Proxy(t, handler);
+    for (let i = 0; i < 100; ++i)
+        proxy = new Proxy(proxy, handler);
+    proxy.prop = 20;
+    assert(callCount === 101);
+}, 10);
diff --git a/implementation-contributed/javascriptcore/stress/regexp-compile-oom.js b/implementation-contributed/javascriptcore/stress/regexp-compile-oom.js
index 45c63d9e77acfb5dc8a1126a533388d271f4d74f..b1c62e9065b60c5be700936f93b600821b7a1cd3 100644
--- a/implementation-contributed/javascriptcore/stress/regexp-compile-oom.js
+++ b/implementation-contributed/javascriptcore/stress/regexp-compile-oom.js
@@ -1,18 +1,38 @@
 //@ skip if $hostOS != "darwin"
 // Test that throw an OOM exception when compiling a pathological, but valid nested RegExp.
 
-function recurseAndTest(depth, f, expectedException)
+var failures = [];
+
+class TestAndExpectedException
+{
+    constructor(func, exception)
+    {
+        this.func = func;
+        this.exception = exception;
+    }
+
+    runTest()
+    {
+        try {
+            this.func();
+            failures.push("Running " + this.func + ", expected OOM exception, but didn't get one");
+        } catch (e) {
+            let errStr = e.toString();
+            if (errStr != this.exception)
+                failures.push("Running " + this.func + ", expected: \"" + this.exception + "\" but got \"" + errStr + "\"");
+        }       
+    }
+}
+
+function recurseAndTest(depth, testList)
 {
     // Probe stack depth
     try {
-        let result = recurseAndTest(depth + 1, f, expectedException);
+        let result = recurseAndTest(depth + 1, testList);
         if (result == 0) {
-            try {
-                // Call the test function with a nearly full stack.
-                f();
-            } catch (e) {
-                return e.toString();
-            }
+            // Call the test functions with a nearly full stack.
+            for (const test of testList)
+                test.runTest();
 
             return 1;
         } else if (result < 0)
@@ -20,26 +40,40 @@ function recurseAndTest(depth, f, expectedException)
         else
             return result;
     } catch (e) {
-        // Go up a several frames and then call the test function
-        return -10;
+        // Go up a several frames and then call the test functions
+        return -24;
     }
 
     return 1;
 }
 
-let deepRE = /((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((x))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))/;
-let matchLen = 381; // The number of parens plus 1 for the whole match.
+let deepRE = new RegExp("((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((x))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))");
+let deepGlobalRE = new RegExp(deepRE, "g");
+
+let matchLen = 401; // The number of parens plus 1 for the whole match.
 
 let regExpOOMError = "Error: Out of memory: Invalid regular expression: too many nested disjunctions";
 
-// Test that both exec (captured compilation) and test (match only compilation) handles OOM.
-let result = recurseAndTest(1, () => { deepRE.exec(); });
-if (result != regExpOOMError)
-    throw "Expected: \"" + regExpOOMError + "\" but got \"" + result + "\"";
+testList = [];
+
+// Test that all RegExp related APIs that compile RE's properly handle OOM.
+testList.push(new TestAndExpectedException(() => { deepRE.exec("x"); }, regExpOOMError));
+testList.push(new TestAndExpectedException(() => { deepRE.test("x"); }, regExpOOMError));
+testList.push(new TestAndExpectedException(() => { "x".match(deepRE); }, regExpOOMError));
+testList.push(new TestAndExpectedException(() => { "x".match(deepGlobalRE); }, regExpOOMError));
+testList.push(new TestAndExpectedException(() => { "x".replace(deepGlobalRE, ""); }, regExpOOMError));
+testList.push(new TestAndExpectedException(() => { "x".replace(deepGlobalRE, "X"); }, regExpOOMError));
+testList.push(new TestAndExpectedException(() => { "x".replace(deepGlobalRE, () => { return "X" }); }, regExpOOMError));
+testList.push(new TestAndExpectedException(() => { "x".search(deepRE); }, regExpOOMError));
 
-result = recurseAndTest(1, () => { deepRE.test(); });
-if (result != regExpOOMError)
-    throw "Expected: \"" + regExpOOMError + "\" but got \"" + result + "\"";
+recurseAndTest(1, testList);
+
+if (failures.length) {
+    print("Got the following failures:");
+    for (const failure of failures)
+        print(failure);
+    throw "Got failures";
+}
 
 // Test that the RegExp works correctly with RegExp.exec() and RegExp.test() when there is sufficient stack space to compile it.
 let m = deepRE.exec("x");
diff --git a/implementation-contributed/javascriptcore/stress/regress-179562.js b/implementation-contributed/javascriptcore/stress/regress-179562.js
new file mode 100644
index 0000000000000000000000000000000000000000..488bf9b3ae91b2aeb57175652f4c99eaf7ba2b94
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/regress-179562.js
@@ -0,0 +1,33 @@
+//@ runFTLNoCJIT("--maxPerThreadStackUsage=400000") if $jitTests
+
+function runNearStackLimit(f) {
+    function t() {
+        try {
+            return t();
+        } catch (e) {
+            return f();
+        }
+    }
+    return t()
+}
+
+function foo(a, b) {
+  return [{
+    name: b + "" + a
+  }];
+}
+
+var exception;
+try {
+    __v_25012 = [].concat(
+        foo(1, []),
+        runNearStackLimit(() => {
+            return foo("bla", Symbol.search);
+        })
+    );
+} catch (e) {
+    exception = e;
+}
+
+if (exception != "TypeError: Cannot convert a symbol to a string")
+    throw "FAILED";
diff --git a/implementation-contributed/javascriptcore/stress/rest-parameter-many-arguments.js b/implementation-contributed/javascriptcore/stress/rest-parameter-many-arguments.js
new file mode 100644
index 0000000000000000000000000000000000000000..16a1f288314e557fa4069977e24964265d3c6b2c
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/rest-parameter-many-arguments.js
@@ -0,0 +1,52 @@
+//@ skip if $architecture == "x86"
+//@ if $architecture == "x86" then defaultSpotCheckNoMaximalFlush else defaultRun end
+
+function assert(b) {
+    if (!b)
+        throw new Error("Bad!")
+}
+noInline(assert);
+
+let calledGet = false;
+let definedAccessor = false;
+function test() {
+    function foo(...rest) {
+        return rest;
+    }
+    noInline(foo);
+
+    for (let i = 0; i < 10000; i++) {
+        const size = 800;
+        let arr = new Array(size);
+        for (let i = 0; i < size; i++)
+            arr[i] = i;
+        let result = foo(...arr);
+
+        assert(result.length === arr.length);
+        assert(result.length === size);
+        for (let i = 0; i < arr.length; i++) {
+            assert(arr[i] === result[i]);
+            assert(result[i] === i);
+        }
+        if (definedAccessor) {
+            calledGet = false;
+            result[0];
+            assert(!calledGet);
+            arr[0];
+            assert(calledGet);
+
+            let testArr = [...arr];
+            calledGet = false;
+            testArr[0];
+            assert(!calledGet);
+        }
+    }
+}
+test();
+
+definedAccessor = true;
+Reflect.defineProperty(Array.prototype, "0", {
+    get() { calledGet = true; return 0; },
+    set(x) {  }
+});
+test();
diff --git a/implementation-contributed/javascriptcore/stress/sampling-profiler-richards.js b/implementation-contributed/javascriptcore/stress/sampling-profiler-richards.js
index 40af90290a7a8dacf7ede36a41846a2f2ecc9b68..475063b37b66c7bc28aeaa4cb333934f5f7037f8 100644
--- a/implementation-contributed/javascriptcore/stress/sampling-profiler-richards.js
+++ b/implementation-contributed/javascriptcore/stress/sampling-profiler-richards.js
@@ -1,6 +1,7 @@
 // [JSC] [Armv7] stress/sampling-profiler-richards.js crashes
 // https://bugs.webkit.org/show_bug.cgi?id=190426
 //@ skip if $architecture == "arm" and $hostOS == "linux"
+//@ skip if $architecture == "x86"
 //@ runDefault("--collectContinuously=1", "--useSamplingProfiler=1", "--collectSamplingProfilerDataForJSCShell=1")
 
 "use strict";
diff --git a/implementation-contributed/javascriptcore/stress/splay-flash-access-1ms.js b/implementation-contributed/javascriptcore/stress/splay-flash-access-1ms.js
new file mode 100644
index 0000000000000000000000000000000000000000..aa676ee7c056ea1f8f0b27386624298bc5085dac
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/splay-flash-access-1ms.js
@@ -0,0 +1,904 @@
+//@ skip if $memoryLimited
+//@ skip if $architecture == "x86"
+//@ runNoisyTestDefault
+//@ runNoisyTestNoCJIT
+
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2015 Apple Inc. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+// Performance.now is used in latency benchmarks, the fallback is Date.now.
+var performance = performance || {};
+performance.now = (function() {
+  return performance.now       ||
+         performance.mozNow    ||
+         performance.msNow     ||
+         performance.oNow      ||
+         performance.webkitNow ||
+         Date.now;
+})();
+
+// Simple framework for running the benchmark suites and
+// computing a score based on the timing measurements.
+
+
+// A benchmark has a name (string) and a function that will be run to
+// do the performance measurement. The optional setup and tearDown
+// arguments are functions that will be invoked before and after
+// running the benchmark, but the running time of these functions will
+// not be accounted for in the benchmark score.
+function Benchmark(name, doWarmup, doDeterministic, run, setup, tearDown, latencyResult, minIterations) {
+  this.name = name;
+  this.doWarmup = doWarmup;
+  this.doDeterministic = doDeterministic;
+  this.run = run;
+  this.Setup = setup ? setup : function() { };
+  this.TearDown = tearDown ? tearDown : function() { };
+  this.latencyResult = latencyResult ? latencyResult : null; 
+  this.minIterations = minIterations ? minIterations : 32;
+}
+
+
+// Benchmark results hold the benchmark and the measured time used to
+// run the benchmark. The benchmark score is computed later once a
+// full benchmark suite has run to completion. If latency is set to 0
+// then there is no latency score for this benchmark.
+function BenchmarkResult(benchmark, time, latency) {
+  this.benchmark = benchmark;
+  this.time = time;
+  this.latency = latency;
+}
+
+
+// Automatically convert results to numbers. Used by the geometric
+// mean computation.
+BenchmarkResult.prototype.valueOf = function() {
+  return this.time;
+}
+
+
+// Suites of benchmarks consist of a name and the set of benchmarks in
+// addition to the reference timing that the final score will be based
+// on. This way, all scores are relative to a reference run and higher
+// scores implies better performance.
+function BenchmarkSuite(name, reference, benchmarks) {
+  this.name = name;
+  this.reference = reference;
+  this.benchmarks = benchmarks;
+  BenchmarkSuite.suites.push(this);
+}
+
+
+// Keep track of all declared benchmark suites.
+BenchmarkSuite.suites = [];
+
+// Scores are not comparable across versions. Bump the version if
+// you're making changes that will affect that scores, e.g. if you add
+// a new benchmark or change an existing one.
+BenchmarkSuite.version = '9';
+
+// Override the alert function to throw an exception instead.
+alert = function(s) {
+  throw "Alert called with argument: " + s;
+};
+
+
+// To make the benchmark results predictable, we replace Math.random
+// with a 100% deterministic alternative.
+BenchmarkSuite.ResetRNG = function() {
+  Math.random = (function() {
+    var seed = 49734321;
+    return function() {
+      // Robert Jenkins' 32 bit integer hash function.
+      seed = ((seed + 0x7ed55d16) + (seed << 12))  & 0xffffffff;
+      seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffffffff;
+      seed = ((seed + 0x165667b1) + (seed << 5))   & 0xffffffff;
+      seed = ((seed + 0xd3a2646c) ^ (seed << 9))   & 0xffffffff;
+      seed = ((seed + 0xfd7046c5) + (seed << 3))   & 0xffffffff;
+      seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffffffff;
+      return (seed & 0xfffffff) / 0x10000000;
+    };
+  })();
+}
+
+
+// Runs all registered benchmark suites and optionally yields between
+// each individual benchmark to avoid running for too long in the
+// context of browsers. Once done, the final score is reported to the
+// runner.
+BenchmarkSuite.RunSuites = function(runner) {
+  var continuation = null;
+  var suites = BenchmarkSuite.suites;
+  var length = suites.length;
+  BenchmarkSuite.scores = [];
+  var index = 0;
+  function RunStep() {
+    while (continuation || index < length) {
+      if (continuation) {
+        continuation = continuation();
+      } else {
+        var suite = suites[index++];
+        if (runner.NotifyStart) runner.NotifyStart(suite.name);
+        continuation = suite.RunStep(runner);
+      }
+      if (continuation && typeof window != 'undefined' && window.setTimeout) {
+        window.setTimeout(RunStep, 25);
+        return;
+      }
+    }
+
+    // show final result
+    if (runner.NotifyScore) {
+      var score = BenchmarkSuite.GeometricMean(BenchmarkSuite.scores);
+      var formatted = BenchmarkSuite.FormatScore(100 * score);
+      runner.NotifyScore(formatted);
+    }
+  }
+  RunStep();
+}
+
+
+// Counts the total number of registered benchmarks. Useful for
+// showing progress as a percentage.
+BenchmarkSuite.CountBenchmarks = function() {
+  var result = 0;
+  var suites = BenchmarkSuite.suites;
+  for (var i = 0; i < suites.length; i++) {
+    result += suites[i].benchmarks.length;
+  }
+  return result;
+}
+
+
+// Computes the geometric mean of a set of numbers.
+BenchmarkSuite.GeometricMean = function(numbers) {
+  var log = 0;
+  for (var i = 0; i < numbers.length; i++) {
+    log += Math.log(numbers[i]);
+  }
+  return Math.pow(Math.E, log / numbers.length);
+}
+
+
+// Computes the geometric mean of a set of throughput time measurements.
+BenchmarkSuite.GeometricMeanTime = function(measurements) {
+  var log = 0;
+  for (var i = 0; i < measurements.length; i++) {
+    log += Math.log(measurements[i].time);
+  }
+  return Math.pow(Math.E, log / measurements.length);
+}
+
+
+// Computes the average of the worst samples. For example, if percentile is 99, this will report the
+// average of the worst 1% of the samples.
+BenchmarkSuite.AverageAbovePercentile = function(numbers, percentile) {
+  // Don't change the original array.
+  numbers = numbers.slice();
+  
+  // Sort in ascending order.
+  numbers.sort(function(a, b) { return a - b; });
+  
+  // Now the elements we want are at the end. Keep removing them until the array size shrinks too much.
+  // Examples assuming percentile = 99:
+  //
+  // - numbers.length starts at 100: we will remove just the worst entry and then not remove anymore,
+  //   since then numbers.length / originalLength = 0.99.
+  //
+  // - numbers.length starts at 1000: we will remove the ten worst.
+  //
+  // - numbers.length starts at 10: we will remove just the worst.
+  var numbersWeWant = [];
+  var originalLength = numbers.length;
+  while (numbers.length / originalLength > percentile / 100)
+    numbersWeWant.push(numbers.pop());
+  
+  var sum = 0;
+  for (var i = 0; i < numbersWeWant.length; ++i)
+    sum += numbersWeWant[i];
+  
+  var result = sum / numbersWeWant.length;
+  
+  // Do a sanity check.
+  if (numbers.length && result < numbers[numbers.length - 1]) {
+    throw "Sanity check fail: the worst case result is " + result +
+      " but we didn't take into account " + numbers;
+  }
+  
+  return result;
+}
+
+
+// Computes the geometric mean of a set of latency measurements.
+BenchmarkSuite.GeometricMeanLatency = function(measurements) {
+  var log = 0;
+  var hasLatencyResult = false;
+  for (var i = 0; i < measurements.length; i++) {
+    if (measurements[i].latency != 0) {
+      log += Math.log(measurements[i].latency);
+      hasLatencyResult = true;
+    }
+  }
+  if (hasLatencyResult) {
+    return Math.pow(Math.E, log / measurements.length);
+  } else {
+    return 0;
+  }
+}
+
+
+// Converts a score value to a string with at least three significant
+// digits.
+BenchmarkSuite.FormatScore = function(value) {
+  if (value > 100) {
+    return value.toFixed(0);
+  } else {
+    return value.toPrecision(3);
+  }
+}
+
+// Notifies the runner that we're done running a single benchmark in
+// the benchmark suite. This can be useful to report progress.
+BenchmarkSuite.prototype.NotifyStep = function(result) {
+  this.results.push(result);
+  if (this.runner.NotifyStep) this.runner.NotifyStep(result.benchmark.name);
+}
+
+
+// Notifies the runner that we're done with running a suite and that
+// we have a result which can be reported to the user if needed.
+BenchmarkSuite.prototype.NotifyResult = function() {
+  var mean = BenchmarkSuite.GeometricMeanTime(this.results);
+  var score = this.reference[0] / mean;
+  BenchmarkSuite.scores.push(score);
+  if (this.runner.NotifyResult) {
+    var formatted = BenchmarkSuite.FormatScore(100 * score);
+    this.runner.NotifyResult(this.name, formatted);
+  }
+  if (this.reference.length == 2) {
+    var meanLatency = BenchmarkSuite.GeometricMeanLatency(this.results);
+    if (meanLatency != 0) {
+      var scoreLatency = this.reference[1] / meanLatency;
+      BenchmarkSuite.scores.push(scoreLatency);
+      if (this.runner.NotifyResult) {
+        var formattedLatency = BenchmarkSuite.FormatScore(100 * scoreLatency)
+        this.runner.NotifyResult(this.name + "Latency", formattedLatency);
+      }
+    }
+  }
+}
+
+
+// Notifies the runner that running a benchmark resulted in an error.
+BenchmarkSuite.prototype.NotifyError = function(error) {
+  if (this.runner.NotifyError) {
+    this.runner.NotifyError(this.name, error);
+  }
+  if (this.runner.NotifyStep) {
+    this.runner.NotifyStep(this.name);
+  }
+}
+
+
+// Runs a single benchmark for at least a second and computes the
+// average time it takes to run a single iteration.
+BenchmarkSuite.prototype.RunSingleBenchmark = function(benchmark, data) {
+  function Measure(data) {
+    var elapsed = 0;
+    var start = new Date();
+  
+  // Run either for 1 second or for the number of iterations specified
+  // by minIterations, depending on the config flag doDeterministic.
+    for (var i = 0; (benchmark.doDeterministic ? 
+      i<benchmark.minIterations : elapsed < 1000); i++) {
+      benchmark.run();
+      elapsed = new Date() - start;
+    }
+    if (data != null) {
+      data.runs += i;
+      data.elapsed += elapsed;
+    }
+  }
+
+  // Sets up data in order to skip or not the warmup phase.
+  if (!benchmark.doWarmup && data == null) {
+    data = { runs: 0, elapsed: 0 };
+  }
+
+  if (data == null) {
+    Measure(null);
+    return { runs: 0, elapsed: 0 };
+  } else {
+    Measure(data);
+    // If we've run too few iterations, we continue for another second.
+    if (data.runs < benchmark.minIterations) return data;
+    var usec = (data.elapsed * 1000) / data.runs;
+    var latencySamples = (benchmark.latencyResult != null) ? benchmark.latencyResult() : [0];
+    var percentile = 99.5;
+    var latency = BenchmarkSuite.AverageAbovePercentile(latencySamples, percentile) * 1000;
+    this.NotifyStep(new BenchmarkResult(benchmark, usec, latency));
+    return null;
+  }
+}
+
+
+// This function starts running a suite, but stops between each
+// individual benchmark in the suite and returns a continuation
+// function which can be invoked to run the next benchmark. Once the
+// last benchmark has been executed, null is returned.
+BenchmarkSuite.prototype.RunStep = function(runner) {
+  BenchmarkSuite.ResetRNG();
+  this.results = [];
+  this.runner = runner;
+  var length = this.benchmarks.length;
+  var index = 0;
+  var suite = this;
+  var data;
+
+  // Run the setup, the actual benchmark, and the tear down in three
+  // separate steps to allow the framework to yield between any of the
+  // steps.
+
+  function RunNextSetup() {
+    if (index < length) {
+      try {
+        suite.benchmarks[index].Setup();
+      } catch (e) {
+        suite.NotifyError(e);
+        return null;
+      }
+      return RunNextBenchmark;
+    }
+    suite.NotifyResult();
+    return null;
+  }
+
+  function RunNextBenchmark() {
+    try {
+      data = suite.RunSingleBenchmark(suite.benchmarks[index], data);
+    } catch (e) {
+      suite.NotifyError(e);
+      return null;
+    }
+    // If data is null, we're done with this benchmark.
+    return (data == null) ? RunNextTearDown : RunNextBenchmark();
+  }
+
+  function RunNextTearDown() {
+    try {
+      suite.benchmarks[index++].TearDown();
+    } catch (e) {
+      suite.NotifyError(e);
+      return null;
+    }
+    return RunNextSetup;
+  }
+
+  // Start out running the setup.
+  return RunNextSetup();
+}
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Copyright (C) 2015 Apple Inc. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// This benchmark is based on a JavaScript log processing module used
+// by the V8 profiler to generate execution time profiles for runs of
+// JavaScript applications, and it effectively measures how fast the
+// JavaScript engine is at allocating nodes and reclaiming the memory
+// used for old nodes. Because of the way splay trees work, the engine
+// also has to deal with a lot of changes to the large tree object
+// graph.
+
+var Splay = new BenchmarkSuite('Splay', [81491, 2739514], [
+  new Benchmark("Splay", true, false, 
+    SplayRun, SplaySetup, SplayTearDown, SplayLatency)
+]);
+
+
+// Configuration.
+var kSplayTreeSize = 8000;
+var kSplayTreeModifications = 80;
+var kSplayTreePayloadDepth = 5;
+
+var splayTree = null;
+var splaySampleTimeStart = 0.0;
+
+function GeneratePayloadTree(depth, tag) {
+  if (depth == 0) {
+    return {
+      array  : [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
+      string : 'String for key ' + tag + ' in leaf node'
+    };
+  } else {
+    return {
+      left:  GeneratePayloadTree(depth - 1, tag),
+      right: GeneratePayloadTree(depth - 1, tag)
+    };
+  }
+}
+
+
+function GenerateKey() {
+  // The benchmark framework guarantees that Math.random is
+  // deterministic; see base.js.
+  return Math.random();
+}
+
+var splaySamples = [];
+
+function SplayLatency() {
+  return splaySamples;
+}
+
+function SplayUpdateStats(time) {
+  var pause = time - splaySampleTimeStart;
+  splaySampleTimeStart = time;
+  splaySamples.push(pause);
+}
+
+function InsertNewNode() {
+  // Insert new node with a unique key.
+  var key;
+  do {
+    key = GenerateKey();
+  } while (splayTree.find(key) != null);
+  var payload = GeneratePayloadTree(kSplayTreePayloadDepth, String(key));
+  splayTree.insert(key, payload);
+  return key;
+}
+
+
+function SplaySetup() {
+  // Check if the platform has the performance.now high resolution timer.
+  // If not, throw exception and quit.
+  if (!performance.now) {
+    throw "PerformanceNowUnsupported";
+  }
+
+  splayTree = new SplayTree();
+  splaySampleTimeStart = performance.now()
+  for (var i = 0; i < kSplayTreeSize; i++) {
+    InsertNewNode();
+    if ((i+1) % 20 == 19) {
+      SplayUpdateStats(performance.now());
+    }
+  }
+}
+
+
+function SplayTearDown() {
+  // Allow the garbage collector to reclaim the memory
+  // used by the splay tree no matter how we exit the
+  // tear down function.
+  var keys = splayTree.exportKeys();
+  splayTree = null;
+
+  splaySamples = [];
+
+  // Verify that the splay tree has the right size.
+  var length = keys.length;
+  if (length != kSplayTreeSize) {
+    throw new Error("Splay tree has wrong size");
+  }
+
+  // Verify that the splay tree has sorted, unique keys.
+  for (var i = 0; i < length - 1; i++) {
+    if (keys[i] >= keys[i + 1]) {
+      throw new Error("Splay tree not sorted");
+    }
+  }
+}
+
+
+function SplayRun() {
+  // Replace a few nodes in the splay tree.
+  for (var i = 0; i < kSplayTreeModifications; i++) {
+    var key = InsertNewNode();
+    var greatest = splayTree.findGreatestLessThan(key);
+    if (greatest == null) splayTree.remove(key);
+    else splayTree.remove(greatest.key);
+  }
+  SplayUpdateStats(performance.now());
+}
+
+
+/**
+ * Constructs a Splay tree.  A splay tree is a self-balancing binary
+ * search tree with the additional property that recently accessed
+ * elements are quick to access again. It performs basic operations
+ * such as insertion, look-up and removal in O(log(n)) amortized time.
+ *
+ * @constructor
+ */
+function SplayTree() {
+};
+
+
+/**
+ * Pointer to the root node of the tree.
+ *
+ * @type {SplayTree.Node}
+ * @private
+ */
+SplayTree.prototype.root_ = null;
+
+
+/**
+ * @return {boolean} Whether the tree is empty.
+ */
+SplayTree.prototype.isEmpty = function() {
+  return !this.root_;
+};
+
+
+/**
+ * Inserts a node into the tree with the specified key and value if
+ * the tree does not already contain a node with the specified key. If
+ * the value is inserted, it becomes the root of the tree.
+ *
+ * @param {number} key Key to insert into the tree.
+ * @param {*} value Value to insert into the tree.
+ */
+SplayTree.prototype.insert = function(key, value) {
+  if (this.isEmpty()) {
+    this.root_ = new SplayTree.Node(key, value);
+    return;
+  }
+  // Splay on the key to move the last node on the search path for
+  // the key to the root of the tree.
+  this.splay_(key);
+  if (this.root_.key == key) {
+    return;
+  }
+  var node = new SplayTree.Node(key, value);
+  if (key > this.root_.key) {
+    node.left = this.root_;
+    node.right = this.root_.right;
+    this.root_.right = null;
+  } else {
+    node.right = this.root_;
+    node.left = this.root_.left;
+    this.root_.left = null;
+  }
+  this.root_ = node;
+};
+
+
+/**
+ * Removes a node with the specified key from the tree if the tree
+ * contains a node with this key. The removed node is returned. If the
+ * key is not found, an exception is thrown.
+ *
+ * @param {number} key Key to find and remove from the tree.
+ * @return {SplayTree.Node} The removed node.
+ */
+SplayTree.prototype.remove = function(key) {
+  if (this.isEmpty()) {
+    throw Error('Key not found: ' + key);
+  }
+  this.splay_(key);
+  if (this.root_.key != key) {
+    throw Error('Key not found: ' + key);
+  }
+  var removed = this.root_;
+  if (!this.root_.left) {
+    this.root_ = this.root_.right;
+  } else {
+    var right = this.root_.right;
+    this.root_ = this.root_.left;
+    // Splay to make sure that the new root has an empty right child.
+    this.splay_(key);
+    // Insert the original right child as the right child of the new
+    // root.
+    this.root_.right = right;
+  }
+  return removed;
+};
+
+
+/**
+ * Returns the node having the specified key or null if the tree doesn't contain
+ * a node with the specified key.
+ *
+ * @param {number} key Key to find in the tree.
+ * @return {SplayTree.Node} Node having the specified key.
+ */
+SplayTree.prototype.find = function(key) {
+  if (this.isEmpty()) {
+    return null;
+  }
+  this.splay_(key);
+  return this.root_.key == key ? this.root_ : null;
+};
+
+
+/**
+ * @return {SplayTree.Node} Node having the maximum key value.
+ */
+SplayTree.prototype.findMax = function(opt_startNode) {
+  if (this.isEmpty()) {
+    return null;
+  }
+  var current = opt_startNode || this.root_;
+  while (current.right) {
+    current = current.right;
+  }
+  return current;
+};
+
+
+/**
+ * @return {SplayTree.Node} Node having the maximum key value that
+ *     is less than the specified key value.
+ */
+SplayTree.prototype.findGreatestLessThan = function(key) {
+  if (this.isEmpty()) {
+    return null;
+  }
+  // Splay on the key to move the node with the given key or the last
+  // node on the search path to the top of the tree.
+  this.splay_(key);
+  // Now the result is either the root node or the greatest node in
+  // the left subtree.
+  if (this.root_.key < key) {
+    return this.root_;
+  } else if (this.root_.left) {
+    return this.findMax(this.root_.left);
+  } else {
+    return null;
+  }
+};
+
+
+/**
+ * @return {Array<*>} An array containing all the keys of tree's nodes.
+ */
+SplayTree.prototype.exportKeys = function() {
+  var result = [];
+  if (!this.isEmpty()) {
+    this.root_.traverse_(function(node) { result.push(node.key); });
+  }
+  return result;
+};
+
+
+/**
+ * Perform the splay operation for the given key. Moves the node with
+ * the given key to the top of the tree.  If no node has the given
+ * key, the last node on the search path is moved to the top of the
+ * tree. This is the simplified top-down splaying algorithm from:
+ * "Self-adjusting Binary Search Trees" by Sleator and Tarjan
+ *
+ * @param {number} key Key to splay the tree on.
+ * @private
+ */
+SplayTree.prototype.splay_ = function(key) {
+  if (this.isEmpty()) {
+    return;
+  }
+  // Create a dummy node.  The use of the dummy node is a bit
+  // counter-intuitive: The right child of the dummy node will hold
+  // the L tree of the algorithm.  The left child of the dummy node
+  // will hold the R tree of the algorithm.  Using a dummy node, left
+  // and right will always be nodes and we avoid special cases.
+  var dummy, left, right;
+  dummy = left = right = new SplayTree.Node(null, null);
+  var current = this.root_;
+  while (true) {
+    if (key < current.key) {
+      if (!current.left) {
+        break;
+      }
+      if (key < current.left.key) {
+        // Rotate right.
+        var tmp = current.left;
+        current.left = tmp.right;
+        tmp.right = current;
+        current = tmp;
+        if (!current.left) {
+          break;
+        }
+      }
+      // Link right.
+      right.left = current;
+      right = current;
+      current = current.left;
+    } else if (key > current.key) {
+      if (!current.right) {
+        break;
+      }
+      if (key > current.right.key) {
+        // Rotate left.
+        var tmp = current.right;
+        current.right = tmp.left;
+        tmp.left = current;
+        current = tmp;
+        if (!current.right) {
+          break;
+        }
+      }
+      // Link left.
+      left.right = current;
+      left = current;
+      current = current.right;
+    } else {
+      break;
+    }
+  }
+  // Assemble.
+  left.right = current.left;
+  right.left = current.right;
+  current.left = dummy.right;
+  current.right = dummy.left;
+  this.root_ = current;
+};
+
+
+/**
+ * Constructs a Splay tree node.
+ *
+ * @param {number} key Key.
+ * @param {*} value Value.
+ */
+SplayTree.Node = function(key, value) {
+  this.key = key;
+  this.value = value;
+};
+
+
+/**
+ * @type {SplayTree.Node}
+ */
+SplayTree.Node.prototype.left = null;
+
+
+/**
+ * @type {SplayTree.Node}
+ */
+SplayTree.Node.prototype.right = null;
+
+
+/**
+ * Performs an ordered traversal of the subtree starting at
+ * this SplayTree.Node.
+ *
+ * @param {function(SplayTree.Node)} f Visitor function.
+ * @private
+ */
+SplayTree.Node.prototype.traverse_ = function(f) {
+  var current = this;
+  while (current) {
+    var left = current.left;
+    if (left) left.traverse_(f);
+    f(current);
+    current = current.right;
+  }
+};
+function jscSetUp() {
+    SplaySetup();
+}
+
+function jscTearDown() {
+    SplayTearDown();
+}
+
+function jscRun() {
+    SplayRun();
+}
+
+jscSetUp();
+var __before = preciseTime();
+var times = [];
+for (var i = 0; i < 2000; ++i) {
+    var _before = preciseTime();
+    jscRun();
+    var _after = preciseTime();
+    times.push(_after - _before);
+    flashHeapAccess(1);
+}
+var __after = preciseTime();
+jscTearDown();
+
+function averageAbovePercentile(numbers, percentile) {
+    // Don't change the original array.
+    numbers = numbers.slice();
+    
+    // Sort in ascending order.
+    numbers.sort(function(a, b) { return a - b; });
+    
+    // Now the elements we want are at the end. Keep removing them until the array size shrinks too much.
+    // Examples assuming percentile = 99:
+    //
+    // - numbers.length starts at 100: we will remove just the worst entry and then not remove anymore,
+    //   since then numbers.length / originalLength = 0.99.
+    //
+    // - numbers.length starts at 1000: we will remove the ten worst.
+    //
+    // - numbers.length starts at 10: we will remove just the worst.
+    var numbersWeWant = [];
+    var originalLength = numbers.length;
+    while (numbers.length / originalLength > percentile / 100)
+        numbersWeWant.push(numbers.pop());
+    
+    var sum = 0;
+    for (var i = 0; i < numbersWeWant.length; ++i)
+        sum += numbersWeWant[i];
+    
+    var result = sum / numbersWeWant.length;
+    
+    // Do a sanity check.
+    if (numbers.length && result < numbers[numbers.length - 1]) {
+        throw "Sanity check fail: the worst case result is " + result +
+            " but we didn't take into account " + numbers;
+    }
+    
+    return result;
+}
+
+print("That took " + (__after - __before) * 1000 + " ms.");
+
+function printPercentile(percentile)
+{
+    print("Above " + percentile + "%: " + averageAbovePercentile(times, percentile) * 1000 + " ms.");
+}
+
+printPercentile(99.9);
+printPercentile(99.5);
+printPercentile(99);
+printPercentile(97.5);
+printPercentile(95);
+printPercentile(90);
+printPercentile(75);
+printPercentile(50);
+printPercentile(0);
+
+gc();
diff --git a/implementation-contributed/javascriptcore/stress/tailCallForwardArguments.js b/implementation-contributed/javascriptcore/stress/tailCallForwardArguments.js
new file mode 100644
index 0000000000000000000000000000000000000000..69725525d679c681c86390d9560cd767ec02501e
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/tailCallForwardArguments.js
@@ -0,0 +1,165 @@
+//@ skip if $architecture == "x86"
+
+var createBuiltin = $vm.createBuiltin;
+
+// This is pretty bad but I need a private name.
+var putFuncToPrivateName = createBuiltin(`(function (func) { @arrayIteratorIsDone = func })`)
+putFuncToPrivateName(function (a,b) { return b; })
+
+function createTailCallForwardingFuncWith(body, thisValue) {
+    return createBuiltin(`(function (a) {
+        "use strict";
+
+        ${body}
+
+        return @tailCallForwardArguments(@arrayIteratorIsDone, ${thisValue});
+    })`);
+}
+
+var foo = createTailCallForwardingFuncWith("", "@undefined");
+
+function baz() {
+    return foo.call(true, 7);
+}
+noInline(baz);
+
+
+
+var fooNoInline = createTailCallForwardingFuncWith("", "@undefined");
+noInline(foo);
+
+for (let i = 0; i < 100000; i++) {
+    if (baz.call() !== undefined)
+        throw new Error(i);
+    if (fooNoInline.call(undefined, 3) !== undefined)
+        throw new Error(i);
+}
+
+putFuncToPrivateName(function () { "use strict"; return { thisValue: this, argumentsValue: arguments};  });
+var foo2 = createTailCallForwardingFuncWith("", "this");
+var fooNI2 = createTailCallForwardingFuncWith("", "this");
+noInline(fooNI2);
+
+function baz2() {
+    return foo2.call(true, 7);
+}
+noInline(baz2);
+
+for (let i = 0; i < 100000; i++) {
+    let result = foo2.call(true, 7);
+    if (result.thisValue !== true || result.argumentsValue.length !== 1 || result.argumentsValue[0] !== 7)
+        throw new Error(i);
+    result = baz2.call();
+    if (result.thisValue !== true || result.argumentsValue.length !== 1 || result.argumentsValue[0] !== 7)
+        throw new Error(i);
+    result = fooNI2.call(true, 7);
+    if (result.thisValue !== true || result.argumentsValue.length !== 1 || result.argumentsValue[0] !== 7)
+        throw new Error(i);
+}
+
+putFuncToPrivateName(function () { "use strict"; return this;  });
+var foo3 = createTailCallForwardingFuncWith("", "{ thisValue: this, otherValue: 'hello'} ");
+var fooNI3 = createTailCallForwardingFuncWith("", "{ thisValue: this, otherValue: 'hello'} ");
+noInline(fooNI3);
+function baz3() {
+    return foo3.call(true, 7);
+}
+noInline(baz3);
+
+for (let i = 0; i < 100000; i++) {
+    let result = foo3.call(true, 7);
+    if (result.thisValue !== true)
+        throw new Error(i);
+    result = baz3.call();
+    if (result.thisValue !== true)
+        throw new Error(i);
+    result = fooNI3.call(true, 7);
+    if (result.thisValue !== true)
+        throw new Error(i);
+}
+
+
+putFuncToPrivateName(function () { "use strict"; return this;  });
+let bodyText = `
+for (let i = 0; i < 100; i++) {
+    if (a + i === 100)
+        return a;
+}
+`;
+var foo4 = createTailCallForwardingFuncWith(bodyText, "{ thisValue: this, otherValue: 'hello'} ");
+var fooNI4 = createTailCallForwardingFuncWith(bodyText, "{ thisValue: this, otherValue: 'hello'} ");
+noInline(fooNI4);
+function baz4() {
+    return foo4.call(true, 0);
+}
+noInline(baz4);
+
+for (let i = 0; i < 100000; i++) {
+    let result = foo4.call(true, 0);
+    if (result.thisValue !== true || result.otherValue !== "hello")
+        throw new Error(i);
+    result = baz4.call();
+    if (result.thisValue !== true || result.otherValue !== "hello")
+        throw new Error(i);
+    result = fooNI4.call(true, 0);
+    if (result.thisValue !== true || result.otherValue !== "hello")
+        throw new Error(i);
+    result = fooNI4.call(true, 1);
+    if (result !== 1)
+        throw new Error(i);
+    result = fooNI4.call(true, "");
+    if (result.thisValue !== true || result.otherValue !== "hello")
+        throw new Error(i);
+}
+
+var testFunc = function () { "use strict"; return this;  }
+noInline(testFunc);
+putFuncToPrivateName(testFunc);
+
+var foo5 = createTailCallForwardingFuncWith(bodyText, "{ thisValue: this, otherValue: 'hello'} ");
+var fooNI5 = createTailCallForwardingFuncWith(bodyText, "{ thisValue: this, otherValue: 'hello'} ");
+noInline(fooNI5);
+function baz5() {
+    return foo5.call(true, 0);
+}
+noInline(baz5);
+
+for (let i = 0; i < 100000; i++) {
+    let result = foo5.call(true, 0);
+    if (result.thisValue !== true || result.otherValue !== "hello")
+        throw new Error(i);
+    result = baz5.call();
+    if (result.thisValue !== true || result.otherValue !== "hello")
+        throw new Error(i);
+    result = fooNI5.call(true, 0);
+    if (result.thisValue !== true || result.otherValue !== "hello")
+        throw new Error(i);
+    result = fooNI5.call(true, 1);
+    if (result !== 1)
+        throw new Error(i);
+    result = fooNI5.call(true, "");
+    if (result.thisValue !== true || result.otherValue !== "hello")
+        throw new Error(i);
+}
+
+putFuncToPrivateName(function() { return arguments; });
+var foo6 = createTailCallForwardingFuncWith(bodyText, "{ thisValue: this, otherValue: 'hello'} ");
+function baz6() {
+    "use strict"
+    return foo6.apply(this, arguments);
+}
+noInline(baz6);
+
+function arrayEq(a, b) {
+    if (a.length !== b.length)
+        throw new Error();
+    for (let i = 0; i < a.length; i++) {
+        if (a[i] !== b[i])
+            throw new Error();
+    }
+}
+let args = ["a", {}, [], Symbol(), 1, 1.234, undefined, null];
+for (let i = 0; i < 100000; i++) {
+    let result = baz6.apply(undefined, args);
+    arrayEq(result, args);
+}
diff --git a/implementation-contributed/javascriptcore/stress/typed-array-get-by-val-profiling.js b/implementation-contributed/javascriptcore/stress/typed-array-get-by-val-profiling.js
new file mode 100644
index 0000000000000000000000000000000000000000..fe9ad101d2d4ce98448e8047f7e7b0e975e71c67
--- /dev/null
+++ b/implementation-contributed/javascriptcore/stress/typed-array-get-by-val-profiling.js
@@ -0,0 +1,93 @@
+//@ slow!
+
+function testArray(arrayType)
+{
+    var testCode =
+        `
+        // We make this look like a polymorphic types for incomingObject but the GetByVal are never actually
+        // polymorphic. The boolean isTypedArray let us differentiate the types.
+        function ${ arrayType }AndObjectSpeculationInBounds(incomingObject, iterationLength, isTypedArray) {
+            var output = 0;
+            output += incomingObject.length;
+
+            if (isTypedArray) {
+                for (var i = 0; i < iterationLength; ++i) {
+                    output += incomingObject[i];
+                }
+            } else {
+                for (var i = 0; i < iterationLength; ++i) {
+                    output += incomingObject[i];
+                }
+            }
+            return output;
+        }
+        noInline(${ arrayType }AndObjectSpeculationInBounds);
+
+        var typedArray = new ${ arrayType }(64);
+        var regularArray = new Array(64);
+        for (var i = 0; i < 64; ++i) {
+            typedArray[i] = i;
+            regularArray[i] = i;
+        }
+
+        // Access in bounds.
+        for (var i = 0; i < 1e4; ++i) {
+            var output = ${ arrayType }AndObjectSpeculationInBounds(typedArray, 64, true);
+            if (output !== 32 * 65)
+                throw "${ arrayType }AndObjectSpeculationInBounds(typedArray, 64, true) failed, value = " + output;
+
+            var output = ${ arrayType }AndObjectSpeculationInBounds(regularArray, 64, false);
+            if (output !== 32 * 65)
+                throw "${ arrayType }AndObjectSpeculationInBounds(regularArray, 64, false) failed, value = " + output;
+        }
+
+        // One out of bounds on top of the in bounds profile.
+        {
+            var output = ${ arrayType }AndObjectSpeculationInBounds(typedArray, 128, true);
+            if (output === output)
+                throw "${ arrayType }AndObjectSpeculationInBounds(typedArray, 128, true) failed, value = " + output;
+
+            var output = ${ arrayType }AndObjectSpeculationInBounds(regularArray, 128, false);
+            if (output === output)
+                throw "${ arrayType }AndObjectSpeculationInBounds(regularArray, 128, false) failed, value = " + output;
+        }
+
+        // Same but here we make out-of-bounds a normal case.
+        function ${ arrayType }AndObjectSpeculationOutOfBounds(incomingObject, iterationLength, isTypedArray) {
+            var output = 0;
+            output += incomingObject.length;
+
+            if (isTypedArray) {
+                for (var i = 0; i < iterationLength; ++i) {
+                    output += incomingObject[i]|0;
+                }
+            } else {
+                for (var i = 0; i < iterationLength; ++i) {
+                    output += incomingObject[i]|0;
+                }
+            }
+            return output;
+        }
+        noInline(${ arrayType }AndObjectSpeculationOutOfBounds);
+
+        for (var i = 0; i < 1e4; ++i) {
+            var output = ${ arrayType }AndObjectSpeculationOutOfBounds(typedArray, 128, true);
+            if (output !== 32 * 65)
+                throw "${ arrayType }AndObjectSpeculationOutOfBounds(typedArray, 128, true) failed, value = " + output;
+
+            var output = ${ arrayType }AndObjectSpeculationOutOfBounds(regularArray, 128, false);
+            if (output !== 32 * 65)
+                throw "${ arrayType }AndObjectSpeculationOutOfBounds(regularArray, 128, false) failed, value = " + output;
+        }`
+    eval(testCode);
+}
+
+testArray("Int8Array");
+testArray("Uint8Array");
+testArray("Uint8ClampedArray");
+testArray("Int16Array");
+testArray("Uint16Array");
+testArray("Int32Array");
+testArray("Uint32Array");
+testArray("Float32Array");
+testArray("Float64Array");