Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (194560 => 194561)
--- trunk/Source/_javascript_Core/ChangeLog 2016-01-04 22:53:57 UTC (rev 194560)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-01-04 23:08:32 UTC (rev 194561)
@@ -1,3 +1,52 @@
+2016-01-04 Filip Pizlo <fpi...@apple.com>
+
+ FTL B3 should do binary snippets
+ https://bugs.webkit.org/show_bug.cgi?id=152668
+
+ Reviewed by Mark Lam.
+
+ This finishes all of the rest of the snippets.
+
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (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):
+ (JSC::FTL::DFG::LowerDFGToLLVM::emitBinaryBitOpSnippet):
+ (JSC::FTL::DFG::LowerDFGToLLVM::emitRightShiftSnippet):
+ (JSC::FTL::DFG::LowerDFGToLLVM::allocateCell):
+ * tests/stress/object-bit-or.js: Added.
+ (foo):
+ (things.valueOf):
+ * tests/stress/object-bit-xor.js: Added.
+ (foo):
+ (things.valueOf):
+ * tests/stress/object-lshift.js: Added.
+ (foo):
+ (things.valueOf):
+ * tests/stress/object-rshift.js: Added.
+ (foo):
+ (things.valueOf):
+ * tests/stress/object-urshift.js: Added.
+ (foo):
+ (things.valueOf):
+ * tests/stress/untyped-bit-or.js: Added.
+ (foo):
+ (valueOf):
+ * tests/stress/untyped-bit-xor.js: Added.
+ (foo):
+ (valueOf):
+ * tests/stress/untyped-lshift.js: Added.
+ (foo):
+ (valueOf):
+ * tests/stress/untyped-rshift.js: Added.
+ (foo):
+ (valueOf):
+ * tests/stress/untyped-urshift.js: Added.
+ (foo):
+ (valueOf):
+
2016-01-04 Mark Lam <mark....@apple.com>
isUntypedSpeculationForArithmetic is wrong.
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (194560 => 194561)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2016-01-04 22:53:57 UTC (rev 194560)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2016-01-04 23:08:32 UTC (rev 194561)
@@ -53,8 +53,12 @@
#include "FTLWeightedTarget.h"
#include "JITAddGenerator.h"
#include "JITBitAndGenerator.h"
+#include "JITBitOrGenerator.h"
+#include "JITBitXorGenerator.h"
#include "JITDivGenerator.h"
+#include "JITLeftShiftGenerator.h"
#include "JITMulGenerator.h"
+#include "JITRightShiftGenerator.h"
#include "JITSubGenerator.h"
#include "JSArrowFunction.h"
#include "JSCInlines.h"
@@ -2303,8 +2307,12 @@
void compileBitOr()
{
- if (m_node->child1().useKind() == UntypedUse || m_node->child2().useKind() == UntypedUse) {
+ if (m_node->isBinaryUseKind(UntypedUse)) {
+#if FTL_USES_B3
+ emitBinaryBitOpSnippet<JITBitOrGenerator>(operationValueBitOr);
+#else // FTL_USES_B3
compileUntypedBinaryOp<BitOrDescriptor>();
+#endif // FTL_USES_B3
return;
}
setInt32(m_out.bitOr(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
@@ -2312,8 +2320,12 @@
void compileBitXor()
{
- if (m_node->child1().useKind() == UntypedUse || m_node->child2().useKind() == UntypedUse) {
+ if (m_node->isBinaryUseKind(UntypedUse)) {
+#if FTL_USES_B3
+ emitBinaryBitOpSnippet<JITBitXorGenerator>(operationValueBitXor);
+#else // FTL_USES_B3
compileUntypedBinaryOp<BitXorDescriptor>();
+#endif // FTL_USES_B3
return;
}
setInt32(m_out.bitXor(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
@@ -2321,8 +2333,12 @@
void compileBitRShift()
{
- if (m_node->child1().useKind() == UntypedUse || m_node->child2().useKind() == UntypedUse) {
+ if (m_node->isBinaryUseKind(UntypedUse)) {
+#if FTL_USES_B3
+ emitRightShiftSnippet(JITRightShiftGenerator::SignedShift);
+#else // FTL_USES_B3
compileUntypedBinaryOp<BitRShiftDescriptor>();
+#endif // FTL_USES_B3
return;
}
setInt32(m_out.aShr(
@@ -2332,8 +2348,12 @@
void compileBitLShift()
{
- if (m_node->child1().useKind() == UntypedUse || m_node->child2().useKind() == UntypedUse) {
+ if (m_node->isBinaryUseKind(UntypedUse)) {
+#if FTL_USES_B3
+ emitBinaryBitOpSnippet<JITLeftShiftGenerator>(operationValueBitLShift);
+#else // FTL_USES_B3
compileUntypedBinaryOp<BitLShiftDescriptor>();
+#endif // FTL_USES_B3
return;
}
setInt32(m_out.shl(
@@ -2343,8 +2363,12 @@
void compileBitURShift()
{
- if (m_node->child1().useKind() == UntypedUse || m_node->child2().useKind() == UntypedUse) {
+ if (m_node->isBinaryUseKind(UntypedUse)) {
+#if FTL_USES_B3
+ emitRightShiftSnippet(JITRightShiftGenerator::UnsignedShift);
+#else // FTL_USES_B3
compileUntypedBinaryOp<BitURShiftDescriptor>();
+#endif // FTL_USES_B3
return;
}
setInt32(m_out.lShr(
@@ -7511,6 +7535,65 @@
setJSValue(patchpoint);
}
+
+ void emitRightShiftSnippet(JITRightShiftGenerator::ShiftType shiftType)
+ {
+ Node* node = m_node;
+
+ // FIXME: Make this do exceptions.
+ // https://bugs.webkit.org/show_bug.cgi?id=151686
+
+ LValue left = lowJSValue(node->child1());
+ LValue right = lowJSValue(node->child2());
+
+ SnippetOperand leftOperand(m_state.forNode(node->child1()).resultType());
+ SnippetOperand rightOperand(m_state.forNode(node->child2()).resultType());
+
+ PatchpointValue* patchpoint = m_out.patchpoint(Int64);
+ patchpoint->append(left, ValueRep::SomeRegister);
+ patchpoint->append(right, ValueRep::SomeRegister);
+ patchpoint->append(m_tagMask, ValueRep::reg(GPRInfo::tagMaskRegister));
+ patchpoint->append(m_tagTypeNumber, ValueRep::reg(GPRInfo::tagTypeNumberRegister));
+ patchpoint->numGPScratchRegisters = 1;
+ patchpoint->numFPScratchRegisters = 1;
+ patchpoint->clobber(RegisterSet::macroScratchRegisters());
+ State* state = &m_ftlState;
+ patchpoint->setGenerator(
+ [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
+ AllowMacroScratchRegisterUsage allowScratch(jit);
+
+ auto generator = Box<JITRightShiftGenerator>::create(
+ leftOperand, rightOperand, JSValueRegs(params[0].gpr()),
+ JSValueRegs(params[1].gpr()), JSValueRegs(params[2].gpr()),
+ params.fpScratch(0), params.gpScratch(0), InvalidFPRReg, shiftType);
+
+ generator->generateFastPath(jit);
+ generator->endJumpList().link(&jit);
+ CCallHelpers::Label done = jit.label();
+
+ params.addLatePath(
+ [=] (CCallHelpers& jit) {
+ AllowMacroScratchRegisterUsage allowScratch(jit);
+
+ // FIXME: Make this do something.
+ CCallHelpers::JumpList exceptions;
+
+ generator->slowPathJumpList().link(&jit);
+
+ J_JITOperation_EJJ slowPathFunction =
+ shiftType == JITRightShiftGenerator::SignedShift
+ ? operationValueBitRShift : operationValueBitURShift;
+
+ callOperation(
+ *state, params.unavailableRegisters(), jit, node->origin.semantic,
+ &exceptions, slowPathFunction, params[0].gpr(), params[1].gpr(),
+ params[2].gpr());
+ jit.jump().linkTo(done, &jit);
+ });
+ });
+
+ setJSValue(patchpoint);
+ }
#endif // FTL_USES_B3
LValue allocateCell(LValue allocator, LBasicBlock slowPath)
Added: trunk/Source/_javascript_Core/tests/stress/object-bit-or.js (0 => 194561)
--- trunk/Source/_javascript_Core/tests/stress/object-bit-or.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/object-bit-or.js 2016-01-04 23:08:32 UTC (rev 194561)
@@ -0,0 +1,16 @@
+function foo(a, b) {
+ return a | b;
+}
+
+noInline(foo);
+
+var things = [{valueOf: function() { return 6; }}];
+var results = [14];
+
+for (var i = 0; i < 100000; ++i) {
+ var result = foo(things[i % things.length], 10);
+ var expected = results[i % results.length];
+ if (result != expected)
+ throw "Error: bad result for i = " + i + ": " + result;
+}
+
Added: trunk/Source/_javascript_Core/tests/stress/object-bit-xor.js (0 => 194561)
--- trunk/Source/_javascript_Core/tests/stress/object-bit-xor.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/object-bit-xor.js 2016-01-04 23:08:32 UTC (rev 194561)
@@ -0,0 +1,16 @@
+function foo(a, b) {
+ return a ^ b;
+}
+
+noInline(foo);
+
+var things = [{valueOf: function() { return 6; }}];
+var results = [12];
+
+for (var i = 0; i < 100000; ++i) {
+ var result = foo(things[i % things.length], 10);
+ var expected = results[i % results.length];
+ if (result != expected)
+ throw "Error: bad result for i = " + i + ": " + result;
+}
+
Added: trunk/Source/_javascript_Core/tests/stress/object-lshift.js (0 => 194561)
--- trunk/Source/_javascript_Core/tests/stress/object-lshift.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/object-lshift.js 2016-01-04 23:08:32 UTC (rev 194561)
@@ -0,0 +1,16 @@
+function foo(a, b) {
+ return a << b;
+}
+
+noInline(foo);
+
+var things = [{valueOf: function() { return 4; }}];
+var results = [8];
+
+for (var i = 0; i < 100000; ++i) {
+ var result = foo(things[i % things.length], 1);
+ var expected = results[i % results.length];
+ if (result != expected)
+ throw "Error: bad result for i = " + i + ": " + result;
+}
+
Added: trunk/Source/_javascript_Core/tests/stress/object-rshift.js (0 => 194561)
--- trunk/Source/_javascript_Core/tests/stress/object-rshift.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/object-rshift.js 2016-01-04 23:08:32 UTC (rev 194561)
@@ -0,0 +1,16 @@
+function foo(a, b) {
+ return a >> b;
+}
+
+noInline(foo);
+
+var things = [{valueOf: function() { return -4; }}];
+var results = [-2];
+
+for (var i = 0; i < 100000; ++i) {
+ var result = foo(things[i % things.length], 1);
+ var expected = results[i % results.length];
+ if (result != expected)
+ throw "Error: bad result for i = " + i + ": " + result;
+}
+
Added: trunk/Source/_javascript_Core/tests/stress/object-urshift.js (0 => 194561)
--- trunk/Source/_javascript_Core/tests/stress/object-urshift.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/object-urshift.js 2016-01-04 23:08:32 UTC (rev 194561)
@@ -0,0 +1,16 @@
+function foo(a, b) {
+ return a >>> b;
+}
+
+noInline(foo);
+
+var things = [{valueOf: function() { return -4; }}];
+var results = [2147483646];
+
+for (var i = 0; i < 100000; ++i) {
+ var result = foo(things[i % things.length], 1);
+ var expected = results[i % results.length];
+ if (result != expected)
+ throw "Error: bad result for i = " + i + ": " + result;
+}
+
Added: trunk/Source/_javascript_Core/tests/stress/untyped-bit-or.js (0 => 194561)
--- trunk/Source/_javascript_Core/tests/stress/untyped-bit-or.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/untyped-bit-or.js 2016-01-04 23:08:32 UTC (rev 194561)
@@ -0,0 +1,16 @@
+function foo(a, b) {
+ return a | b;
+}
+
+noInline(foo);
+
+var things = [1, 2.5, "3", {valueOf: function() { return 4; }}];
+var results = [3, 2, 3, 6];
+
+for (var i = 0; i < 100000; ++i) {
+ var result = foo(things[i % things.length], 2);
+ var expected = results[i % results.length];
+ if (result != expected)
+ throw "Error: bad result for i = " + i + ": " + result;
+}
+
Added: trunk/Source/_javascript_Core/tests/stress/untyped-bit-xor.js (0 => 194561)
--- trunk/Source/_javascript_Core/tests/stress/untyped-bit-xor.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/untyped-bit-xor.js 2016-01-04 23:08:32 UTC (rev 194561)
@@ -0,0 +1,16 @@
+function foo(a, b) {
+ return a ^ b;
+}
+
+noInline(foo);
+
+var things = [1, 2.5, "3", {valueOf: function() { return 4; }}];
+var results = [3, 0, 1, 6];
+
+for (var i = 0; i < 100000; ++i) {
+ var result = foo(things[i % things.length], 2);
+ var expected = results[i % results.length];
+ if (result != expected)
+ throw "Error: bad result for i = " + i + ": " + result;
+}
+
Added: trunk/Source/_javascript_Core/tests/stress/untyped-lshift.js (0 => 194561)
--- trunk/Source/_javascript_Core/tests/stress/untyped-lshift.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/untyped-lshift.js 2016-01-04 23:08:32 UTC (rev 194561)
@@ -0,0 +1,16 @@
+function foo(a, b) {
+ return a << b;
+}
+
+noInline(foo);
+
+var things = [1, 2.5, "3", {valueOf: function() { return 4; }}];
+var results = [2, 4, 6, 8];
+
+for (var i = 0; i < 100000; ++i) {
+ var result = foo(things[i % things.length], 1);
+ var expected = results[i % results.length];
+ if (result != expected)
+ throw "Error: bad result for i = " + i + ": " + result;
+}
+
Added: trunk/Source/_javascript_Core/tests/stress/untyped-rshift.js (0 => 194561)
--- trunk/Source/_javascript_Core/tests/stress/untyped-rshift.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/untyped-rshift.js 2016-01-04 23:08:32 UTC (rev 194561)
@@ -0,0 +1,16 @@
+function foo(a, b) {
+ return a >> b;
+}
+
+noInline(foo);
+
+var things = [1, 2.5, "3", {valueOf: function() { return 4; }}];
+var results = [0, 1, 1, 2];
+
+for (var i = 0; i < 100000; ++i) {
+ var result = foo(things[i % things.length], 1);
+ var expected = results[i % results.length];
+ if (result != expected)
+ throw "Error: bad result for i = " + i + ": " + result;
+}
+
Added: trunk/Source/_javascript_Core/tests/stress/untyped-urshift.js (0 => 194561)
--- trunk/Source/_javascript_Core/tests/stress/untyped-urshift.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/untyped-urshift.js 2016-01-04 23:08:32 UTC (rev 194561)
@@ -0,0 +1,16 @@
+function foo(a, b) {
+ return a >>> b;
+}
+
+noInline(foo);
+
+var things = [1, 2.5, "-3", {valueOf: function() { return 4; }}];
+var results = [0, 1, 2147483646, 2];
+
+for (var i = 0; i < 100000; ++i) {
+ var result = foo(things[i % things.length], 1);
+ var expected = results[i % results.length];
+ if (result != expected)
+ throw "Error: bad result for i = " + i + ": " + result;
+}
+