Skip to content
Permalink
Browse files
Polymorphic operand types for DFG and FTL bit operators.
https://bugs.webkit.org/show_bug.cgi?id=152191

Reviewed by Saam Barati.

Source/JavaScriptCore:

* bytecode/SpeculatedType.h:
(JSC::isUntypedSpeculationForBitOps):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGNode.h:
(JSC::DFG::Node::shouldSpeculateUntypedForBitOps):
- Added check for types not supported by ValueToInt32, and therefore should be
  treated as untyped for bitops.

* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
- Handled untyped operands.

* dfg/DFGOperations.cpp:
* dfg/DFGOperations.h:
- Added DFG slow path functions for bitops.

* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::emitUntypedBitOp):
(JSC::DFG::SpeculativeJIT::compileBitwiseOp):
(JSC::DFG::SpeculativeJIT::emitUntypedRightShiftBitOp):
(JSC::DFG::SpeculativeJIT::compileShiftOp):
* dfg/DFGSpeculativeJIT.h:
- Added DFG backend support untyped operands for bitops.

* dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::handleNode):
- Limit bitops strength reduction only to when we don't have untyped operands.
  This is because values that are not int32s need to be converted to int32.
  Without untyped operands, the ValueToInt32 node takes care of this.
  With untyped operands, we cannot use ValueToInt32, and need to do the conversion
  in the code emitted for the bitop node itself.  For example:

      5.5 | 0; // yields 5 because ValueToInt32 converts the 5.5 to a 5.
      "abc" | 0; // would yield "abc" instead of the expected 0 if we let
                 // strength reduction do its thing.

* ftl/FTLCompileBinaryOp.cpp:
(JSC::FTL::generateBinaryBitOpFastPath):
(JSC::FTL::generateRightShiftFastPath):
(JSC::FTL::generateBinaryOpFastPath):

* ftl/FTLInlineCacheDescriptor.h:
(JSC::FTL::BitAndDescriptor::BitAndDescriptor):
(JSC::FTL::BitAndDescriptor::icSize):
(JSC::FTL::BitAndDescriptor::nodeType):
(JSC::FTL::BitAndDescriptor::opName):
(JSC::FTL::BitAndDescriptor::slowPathFunction):
(JSC::FTL::BitAndDescriptor::nonNumberSlowPathFunction):
(JSC::FTL::BitOrDescriptor::BitOrDescriptor):
(JSC::FTL::BitOrDescriptor::icSize):
(JSC::FTL::BitOrDescriptor::nodeType):
(JSC::FTL::BitOrDescriptor::opName):
(JSC::FTL::BitOrDescriptor::slowPathFunction):
(JSC::FTL::BitOrDescriptor::nonNumberSlowPathFunction):
(JSC::FTL::BitXorDescriptor::BitXorDescriptor):
(JSC::FTL::BitXorDescriptor::icSize):
(JSC::FTL::BitXorDescriptor::nodeType):
(JSC::FTL::BitXorDescriptor::opName):
(JSC::FTL::BitXorDescriptor::slowPathFunction):
(JSC::FTL::BitXorDescriptor::nonNumberSlowPathFunction):
(JSC::FTL::BitLShiftDescriptor::BitLShiftDescriptor):
(JSC::FTL::BitLShiftDescriptor::icSize):
(JSC::FTL::BitLShiftDescriptor::nodeType):
(JSC::FTL::BitLShiftDescriptor::opName):
(JSC::FTL::BitLShiftDescriptor::slowPathFunction):
(JSC::FTL::BitLShiftDescriptor::nonNumberSlowPathFunction):
(JSC::FTL::BitRShiftDescriptor::BitRShiftDescriptor):
(JSC::FTL::BitRShiftDescriptor::icSize):
(JSC::FTL::BitRShiftDescriptor::nodeType):
(JSC::FTL::BitRShiftDescriptor::opName):
(JSC::FTL::BitRShiftDescriptor::slowPathFunction):
(JSC::FTL::BitRShiftDescriptor::nonNumberSlowPathFunction):
(JSC::FTL::BitURShiftDescriptor::BitURShiftDescriptor):
(JSC::FTL::BitURShiftDescriptor::icSize):
(JSC::FTL::BitURShiftDescriptor::nodeType):
(JSC::FTL::BitURShiftDescriptor::opName):
(JSC::FTL::BitURShiftDescriptor::slowPathFunction):
(JSC::FTL::BitURShiftDescriptor::nonNumberSlowPathFunction):
- Added support for bitop ICs.

* ftl/FTLInlineCacheSize.cpp:
(JSC::FTL::sizeOfBitAnd):
(JSC::FTL::sizeOfBitOr):
(JSC::FTL::sizeOfBitXor):
(JSC::FTL::sizeOfBitLShift):
(JSC::FTL::sizeOfBitRShift):
(JSC::FTL::sizeOfBitURShift):
* ftl/FTLInlineCacheSize.h:
- Added new bitop IC sizes.  These are just estimates for now that work adequately,
  and are shown to not impact performance on benchmarks.  We will re-tune these
  sizes values later in another patch once all snippet ICs have been added.

* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileBitAnd):
(JSC::FTL::DFG::LowerDFGToLLVM::compileBitOr):
(JSC::FTL::DFG::LowerDFGToLLVM::compileBitXor):
(JSC::FTL::DFG::LowerDFGToLLVM::compileBitRShift):
(JSC::FTL::DFG::LowerDFGToLLVM::compileBitLShift):
(JSC::FTL::DFG::LowerDFGToLLVM::compileBitURShift):
- Added support for bitop ICs.

* jit/JITLeftShiftGenerator.cpp:
(JSC::JITLeftShiftGenerator::generateFastPath):
* jit/JITLeftShiftGenerator.h:
(JSC::JITLeftShiftGenerator::JITLeftShiftGenerator):
* jit/JITRightShiftGenerator.cpp:
(JSC::JITRightShiftGenerator::generateFastPath):
- The shift MASM operatons need to ensure that the shiftAmount is not in the same
  register as the destination register.  With the baselineJIT and DFG, this is
  ensured in how we allocate these registers, and hence, the bug does not manifest.
  With the FTL, these registers are not guaranteed to be unique.  Hence, we need
  to fix the shift op snippet code to compensate for this.

LayoutTests:

* js/regress/ftl-polymorphic-bitand-expected.txt: Added.
* js/regress/ftl-polymorphic-bitand.html: Added.
* js/regress/ftl-polymorphic-bitor-expected.txt: Added.
* js/regress/ftl-polymorphic-bitor.html: Added.
* js/regress/ftl-polymorphic-bitxor-expected.txt: Added.
* js/regress/ftl-polymorphic-bitxor.html: Added.
* js/regress/ftl-polymorphic-lshift-expected.txt: Added.
* js/regress/ftl-polymorphic-lshift.html: Added.
* js/regress/ftl-polymorphic-rshift-expected.txt: Added.
* js/regress/ftl-polymorphic-rshift.html: Added.
* js/regress/ftl-polymorphic-urshift-expected.txt: Added.
* js/regress/ftl-polymorphic-urshift.html: Added.
* js/regress/script-tests/ftl-polymorphic-bitand.js: Added.
(o1.valueOf):
(foo):
* js/regress/script-tests/ftl-polymorphic-bitor.js: Added.
(o1.valueOf):
(foo):
* js/regress/script-tests/ftl-polymorphic-bitxor.js: Added.
(o1.valueOf):
(foo):
* js/regress/script-tests/ftl-polymorphic-lshift.js: Added.
(o1.valueOf):
(foo):
* js/regress/script-tests/ftl-polymorphic-rshift.js: Added.
(o1.valueOf):
(foo):
* js/regress/script-tests/ftl-polymorphic-urshift.js: Added.
(o1.valueOf):
(foo):



Canonical link: https://commits.webkit.org/170418@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@194113 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Mark Lam committed Dec 15, 2015
1 parent 117743f commit fbd92c0bf6b53e8b19fe49b52f9aac020b525587
Showing with 1,240 additions and 17 deletions.
  1. +38 −0 LayoutTests/ChangeLog
  2. +10 −0 LayoutTests/js/regress/ftl-polymorphic-bitand-expected.txt
  3. +12 −0 LayoutTests/js/regress/ftl-polymorphic-bitand.html
  4. +10 −0 LayoutTests/js/regress/ftl-polymorphic-bitor-expected.txt
  5. +12 −0 LayoutTests/js/regress/ftl-polymorphic-bitor.html
  6. +10 −0 LayoutTests/js/regress/ftl-polymorphic-bitxor-expected.txt
  7. +12 −0 LayoutTests/js/regress/ftl-polymorphic-bitxor.html
  8. +10 −0 LayoutTests/js/regress/ftl-polymorphic-lshift-expected.txt
  9. +12 −0 LayoutTests/js/regress/ftl-polymorphic-lshift.html
  10. +10 −0 LayoutTests/js/regress/ftl-polymorphic-rshift-expected.txt
  11. +12 −0 LayoutTests/js/regress/ftl-polymorphic-rshift.html
  12. +10 −0 LayoutTests/js/regress/ftl-polymorphic-urshift-expected.txt
  13. +12 −0 LayoutTests/js/regress/ftl-polymorphic-urshift.html
  14. +42 −0 LayoutTests/js/regress/script-tests/ftl-polymorphic-bitand.js
  15. +42 −0 LayoutTests/js/regress/script-tests/ftl-polymorphic-bitor.js
  16. +42 −0 LayoutTests/js/regress/script-tests/ftl-polymorphic-bitxor.js
  17. +42 −0 LayoutTests/js/regress/script-tests/ftl-polymorphic-lshift.js
  18. +42 −0 LayoutTests/js/regress/script-tests/ftl-polymorphic-rshift.js
  19. +42 −0 LayoutTests/js/regress/script-tests/ftl-polymorphic-urshift.js
  20. +123 −1 Source/JavaScriptCore/ChangeLog
  21. +5 −0 Source/JavaScriptCore/bytecode/SpeculatedType.h
  22. +6 −0 Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
  23. +14 −6 Source/JavaScriptCore/dfg/DFGClobberize.h
  24. +6 −0 Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
  25. +10 −0 Source/JavaScriptCore/dfg/DFGNode.h
  26. +78 −0 Source/JavaScriptCore/dfg/DFGOperations.cpp
  27. +6 −0 Source/JavaScriptCore/dfg/DFGOperations.h
  28. +231 −0 Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
  29. +6 −0 Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
  30. +2 −2 Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp
  31. +96 −3 Source/JavaScriptCore/ftl/FTLCompileBinaryOp.cpp
  32. +78 −0 Source/JavaScriptCore/ftl/FTLInlineCacheDescriptor.h
  33. +102 −0 Source/JavaScriptCore/ftl/FTLInlineCacheSize.cpp
  34. +6 −0 Source/JavaScriptCore/ftl/FTLInlineCacheSize.h
  35. +24 −0 Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
  36. +15 −1 Source/JavaScriptCore/jit/JITLeftShiftGenerator.cpp
  37. +2 −2 Source/JavaScriptCore/jit/JITLeftShiftGenerator.h
  38. +8 −2 Source/JavaScriptCore/jit/JITRightShiftGenerator.cpp
@@ -1,3 +1,41 @@
2015-12-15 Mark Lam <mark.lam@apple.com>

Polymorphic operand types for DFG and FTL bit operators.
https://bugs.webkit.org/show_bug.cgi?id=152191

Reviewed by Saam Barati.

* js/regress/ftl-polymorphic-bitand-expected.txt: Added.
* js/regress/ftl-polymorphic-bitand.html: Added.
* js/regress/ftl-polymorphic-bitor-expected.txt: Added.
* js/regress/ftl-polymorphic-bitor.html: Added.
* js/regress/ftl-polymorphic-bitxor-expected.txt: Added.
* js/regress/ftl-polymorphic-bitxor.html: Added.
* js/regress/ftl-polymorphic-lshift-expected.txt: Added.
* js/regress/ftl-polymorphic-lshift.html: Added.
* js/regress/ftl-polymorphic-rshift-expected.txt: Added.
* js/regress/ftl-polymorphic-rshift.html: Added.
* js/regress/ftl-polymorphic-urshift-expected.txt: Added.
* js/regress/ftl-polymorphic-urshift.html: Added.
* js/regress/script-tests/ftl-polymorphic-bitand.js: Added.
(o1.valueOf):
(foo):
* js/regress/script-tests/ftl-polymorphic-bitor.js: Added.
(o1.valueOf):
(foo):
* js/regress/script-tests/ftl-polymorphic-bitxor.js: Added.
(o1.valueOf):
(foo):
* js/regress/script-tests/ftl-polymorphic-lshift.js: Added.
(o1.valueOf):
(foo):
* js/regress/script-tests/ftl-polymorphic-rshift.js: Added.
(o1.valueOf):
(foo):
* js/regress/script-tests/ftl-polymorphic-urshift.js: Added.
(o1.valueOf):
(foo):

2015-12-15 Adam Bergkvist <adam.bergkvist@ericsson.com>

WebRTC: Test that RTCPeerConnection promise functions reject on closed state
@@ -0,0 +1,10 @@
JSRegress/ftl-polymorphic-bitand

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS no exception thrown
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<script src="../../resources/regress-pre.js"></script>
<script src="script-tests/ftl-polymorphic-bitand.js"></script>
<script src="../../resources/regress-post.js"></script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
@@ -0,0 +1,10 @@
JSRegress/ftl-polymorphic-bitor

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS no exception thrown
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<script src="../../resources/regress-pre.js"></script>
<script src="script-tests/ftl-polymorphic-bitor.js"></script>
<script src="../../resources/regress-post.js"></script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
@@ -0,0 +1,10 @@
JSRegress/ftl-polymorphic-bitxor

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS no exception thrown
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<script src="../../resources/regress-pre.js"></script>
<script src="script-tests/ftl-polymorphic-bitxor.js"></script>
<script src="../../resources/regress-post.js"></script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
@@ -0,0 +1,10 @@
JSRegress/ftl-polymorphic-lshift

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS no exception thrown
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<script src="../../resources/regress-pre.js"></script>
<script src="script-tests/ftl-polymorphic-lshift.js"></script>
<script src="../../resources/regress-post.js"></script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
@@ -0,0 +1,10 @@
JSRegress/ftl-polymorphic-rshift

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS no exception thrown
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<script src="../../resources/regress-pre.js"></script>
<script src="script-tests/ftl-polymorphic-rshift.js"></script>
<script src="../../resources/regress-post.js"></script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
@@ -0,0 +1,10 @@
JSRegress/ftl-polymorphic-urshift

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


PASS no exception thrown
PASS successfullyParsed is true

TEST COMPLETE

@@ -0,0 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<script src="../../resources/regress-pre.js"></script>
<script src="script-tests/ftl-polymorphic-urshift.js"></script>
<script src="../../resources/regress-post.js"></script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
@@ -0,0 +1,42 @@
//@ runFTLNoCJIT
var o1 = {
i: 0,
valueOf: function() { return this.i; }
};

result = 0;
function foo(a, b) {
var result = 0;
for (var j = 0; j < 10; j++) {
var temp;
if (a > b)
temp = a & b;
else
temp = b & 1;
result += temp;
}
for (var i = 0; i < 1000; i++)
result += i;
return result;
}
noInline(foo);

var iterations;
var expectedResult;
if (this.window) {
// The layout test doesn't like too many iterations and may time out.
iterations = 10000;
expectedResult = 4995999180;
} else {
iterations = 100000;
expectedResult = 49955499180;
}


for (var i = 0; i <= iterations; i++) {
o1.i = i + 2;
result += foo(o1, 10);
}

if (result != expectedResult)
throw "Bad result: " + result;
@@ -0,0 +1,42 @@
//@ runFTLNoCJIT
var o1 = {
i: 0,
valueOf: function() { return this.i; }
};

result = 0;
function foo(a, b) {
var result = 0;
for (var j = 0; j < 10; j++) {
var temp;
if (a > b)
temp = a | b;
else
temp = b | 1;
result += temp;
}
for (var i = 0; i < 1000; i++)
result += i;
return result;
}
noInline(foo);

var iterations;
var expectedResult;
if (this.window) {
// The layout test doesn't like too many iterations and may time out.
iterations = 10000;
expectedResult = 5496249490;
} else {
iterations = 100000;
expectedResult = 99957999490;
}


for (var i = 0; i <= iterations; i++) {
o1.i = i + 2;
result += foo(o1, 10);
}

if (result != expectedResult)
throw "Bad result: " + result;
@@ -0,0 +1,42 @@
//@ runFTLNoCJIT
var o1 = {
i: 0,
valueOf: function() { return this.i; }
};

result = 0;
function foo(a, b) {
var result = 0;
for (var j = 0; j < 10; j++) {
var temp;
if (a > b)
temp = a ^ b;
else
temp = b ^ 1;
result += temp;
}
for (var i = 0; i < 1000; i++)
result += i;
return result;
}
noInline(foo);

var iterations;
var expectedResult;
if (this.window) {
// The layout test doesn't like too many iterations and may time out.
iterations = 10000;
expectedResult = 5495749810;
} else {
iterations = 100000;
expectedResult = 99952999810;
}


for (var i = 0; i <= iterations; i++) {
o1.i = i + 2;
result += foo(o1, 10);
}

if (result != expectedResult)
throw "Bad result: " + result;
@@ -0,0 +1,42 @@
//@ runFTLNoCJIT
var o1 = {
i: 0,
valueOf: function() { return this.i; }
};

result = 0;
function foo(a, b) {
var result = 0;
for (var j = 0; j < 10; j++) {
var temp;
if (a > b)
temp = a << b;
else
temp = b << 1;
result += temp;
}
for (var i = 0; i < 1000; i++)
result += i;
return result;
}
noInline(foo);

var iterations;
var expectedResult;
if (this.window) {
// The layout test doesn't like too many iterations and may time out.
iterations = 10000;
expectedResult = 517250968820;
} else {
iterations = 100000;
expectedResult = 51252509968820;
}


for (var i = 0; i <= iterations; i++) {
o1.i = i + 2;
result += foo(o1, 10);
}

if (result != expectedResult)
throw "Bad result: " + result;

0 comments on commit fbd92c0

Please sign in to comment.