Diff
Modified: releases/WebKitGTK/webkit-2.22/JSTests/ChangeLog (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/JSTests/ChangeLog 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/JSTests/ChangeLog 2018-08-24 08:07:53 UTC (rev 235290)
@@ -1,3 +1,98 @@
+2018-08-20 Saam barati <[email protected]>
+
+ Inline DataView accesses into DFG/FTL
+ https://bugs.webkit.org/show_bug.cgi?id=188573
+ <rdar://problem/43286746>
+
+ Reviewed by Michael Saboff.
+
+ * microbenchmarks/data-view-accesses-2.js: Added.
+ (assert):
+ (let.p.of.Object.keys.let.str):
+ (let.p.of.Object.keys):
+ (test):
+ * microbenchmarks/data-view-accesses.js: Added.
+ (assert):
+ (let.p.of.Object.keys.let.str):
+ (let.p.of.Object.keys):
+ * stress/dataview-jit-bounds-checks.js: Added.
+ (assert):
+ (let.p.of.Object.keys.let.str):
+ (let.p.of.Object.keys):
+ * stress/dataview-jit-get.js: Added.
+ (assert):
+ (test1.bigEndian):
+ (test1.littleEndian):
+ (test1.biEndian):
+ (test1):
+ (test2.bigEndian):
+ (test2.littleEndian):
+ (test2.biEndian):
+ (test2):
+ (test3.bigEndian):
+ (test3.littleEndian):
+ (test3.biEndian):
+ (test3):
+ (test4.bigEndian):
+ (test4.littleEndian):
+ (test4.biEndian):
+ (test4):
+ (test5.bigEndian):
+ (test5.littleEndian):
+ (test5.biEndian):
+ (test5):
+ (test6.bigEndian):
+ (test6.littleEndian):
+ (test6.biEndian):
+ (test6):
+ (test7.load):
+ (test7):
+ (test8.load):
+ (test8):
+ * stress/dataview-jit-neuter.js: Added.
+ (assert):
+ (test.load):
+ (test):
+ (test2.load):
+ (test2):
+ * stress/dataview-jit-set.js: Added.
+ (assert):
+ (isLittleEndian):
+ (readByte):
+ (readHex):
+ (test.storeLittleEndian):
+ (test.storeBigEndian):
+ (test.store):
+ (test):
+ (test2.storeLittleEndian):
+ (test2.storeBigEndian):
+ (test2.store):
+ (test2):
+ (test3.storeLittleEndian):
+ (test3.storeBigEndian):
+ (test3.store):
+ (test3):
+ (test4.storeLittleEndian):
+ (test4.storeBigEndian):
+ (test4.store):
+ (test4):
+ (test5.storeLittleEndian):
+ (test5.storeBigEndian):
+ (test5.store):
+ (test5):
+ (test6.storeLittleEndian):
+ (test6.storeBigEndian):
+ (test6.store):
+ (test6):
+ (test7.store):
+ (test7):
+ (test8.store):
+ (test8):
+ * stress/dataview-jit-unaligned-accesses.js: Added.
+ (assert):
+ (let.p.of.Object.keys.let.str):
+ (let.p.of.Object.keys):
+
2018-08-20 Yusuke Suzuki <[email protected]>
[YARR] Extend size of fixed characters bulk matching in 64bit platform
Added: releases/WebKitGTK/webkit-2.22/JSTests/microbenchmarks/data-view-accesses-2.js (0 => 235290)
--- releases/WebKitGTK/webkit-2.22/JSTests/microbenchmarks/data-view-accesses-2.js (rev 0)
+++ releases/WebKitGTK/webkit-2.22/JSTests/microbenchmarks/data-view-accesses-2.js 2018-08-24 08:07:53 UTC (rev 235290)
@@ -0,0 +1,78 @@
+"use strict";
+
+function assert(b, m = "") {
+ if (!b)
+ throw new Error("Bad: " + m);
+}
+
+let getOps = {
+ getUint8: 1,
+ getUint16: 2,
+ getUint32: 4,
+ getInt8: 1,
+ getInt16: 2,
+ getInt32: 4,
+ getFloat32: 4,
+ getFloat64: 8,
+};
+
+let setOps = {
+ setUint8: 1,
+ setUint16: 2,
+ setUint32: 4,
+ setInt8: 1,
+ setInt16: 2,
+ setInt32: 4,
+ setFloat32: 4,
+ setFloat64: 8,
+};
+
+let getFuncs = [];
+for (let p of Object.keys(getOps)) {
+ let byteSize = getOps[p];
+ let str = `
+ (function (dv, byteLength) {
+ let sum = 0;
+ for (let i = 0; i < byteLength; i += ${byteSize}) {
+ sum += dv.${p}(i, false);
+ }
+ return sum;
+ });
+ `;
+
+ let func = eval(str);
+ noInline(func);
+ getFuncs.push(func);
+}
+
+let setFuncs = [];
+for (let p of Object.keys(setOps)) {
+ let byteSize = setOps[p];
+ let value = 10;
+ if (p.indexOf("float") !== -1)
+ value = 10.5;
+ let str = `
+ (function (dv, byteLength) {
+ for (let i = 0; i < byteLength; i += ${byteSize}) {
+ dv.${p}(i, ${value}, false);
+ }
+ });
+ `;
+
+ let func = eval(str);
+ noInline(func);
+ setFuncs.push(func);
+}
+
+function test() {
+ const size = 16*1024;
+ let ab = new ArrayBuffer(size);
+ let dv = new DataView(ab);
+ for (let i = 0; i < 1000; ++i) {
+ for (let f of getFuncs)
+ f(dv, size);
+ for (let f of setFuncs)
+ f(dv, size);
+ }
+}
+test();
Added: releases/WebKitGTK/webkit-2.22/JSTests/microbenchmarks/data-view-accesses.js (0 => 235290)
--- releases/WebKitGTK/webkit-2.22/JSTests/microbenchmarks/data-view-accesses.js (rev 0)
+++ releases/WebKitGTK/webkit-2.22/JSTests/microbenchmarks/data-view-accesses.js 2018-08-24 08:07:53 UTC (rev 235290)
@@ -0,0 +1,75 @@
+"use strict";
+
+function assert(b, m = "") {
+ if (!b)
+ throw new Error("Bad: " + m);
+}
+
+let getOps = {
+ getUint8: 1,
+ getUint16: 2,
+ getUint32: 4,
+ getInt8: 1,
+ getInt16: 2,
+ getInt32: 4,
+ getFloat32: 4,
+ getFloat64: 8,
+};
+
+let setOps = {
+ setUint8: 1,
+ setUint16: 2,
+ setUint32: 4,
+ setInt8: 1,
+ setInt16: 2,
+ setInt32: 4,
+ setFloat32: 4,
+ setFloat64: 8,
+};
+
+let getFuncs = [];
+for (let p of Object.keys(getOps)) {
+ let endOfCall = getOps[p] === 1 ? ");" : ", true);";
+ let str = `
+ (function ${p}(dv, index) {
+ return dv.${p}(index${endOfCall}
+ })
+ `;
+
+ let func = eval(str);
+ noInline(func);
+ getFuncs.push(func);
+}
+
+let setFuncs = [];
+for (let p of Object.keys(setOps)) {
+ let endOfCall = setOps[p] === 1 ? ");" : ", true);";
+ let str = `
+ (function ${p}(dv, index, value) {
+ dv.${p}(index, value${endOfCall}
+ })
+ `;
+
+ let func = eval(str);
+ noInline(func);
+ setFuncs.push(func);
+}
+
+function test() {
+ const size = 16*1024;
+ let ab = new ArrayBuffer(size);
+ let dv = new DataView(ab);
+ for (let i = 0; i < 1000000; ++i) {
+ let index = (Math.random() * size) >>> 0;
+ index = Math.max(index - 8, 0);
+ for (let f of getFuncs) {
+ f(dv, index);
+ }
+
+ for (let f of setFuncs) {
+ f(dv, index, 10);
+ }
+ }
+
+}
+test();
Added: releases/WebKitGTK/webkit-2.22/JSTests/stress/dataview-jit-bounds-checks.js (0 => 235290)
--- releases/WebKitGTK/webkit-2.22/JSTests/stress/dataview-jit-bounds-checks.js (rev 0)
+++ releases/WebKitGTK/webkit-2.22/JSTests/stress/dataview-jit-bounds-checks.js 2018-08-24 08:07:53 UTC (rev 235290)
@@ -0,0 +1,114 @@
+"use strict";
+
+function assert(b, m = "") {
+ if (!b)
+ throw new Error("Bad: " + m);
+}
+
+let getOps = {
+ getUint8: 1,
+ getUint16: 2,
+ getUint32: 4,
+ getInt8: 1,
+ getInt16: 2,
+ getInt32: 4,
+ getFloat32: 4,
+ getFloat64: 8,
+};
+
+let setOps = {
+ setUint8: 1,
+ setUint16: 2,
+ setUint32: 4,
+ setInt8: 1,
+ setInt16: 2,
+ setInt32: 4,
+ setFloat32: 4,
+ setFloat64: 8,
+};
+
+let getFuncs = [];
+for (let p of Object.keys(getOps)) {
+ let endOfCall = getOps[p] === 1 ? ");" : ", true);";
+ let str = `
+ (function ${p}(dv, index) {
+ return dv.${p}(index${endOfCall}
+ })
+ `;
+
+ let func = eval(str);
+ noInline(func);
+ getFuncs.push(func);
+}
+
+let setFuncs = [];
+for (let p of Object.keys(setOps)) {
+ let endOfCall = setOps[p] === 1 ? ");" : ", true);";
+ let str = `
+ (function ${p}(dv, index, value) {
+ return dv.${p}(index, value${endOfCall}
+ })
+ `;
+
+ let func = eval(str);
+ noInline(func);
+ setFuncs.push(func);
+}
+
+function assertThrowsRangeError(f) {
+ let e = null;
+ try {
+ f();
+ } catch(err) {
+ e = err;
+ }
+ assert(e instanceof RangeError, e);
+}
+
+function test(warmup) {
+ const size = 16*1024;
+ let ab = new ArrayBuffer(size);
+ let dv = new DataView(ab);
+ for (let i = 0; i < warmup; ++i) {
+ for (let f of getFuncs) {
+ f(dv, 0);
+ }
+
+ for (let f of setFuncs) {
+ f(dv, 0, 10);
+ }
+ }
+
+ for (let f of getFuncs) {
+ assertThrowsRangeError(() => {
+ let index = size - getOps[f.name] + 1;
+ f(dv, index);
+ });
+ assertThrowsRangeError(() => {
+ let index = -1;
+ f(dv, index);
+ });
+ assertThrowsRangeError(() => {
+ let index = -2147483648;
+ f(dv, index);
+ });
+ }
+
+ for (let f of setFuncs) {
+ assertThrowsRangeError(() => {
+ let index = size - setOps[f.name] + 1;
+ f(dv, index, 10);
+ });
+ assertThrowsRangeError(() => {
+ let index = -1;
+ f(dv, index, 10);
+ });
+ assertThrowsRangeError(() => {
+ let index = -2147483648;
+ f(dv, index, 10);
+ });
+ }
+}
+
+test(2000);
+test(10000);
Added: releases/WebKitGTK/webkit-2.22/JSTests/stress/dataview-jit-get.js (0 => 235290)
--- releases/WebKitGTK/webkit-2.22/JSTests/stress/dataview-jit-get.js (rev 0)
+++ releases/WebKitGTK/webkit-2.22/JSTests/stress/dataview-jit-get.js 2018-08-24 08:07:53 UTC (rev 235290)
@@ -0,0 +1,305 @@
+"use strict";
+
+function assert(b) {
+ if (!b)
+ throw new Error("Bad!");
+}
+
+function test1() {
+ function bigEndian(o, i) {
+ return o.getInt32(i, false);
+ }
+ noInline(bigEndian);
+ function littleEndian(o, i) {
+ return o.getInt32(i, true);
+ }
+ noInline(littleEndian);
+ function biEndian(o, i, b) {
+ return o.getInt32(i, b);
+ }
+ noInline(biEndian);
+
+ let ab = new ArrayBuffer(4);
+ let ta = new Int32Array(ab);
+ ta[0] = 0x01020304;
+ let dv = new DataView(ab);
+
+ for (let i = 0; i < 10000; ++i) {
+ assert(bigEndian(dv, 0) === 0x04030201);
+ assert(littleEndian(dv, 0) === 0x01020304);
+ if (i % 2)
+ assert(biEndian(dv, 0, true) === 0x01020304);
+ else
+ assert(biEndian(dv, 0, false) === 0x04030201);
+ }
+
+ for (let i = 0; i < 10000; ++i) {
+ assert(bigEndian(dv, 0) === 0x04030201);
+ assert(littleEndian(dv, 0) === 0x01020304);
+ if (i % 2)
+ assert(biEndian(dv, 0, true) === 0x01020304);
+ else
+ assert(biEndian(dv, 0, false) === 0x04030201);
+ }
+
+ // Make sure we get the right sign.
+ ta[0] = -32361386; // 0xfe123456
+ for (let i = 0; i < 10000; ++i) {
+ assert(bigEndian(dv, 0) === 0x563412fe);
+ assert(littleEndian(dv, 0) === -32361386);
+ if (i % 2)
+ assert(biEndian(dv, 0, true) === -32361386);
+ else
+ assert(biEndian(dv, 0, false) === 0x563412fe);
+ }
+
+ // -2146290602 == (int)0x80123456
+ ta[0] = 0x56341280;
+ for (let i = 0; i < 10000; ++i) {
+ assert(bigEndian(dv, 0) === -2146290602);
+ assert(littleEndian(dv, 0) === 0x56341280);
+ if (i % 2)
+ assert(biEndian(dv, 0, true) === 0x56341280);
+ else
+ assert(biEndian(dv, 0, false) === -2146290602);
+ }
+}
+test1();
+
+function test2() {
+ function bigEndian(o, i) {
+ return o.getInt16(i, false);
+ }
+ noInline(bigEndian);
+ function littleEndian(o, i) {
+ return o.getInt16(i, true);
+ }
+ noInline(littleEndian);
+ function biEndian(o, i, b) {
+ return o.getInt16(i, b);
+ }
+ noInline(biEndian);
+
+ let ab = new ArrayBuffer(2);
+ let ta = new Int16Array(ab);
+ ta[0] = 0x0102;
+ let dv = new DataView(ab);
+
+ for (let i = 0; i < 10000; ++i) {
+ assert(bigEndian(dv, 0) === 0x0201);
+ assert(littleEndian(dv, 0) === 0x0102);
+ if (i % 2)
+ assert(biEndian(dv, 0, true) === 0x0102);
+ else
+ assert(biEndian(dv, 0, false) === 0x0201);
+ }
+
+ // Check sign.
+ ta[0] = -512; // 0xfe00
+ for (let i = 0; i < 10000; ++i) {
+ assert(bigEndian(dv, 0) === 0x00fe);
+ assert(littleEndian(dv, 0) === -512);
+ if (i % 2)
+ assert(biEndian(dv, 0, true) === -512);
+ else
+ assert(biEndian(dv, 0, false) === 0x00fe);
+ }
+
+ // Check sign extension.
+ ta[0] = 0x00fe;
+ for (let i = 0; i < 10000; ++i) {
+ assert(bigEndian(dv, 0) === -512);
+ assert(littleEndian(dv, 0) === 0x00fe);
+ if (i % 2)
+ assert(biEndian(dv, 0, true) === 0x00fe);
+ else
+ assert(biEndian(dv, 0, false) === -512);
+ }
+}
+test2();
+
+function test3() {
+ function bigEndian(o, i) {
+ return o.getFloat32(i, false);
+ }
+ noInline(bigEndian);
+ function littleEndian(o, i) {
+ return o.getFloat32(i, true);
+ }
+ noInline(littleEndian);
+ function biEndian(o, i, b) {
+ return o.getFloat32(i, b);
+ }
+ noInline(biEndian);
+
+ let ab = new ArrayBuffer(4);
+ let ta = new Float32Array(ab);
+ const normal = 12912.403; // 0x4649c19d
+ const normalAsDouble = 12912.403320312500;
+
+ const flipped = -5.1162437589918884e-21;
+ ta[0] = normal;
+
+ let dv = new DataView(ab);
+ for (let i = 0; i < 10000; ++i) {
+ assert(bigEndian(dv, 0) === flipped);
+ assert(littleEndian(dv, 0) === 12912.403320312500);
+ if (i % 2)
+ assert(biEndian(dv, 0, true) === normalAsDouble);
+ else
+ assert(biEndian(dv, 0, false) === flipped);
+ }
+}
+test3();
+
+function test4() {
+ function bigEndian(o, i) {
+ return o.getUint32(i, false);
+ }
+ noInline(bigEndian);
+ function littleEndian(o, i) {
+ return o.getUint32(i, true);
+ }
+ noInline(littleEndian);
+ function biEndian(o, i, b) {
+ return o.getUint32(i, b);
+ }
+ noInline(biEndian);
+
+ let ab = new ArrayBuffer(4);
+ let ta = new Uint32Array(ab);
+ ta[0] = 0xa0b0d0f0;
+
+ let dv = new DataView(ab);
+ for (let i = 0; i < 10000; ++i) {
+ assert(bigEndian(dv, 0) === 0xf0d0b0a0);
+ assert(littleEndian(dv, 0) === 0xa0b0d0f0);
+ if (i % 2)
+ assert(biEndian(dv, 0, true) === 0xa0b0d0f0);
+ else
+ assert(biEndian(dv, 0, false) === 0xf0d0b0a0);
+ }
+}
+test4();
+
+function test5() {
+ function bigEndian(o, i) {
+ return o.getUint16(i, false);
+ }
+ noInline(bigEndian);
+ function littleEndian(o, i) {
+ return o.getUint16(i, true);
+ }
+ noInline(littleEndian);
+ function biEndian(o, i, b) {
+ return o.getUint16(i, b);
+ }
+ noInline(biEndian);
+
+ let ab = new ArrayBuffer(4);
+ let ta = new Uint32Array(ab);
+ ta[0] = 0xa0b0d0f0;
+
+ let dv = new DataView(ab);
+ for (let i = 0; i < 10000; ++i) {
+ assert(littleEndian(dv, 0) == 0xd0f0);
+ assert(bigEndian(dv, 0) == 0xf0d0);
+
+ assert(littleEndian(dv, 1) == 0xb0d0);
+ assert(bigEndian(dv, 1) == 0xd0b0);
+
+ assert(littleEndian(dv, 2) == 0xa0b0);
+ assert(bigEndian(dv, 2) == 0xb0a0);
+
+ assert(biEndian(dv, 0, true) == 0xd0f0);
+ assert(biEndian(dv, 0, false) == 0xf0d0);
+
+ assert(biEndian(dv, 1, true) == 0xb0d0);
+ assert(biEndian(dv, 1, false) == 0xd0b0);
+
+ assert(biEndian(dv, 2, true) == 0xa0b0);
+ assert(biEndian(dv, 2, false) == 0xb0a0);
+ }
+}
+test5();
+
+function test6() {
+ function bigEndian(o, i) {
+ return o.getInt16(i, false);
+ }
+ noInline(bigEndian);
+ function littleEndian(o, i) {
+ return o.getInt16(i, true);
+ }
+ noInline(littleEndian);
+ function biEndian(o, i, b) {
+ return o.getInt16(i, b);
+ }
+ noInline(biEndian);
+
+ let ab = new ArrayBuffer(4);
+ let ta = new Uint32Array(ab);
+ ta[0] = 0xa070fa01;
+
+ let dv = new DataView(ab);
+ for (let i = 0; i < 10000; ++i) {
+ assert(littleEndian(dv, 0) == -1535);
+ assert(bigEndian(dv, 0) == 0x01fa);
+
+ assert(littleEndian(dv, 1) == 0x70fa);
+ assert(bigEndian(dv, 1) == -1424);
+
+ assert(littleEndian(dv, 2) == -24464);
+ assert(bigEndian(dv, 2) == 0x70a0);
+
+ assert(biEndian(dv, 0, true) == -1535);
+ assert(biEndian(dv, 0, false) == 0x01fa);
+
+ assert(biEndian(dv, 1, true) == 0x70fa);
+ assert(biEndian(dv, 1, false) == -1424);
+
+ assert(biEndian(dv, 2, true) == -24464);
+ assert(biEndian(dv, 2, false) == 0x70a0);
+ }
+}
+test6();
+
+function test7() {
+ function load(o, i) {
+ return o.getInt8(i);
+ }
+ noInline(load);
+
+ let ab = new ArrayBuffer(4);
+ let ta = new Uint32Array(ab);
+ ta[0] = 0xa070fa01;
+
+ let dv = new DataView(ab);
+ for (let i = 0; i < 10000; ++i) {
+ assert(load(dv, 0) === 0x01);
+ assert(load(dv, 1) === -6);
+ assert(load(dv, 2) === 0x70);
+ assert(load(dv, 3) === -96);
+ }
+}
+test7();
+
+function test8() {
+ function load(o, i) {
+ return o.getUint8(i);
+ }
+ noInline(load);
+
+ let ab = new ArrayBuffer(4);
+ let ta = new Uint32Array(ab);
+ ta[0] = 0xa070fa01;
+
+ let dv = new DataView(ab);
+ for (let i = 0; i < 10000; ++i) {
+ assert(load(dv, 0) === 0x01);
+ assert(load(dv, 1) === 0xfa);
+ assert(load(dv, 2) === 0x70);
+ assert(load(dv, 3) === 0xa0)
+ }
+}
+test8();
Added: releases/WebKitGTK/webkit-2.22/JSTests/stress/dataview-jit-neuter.js (0 => 235290)
--- releases/WebKitGTK/webkit-2.22/JSTests/stress/dataview-jit-neuter.js (rev 0)
+++ releases/WebKitGTK/webkit-2.22/JSTests/stress/dataview-jit-neuter.js 2018-08-24 08:07:53 UTC (rev 235290)
@@ -0,0 +1,59 @@
+"use strict";
+
+function assert(b) {
+ if (!b)
+ throw new Error("Bad!");
+}
+
+function test() {
+ function load(o, i) {
+ return o.getUint8(i);
+ }
+ noInline(load);
+
+ let ab = new ArrayBuffer(4);
+ let ta = new Uint32Array(ab);
+ ta[0] = 0xa070fa01;
+ let dv = new DataView(ab);
+
+ for (let i = 0; i < 1000; ++i) {
+ assert(load(dv, 0) === 0x01);
+ }
+
+ transferArrayBuffer(ab);
+ let e = null;
+ try {
+ load(dv, 0);
+ } catch(err) {
+ e = err;
+ }
+ assert(e instanceof RangeError);
+}
+test();
+
+
+function test2() {
+ function load(o, i) {
+ return o.getUint8(i);
+ }
+ noInline(load);
+
+ let ab = new ArrayBuffer(4);
+ let ta = new Uint32Array(ab);
+ ta[0] = 0xa070fa01;
+ let dv = new DataView(ab);
+
+ for (let i = 0; i < 10000; ++i) {
+ assert(load(dv, 0) === 0x01);
+ }
+
+ transferArrayBuffer(ab);
+ let e = null;
+ try {
+ load(dv, 0);
+ } catch(err) {
+ e = err;
+ }
+ assert(e instanceof RangeError);
+}
+test2();
Added: releases/WebKitGTK/webkit-2.22/JSTests/stress/dataview-jit-set.js (0 => 235290)
--- releases/WebKitGTK/webkit-2.22/JSTests/stress/dataview-jit-set.js (rev 0)
+++ releases/WebKitGTK/webkit-2.22/JSTests/stress/dataview-jit-set.js 2018-08-24 08:07:53 UTC (rev 235290)
@@ -0,0 +1,440 @@
+"use strict";
+
+function assert(b) {
+ if (!b)
+ throw new Error;
+}
+
+function readHex(dv, bytes) {
+ function isLittleEndian() {
+ let b = new ArrayBuffer(4);
+ let dv = new DataView(b);
+ dv.setInt32(0, 0x00112233, true);
+ return dv.getUint8(0) === 0x33;
+ }
+ let str = "";
+ function readByte(i) {
+ let b = dv.getUint8(i).toString(16);
+ if (b.length === 1)
+ b = "0" + b;
+ else
+ assert(b.length === 2)
+ return b;
+ }
+ if (isLittleEndian()) {
+ for (let i = bytes; i--;)
+ str = str + readByte(i);
+ } else {
+ for (let i = 0; i < bytes; ++i)
+ str = str + readByte(i);
+ }
+
+ return "0x" + str;
+}
+
+{
+ let b = new ArrayBuffer(4);
+ let dv = new DataView(b);
+ dv.setInt32(0, 0x00112233, true);
+ assert(readHex(dv, 4) === "0x00112233");
+}
+
+function test() {
+ function storeLittleEndian(dv, index, value) {
+ dv.setInt16(index, value, true);
+ }
+ noInline(storeLittleEndian);
+
+ function storeBigEndian(dv, index, value) {
+ dv.setInt16(index, value, false);
+ }
+ noInline(storeBigEndian);
+
+ function store(dv, index, value, littleEndian) {
+ dv.setInt16(index, value, littleEndian);
+ }
+ noInline(store);
+
+ let buffer = new ArrayBuffer(2);
+ let arr = new Uint16Array(buffer);
+ let dv = new DataView(buffer);
+
+ for (let i = 0; i < 10000; ++i) {
+ storeLittleEndian(dv, 0, 0xfaba);
+ assert(arr[0] === 0xfaba);
+
+ store(dv, 0, 0xabcd, true);
+ assert(arr[0] === 0xabcd);
+
+ store(dv, 0, 0xbadbeef, true);
+ assert(arr[0] === 0xbeef);
+
+ storeLittleEndian(dv, 0, 0xbb4db33f, true);
+ assert(arr[0] === 0xb33f);
+
+ storeBigEndian(dv, 0, 0xfada);
+ assert(arr[0] === 0xdafa);
+
+ storeBigEndian(dv, 0, 0x12ab);
+ assert(arr[0] === 0xab12);
+
+ store(dv, 0, 0x1234, false);
+ assert(arr[0] === 0x3412);
+
+ store(dv, 0, 0x0102, false);
+ assert(arr[0] === 0x0201);
+
+ store(dv, 0, -1, false);
+ assert(arr[0] === 0xffff);
+
+ store(dv, 0, -2, false);
+ assert(arr[0] === 0xfeff);
+
+ storeBigEndian(dv, 0, -1);
+ assert(arr[0] === 0xffff);
+
+ storeBigEndian(dv, 0, -2);
+ assert(arr[0] === 0xfeff);
+
+ storeBigEndian(dv, 0, -2147483648);
+ assert(arr[0] === 0x0000);
+
+ storeLittleEndian(dv, 0, -2147483648);
+ assert(arr[0] === 0x0000);
+
+ storeLittleEndian(dv, 0, -2147478988);
+ assert(arr[0] === 0x1234);
+
+ storeBigEndian(dv, 0, -2147478988);
+ assert(arr[0] === 0x3412);
+ }
+}
+test();
+
+function test2() {
+ function storeLittleEndian(dv, index, value) {
+ dv.setUint16(index, value, true);
+ }
+ noInline(storeLittleEndian);
+
+ function storeBigEndian(dv, index, value) {
+ dv.setUint16(index, value, false);
+ }
+ noInline(storeBigEndian);
+
+ function store(dv, index, value, littleEndian) {
+ dv.setUint16(index, value, littleEndian);
+ }
+ noInline(store);
+
+ let buffer = new ArrayBuffer(2);
+ let arr = new Uint16Array(buffer);
+ let dv = new DataView(buffer);
+
+ for (let i = 0; i < 10000; ++i) {
+ storeLittleEndian(dv, 0, 0xfaba);
+ assert(arr[0] === 0xfaba);
+
+ store(dv, 0, 0xabcd, true);
+ assert(arr[0] === 0xabcd);
+
+ store(dv, 0, 0xbadbeef, true);
+ assert(arr[0] === 0xbeef);
+
+ storeLittleEndian(dv, 0, 0xbb4db33f, true);
+ assert(arr[0] === 0xb33f);
+
+ storeBigEndian(dv, 0, 0xfada);
+ assert(arr[0] === 0xdafa);
+
+ storeBigEndian(dv, 0, 0x12ab);
+ assert(arr[0] === 0xab12);
+
+ store(dv, 0, 0x1234, false);
+ assert(arr[0] === 0x3412);
+
+ store(dv, 0, 0x0102, false);
+ assert(arr[0] === 0x0201);
+
+ store(dv, 0, -1, false);
+ assert(arr[0] === 0xffff);
+
+ store(dv, 0, -2, false);
+ assert(arr[0] === 0xfeff);
+
+ storeBigEndian(dv, 0, -1);
+ assert(arr[0] === 0xffff);
+
+ storeBigEndian(dv, 0, -2);
+ assert(arr[0] === 0xfeff);
+
+ storeBigEndian(dv, 0, -2147483648);
+ assert(arr[0] === 0x0000);
+
+ storeLittleEndian(dv, 0, -2147483648);
+ assert(arr[0] === 0x0000);
+
+ storeLittleEndian(dv, 0, -2147478988);
+ assert(arr[0] === 0x1234);
+
+ storeBigEndian(dv, 0, -2147478988);
+ assert(arr[0] === 0x3412);
+ }
+}
+test2();
+
+function test3() {
+ function storeLittleEndian(dv, index, value) {
+ dv.setUint32(index, value, true);
+ }
+ noInline(storeLittleEndian);
+
+ function storeBigEndian(dv, index, value) {
+ dv.setUint32(index, value, false);
+ }
+ noInline(storeBigEndian);
+
+ function store(dv, index, value, littleEndian) {
+ dv.setUint32(index, value, littleEndian);
+ }
+ noInline(store);
+
+ let buffer = new ArrayBuffer(4);
+ let arr = new Uint32Array(buffer);
+ let arr2 = new Int32Array(buffer);
+ let dv = new DataView(buffer);
+
+ for (let i = 0; i < 10000; ++i) {
+ storeLittleEndian(dv, 0, 0xffffffff);
+ assert(arr[0] === 0xffffffff);
+ assert(arr2[0] === -1);
+
+ storeLittleEndian(dv, 0, 0xffaabbcc);
+ assert(arr[0] === 0xffaabbcc);
+
+ storeBigEndian(dv, 0, 0x12345678);
+ assert(arr[0] === 0x78563412);
+
+ storeBigEndian(dv, 0, 0xffaabbcc);
+ assert(arr[0] === 0xccbbaaff);
+
+ store(dv, 0, 0xfaeadaca, false);
+ assert(arr[0] === 0xcadaeafa);
+
+ store(dv, 0, 0xcadaeafa, false);
+ assert(arr2[0] === -85271862);
+
+ store(dv, 0, 0x12345678, false);
+ assert(arr[0] === 0x78563412);
+
+ storeBigEndian(dv, 0, 0xbeeffeeb);
+ assert(arr2[0] === -335614018);
+ }
+}
+test3();
+
+function test4() {
+ function storeLittleEndian(dv, index, value) {
+ dv.setInt32(index, value, true);
+ }
+ noInline(storeLittleEndian);
+
+ function storeBigEndian(dv, index, value) {
+ dv.setInt32(index, value, false);
+ }
+ noInline(storeBigEndian);
+
+ function store(dv, index, value, littleEndian) {
+ dv.setInt32(index, value, littleEndian);
+ }
+ noInline(store);
+
+ let buffer = new ArrayBuffer(4);
+ let arr = new Uint32Array(buffer);
+ let arr2 = new Int32Array(buffer);
+ let dv = new DataView(buffer);
+
+ for (let i = 0; i < 10000; ++i) {
+ storeLittleEndian(dv, 0, 0xffffffff);
+ assert(arr[0] === 0xffffffff);
+ assert(arr2[0] === -1);
+
+ storeLittleEndian(dv, 0, 0xffaabbcc);
+ assert(arr[0] === 0xffaabbcc);
+
+ storeBigEndian(dv, 0, 0x12345678);
+ assert(arr[0] === 0x78563412);
+
+ storeBigEndian(dv, 0, 0xffaabbcc);
+ assert(arr[0] === 0xccbbaaff);
+
+ store(dv, 0, 0xfaeadaca, false);
+ assert(arr[0] === 0xcadaeafa);
+
+ store(dv, 0, 0xcadaeafa, false);
+ assert(arr2[0] === -85271862);
+
+ store(dv, 0, 0x12345678, false);
+ assert(arr[0] === 0x78563412);
+
+ storeBigEndian(dv, 0, 0xbeeffeeb);
+ assert(arr2[0] === -335614018);
+ }
+}
+test4();
+
+function test5() {
+ function storeLittleEndian(dv, index, value) {
+ dv.setFloat32(index, value, true);
+ }
+ noInline(storeLittleEndian);
+
+ function storeBigEndian(dv, index, value) {
+ dv.setFloat32(index, value, false);
+ }
+ noInline(storeBigEndian);
+
+ function store(dv, index, value, littleEndian) {
+ dv.setFloat32(index, value, littleEndian);
+ }
+ noInline(store);
+
+ let buffer = new ArrayBuffer(4);
+ let arr = new Float32Array(buffer);
+ let bits = new Uint32Array(buffer);
+ let dv = new DataView(buffer);
+
+ for (let i = 0; i < 10000; ++i) {
+ storeLittleEndian(dv, 0, 1.5);
+ assert(arr[0] === 1.5);
+
+ storeLittleEndian(dv, 0, 12912.124123215122);
+ assert(arr[0] === 12912.1240234375);
+ assert(bits[0] === 0x4649c07f);
+
+ storeLittleEndian(dv, 0, NaN);
+ assert(isNaN(arr[0]));
+ assert(bits[0] === 0x7FC00000);
+
+ storeLittleEndian(dv, 0, 2.3879393e-38);
+ assert(arr[0] === 2.387939260590663e-38);
+ assert(bits[0] === 0x01020304);
+
+ storeBigEndian(dv, 0, 2.3879393e-38);
+ assert(arr[0] === 1.539989614439558e-36);
+ assert(bits[0] === 0x04030201);
+ }
+}
+test5();
+
+function test6() {
+ function storeLittleEndian(dv, index, value) {
+ dv.setFloat64(index, value, true);
+ }
+ noInline(storeLittleEndian);
+
+ function storeBigEndian(dv, index, value) {
+ dv.setFloat64(index, value, false);
+ }
+ noInline(storeBigEndian);
+
+ function store(dv, index, value, littleEndian) {
+ dv.setFloat64(index, value, littleEndian);
+ }
+ noInline(store);
+
+ let buffer = new ArrayBuffer(8);
+ let arr = new Float64Array(buffer);
+ let dv = new DataView(buffer);
+
+ for (let i = 0; i < 10000; ++i) {
+ storeLittleEndian(dv, 0, NaN);
+ assert(isNaN(arr[0]));
+
+ storeLittleEndian(dv, 0, -2.5075187084135162e+284);
+ assert(arr[0] === -2.5075187084135162e+284);
+ assert(readHex(dv, 8) === "0xfafafafafafafafa");
+
+ store(dv, 0, 124.553, true);
+ assert(readHex(dv, 8) === "0x405f23645a1cac08");
+
+ store(dv, 0, Infinity, true);
+ assert(readHex(dv, 8) === "0x7ff0000000000000");
+
+ store(dv, 0, Infinity, false);
+ assert(readHex(dv, 8) === "0x000000000000f07f");
+
+ store(dv, 0, -Infinity, true);
+ assert(readHex(dv, 8) === "0xfff0000000000000");
+
+ storeBigEndian(dv, 0, -2.5075187084135162e+284);
+ assert(arr[0] === -2.5075187084135162e+284);
+ assert(readHex(dv, 8) === "0xfafafafafafafafa");
+
+ storeBigEndian(dv, 0, 124.553);
+ assert(readHex(dv, 8) === "0x08ac1c5a64235f40");
+ }
+}
+test6();
+
+function test7() {
+ function store(dv, index, value) {
+ dv.setInt8(index, value);
+ }
+ noInline(store);
+
+ let buffer = new ArrayBuffer(1);
+ let arr = new Uint8Array(buffer);
+ let arr2 = new Int8Array(buffer);
+ let dv = new DataView(buffer);
+
+ for (let i = 0; i < 10000; ++i) {
+ store(dv, 0, 0xff);
+ assert(arr[0] === 0xff);
+ assert(arr2[0] === -1);
+
+ store(dv, 0, 0xff00);
+ assert(arr[0] === 0);
+ assert(arr2[0] === 0);
+
+ store(dv, 0, -1);
+ assert(arr[0] === 0xff);
+ assert(arr2[0] === -1);
+
+ store(dv, 0, 0x0badbeef);
+ assert(arr[0] === 0xef);
+ assert(arr2[0] === -17);
+ }
+}
+test7();
+
+function test8() {
+ function store(dv, index, value) {
+ dv.setInt8(index, value);
+ }
+ noInline(store);
+
+ let buffer = new ArrayBuffer(1);
+ let arr = new Uint8Array(buffer);
+ let arr2 = new Int8Array(buffer);
+ let dv = new DataView(buffer);
+
+ for (let i = 0; i < 10000; ++i) {
+ store(dv, 0, 0xff);
+ assert(arr[0] === 0xff);
+ assert(arr2[0] === -1);
+
+ store(dv, 0, 0xff00);
+ assert(arr[0] === 0);
+ assert(arr2[0] === 0);
+
+ store(dv, 0, -1);
+ assert(arr[0] === 0xff);
+ assert(arr2[0] === -1);
+
+ store(dv, 0, 0x0badbeef);
+ assert(arr[0] === 0xef);
+ assert(arr2[0] === -17);
+ }
+}
+test8();
Added: releases/WebKitGTK/webkit-2.22/JSTests/stress/dataview-jit-unaligned-accesses.js (0 => 235290)
--- releases/WebKitGTK/webkit-2.22/JSTests/stress/dataview-jit-unaligned-accesses.js (rev 0)
+++ releases/WebKitGTK/webkit-2.22/JSTests/stress/dataview-jit-unaligned-accesses.js 2018-08-24 08:07:53 UTC (rev 235290)
@@ -0,0 +1,75 @@
+"use strict";
+
+function assert(b, m = "") {
+ if (!b)
+ throw new Error("Bad: " + m);
+}
+
+let getOps = {
+ getUint8: 1,
+ getUint16: 2,
+ getUint32: 4,
+ getInt8: 1,
+ getInt16: 2,
+ getInt32: 4,
+ getFloat32: 4,
+ getFloat64: 8,
+};
+
+let setOps = {
+ setUint8: 1,
+ setUint16: 2,
+ setUint32: 4,
+ setInt8: 1,
+ setInt16: 2,
+ setInt32: 4,
+ setFloat32: 4,
+ setFloat64: 8,
+};
+
+let getFuncs = [];
+for (let p of Object.keys(getOps)) {
+ let endOfCall = getOps[p] === 1 ? ");" : ", true);";
+ let str = `
+ (function ${p}(dv, index) {
+ return dv.${p}(index${endOfCall}
+ })
+ `;
+
+ let func = eval(str);
+ noInline(func);
+ getFuncs.push(func);
+}
+
+let setFuncs = [];
+for (let p of Object.keys(setOps)) {
+ let endOfCall = setOps[p] === 1 ? ");" : ", true);";
+ let str = `
+ (function ${p}(dv, index, value) {
+ dv.${p}(index, value${endOfCall}
+ })
+ `;
+
+ let func = eval(str);
+ noInline(func);
+ setFuncs.push(func);
+}
+
+function test() {
+ const size = 16*1024;
+ let ab = new ArrayBuffer(size);
+ let dv = new DataView(ab);
+ for (let i = 0; i < 100000; ++i) {
+ let index = (Math.random() * size) >>> 0;
+ index = Math.max(index - 8, 0);
+ for (let f of getFuncs) {
+ f(dv, index);
+ }
+
+ for (let f of setFuncs) {
+ f(dv, index, 10);
+ }
+ }
+
+}
+test();
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/ChangeLog (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/ChangeLog 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/ChangeLog 2018-08-24 08:07:53 UTC (rev 235290)
@@ -1,3 +1,103 @@
+2018-08-20 Saam barati <[email protected]>
+
+ Inline DataView accesses into DFG/FTL
+ https://bugs.webkit.org/show_bug.cgi?id=188573
+ <rdar://problem/43286746>
+
+ Reviewed by Michael Saboff.
+
+ This patch teaches the DFG/FTL to inline DataView accesses. The approach is
+ straight forward. We inline the various get*/set* operations as intrinsics.
+
+ This patch takes the most obvious approach for now. We OSR exit when:
+ - An isLittleEndian argument is provided, and is not a boolean.
+ - The index isn't an integer.
+ - The |this| isn't a DataView.
+ - We do an OOB access (or see a neutered array)
+
+ To implement this change in a performant way, this patch teaches the macro
+ assembler how to emit byte swap operations. The semantics of the added functions
+ are byteSwap + zero extend. This means for the 16bit byte swaps, we need
+ to actually emit zero extend instructions. For the 32/64bit byte swaps,
+ the instructions already have these semantics.
+
+ This patch is just a lightweight initial implementation. There are some easy
+ extensions we can do in future changes:
+ - Teach B3 how to byte swap: https://bugs.webkit.org/show_bug.cgi?id=188759
+ - CSE DataViewGet* nodes: https://bugs.webkit.org/show_bug.cgi?id=188768
+
+ * assembler/MacroAssemblerARM64.h:
+ (JSC::MacroAssemblerARM64::byteSwap16):
+ (JSC::MacroAssemblerARM64::byteSwap32):
+ (JSC::MacroAssemblerARM64::byteSwap64):
+ * assembler/MacroAssemblerX86Common.h:
+ (JSC::MacroAssemblerX86Common::byteSwap32):
+ (JSC::MacroAssemblerX86Common::byteSwap16):
+ (JSC::MacroAssemblerX86Common::byteSwap64):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::bswapl_r):
+ (JSC::X86Assembler::bswapq_r):
+ (JSC::X86Assembler::shiftInstruction16):
+ (JSC::X86Assembler::rolw_i8r):
+ (JSC::X86Assembler::X86InstructionFormatter::SingleInstructionBufferWriter::memoryModRM):
+ * assembler/testmasm.cpp:
+ (JSC::testByteSwap):
+ (JSC::run):
+ * bytecode/DataFormat.h:
+ * bytecode/SpeculatedType.cpp:
+ (JSC::dumpSpeculation):
+ (JSC::speculationFromClassInfo):
+ (JSC::speculationFromJSType):
+ (JSC::speculationFromString):
+ * bytecode/SpeculatedType.h:
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
+ * dfg/DFGClobberize.h:
+ (JSC::DFG::clobberize):
+ * dfg/DFGDoesGC.cpp:
+ (JSC::DFG::doesGC):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::hasHeapPrediction):
+ (JSC::DFG::Node::dataViewData):
+ * dfg/DFGNodeType.h:
+ * dfg/DFGPredictionPropagationPhase.cpp:
+ * dfg/DFGSafeToExecute.h:
+ (JSC::DFG::SafeToExecuteEdge::operator()):
+ (JSC::DFG::safeToExecute):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::speculateDataViewObject):
+ (JSC::DFG::SpeculativeJIT::speculate):
+ * dfg/DFGSpeculativeJIT.h:
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGUseKind.cpp:
+ (WTF::printInternal):
+ * dfg/DFGUseKind.h:
+ (JSC::DFG::typeFilterFor):
+ (JSC::DFG::isCell):
+ * ftl/FTLCapabilities.cpp:
+ (JSC::FTL::canCompile):
+ * ftl/FTLLowerDFGToB3.cpp:
+ (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+ (JSC::FTL::DFG::LowerDFGToB3::byteSwap32):
+ (JSC::FTL::DFG::LowerDFGToB3::byteSwap64):
+ (JSC::FTL::DFG::LowerDFGToB3::emitCodeBasedOnEndiannessBranch):
+ (JSC::FTL::DFG::LowerDFGToB3::compileDataViewGet):
+ (JSC::FTL::DFG::LowerDFGToB3::compileDataViewSet):
+ (JSC::FTL::DFG::LowerDFGToB3::lowDataViewObject):
+ (JSC::FTL::DFG::LowerDFGToB3::speculate):
+ (JSC::FTL::DFG::LowerDFGToB3::speculateDataViewObject):
+ * runtime/Intrinsic.cpp:
+ (JSC::intrinsicName):
+ * runtime/Intrinsic.h:
+ * runtime/JSDataViewPrototype.cpp:
+
2018-08-20 Yusuke Suzuki <[email protected]>
[YARR] Extend size of fixed characters bulk matching in 64bit platform
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/assembler/MacroAssemblerARM64.h (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/assembler/MacroAssemblerARM64.h 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/assembler/MacroAssemblerARM64.h 2018-08-24 08:07:53 UTC (rev 235290)
@@ -451,6 +451,22 @@
m_assembler.clz<64>(dest, dest);
}
+ void byteSwap16(RegisterID dst)
+ {
+ m_assembler.rev16<32>(dst, dst);
+ zeroExtend16To32(dst, dst);
+ }
+
+ void byteSwap32(RegisterID dst)
+ {
+ m_assembler.rev<32>(dst, dst);
+ }
+
+ void byteSwap64(RegisterID dst)
+ {
+ m_assembler.rev<64>(dst, dst);
+ }
+
// Only used for testing purposes.
void illegalInstruction()
{
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/assembler/MacroAssemblerX86Common.h 2018-08-24 08:07:53 UTC (rev 235290)
@@ -408,6 +408,24 @@
m_assembler.popcnt_rr(src, dst);
}
+ void byteSwap32(RegisterID dst)
+ {
+ m_assembler.bswapl_r(dst);
+ }
+
+ void byteSwap16(RegisterID dst)
+ {
+ m_assembler.rolw_i8r(8, dst);
+ zeroExtend16To32(dst, dst);
+ }
+
+#if CPU(X86_64)
+ void byteSwap64(RegisterID dst)
+ {
+ m_assembler.bswapq_r(dst);
+ }
+#endif
+
// Only used for testing purposes.
void illegalInstruction()
{
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/assembler/X86Assembler.h (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/assembler/X86Assembler.h 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/assembler/X86Assembler.h 2018-08-24 08:07:53 UTC (rev 235290)
@@ -339,6 +339,7 @@
OP2_XADDb = 0xC0,
OP2_XADD = 0xC1,
OP2_PEXTRW_GdUdIb = 0xC5,
+ OP2_BSWAP = 0xC8,
OP2_PSLLQ_UdqIb = 0x73,
OP2_PSRLQ_UdqIb = 0x73,
OP2_POR_VdqWdq = 0XEB,
@@ -1640,6 +1641,18 @@
}
#endif
+ void bswapl_r(RegisterID dst)
+ {
+ m_formatter.twoByteOp(OP2_BSWAP, dst);
+ }
+
+#if CPU(X86_64)
+ void bswapq_r(RegisterID dst)
+ {
+ m_formatter.twoByteOp64(OP2_BSWAP, dst);
+ }
+#endif
+
void tzcnt_rr(RegisterID src, RegisterID dst)
{
m_formatter.prefix(PRE_SSE_F3);
@@ -1703,6 +1716,18 @@
m_formatter.immediate8(imm);
}
}
+
+ template<GroupOpcodeID op>
+ void shiftInstruction16(int imm, RegisterID dst)
+ {
+ m_formatter.prefix(PRE_OPERAND_SIZE);
+ if (imm == 1)
+ m_formatter.oneByteOp(OP_GROUP2_Ev1, op, dst);
+ else {
+ m_formatter.oneByteOp(OP_GROUP2_EvIb, op, dst);
+ m_formatter.immediate8(imm);
+ }
+ }
public:
void sarl_i8r(int imm, RegisterID dst)
@@ -1755,6 +1780,11 @@
m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_ROL, dst);
}
+ void rolw_i8r(int imm, RegisterID dst)
+ {
+ shiftInstruction16<GROUP2_OP_ROL>(imm, dst);
+ }
+
#if CPU(X86_64)
private:
template<GroupOpcodeID op>
@@ -4334,6 +4364,14 @@
writer.putByteUnchecked(opcode);
}
+ void twoByteOp(TwoByteOpcodeID opcode, int reg)
+ {
+ SingleInstructionBufferWriter writer(m_buffer);
+ writer.emitRexIfNeeded(0, 0, reg);
+ writer.putByteUnchecked(OP_2BYTE_ESCAPE);
+ writer.putByteUnchecked(opcode + (reg & 7));
+ }
+
void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID rm)
{
SingleInstructionBufferWriter writer(m_buffer);
@@ -4507,6 +4545,14 @@
writer.memoryModRMAddr(reg, address);
}
+ void twoByteOp64(TwoByteOpcodeID opcode, int reg)
+ {
+ SingleInstructionBufferWriter writer(m_buffer);
+ writer.emitRexW(0, 0, reg);
+ writer.putByteUnchecked(OP_2BYTE_ESCAPE);
+ writer.putByteUnchecked(opcode + (reg & 7));
+ }
+
void twoByteOp64(TwoByteOpcodeID opcode, int reg, RegisterID rm)
{
SingleInstructionBufferWriter writer(m_buffer);
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/assembler/testmasm.cpp (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/assembler/testmasm.cpp 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/assembler/testmasm.cpp 2018-08-24 08:07:53 UTC (rev 235290)
@@ -863,6 +863,41 @@
}
#endif // ENABLE(MASM_PROBE)
+void testByteSwap()
+{
+#if CPU(X86_64) || CPU(ARM64)
+ auto byteSwap16 = compile([] (CCallHelpers& jit) {
+ jit.emitFunctionPrologue();
+ jit.move(GPRInfo::argumentGPR0, GPRInfo::returnValueGPR);
+ jit.byteSwap16(GPRInfo::returnValueGPR);
+ jit.emitFunctionEpilogue();
+ jit.ret();
+ });
+ CHECK_EQ(invoke<uint64_t>(byteSwap16, 0xaabbccddee001122), static_cast<uint64_t>(0x2211));
+ CHECK_EQ(invoke<uint64_t>(byteSwap16, 0xaabbccddee00ffaa), static_cast<uint64_t>(0xaaff));
+
+ auto byteSwap32 = compile([] (CCallHelpers& jit) {
+ jit.emitFunctionPrologue();
+ jit.move(GPRInfo::argumentGPR0, GPRInfo::returnValueGPR);
+ jit.byteSwap32(GPRInfo::returnValueGPR);
+ jit.emitFunctionEpilogue();
+ jit.ret();
+ });
+ CHECK_EQ(invoke<uint64_t>(byteSwap32, 0xaabbccddee001122), static_cast<uint64_t>(0x221100ee));
+ CHECK_EQ(invoke<uint64_t>(byteSwap32, 0xaabbccddee00ffaa), static_cast<uint64_t>(0xaaff00ee));
+
+ auto byteSwap64 = compile([] (CCallHelpers& jit) {
+ jit.emitFunctionPrologue();
+ jit.move(GPRInfo::argumentGPR0, GPRInfo::returnValueGPR);
+ jit.byteSwap64(GPRInfo::returnValueGPR);
+ jit.emitFunctionEpilogue();
+ jit.ret();
+ });
+ CHECK_EQ(invoke<uint64_t>(byteSwap64, 0xaabbccddee001122), static_cast<uint64_t>(0x221100eeddccbbaa));
+ CHECK_EQ(invoke<uint64_t>(byteSwap64, 0xaabbccddee00ffaa), static_cast<uint64_t>(0xaaff00eeddccbbaa));
+#endif
+}
+
#define RUN(test) do { \
if (!shouldRun(#test)) \
break; \
@@ -947,6 +982,8 @@
RUN(testProbeModifiesStackValues());
#endif // ENABLE(MASM_PROBE)
+ RUN(testByteSwap());
+
if (tasks.isEmpty())
usage();
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/bytecode/DataFormat.h (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/bytecode/DataFormat.h 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/bytecode/DataFormat.h 2018-08-24 08:07:53 UTC (rev 235290)
@@ -38,7 +38,7 @@
enum DataFormat {
DataFormatNone = 0,
DataFormatInt32 = 1,
- DataFormatInt52 = 2, // Int52's are left-shifted by 16 by default.
+ DataFormatInt52 = 2, // Int52's are left-shifted by 12 by default.
DataFormatStrictInt52 = 3, // "Strict" Int52 means it's not shifted.
DataFormatDouble = 4,
DataFormatBoolean = 5,
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/bytecode/SpeculatedType.cpp (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/bytecode/SpeculatedType.cpp 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/bytecode/SpeculatedType.cpp 2018-08-24 08:07:53 UTC (rev 235290)
@@ -203,6 +203,11 @@
strOut.print("DerivedArray");
else
isTop = false;
+
+ if (value & SpecDataViewObject)
+ strOut.print("DataView");
+ else
+ isTop = false;
}
if ((value & SpecString) == SpecString)
@@ -432,6 +437,9 @@
if (classInfo == ProxyObject::info())
return SpecProxyObject;
+
+ if (classInfo == JSDataView::info())
+ return SpecDataViewObject;
if (classInfo->isSubClassOf(JSFunction::info())) {
if (classInfo == JSBoundFunction::info())
@@ -559,6 +567,8 @@
return SpecWeakMapObject;
case JSWeakSetType:
return SpecWeakSetObject;
+ case DataViewType:
+ return SpecDataViewObject;
default:
ASSERT_NOT_REACHED();
}
@@ -750,6 +760,8 @@
return SpecProxyObject;
if (!strncmp(speculation, "SpecDerivedArray", strlen("SpecDerivedArray")))
return SpecDerivedArray;
+ if (!strncmp(speculation, "SpecDataViewObject", strlen("SpecDataViewObject")))
+ return SpecDataViewObject;
if (!strncmp(speculation, "SpecObjectOther", strlen("SpecObjectOther")))
return SpecObjectOther;
if (!strncmp(speculation, "SpecObject", strlen("SpecObject")))
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/bytecode/SpeculatedType.h (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/bytecode/SpeculatedType.h 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/bytecode/SpeculatedType.h 2018-08-24 08:07:53 UTC (rev 235290)
@@ -65,7 +65,6 @@
static const SpeculatedType SpecProxyObject = 1ull << 21; // It's definitely a Proxy object or one of its subclasses.
static const SpeculatedType SpecDerivedArray = 1ull << 22; // It's definitely a DerivedArray object.
static const SpeculatedType SpecObjectOther = 1ull << 23; // It's definitely an object but not JSFinalObject, JSArray, or JSFunction.
-static const SpeculatedType SpecObject = SpecFinalObject | SpecArray | SpecFunction | SpecTypedArrayView | SpecDirectArguments | SpecScopedArguments | SpecStringObject | SpecRegExpObject | SpecMapObject | SpecSetObject | SpecWeakMapObject | SpecWeakSetObject | SpecProxyObject | SpecDerivedArray | SpecObjectOther; // Bitmask used for testing for any kind of object prediction.
static const SpeculatedType SpecStringIdent = 1ull << 24; // It's definitely a JSString, and it's an identifier.
static const SpeculatedType SpecStringVar = 1ull << 25; // It's definitely a JSString, and it's not an identifier.
static const SpeculatedType SpecString = SpecStringIdent | SpecStringVar; // It's definitely a JSString.
@@ -93,7 +92,9 @@
static const SpeculatedType SpecMisc = SpecBoolean | SpecOther; // It's definitely either a boolean, Null, or Undefined.
static const SpeculatedType SpecEmpty = 1ull << 37; // It's definitely an empty value marker.
static const SpeculatedType SpecBigInt = 1ull << 38; // It's definitely a BigInt.
+static const SpeculatedType SpecDataViewObject = 1ull << 39; // It's definitely a JSDataView.
static const SpeculatedType SpecPrimitive = SpecString | SpecSymbol | SpecBytecodeNumber | SpecMisc | SpecBigInt; // It's any non-Object JSValue.
+static const SpeculatedType SpecObject = SpecFinalObject | SpecArray | SpecFunction | SpecTypedArrayView | SpecDirectArguments | SpecScopedArguments | SpecStringObject | SpecRegExpObject | SpecMapObject | SpecSetObject | SpecWeakMapObject | SpecWeakSetObject | SpecProxyObject | SpecDerivedArray | SpecObjectOther | SpecDataViewObject; // Bitmask used for testing for any kind of object prediction.
static const SpeculatedType SpecCell = SpecObject | SpecString | SpecSymbol | SpecCellOther | SpecBigInt; // It's definitely a JSCell.
static const SpeculatedType SpecHeapTop = SpecCell | SpecBytecodeNumber | SpecMisc; // It can be any of the above, except for SpecInt52Only and SpecDoubleImpureNaN.
static const SpeculatedType SpecBytecodeTop = SpecHeapTop | SpecEmpty; // It can be any of the above, except for SpecInt52Only and SpecDoubleImpureNaN. Corresponds to what could be found in a bytecode local.
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2018-08-24 08:07:53 UTC (rev 235290)
@@ -3770,9 +3770,30 @@
filter(node->child1(), SpecCell);
break;
}
-
+
+ case DataViewGetInt: {
+ DataViewData data = ""
+ if (data.byteSize < 4)
+ setNonCellTypeForNode(node, SpecInt32Only);
+ else {
+ ASSERT(data.byteSize == 4);
+ if (data.isSigned)
+ setNonCellTypeForNode(node, SpecInt32Only);
+ else
+ setNonCellTypeForNode(node, SpecAnyInt);
+ }
break;
+ }
+ case DataViewGetFloat: {
+ setNonCellTypeForNode(node, SpecFullDouble);
+ break;
+ }
+
+ case DataViewSet: {
+ break;
+ }
+
case Unreachable:
// It may be that during a previous run of AI we proved that something was unreachable, but
// during this run of AI we forget that it's unreachable. AI's proofs don't have to get
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2018-08-24 08:07:53 UTC (rev 235290)
@@ -3079,6 +3079,180 @@
return true;
}
+ case DataViewGetInt8:
+ case DataViewGetUint8:
+ case DataViewGetInt16:
+ case DataViewGetUint16:
+ case DataViewGetInt32:
+ case DataViewGetUint32:
+ case DataViewGetFloat32:
+ case DataViewGetFloat64: {
+ if (!is64Bit())
+ return false;
+
+ // To inline data view accesses, we assume the architecture we're running on:
+ // - Is little endian.
+ // - Allows unaligned loads/stores without crashing.
+
+ if (argumentCountIncludingThis < 2)
+ return false;
+ if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType))
+ return false;
+
+ insertChecks();
+
+ uint8_t byteSize;
+ NodeType op = DataViewGetInt;
+ bool isSigned = false;
+ switch (intrinsic) {
+ case DataViewGetInt8:
+ isSigned = true;
+ FALLTHROUGH;
+ case DataViewGetUint8:
+ byteSize = 1;
+ break;
+
+ case DataViewGetInt16:
+ isSigned = true;
+ FALLTHROUGH;
+ case DataViewGetUint16:
+ byteSize = 2;
+ break;
+
+ case DataViewGetInt32:
+ isSigned = true;
+ FALLTHROUGH;
+ case DataViewGetUint32:
+ byteSize = 4;
+ break;
+
+ case DataViewGetFloat32:
+ byteSize = 4;
+ op = DataViewGetFloat;
+ break;
+ case DataViewGetFloat64:
+ byteSize = 8;
+ op = DataViewGetFloat;
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+
+ TriState isLittleEndian = MixedTriState;
+ Node* littleEndianChild = nullptr;
+ if (byteSize > 1) {
+ if (argumentCountIncludingThis < 3)
+ isLittleEndian = FalseTriState;
+ else {
+ littleEndianChild = get(virtualRegisterForArgument(2, registerOffset));
+ if (littleEndianChild->hasConstant()) {
+ JSValue constant = littleEndianChild->constant()->value();
+ isLittleEndian = constant.pureToBoolean();
+ if (isLittleEndian != MixedTriState)
+ littleEndianChild = nullptr;
+ } else
+ isLittleEndian = MixedTriState;
+ }
+ }
+
+ DataViewData data { };
+ data.isLittleEndian = isLittleEndian;
+ data.isSigned = isSigned;
+ data.byteSize = byteSize;
+
+ set(VirtualRegister(resultOperand),
+ addToGraph(op, OpInfo(data.asQuadWord), OpInfo(prediction), get(virtualRegisterForArgument(0, registerOffset)), get(virtualRegisterForArgument(1, registerOffset)), littleEndianChild));
+ return true;
+ }
+
+ case DataViewSetInt8:
+ case DataViewSetUint8:
+ case DataViewSetInt16:
+ case DataViewSetUint16:
+ case DataViewSetInt32:
+ case DataViewSetUint32:
+ case DataViewSetFloat32:
+ case DataViewSetFloat64: {
+ if (!is64Bit())
+ return false;
+
+ if (argumentCountIncludingThis < 3)
+ return false;
+
+ if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType))
+ return false;
+
+ insertChecks();
+
+ uint8_t byteSize;
+ bool isFloatingPoint = false;
+ bool isSigned = false;
+ switch (intrinsic) {
+ case DataViewSetInt8:
+ isSigned = true;
+ FALLTHROUGH;
+ case DataViewSetUint8:
+ byteSize = 1;
+ break;
+
+ case DataViewSetInt16:
+ isSigned = true;
+ FALLTHROUGH;
+ case DataViewSetUint16:
+ byteSize = 2;
+ break;
+
+ case DataViewSetInt32:
+ isSigned = true;
+ FALLTHROUGH;
+ case DataViewSetUint32:
+ byteSize = 4;
+ break;
+
+ case DataViewSetFloat32:
+ isFloatingPoint = true;
+ byteSize = 4;
+ break;
+ case DataViewSetFloat64:
+ isFloatingPoint = true;
+ byteSize = 8;
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+
+ TriState isLittleEndian = MixedTriState;
+ Node* littleEndianChild = nullptr;
+ if (byteSize > 1) {
+ if (argumentCountIncludingThis < 4)
+ isLittleEndian = FalseTriState;
+ else {
+ littleEndianChild = get(virtualRegisterForArgument(3, registerOffset));
+ if (littleEndianChild->hasConstant()) {
+ JSValue constant = littleEndianChild->constant()->value();
+ isLittleEndian = constant.pureToBoolean();
+ if (isLittleEndian != MixedTriState)
+ littleEndianChild = nullptr;
+ } else
+ isLittleEndian = MixedTriState;
+ }
+ }
+
+ DataViewData data { };
+ data.isLittleEndian = isLittleEndian;
+ data.isSigned = isSigned;
+ data.byteSize = byteSize;
+ data.isFloatingPoint = isFloatingPoint;
+
+ addVarArgChild(get(virtualRegisterForArgument(0, registerOffset)));
+ addVarArgChild(get(virtualRegisterForArgument(1, registerOffset)));
+ addVarArgChild(get(virtualRegisterForArgument(2, registerOffset)));
+ addVarArgChild(littleEndianChild);
+
+ addToGraph(Node::VarArg, DataViewSet, OpInfo(data.asQuadWord), OpInfo());
+ return true;
+ }
+
case HasOwnPropertyIntrinsic: {
if (argumentCountIncludingThis != 2)
return false;
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGClobberize.h (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGClobberize.h 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGClobberize.h 2018-08-24 08:07:53 UTC (rev 235290)
@@ -1758,7 +1758,21 @@
case NumberToStringWithValidRadixConstant:
def(PureValue(node, node->validRadixConstant()));
return;
-
+
+ case DataViewGetFloat:
+ case DataViewGetInt: {
+ read(MiscFields);
+ read(TypedArrayProperties);
+ return;
+ }
+
+ case DataViewSet: {
+ read(MiscFields);
+ read(TypedArrayProperties);
+ write(TypedArrayProperties);
+ return;
+ }
+
case LastNodeType:
RELEASE_ASSERT_NOT_REACHED();
return;
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGDoesGC.cpp (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGDoesGC.cpp 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGDoesGC.cpp 2018-08-24 08:07:53 UTC (rev 235290)
@@ -318,6 +318,9 @@
case FilterGetByIdStatus:
case FilterPutByIdStatus:
case FilterInByIdStatus:
+ case DataViewGetInt:
+ case DataViewGetFloat:
+ case DataViewSet:
return false;
case PushWithScope:
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2018-08-24 08:07:53 UTC (rev 235290)
@@ -2104,6 +2104,60 @@
fixEdge<CellUse>(node->child1());
break;
+ case DataViewGetInt:
+ case DataViewGetFloat: {
+ fixEdge<DataViewObjectUse>(node->child1());
+ fixEdge<Int32Use>(node->child2());
+ if (node->child3())
+ fixEdge<BooleanUse>(node->child3());
+
+ if (node->op() == DataViewGetInt) {
+ DataViewData data = ""
+ switch (data.byteSize) {
+ case 1:
+ case 2:
+ node->setResult(NodeResultInt32);
+ break;
+ case 4:
+ if (data.isSigned)
+ node->setResult(NodeResultInt32);
+ else
+ node->setResult(NodeResultInt52);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ }
+ break;
+ }
+
+ case DataViewSet: {
+ fixEdge<DataViewObjectUse>(m_graph.varArgChild(node, 0));
+ fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
+ if (m_graph.varArgChild(node, 3))
+ fixEdge<BooleanUse>(m_graph.varArgChild(node, 3));
+
+ DataViewData data = ""
+ Edge& valueToStore = m_graph.varArgChild(node, 2);
+ if (data.isFloatingPoint)
+ fixEdge<DoubleRepUse>(valueToStore);
+ else {
+ switch (data.byteSize) {
+ case 1:
+ case 2:
+ fixEdge<Int32Use>(valueToStore);
+ break;
+ case 4:
+ if (data.isSigned)
+ fixEdge<Int32Use>(valueToStore);
+ else
+ fixEdge<Int52RepUse>(valueToStore);
+ break;
+ }
+ }
+ break;
+ }
+
#if !ASSERT_DISABLED
// Have these no-op cases here to ensure that nobody forgets to add handlers for new opcodes.
case SetArgument:
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGNode.h (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGNode.h 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGNode.h 2018-08-24 08:07:53 UTC (rev 235290)
@@ -117,6 +117,19 @@
static_assert(sizeof(IndexingType) <= sizeof(unsigned), "");
static_assert(sizeof(NewArrayBufferData) == sizeof(uint64_t), "");
+struct DataViewData {
+ union {
+ struct {
+ uint8_t byteSize;
+ bool isSigned;
+ bool isFloatingPoint; // Used for the DataViewSet node.
+ TriState isLittleEndian;
+ };
+ uint64_t asQuadWord;
+ };
+};
+static_assert(sizeof(DataViewData) == sizeof(uint64_t), "");
+
struct BranchTarget {
BranchTarget()
: block(0)
@@ -1659,6 +1672,8 @@
case GetDynamicVar:
case ExtractValueFromWeakMapGet:
case ToThis:
+ case DataViewGetInt:
+ case DataViewGetFloat:
return true;
default:
return false;
@@ -2143,6 +2158,12 @@
return m_opInfo.as<unsigned>();
}
+ DataViewData dataViewData()
+ {
+ ASSERT(op() == DataViewGetInt || op() == DataViewGetFloat || op() == DataViewSet);
+ return bitwise_cast<DataViewData>(m_opInfo.as<uint64_t>());
+ }
+
bool shouldGenerate()
{
return m_refCount;
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGNodeType.h (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGNodeType.h 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGNodeType.h 2018-08-24 08:07:53 UTC (rev 235290)
@@ -483,6 +483,10 @@
macro(FilterGetByIdStatus, NodeMustGenerate) \
macro(FilterInByIdStatus, NodeMustGenerate) \
macro(FilterPutByIdStatus, NodeMustGenerate) \
+ /* Data view access */ \
+ macro(DataViewGetInt, NodeMustGenerate | NodeResultJS) /* The gets are must generate for now because they do bounds checks */ \
+ macro(DataViewGetFloat, NodeMustGenerate | NodeResultDouble) \
+ macro(DataViewSet, NodeMustGenerate | NodeMustGenerate | NodeHasVarArgs) \
// This enum generates a monotonically increasing id for all Node types,
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGPredictionPropagationPhase.cpp 2018-08-24 08:07:53 UTC (rev 235290)
@@ -621,7 +621,14 @@
}
break;
}
-
+
+ case DataViewSet: {
+ DataViewData data = ""
+ if (data.isFloatingPoint)
+ m_graph.voteNode(m_graph.varArgChild(node, 2), VoteValue, weight);
+ break;
+ }
+
case MovHint:
// Ignore these since they have no effect on in-DFG execution.
break;
@@ -750,7 +757,9 @@
case CallDOMGetter:
case GetDynamicVar:
case GetPrototypeOf:
- case ExtractValueFromWeakMapGet: {
+ case ExtractValueFromWeakMapGet:
+ case DataViewGetInt:
+ case DataViewGetFloat: {
setPrediction(m_currentNode->getHeapPrediction());
break;
}
@@ -1220,6 +1229,7 @@
case FilterPutByIdStatus:
case FilterInByIdStatus:
case ClearCatchLocals:
+ case DataViewSet:
break;
// This gets ignored because it only pretends to produce a value.
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGSafeToExecute.h (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2018-08-24 08:07:53 UTC (rev 235290)
@@ -65,6 +65,7 @@
case SetObjectUse:
case WeakMapObjectUse:
case WeakSetObjectUse:
+ case DataViewObjectUse:
case ObjectOrOtherUse:
case StringIdentUse:
case StringUse:
@@ -462,6 +463,8 @@
case AtomicsIsLockFree:
case InitializeEntrypointArguments:
case MatchStructure:
+ case DataViewGetInt:
+ case DataViewGetFloat:
return true;
case ArraySlice:
@@ -602,6 +605,9 @@
return true;
}
+ case DataViewSet:
+ return false;
+
case SetAdd:
case MapSet:
return false;
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2018-08-24 08:07:53 UTC (rev 235290)
@@ -9903,6 +9903,20 @@
speculateWeakSetObject(edge, operand.gpr());
}
+void SpeculativeJIT::speculateDataViewObject(Edge edge, GPRReg cell)
+{
+ speculateCellType(edge, cell, SpecDataViewObject, DataViewType);
+}
+
+void SpeculativeJIT::speculateDataViewObject(Edge edge)
+{
+ if (!needsTypeCheck(edge, SpecDataViewObject))
+ return;
+
+ SpeculateCellOperand operand(this, edge);
+ speculateDataViewObject(edge, operand.gpr());
+}
+
void SpeculativeJIT::speculateObjectOrOther(Edge edge)
{
if (!needsTypeCheck(edge, SpecObject | SpecOther))
@@ -10271,6 +10285,9 @@
case WeakSetObjectUse:
speculateWeakSetObject(edge);
break;
+ case DataViewObjectUse:
+ speculateDataViewObject(edge);
+ break;
case ObjectOrOtherUse:
speculateObjectOrOther(edge);
break;
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2018-08-24 08:07:53 UTC (rev 235290)
@@ -1610,6 +1610,8 @@
void speculateWeakMapObject(Edge, GPRReg cell);
void speculateWeakSetObject(Edge);
void speculateWeakSetObject(Edge, GPRReg cell);
+ void speculateDataViewObject(Edge);
+ void speculateDataViewObject(Edge, GPRReg cell);
void speculateObjectOrOther(Edge);
void speculateString(Edge edge, GPRReg cell);
void speculateStringIdentAndLoadStorage(Edge edge, GPRReg string, GPRReg storage);
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2018-08-24 08:07:53 UTC (rev 235290)
@@ -4107,6 +4107,9 @@
case EntrySwitch:
case CPUIntrinsic:
case AssertNotEmpty:
+ case DataViewGetInt:
+ case DataViewGetFloat:
+ case DataViewSet:
DFG_CRASH(m_jit.graph(), node, "unexpected node in DFG backend");
break;
}
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2018-08-24 08:07:53 UTC (rev 235290)
@@ -4553,6 +4553,365 @@
compileClearCatchLocals(node);
break;
+ case DataViewGetFloat:
+ case DataViewGetInt: {
+ SpeculateCellOperand dataView(this, node->child1());
+ GPRReg dataViewGPR = dataView.gpr();
+ speculateDataViewObject(node->child1(), dataViewGPR);
+
+ SpeculateInt32Operand index(this, node->child2());
+ GPRReg indexGPR = index.gpr();
+
+ GPRTemporary temp1(this);
+ GPRReg t1 = temp1.gpr();
+ GPRTemporary temp2(this);
+ GPRReg t2 = temp2.gpr();
+
+ std::optional<SpeculateBooleanOperand> isLittleEndianOperand;
+ if (node->child3())
+ isLittleEndianOperand.emplace(this, node->child3());
+ GPRReg isLittleEndianGPR = isLittleEndianOperand ? isLittleEndianOperand->gpr() : InvalidGPRReg;
+
+ DataViewData data = ""
+
+ m_jit.zeroExtend32ToPtr(indexGPR, t2);
+ if (data.byteSize > 1)
+ m_jit.add64(TrustedImm32(data.byteSize - 1), t2);
+ m_jit.load32(MacroAssembler::Address(dataViewGPR, JSArrayBufferView::offsetOfLength()), t1);
+ speculationCheck(OutOfBounds, JSValueRegs(), node,
+ m_jit.branch64(MacroAssembler::AboveOrEqual, t2, t1));
+
+ m_jit.loadPtr(JITCompiler::Address(dataViewGPR, JSArrayBufferView::offsetOfVector()), t2);
+ cageTypedArrayStorage(t2);
+
+ m_jit.zeroExtend32ToPtr(indexGPR, t1);
+ auto baseIndex = JITCompiler::BaseIndex(t2, t1, MacroAssembler::TimesOne);
+
+ if (node->op() == DataViewGetInt) {
+ switch (data.byteSize) {
+ case 1:
+ if (data.isSigned)
+ m_jit.load8SignedExtendTo32(baseIndex, t2);
+ else
+ m_jit.load8(baseIndex, t2);
+ int32Result(t2, node);
+ break;
+ case 2: {
+ auto emitLittleEndianLoad = [&] {
+ if (data.isSigned)
+ m_jit.load16SignedExtendTo32(baseIndex, t2);
+ else
+ m_jit.load16(baseIndex, t2);
+ };
+ auto emitBigEndianLoad = [&] {
+ m_jit.load16(baseIndex, t2);
+ m_jit.byteSwap16(t2);
+ if (data.isSigned)
+ m_jit.signExtend16To32(t2, t2);
+ };
+
+ if (data.isLittleEndian == FalseTriState)
+ emitBigEndianLoad();
+ else if (data.isLittleEndian == TrueTriState)
+ emitLittleEndianLoad();
+ else {
+ RELEASE_ASSERT(isLittleEndianGPR != InvalidGPRReg);
+ auto isBigEndian = m_jit.branchTest32(MacroAssembler::Zero, isLittleEndianGPR, TrustedImm32(1));
+ emitLittleEndianLoad();
+ auto done = m_jit.jump();
+ isBigEndian.link(&m_jit);
+ emitBigEndianLoad();
+ done.link(&m_jit);
+ }
+ int32Result(t2, node);
+ break;
+ }
+ case 4: {
+ m_jit.load32(baseIndex, t2);
+
+ if (data.isLittleEndian == FalseTriState)
+ m_jit.byteSwap32(t2);
+ else if (data.isLittleEndian == MixedTriState) {
+ RELEASE_ASSERT(isLittleEndianGPR != InvalidGPRReg);
+ auto isLittleEndian = m_jit.branchTest32(MacroAssembler::NonZero, isLittleEndianGPR, TrustedImm32(1));
+ m_jit.byteSwap32(t2);
+ isLittleEndian.link(&m_jit);
+ }
+
+ if (data.isSigned)
+ int32Result(t2, node);
+ else
+ strictInt52Result(t2, node);
+ break;
+ }
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ } else {
+ FPRTemporary result(this);
+ FPRReg resultFPR = result.fpr();
+
+ switch (data.byteSize) {
+ case 4: {
+ auto emitLittleEndianCode = [&] {
+ m_jit.loadFloat(baseIndex, resultFPR);
+ m_jit.convertFloatToDouble(resultFPR, resultFPR);
+ };
+
+ auto emitBigEndianCode = [&] {
+ m_jit.load32(baseIndex, t2);
+ m_jit.byteSwap32(t2);
+ m_jit.move32ToFloat(t2, resultFPR);
+ m_jit.convertFloatToDouble(resultFPR, resultFPR);
+ };
+
+ if (data.isLittleEndian == TrueTriState)
+ emitLittleEndianCode();
+ else if (data.isLittleEndian == FalseTriState)
+ emitBigEndianCode();
+ else {
+ RELEASE_ASSERT(isLittleEndianGPR != InvalidGPRReg);
+ auto isBigEndian = m_jit.branchTest32(MacroAssembler::Zero, isLittleEndianGPR, TrustedImm32(1));
+ emitLittleEndianCode();
+ auto done = m_jit.jump();
+ isBigEndian.link(&m_jit);
+ emitBigEndianCode();
+ done.link(&m_jit);
+ }
+
+ break;
+ }
+ case 8: {
+ auto emitLittleEndianCode = [&] {
+ m_jit.loadDouble(baseIndex, resultFPR);
+ };
+
+ auto emitBigEndianCode = [&] {
+ m_jit.load64(baseIndex, t2);
+ m_jit.byteSwap64(t2);
+ m_jit.move64ToDouble(t2, resultFPR);
+ };
+
+ if (data.isLittleEndian == TrueTriState)
+ emitLittleEndianCode();
+ else if (data.isLittleEndian == FalseTriState)
+ emitBigEndianCode();
+ else {
+ RELEASE_ASSERT(isLittleEndianGPR != InvalidGPRReg);
+ auto isBigEndian = m_jit.branchTest32(MacroAssembler::Zero, isLittleEndianGPR, TrustedImm32(1));
+ emitLittleEndianCode();
+ auto done = m_jit.jump();
+ isBigEndian.link(&m_jit);
+ emitBigEndianCode();
+ done.link(&m_jit);
+ }
+
+ break;
+ }
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+
+ doubleResult(resultFPR, node);
+ }
+
+ break;
+ }
+
+ case DataViewSet: {
+ SpeculateCellOperand dataView(this, m_graph.varArgChild(node, 0));
+ GPRReg dataViewGPR = dataView.gpr();
+ speculateDataViewObject(m_graph.varArgChild(node, 0), dataViewGPR);
+
+ SpeculateInt32Operand index(this, m_graph.varArgChild(node, 1));
+ GPRReg indexGPR = index.gpr();
+
+ std::optional<SpeculateStrictInt52Operand> int52Value;
+ std::optional<SpeculateDoubleOperand> doubleValue;
+ std::optional<SpeculateInt32Operand> int32Value;
+ std::optional<FPRTemporary> fprTemporary;
+ GPRReg valueGPR = InvalidGPRReg;
+ FPRReg valueFPR = InvalidFPRReg;
+ FPRReg tempFPR = InvalidFPRReg;
+
+ DataViewData data = ""
+
+ Edge& valueEdge = m_graph.varArgChild(node, 2);
+ switch (valueEdge.useKind()) {
+ case Int32Use:
+ int32Value.emplace(this, valueEdge);
+ valueGPR = int32Value->gpr();
+ break;
+ case DoubleRepUse:
+ doubleValue.emplace(this, valueEdge);
+ valueFPR = doubleValue->fpr();
+ if (data.byteSize == 4) {
+ fprTemporary.emplace(this);
+ tempFPR = fprTemporary->fpr();
+ }
+ break;
+ case Int52RepUse:
+ int52Value.emplace(this, valueEdge);
+ valueGPR = int52Value->gpr();
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+
+ GPRTemporary temp1(this);
+ GPRReg t1 = temp1.gpr();
+ GPRTemporary temp2(this);
+ GPRReg t2 = temp2.gpr();
+ GPRTemporary temp3(this);
+ GPRReg t3 = temp3.gpr();
+
+ std::optional<SpeculateBooleanOperand> isLittleEndianOperand;
+ if (m_graph.varArgChild(node, 3))
+ isLittleEndianOperand.emplace(this, m_graph.varArgChild(node, 3));
+ GPRReg isLittleEndianGPR = isLittleEndianOperand ? isLittleEndianOperand->gpr() : InvalidGPRReg;
+
+ m_jit.zeroExtend32ToPtr(indexGPR, t2);
+ if (data.byteSize > 1)
+ m_jit.add64(TrustedImm32(data.byteSize - 1), t2);
+ m_jit.load32(MacroAssembler::Address(dataViewGPR, JSArrayBufferView::offsetOfLength()), t1);
+ speculationCheck(OutOfBounds, JSValueRegs(), node,
+ m_jit.branch64(MacroAssembler::AboveOrEqual, t2, t1));
+
+ m_jit.loadPtr(JITCompiler::Address(dataViewGPR, JSArrayBufferView::offsetOfVector()), t2);
+ cageTypedArrayStorage(t2);
+
+ m_jit.zeroExtend32ToPtr(indexGPR, t1);
+ auto baseIndex = JITCompiler::BaseIndex(t2, t1, MacroAssembler::TimesOne);
+
+ if (data.isFloatingPoint) {
+ RELEASE_ASSERT(valueFPR != InvalidFPRReg);
+ if (data.byteSize == 4) {
+ RELEASE_ASSERT(tempFPR != InvalidFPRReg);
+ m_jit.convertDoubleToFloat(valueFPR, tempFPR);
+
+ auto emitLittleEndianCode = [&] {
+ m_jit.storeFloat(tempFPR, baseIndex);
+ };
+
+ auto emitBigEndianCode = [&] {
+ m_jit.moveFloatTo32(tempFPR, t3);
+ m_jit.byteSwap32(t3);
+ m_jit.store32(t3, baseIndex);
+ };
+
+ if (data.isLittleEndian == FalseTriState)
+ emitBigEndianCode();
+ else if (data.isLittleEndian == TrueTriState)
+ emitLittleEndianCode();
+ else {
+ RELEASE_ASSERT(isLittleEndianGPR != InvalidGPRReg);
+ auto isBigEndian = m_jit.branchTest32(MacroAssembler::Zero, isLittleEndianGPR, TrustedImm32(1));
+ emitLittleEndianCode();
+ auto done = m_jit.jump();
+ isBigEndian.link(&m_jit);
+ emitBigEndianCode();
+ done.link(&m_jit);
+ }
+ } else {
+ RELEASE_ASSERT(data.byteSize == 8);
+ RELEASE_ASSERT(valueFPR != InvalidFPRReg);
+
+ auto emitLittleEndianCode = [&] {
+ m_jit.storeDouble(valueFPR, baseIndex);
+ };
+ auto emitBigEndianCode = [&] {
+ m_jit.moveDoubleTo64(valueFPR, t3);
+ m_jit.byteSwap64(t3);
+ m_jit.store64(t3, baseIndex);
+ };
+
+ if (data.isLittleEndian == FalseTriState)
+ emitBigEndianCode();
+ else if (data.isLittleEndian == TrueTriState)
+ emitLittleEndianCode();
+ else {
+ RELEASE_ASSERT(isLittleEndianGPR != InvalidGPRReg);
+ auto isBigEndian = m_jit.branchTest32(MacroAssembler::Zero, isLittleEndianGPR, TrustedImm32(1));
+ emitLittleEndianCode();
+ auto done = m_jit.jump();
+ isBigEndian.link(&m_jit);
+ emitBigEndianCode();
+ done.link(&m_jit);
+ }
+ }
+ } else {
+ switch (data.byteSize) {
+ case 1:
+ RELEASE_ASSERT(valueEdge.useKind() == Int32Use);
+ RELEASE_ASSERT(valueGPR != InvalidGPRReg);
+ m_jit.store8(valueGPR, baseIndex);
+ break;
+ case 2: {
+ RELEASE_ASSERT(valueEdge.useKind() == Int32Use);
+ RELEASE_ASSERT(valueGPR != InvalidGPRReg);
+
+ auto emitLittleEndianCode = [&] {
+ m_jit.store16(valueGPR, baseIndex);
+ };
+ auto emitBigEndianCode = [&] {
+ m_jit.move(valueGPR, t3);
+ m_jit.byteSwap16(t3);
+ m_jit.store16(t3, baseIndex);
+ };
+
+ if (data.isLittleEndian == FalseTriState)
+ emitBigEndianCode();
+ else if (data.isLittleEndian == TrueTriState)
+ emitLittleEndianCode();
+ else {
+ RELEASE_ASSERT(isLittleEndianGPR != InvalidGPRReg);
+ auto isBigEndian = m_jit.branchTest32(MacroAssembler::Zero, isLittleEndianGPR, TrustedImm32(1));
+ emitLittleEndianCode();
+ auto done = m_jit.jump();
+ isBigEndian.link(&m_jit);
+ emitBigEndianCode();
+ done.link(&m_jit);
+ }
+ break;
+ }
+ case 4: {
+ RELEASE_ASSERT(valueEdge.useKind() == Int32Use || valueEdge.useKind() == Int52RepUse);
+
+ auto emitLittleEndianCode = [&] {
+ m_jit.store32(valueGPR, baseIndex);
+ };
+
+ auto emitBigEndianCode = [&] {
+ m_jit.zeroExtend32ToPtr(valueGPR, t3);
+ m_jit.byteSwap32(t3);
+ m_jit.store32(t3, baseIndex);
+ };
+
+ if (data.isLittleEndian == FalseTriState)
+ emitBigEndianCode();
+ else if (data.isLittleEndian == TrueTriState)
+ emitLittleEndianCode();
+ else {
+ RELEASE_ASSERT(isLittleEndianGPR != InvalidGPRReg);
+ auto isBigEndian = m_jit.branchTest32(MacroAssembler::Zero, isLittleEndianGPR, TrustedImm32(1));
+ emitLittleEndianCode();
+ auto done = m_jit.jump();
+ isBigEndian.link(&m_jit);
+ emitBigEndianCode();
+ done.link(&m_jit);
+ }
+
+ break;
+ }
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ }
+
+ noResult(node);
+ break;
+ }
+
#if ENABLE(FTL_JIT)
case CheckTierUpInLoop: {
MacroAssembler::Jump callTierUp = m_jit.branchAdd32(
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGUseKind.cpp (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGUseKind.cpp 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGUseKind.cpp 2018-08-24 08:07:53 UTC (rev 235290)
@@ -104,17 +104,20 @@
out.print("DerivedArray");
return;
case MapObjectUse:
- out.print("MapObjectUse");
+ out.print("MapObject");
return;
case SetObjectUse:
- out.print("SetObjectUse");
+ out.print("SetObject");
return;
case WeakMapObjectUse:
- out.print("WeakMapObjectUse");
+ out.print("WeakMapObject");
return;
case WeakSetObjectUse:
- out.print("WeakSetObjectUse");
+ out.print("WeakSetObject");
return;
+ case DataViewObjectUse:
+ out.print("DataViewObject");
+ return;
case ObjectOrOtherUse:
out.print("ObjectOrOther");
return;
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGUseKind.h (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGUseKind.h 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/dfg/DFGUseKind.h 2018-08-24 08:07:53 UTC (rev 235290)
@@ -70,6 +70,7 @@
SetObjectUse,
WeakMapObjectUse,
WeakSetObjectUse,
+ DataViewObjectUse,
StringObjectUse,
StringOrStringObjectUse,
NotStringVarUse,
@@ -160,6 +161,8 @@
return SpecWeakMapObject;
case WeakSetObjectUse:
return SpecWeakSetObject;
+ case DataViewObjectUse:
+ return SpecDataViewObject;
case StringObjectUse:
return SpecStringObject;
case StringOrStringObjectUse:
@@ -259,6 +262,7 @@
case SetObjectUse:
case WeakMapObjectUse:
case WeakSetObjectUse:
+ case DataViewObjectUse:
return true;
default:
return false;
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/ftl/FTLCapabilities.cpp (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2018-08-24 08:07:53 UTC (rev 235290)
@@ -359,6 +359,9 @@
case FilterPutByIdStatus:
case FilterInByIdStatus:
case CreateThis:
+ case DataViewGetInt:
+ case DataViewGetFloat:
+ case DataViewSet:
// These are OK.
break;
@@ -445,6 +448,7 @@
case SetObjectUse:
case WeakMapObjectUse:
case WeakSetObjectUse:
+ case DataViewObjectUse:
case FinalObjectUse:
case RegExpObjectUse:
case ProxyObjectUse:
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2018-08-24 08:07:53 UTC (rev 235290)
@@ -1307,6 +1307,13 @@
case FilterInByIdStatus:
compileFilterICStatus();
break;
+ case DataViewGetInt:
+ case DataViewGetFloat:
+ compileDataViewGet();
+ break;
+ case DataViewSet:
+ compileDataViewSet();
+ break;
case PhantomLocal:
case LoopHint:
@@ -12238,6 +12245,357 @@
{
m_interpreter.filterICStatus(m_node);
}
+
+ LValue byteSwap32(LValue value)
+ {
+ // FIXME: teach B3 byteswap
+ // https://bugs.webkit.org/show_bug.cgi?id=188759
+
+ RELEASE_ASSERT(value->type() == Int32);
+ PatchpointValue* patchpoint = m_out.patchpoint(Int32);
+ patchpoint->appendSomeRegister(value);
+ patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+ jit.move(params[1].gpr(), params[0].gpr());
+ jit.byteSwap32(params[0].gpr());
+ });
+ patchpoint->effects = Effects::none();
+ return patchpoint;
+ }
+
+ LValue byteSwap64(LValue value)
+ {
+ // FIXME: teach B3 byteswap
+ // https://bugs.webkit.org/show_bug.cgi?id=188759
+
+ RELEASE_ASSERT(value->type() == Int64);
+ PatchpointValue* patchpoint = m_out.patchpoint(Int64);
+ patchpoint->appendSomeRegister(value);
+ patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+ jit.move(params[1].gpr(), params[0].gpr());
+ jit.byteSwap64(params[0].gpr());
+ });
+ patchpoint->effects = Effects::none();
+ return patchpoint;
+ }
+
+ template <typename F1, typename F2>
+ LValue emitCodeBasedOnEndiannessBranch(LValue isLittleEndian, const F1& emitLittleEndianCode, const F2& emitBigEndianCode)
+ {
+ LType type;
+
+ LBasicBlock bigEndianCase = m_out.newBlock();
+ LBasicBlock littleEndianCase = m_out.newBlock();
+ LBasicBlock continuation = m_out.newBlock();
+
+ m_out.branch(m_out.testIsZero32(isLittleEndian, m_out.constInt32(1)),
+ unsure(bigEndianCase), unsure(littleEndianCase));
+
+ LBasicBlock lastNext = m_out.appendTo(bigEndianCase, littleEndianCase);
+ LValue bigEndianValue = emitBigEndianCode();
+ type = bigEndianValue ? bigEndianValue->type() : Void;
+ ValueFromBlock bigEndianResult = bigEndianValue ? m_out.anchor(bigEndianValue) : ValueFromBlock();
+ m_out.jump(continuation);
+
+ m_out.appendTo(littleEndianCase, continuation);
+ LValue littleEndianValue = emitLittleEndianCode();
+ ValueFromBlock littleEndianResult = littleEndianValue ? m_out.anchor(littleEndianValue) : ValueFromBlock();
+ RELEASE_ASSERT((!littleEndianValue && !bigEndianValue) || type == littleEndianValue->type());
+ m_out.jump(continuation);
+
+ m_out.appendTo(continuation, lastNext);
+ RELEASE_ASSERT(!!bigEndianResult == !!littleEndianResult);
+ if (bigEndianResult)
+ return m_out.phi(type, bigEndianResult, littleEndianResult);
+ return nullptr;
+ }
+
+ void compileDataViewGet()
+ {
+ LValue dataView = lowDataViewObject(m_node->child1());
+ LValue index = lowInt32(m_node->child2());
+ LValue isLittleEndian = nullptr;
+ if (m_node->child3())
+ isLittleEndian = lowBoolean(m_node->child3());
+
+ DataViewData data = ""
+
+ LValue length = m_out.zeroExtPtr(m_out.load32NonNegative(dataView, m_heaps.JSArrayBufferView_length));
+ LValue indexToCheck = m_out.zeroExtPtr(index);
+ if (data.byteSize > 1)
+ indexToCheck = m_out.add(indexToCheck, m_out.constInt64(data.byteSize - 1));
+ speculate(OutOfBounds, noValue(), nullptr, m_out.aboveOrEqual(indexToCheck, length));
+
+ LValue vector = caged(Gigacage::Primitive, m_out.loadPtr(dataView, m_heaps.JSArrayBufferView_vector));
+
+ TypedPointer pointer(m_heaps.typedArrayProperties, m_out.add(vector, m_out.zeroExtPtr(index)));
+
+ if (m_node->op() == DataViewGetInt) {
+ switch (data.byteSize) {
+ case 1:
+ if (data.isSigned)
+ setInt32(m_out.load8SignExt32(pointer));
+ else
+ setInt32(m_out.load8ZeroExt32(pointer));
+ break;
+ case 2: {
+ auto emitLittleEndianLoad = [&] {
+ if (data.isSigned)
+ return m_out.load16SignExt32(pointer);
+ return m_out.load16ZeroExt32(pointer);
+ };
+
+ auto emitBigEndianLoad = [&] {
+ LValue val = m_out.load16ZeroExt32(pointer);
+
+ PatchpointValue* patchpoint = m_out.patchpoint(Int32);
+ patchpoint->appendSomeRegister(val);
+ patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+ jit.move(params[1].gpr(), params[0].gpr());
+ jit.byteSwap16(params[0].gpr());
+ if (data.isSigned)
+ jit.signExtend16To32(params[0].gpr(), params[0].gpr());
+ });
+ patchpoint->effects = Effects::none();
+
+ return patchpoint;
+ };
+
+ if (data.isLittleEndian == FalseTriState)
+ setInt32(emitBigEndianLoad());
+ else if (data.isLittleEndian == TrueTriState)
+ setInt32(emitLittleEndianLoad());
+ else
+ setInt32(emitCodeBasedOnEndiannessBranch(isLittleEndian, emitLittleEndianLoad, emitBigEndianLoad));
+
+ break;
+ }
+ case 4: {
+ LValue loadedValue = m_out.load32(pointer);
+
+ if (data.isLittleEndian == FalseTriState)
+ loadedValue = byteSwap32(loadedValue);
+ else if (data.isLittleEndian == MixedTriState) {
+ auto emitLittleEndianCode = [&] {
+ return loadedValue;
+ };
+ auto emitBigEndianCode = [&] {
+ return byteSwap32(loadedValue);
+ };
+
+ loadedValue = emitCodeBasedOnEndiannessBranch(isLittleEndian, emitLittleEndianCode, emitBigEndianCode);
+ }
+
+ if (data.isSigned)
+ setInt32(loadedValue);
+ else
+ setStrictInt52(m_out.zeroExt(loadedValue, Int64));
+
+ break;
+ }
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ } else {
+ switch (data.byteSize) {
+ case 4: {
+ auto emitLittleEndianCode = [&] {
+ return m_out.floatToDouble(m_out.loadFloat(pointer));
+ };
+
+ auto emitBigEndianCode = [&] {
+ LValue loadedValue = m_out.load32(pointer);
+ PatchpointValue* patchpoint = m_out.patchpoint(Double);
+ patchpoint->appendSomeRegister(loadedValue);
+ patchpoint->numGPScratchRegisters = 1;
+ patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+ jit.move(params[1].gpr(), params.gpScratch(0));
+ jit.byteSwap32(params.gpScratch(0));
+ jit.move32ToFloat(params.gpScratch(0), params[0].fpr());
+ jit.convertFloatToDouble(params[0].fpr(), params[0].fpr());
+ });
+ patchpoint->effects = Effects::none();
+ return patchpoint;
+ };
+
+ if (data.isLittleEndian == TrueTriState)
+ setDouble(emitLittleEndianCode());
+ else if (data.isLittleEndian == FalseTriState)
+ setDouble(emitBigEndianCode());
+ else
+ setDouble(emitCodeBasedOnEndiannessBranch(isLittleEndian, emitLittleEndianCode, emitBigEndianCode));
+
+ break;
+ }
+ case 8: {
+ auto emitLittleEndianCode = [&] {
+ return m_out.loadDouble(pointer);
+ };
+
+ auto emitBigEndianCode = [&] {
+ LValue loadedValue = m_out.load64(pointer);
+ loadedValue = byteSwap64(loadedValue);
+ return m_out.bitCast(loadedValue, Double);
+ };
+
+ if (data.isLittleEndian == TrueTriState)
+ setDouble(emitLittleEndianCode());
+ else if (data.isLittleEndian == FalseTriState)
+ setDouble(emitBigEndianCode());
+ else
+ setDouble(emitCodeBasedOnEndiannessBranch(isLittleEndian, emitLittleEndianCode, emitBigEndianCode));
+
+ break;
+ }
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ }
+ }
+
+ void compileDataViewSet()
+ {
+ LValue dataView = lowDataViewObject(m_graph.varArgChild(m_node, 0));
+ LValue index = lowInt32(m_graph.varArgChild(m_node, 1));
+ LValue isLittleEndian = nullptr;
+ if (m_graph.varArgChild(m_node, 3))
+ isLittleEndian = lowBoolean(m_graph.varArgChild(m_node, 3));
+
+ DataViewData data = ""
+
+ LValue length = m_out.zeroExtPtr(m_out.load32NonNegative(dataView, m_heaps.JSArrayBufferView_length));
+ LValue indexToCheck = m_out.zeroExtPtr(index);
+ if (data.byteSize > 1)
+ indexToCheck = m_out.add(indexToCheck, m_out.constInt64(data.byteSize - 1));
+ speculate(OutOfBounds, noValue(), nullptr, m_out.aboveOrEqual(indexToCheck, length));
+
+ Edge& valueEdge = m_graph.varArgChild(m_node, 2);
+ LValue valueToStore;
+ switch (valueEdge.useKind()) {
+ case Int32Use:
+ valueToStore = lowInt32(valueEdge);
+ break;
+ case DoubleRepUse:
+ valueToStore = lowDouble(valueEdge);
+ break;
+ case Int52RepUse:
+ valueToStore = lowStrictInt52(valueEdge);
+ break;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+
+ LValue vector = caged(Gigacage::Primitive, m_out.loadPtr(dataView, m_heaps.JSArrayBufferView_vector));
+ TypedPointer pointer(m_heaps.typedArrayProperties, m_out.add(vector, m_out.zeroExtPtr(index)));
+
+ if (data.isFloatingPoint) {
+ if (data.byteSize == 4) {
+ valueToStore = m_out.doubleToFloat(valueToStore);
+
+ auto emitLittleEndianCode = [&] () -> LValue {
+ m_out.storeFloat(valueToStore, pointer);
+ return nullptr;
+ };
+
+ auto emitBigEndianCode = [&] () -> LValue {
+ PatchpointValue* patchpoint = m_out.patchpoint(Int32);
+ patchpoint->appendSomeRegister(valueToStore);
+ patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+ jit.moveFloatTo32(params[1].fpr(), params[0].gpr());
+ jit.byteSwap32(params[0].gpr());
+ });
+ patchpoint->effects = Effects::none();
+ m_out.store32(patchpoint, pointer);
+ return nullptr;
+ };
+
+ if (data.isLittleEndian == FalseTriState)
+ emitBigEndianCode();
+ else if (data.isLittleEndian == TrueTriState)
+ emitLittleEndianCode();
+ else
+ emitCodeBasedOnEndiannessBranch(isLittleEndian, emitLittleEndianCode, emitBigEndianCode);
+
+ } else {
+ RELEASE_ASSERT(data.byteSize == 8);
+ auto emitLittleEndianCode = [&] () -> LValue {
+ m_out.storeDouble(valueToStore, pointer);
+ return nullptr;
+ };
+ auto emitBigEndianCode = [&] () -> LValue {
+ m_out.store64(byteSwap64(m_out.bitCast(valueToStore, Int64)), pointer);
+ return nullptr;
+ };
+
+ if (data.isLittleEndian == FalseTriState)
+ emitBigEndianCode();
+ else if (data.isLittleEndian == TrueTriState)
+ emitLittleEndianCode();
+ else
+ emitCodeBasedOnEndiannessBranch(isLittleEndian, emitLittleEndianCode, emitBigEndianCode);
+ }
+ } else {
+ switch (data.byteSize) {
+ case 1:
+ RELEASE_ASSERT(valueEdge.useKind() == Int32Use);
+ m_out.store32As8(valueToStore, pointer);
+ break;
+ case 2: {
+ RELEASE_ASSERT(valueEdge.useKind() == Int32Use);
+
+ auto emitLittleEndianCode = [&] () -> LValue {
+ m_out.store32As16(valueToStore, pointer);
+ return nullptr;
+ };
+ auto emitBigEndianCode = [&] () -> LValue {
+ PatchpointValue* patchpoint = m_out.patchpoint(Int32);
+ patchpoint->appendSomeRegister(valueToStore);
+ patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+ jit.move(params[1].gpr(), params[0].gpr());
+ jit.byteSwap16(params[0].gpr());
+ });
+ patchpoint->effects = Effects::none();
+
+ m_out.store32As16(patchpoint, pointer);
+ return nullptr;
+ };
+
+ if (data.isLittleEndian == FalseTriState)
+ emitBigEndianCode();
+ else if (data.isLittleEndian == TrueTriState)
+ emitLittleEndianCode();
+ else
+ emitCodeBasedOnEndiannessBranch(isLittleEndian, emitLittleEndianCode, emitBigEndianCode);
+ break;
+ }
+ case 4: {
+ RELEASE_ASSERT(valueEdge.useKind() == Int32Use || valueEdge.useKind() == Int52RepUse);
+
+ if (valueEdge.useKind() == Int52RepUse)
+ valueToStore = m_out.castToInt32(valueToStore);
+
+ auto emitLittleEndianCode = [&] () -> LValue {
+ m_out.store32(valueToStore, pointer);
+ return nullptr;
+ };
+ auto emitBigEndianCode = [&] () -> LValue {
+ m_out.store32(byteSwap32(valueToStore), pointer);
+ return nullptr;
+ };
+
+ if (data.isLittleEndian == FalseTriState)
+ emitBigEndianCode();
+ else if (data.isLittleEndian == TrueTriState)
+ emitLittleEndianCode();
+ else
+ emitCodeBasedOnEndiannessBranch(isLittleEndian, emitLittleEndianCode, emitBigEndianCode);
+
+ break;
+ }
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ }
+ }
void emitSwitchForMultiByOffset(LValue base, bool structuresChecked, Vector<SwitchCase, 2>& cases, LBasicBlock exit)
{
@@ -14468,6 +14826,13 @@
speculateWeakSetObject(edge, result);
return result;
}
+
+ LValue lowDataViewObject(Edge edge)
+ {
+ LValue result = lowCell(edge);
+ speculateDataViewObject(edge, result);
+ return result;
+ }
LValue lowString(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
{
@@ -14943,6 +15308,9 @@
case WeakSetObjectUse:
speculateWeakSetObject(edge);
break;
+ case DataViewObjectUse:
+ speculateDataViewObject(edge);
+ break;
case StringUse:
speculateString(edge);
break;
@@ -15437,6 +15805,17 @@
{
speculateWeakSetObject(edge, lowCell(edge));
}
+
+ void speculateDataViewObject(Edge edge, LValue cell)
+ {
+ FTL_TYPE_CHECK(
+ jsValueValue(cell), edge, SpecDataViewObject, isNotType(cell, DataViewType));
+ }
+
+ void speculateDataViewObject(Edge edge)
+ {
+ speculateDataViewObject(edge, lowCell(edge));
+ }
void speculateString(Edge edge, LValue cell)
{
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/runtime/Intrinsic.cpp (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/runtime/Intrinsic.cpp 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/runtime/Intrinsic.cpp 2018-08-24 08:07:53 UTC (rev 235290)
@@ -239,6 +239,38 @@
return "CPUCpuidIntrinsic";
case CPUPauseIntrinsic:
return "CPUPauseIntrinsic";
+ case DataViewGetInt8:
+ return "DataViewGetInt8";
+ case DataViewGetUint8:
+ return "DataViewGetUint8";
+ case DataViewGetInt16:
+ return "DataViewGetInt16";
+ case DataViewGetUint16:
+ return "DataViewGetUint16";
+ case DataViewGetInt32:
+ return "DataViewGetInt32";
+ case DataViewGetUint32:
+ return "DataViewGetUint32";
+ case DataViewGetFloat32:
+ return "DataViewGetFloat32";
+ case DataViewGetFloat64:
+ return "DataViewGetFloat64";
+ case DataViewSetInt8:
+ return "DataViewSetInt8";
+ case DataViewSetUint8:
+ return "DataViewSetUint8";
+ case DataViewSetInt16:
+ return "DataViewSetInt16";
+ case DataViewSetUint16:
+ return "DataViewSetUint16";
+ case DataViewSetInt32:
+ return "DataViewSetInt32";
+ case DataViewSetUint32:
+ return "DataViewSetUint32";
+ case DataViewSetFloat32:
+ return "DataViewSetFloat32";
+ case DataViewSetFloat64:
+ return "DataViewSetFloat64";
}
RELEASE_ASSERT_NOT_REACHED();
return nullptr;
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/runtime/Intrinsic.h (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/runtime/Intrinsic.h 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/runtime/Intrinsic.h 2018-08-24 08:07:53 UTC (rev 235290)
@@ -139,6 +139,23 @@
CPURdtscIntrinsic,
CPUCpuidIntrinsic,
CPUPauseIntrinsic,
+
+ DataViewGetInt8,
+ DataViewGetUint8,
+ DataViewGetInt16,
+ DataViewGetUint16,
+ DataViewGetInt32,
+ DataViewGetUint32,
+ DataViewGetFloat32,
+ DataViewGetFloat64,
+ DataViewSetInt8,
+ DataViewSetUint8,
+ DataViewSetInt16,
+ DataViewSetUint16,
+ DataViewSetInt32,
+ DataViewSetUint32,
+ DataViewSetFloat32,
+ DataViewSetFloat64,
};
const char* intrinsicName(Intrinsic);
Modified: releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/runtime/JSDataViewPrototype.cpp (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/runtime/JSDataViewPrototype.cpp 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/_javascript_Core/runtime/JSDataViewPrototype.cpp 2018-08-24 08:07:53 UTC (rev 235290)
@@ -39,22 +39,22 @@
/* Source for JSDataViewPrototype.lut.h
@begin dataViewTable
- getInt8 dataViewProtoFuncGetInt8 DontEnum|Function 1
- getUint8 dataViewProtoFuncGetUint8 DontEnum|Function 1
- getInt16 dataViewProtoFuncGetInt16 DontEnum|Function 1
- getUint16 dataViewProtoFuncGetUint16 DontEnum|Function 1
- getInt32 dataViewProtoFuncGetInt32 DontEnum|Function 1
- getUint32 dataViewProtoFuncGetUint32 DontEnum|Function 1
- getFloat32 dataViewProtoFuncGetFloat32 DontEnum|Function 1
- getFloat64 dataViewProtoFuncGetFloat64 DontEnum|Function 1
- setInt8 dataViewProtoFuncSetInt8 DontEnum|Function 2
- setUint8 dataViewProtoFuncSetUint8 DontEnum|Function 2
- setInt16 dataViewProtoFuncSetInt16 DontEnum|Function 2
- setUint16 dataViewProtoFuncSetUint16 DontEnum|Function 2
- setInt32 dataViewProtoFuncSetInt32 DontEnum|Function 2
- setUint32 dataViewProtoFuncSetUint32 DontEnum|Function 2
- setFloat32 dataViewProtoFuncSetFloat32 DontEnum|Function 2
- setFloat64 dataViewProtoFuncSetFloat64 DontEnum|Function 2
+ getInt8 dataViewProtoFuncGetInt8 DontEnum|Function 1 DataViewGetInt8
+ getUint8 dataViewProtoFuncGetUint8 DontEnum|Function 1 DataViewGetUint8
+ getInt16 dataViewProtoFuncGetInt16 DontEnum|Function 1 DataViewGetInt16
+ getUint16 dataViewProtoFuncGetUint16 DontEnum|Function 1 DataViewGetUint16
+ getInt32 dataViewProtoFuncGetInt32 DontEnum|Function 1 DataViewGetInt32
+ getUint32 dataViewProtoFuncGetUint32 DontEnum|Function 1 DataViewGetUint32
+ getFloat32 dataViewProtoFuncGetFloat32 DontEnum|Function 1 DataViewGetFloat32
+ getFloat64 dataViewProtoFuncGetFloat64 DontEnum|Function 1 DataViewGetFloat64
+ setInt8 dataViewProtoFuncSetInt8 DontEnum|Function 2 DataViewSetInt8
+ setUint8 dataViewProtoFuncSetUint8 DontEnum|Function 2 DataViewSetUint8
+ setInt16 dataViewProtoFuncSetInt16 DontEnum|Function 2 DataViewSetInt16
+ setUint16 dataViewProtoFuncSetUint16 DontEnum|Function 2 DataViewSetUint16
+ setInt32 dataViewProtoFuncSetInt32 DontEnum|Function 2 DataViewSetInt32
+ setUint32 dataViewProtoFuncSetUint32 DontEnum|Function 2 DataViewSetUint32
+ setFloat32 dataViewProtoFuncSetFloat32 DontEnum|Function 2 DataViewSetFloat32
+ setFloat64 dataViewProtoFuncSetFloat64 DontEnum|Function 2 DataViewSetFloat64
buffer dataViewProtoGetterBuffer DontEnum|Accessor 0
byteLength dataViewProtoGetterByteLength DontEnum|Accessor 0
byteOffset dataViewProtoGetterByteOffset DontEnum|Accessor 0
Modified: releases/WebKitGTK/webkit-2.22/Source/WTF/ChangeLog (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/WTF/ChangeLog 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/WTF/ChangeLog 2018-08-24 08:07:53 UTC (rev 235290)
@@ -1,3 +1,13 @@
+2018-08-20 Saam barati <[email protected]>
+
+ Inline DataView accesses into DFG/FTL
+ https://bugs.webkit.org/show_bug.cgi?id=188573
+ <rdar://problem/43286746>
+
+ Reviewed by Michael Saboff.
+
+ * wtf/TriState.h:
+
2018-08-19 Yusuke Suzuki <[email protected]>
[WTF] Add WTF::unalignedLoad and WTF::unalignedStore
Modified: releases/WebKitGTK/webkit-2.22/Source/WTF/wtf/TriState.h (235289 => 235290)
--- releases/WebKitGTK/webkit-2.22/Source/WTF/wtf/TriState.h 2018-08-24 08:07:31 UTC (rev 235289)
+++ releases/WebKitGTK/webkit-2.22/Source/WTF/wtf/TriState.h 2018-08-24 08:07:53 UTC (rev 235290)
@@ -28,7 +28,7 @@
namespace WTF {
-enum TriState {
+enum TriState : int8_t {
FalseTriState,
TrueTriState,
MixedTriState