Skip to content

Commit 5023ca9

Browse files
[JSC] Implement CompareStrictEq(String, Untyped) in FTL
https://bugs.webkit.org/show_bug.cgi?id=161229 Reviewed by Geoffrey Garen. JSTests: * stress/compare-strict-eq-on-various-types.js: Added. Source/JavaScriptCore: Add (String, Untyped) uses to FTL CompareStrictEq. This was the last use type not implemented, the node is fully supported by FTL after this patch. * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq): (JSC::FTL::DFG::LowerDFGToB3::compileStringToUntypedStrictEquality): (JSC::FTL::DFG::LowerDFGToB3::nonSpeculativeCompare): Remove the type checks when possible. Canonical link: https://commits.webkit.org/179439@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@205064 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 08bb8a2 commit 5023ca9

5 files changed

Lines changed: 328 additions & 50 deletions

File tree

JSTests/ChangeLog

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
2016-08-26 Benjamin Poulain <benjamin@webkit.org>
2+
3+
[JSC] Implement CompareStrictEq(String, Untyped) in FTL
4+
https://bugs.webkit.org/show_bug.cgi?id=161229
5+
6+
Reviewed by Geoffrey Garen.
7+
8+
* stress/compare-strict-eq-on-various-types.js: Added.
9+
110
2016-08-26 Yusuke Suzuki <utatane.tea@gmail.com>
211

312
[ES6] newPromiseCapabilities should check the given argument is constructor
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
"use strict";
2+
3+
function opaqueKitString() {
4+
return "Kit";
5+
}
6+
noInline(opaqueKitString);
7+
8+
let someObject = new Object;
9+
let validInputTestCases = [
10+
"undefined",
11+
"Symbol(\"WebKit\")",
12+
"null",
13+
"true",
14+
"false",
15+
"0",
16+
"{ valueOf: () => { return Math.E; } }",
17+
"-0",
18+
"42",
19+
"-42",
20+
"Math.PI",
21+
"NaN",
22+
"\"WebKit\"",
23+
"\"Web\" + opaqueKitString()",
24+
"new String(\"WebKit\")",
25+
"someObject",
26+
"validInputTestCases",
27+
];
28+
29+
let leftCases = validInputTestCases.map((element) => { return eval("(" + element + ")"); });
30+
let rightCases = validInputTestCases.map((element) => { return eval("(" + element + ")"); });
31+
32+
// Baseline results.
33+
let expectedEqualResults = [];
34+
let expectedNotEqualResults = [];
35+
for (let testCaseInputLeft of leftCases) {
36+
let equalResultRow = [];
37+
let notEqualResultRow = [];
38+
for (let testCaseInputRight of rightCases) {
39+
equalResultRow.push(testCaseInputLeft === testCaseInputRight);
40+
notEqualResultRow.push(testCaseInputLeft !== testCaseInputRight);
41+
}
42+
expectedEqualResults.push(equalResultRow);
43+
expectedNotEqualResults.push(notEqualResultRow);
44+
}
45+
46+
function isIdentical(result, expected)
47+
{
48+
if (expected === expected) {
49+
if (result !== expected)
50+
return false;
51+
if (!expected && 1 / expected === -Infinity && 1 / result !== -Infinity)
52+
return false;
53+
54+
return true;
55+
}
56+
return result !== result;
57+
}
58+
59+
60+
// Very polymorphic compare.
61+
function opaqueStrictEqualAllTypes(left, right) {
62+
return left === right;
63+
}
64+
noInline(opaqueStrictEqualAllTypes);
65+
noOSRExitFuzzing(opaqueStrictEqualAllTypes);
66+
67+
function opaqueStrictNotEqualAllTypes(left, right) {
68+
return left !== right;
69+
}
70+
noInline(opaqueStrictNotEqualAllTypes);
71+
noOSRExitFuzzing(opaqueStrictNotEqualAllTypes);
72+
73+
function testAllTypesCall() {
74+
for (let i = 0; i < 1e3; ++i) {
75+
for (let leftCaseIndex = 0; leftCaseIndex < leftCases.length; ++leftCaseIndex) {
76+
for (let rightCaseIndex = 0; rightCaseIndex < rightCases.length; ++rightCaseIndex) {
77+
let strictEqualOutput = opaqueStrictEqualAllTypes(leftCases[leftCaseIndex], rightCases[rightCaseIndex]);
78+
if (!isIdentical(strictEqualOutput, expectedEqualResults[leftCaseIndex][rightCaseIndex])) {
79+
throw "Failed testAllTypesCall for equality. Left = " +
80+
leftCases[leftCaseIndex] +
81+
", Right = " +
82+
rightCases[rightCaseIndex] +
83+
", Result = " +
84+
strictEqualOutput;
85+
}
86+
87+
let strictNotEqualOutput = opaqueStrictNotEqualAllTypes(leftCases[leftCaseIndex], rightCases[rightCaseIndex]);
88+
if (!isIdentical(strictNotEqualOutput, expectedNotEqualResults[leftCaseIndex][rightCaseIndex])) {
89+
throw "Failed testAllTypesCall for !equality. Left = " +
90+
leftCases[leftCaseIndex] +
91+
", Right = " +
92+
rightCases[rightCaseIndex] +
93+
", Result = " +
94+
strictEqualOutput;
95+
}
96+
}
97+
}
98+
}
99+
if (numberOfDFGCompiles(opaqueStrictEqualAllTypes) > 2)
100+
throw "opaqueStrictEqualAllTypes() should have been quickly compiled as fully polymorphic.";
101+
if (opaqueStrictNotEqualAllTypes(opaqueStrictEqualAllTypes) > 2)
102+
throw "opaqueStrictEqualAllTypes() should have been quickly compiled as fully polymorphic.";
103+
}
104+
testAllTypesCall();
105+
106+
107+
// Comparing String to every type.
108+
function opaqueStrictEqualStringToAllTypes(left, right) {
109+
return left === right;
110+
}
111+
noInline(opaqueStrictEqualStringToAllTypes);
112+
noOSRExitFuzzing(opaqueStrictEqualStringToAllTypes);
113+
114+
function opaqueStrictEqualAllTypesToString(left, right) {
115+
return left === right;
116+
}
117+
noInline(opaqueStrictEqualAllTypesToString);
118+
noOSRExitFuzzing(opaqueStrictEqualAllTypesToString);
119+
120+
function opaqueStrictNotEqualStringToAllTypes(left, right) {
121+
return left !== right;
122+
}
123+
noInline(opaqueStrictNotEqualStringToAllTypes);
124+
noOSRExitFuzzing(opaqueStrictNotEqualStringToAllTypes);
125+
126+
function opaqueStrictNotEqualAllTypesToString(left, right) {
127+
return left !== right;
128+
}
129+
noInline(opaqueStrictNotEqualAllTypesToString);
130+
noOSRExitFuzzing(opaqueStrictNotEqualAllTypesToString);
131+
132+
function testStringToAllCompare() {
133+
const leftStringIndex = leftCases.indexOf("WebKit");
134+
for (let i = 0; i < 1e3; ++i) {
135+
for (let rightCaseIndex = 0; rightCaseIndex < rightCases.length; ++rightCaseIndex) {
136+
let rightCase = rightCases[rightCaseIndex];
137+
let strictEqualOutput = opaqueStrictEqualStringToAllTypes("Web" + opaqueKitString(), rightCase);
138+
if (!isIdentical(strictEqualOutput, expectedEqualResults[leftStringIndex][rightCaseIndex])) {
139+
throw "Failed opaqueStrictEqualStringToAllTypes() with right = " + rightCase;
140+
}
141+
let strictNotEqualOutput = opaqueStrictNotEqualStringToAllTypes("Web" + opaqueKitString(), rightCase);
142+
if (!isIdentical(strictNotEqualOutput, expectedNotEqualResults[leftStringIndex][rightCaseIndex])) {
143+
throw "Failed opaqueStrictNotEqualStringToAllTypes() with right = " + rightCase;
144+
}
145+
}
146+
}
147+
148+
const rightStringIndex = leftCases.lastIndexOf("WebKit");
149+
for (let i = 0; i < 1e3; ++i) {
150+
for (let leftCaseIndex = 0; leftCaseIndex < leftCases.length; ++leftCaseIndex) {
151+
let leftCase = leftCases[leftCaseIndex];
152+
let strictEqualOutput = opaqueStrictEqualAllTypesToString(leftCase, "Web" + opaqueKitString());
153+
if (!isIdentical(strictEqualOutput, expectedEqualResults[leftCaseIndex][rightStringIndex])) {
154+
throw "Failed opaqueStrictEqualAllTypesToString() with left = " + leftCase;
155+
}
156+
let strictNotEqualOutput = opaqueStrictNotEqualAllTypesToString(leftCase, "Web" + opaqueKitString());
157+
if (!isIdentical(strictNotEqualOutput, expectedNotEqualResults[leftCaseIndex][rightStringIndex])) {
158+
throw "Failed opaqueStrictNotEqualAllTypesToString() with left = " + leftCase;
159+
}
160+
}
161+
}
162+
163+
if (numberOfDFGCompiles(opaqueStrictEqualStringToAllTypes) > 2)
164+
throw "opaqueStrictEqualStringToAllTypes() should quickly converge its types.";
165+
if (numberOfDFGCompiles(opaqueStrictEqualAllTypesToString) > 2)
166+
throw "opaqueStrictEqualAllTypesToString() should quickly converge its types.";
167+
if (numberOfDFGCompiles(opaqueStrictNotEqualStringToAllTypes) > 2)
168+
throw "opaqueStrictNotEqualStringToAllTypes() should quickly converge its types.";
169+
if (numberOfDFGCompiles(opaqueStrictNotEqualAllTypesToString) > 2)
170+
throw "opaqueStrictNotEqualAllTypesToString() should quickly converge its types.";
171+
}
172+
testStringToAllCompare();
173+
174+
175+
// Compare one type to all the others.
176+
function compareOneTypeToAll() {
177+
for (let leftCaseIndex = 0; leftCaseIndex < validInputTestCases.length; ++leftCaseIndex) {
178+
let leftCase = validInputTestCases[leftCaseIndex];
179+
eval(`
180+
function opaqueStrictEqualOneTypeToAll(left, right) {
181+
return left === right;
182+
}
183+
noInline(opaqueStrictEqualOneTypeToAll);
184+
noOSRExitFuzzing(opaqueStrictEqualOneTypeToAll);
185+
186+
function opaqueStrictNotEqualOneTypeToAll(left, right) {
187+
return left !== right;
188+
}
189+
noInline(opaqueStrictNotEqualOneTypeToAll);
190+
noOSRExitFuzzing(opaqueStrictNotEqualOneTypeToAll);
191+
192+
for (let i = 0; i < 1e3; ++i) {
193+
for (let rightCaseIndex = 0; rightCaseIndex < rightCases.length; ++rightCaseIndex) {
194+
let strictEqualOutput = opaqueStrictEqualOneTypeToAll(${leftCase}, rightCases[rightCaseIndex]);
195+
if (!isIdentical(strictEqualOutput, expectedEqualResults[${leftCaseIndex}][rightCaseIndex])) {
196+
throw "Failed opaqueStrictEqualOneTypeToAll() with left case = " + ${leftCase} + ", right case = " + rightCases[rightCaseIndex];
197+
}
198+
let strictNotEqualOutput = opaqueStrictNotEqualOneTypeToAll(${leftCase}, rightCases[rightCaseIndex]);
199+
if (!isIdentical(strictNotEqualOutput, expectedNotEqualResults[${leftCaseIndex}][rightCaseIndex])) {
200+
throw "Failed opaqueStrictNotEqualOneTypeToAll() with left case = " + ${leftCase} + ", right case = " + rightCases[rightCaseIndex];
201+
}
202+
}
203+
}
204+
`);
205+
}
206+
}
207+
compareOneTypeToAll();
208+
209+
function compareAllTypesToOne() {
210+
for (let rightCaseIndex = 0; rightCaseIndex < validInputTestCases.length; ++rightCaseIndex) {
211+
let rightCase = validInputTestCases[rightCaseIndex];
212+
eval(`
213+
function opaqueStrictEqualAllToOne(left, right) {
214+
return left === right;
215+
}
216+
noInline(opaqueStrictEqualAllToOne);
217+
noOSRExitFuzzing(opaqueStrictEqualAllToOne);
218+
219+
function opaqueStrictNotEqualAllToOne(left, right) {
220+
return left !== right;
221+
}
222+
noInline(opaqueStrictNotEqualAllToOne);
223+
noOSRExitFuzzing(opaqueStrictNotEqualAllToOne);
224+
225+
for (let i = 0; i < 1e3; ++i) {
226+
for (let leftCaseIndex = 0; leftCaseIndex < leftCases.length; ++leftCaseIndex) {
227+
let strictEqualOutput = opaqueStrictEqualAllToOne(leftCases[leftCaseIndex], ${rightCase});
228+
if (!isIdentical(strictEqualOutput, expectedEqualResults[leftCaseIndex][${rightCaseIndex}])) {
229+
throw "Failed opaqueStrictEqualAllToOne() with left case = " + leftCases[leftCaseIndex] + ", right case = " + ${rightCase};
230+
}
231+
let strictNotEqualOutput = opaqueStrictNotEqualAllToOne(leftCases[leftCaseIndex], ${rightCase});
232+
if (!isIdentical(strictNotEqualOutput, expectedNotEqualResults[leftCaseIndex][${rightCaseIndex}])) {
233+
throw "Failed opaqueStrictNotEqualAllToOne() with left case = " + leftCases[leftCaseIndex] + ", right case = " + ${rightCase};
234+
}
235+
}
236+
}
237+
`);
238+
}
239+
}
240+
compareAllTypesToOne();

Source/JavaScriptCore/ChangeLog

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
2016-08-26 Benjamin Poulain <benjamin@webkit.org>
2+
3+
[JSC] Implement CompareStrictEq(String, Untyped) in FTL
4+
https://bugs.webkit.org/show_bug.cgi?id=161229
5+
6+
Reviewed by Geoffrey Garen.
7+
8+
Add (String, Untyped) uses to FTL CompareStrictEq.
9+
This was the last use type not implemented, the node is fully
10+
supported by FTL after this patch.
11+
12+
* ftl/FTLCapabilities.cpp:
13+
(JSC::FTL::canCompile):
14+
* ftl/FTLLowerDFGToB3.cpp:
15+
(JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq):
16+
(JSC::FTL::DFG::LowerDFGToB3::compileStringToUntypedStrictEquality):
17+
18+
(JSC::FTL::DFG::LowerDFGToB3::nonSpeculativeCompare):
19+
Remove the type checks when possible.
20+
121
2016-08-26 Johan K. Jensen <johan_jensen@apple.com>
222

323
Web Inspector: Frontend should have access to Resource Timing information

Source/JavaScriptCore/ftl/FTLCapabilities.cpp

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ inline CapabilityLevel canCompile(Node* node)
246246
case GetDynamicVar:
247247
case PutDynamicVar:
248248
case CompareEqPtr:
249+
case CompareStrictEq:
249250
// These are OK.
250251
break;
251252

@@ -388,42 +389,6 @@ inline CapabilityLevel canCompile(Node* node)
388389
if (node->child1().useKind() == OtherUse || node->child2().useKind() == OtherUse)
389390
break;
390391
return CannotCompile;
391-
case CompareStrictEq:
392-
if (node->isBinaryUseKind(Int32Use))
393-
break;
394-
if (node->isBinaryUseKind(Int52RepUse))
395-
break;
396-
if (node->isBinaryUseKind(DoubleRepUse))
397-
break;
398-
if (node->isBinaryUseKind(StringIdentUse))
399-
break;
400-
if (node->isBinaryUseKind(StringUse))
401-
break;
402-
if (node->isBinaryUseKind(ObjectUse, UntypedUse))
403-
break;
404-
if (node->isBinaryUseKind(UntypedUse, ObjectUse))
405-
break;
406-
if (node->isBinaryUseKind(ObjectUse))
407-
break;
408-
if (node->isBinaryUseKind(BooleanUse))
409-
break;
410-
if (node->isBinaryUseKind(UntypedUse))
411-
break;
412-
if (node->isBinaryUseKind(SymbolUse))
413-
break;
414-
if (node->isBinaryUseKind(SymbolUse, UntypedUse))
415-
break;
416-
if (node->isBinaryUseKind(UntypedUse, SymbolUse))
417-
break;
418-
if (node->isBinaryUseKind(MiscUse, UntypedUse))
419-
break;
420-
if (node->isBinaryUseKind(UntypedUse, MiscUse))
421-
break;
422-
if (node->isBinaryUseKind(StringIdentUse, NotStringVarUse))
423-
break;
424-
if (node->isBinaryUseKind(NotStringVarUse, StringIdentUse))
425-
break;
426-
return CannotCompile;
427392
case CompareLess:
428393
case CompareLessEq:
429394
case CompareGreater:

0 commit comments

Comments
 (0)