WebKit Bugzilla
Attachment 358218 Details for
Bug 192663
: [BigInt] Add ValueBitRShift into DFG
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP - Patch
bug-192663-20190102203706.patch (text/plain), 28.90 KB, created by
Caio Lima
on 2019-01-02 15:37:08 PST
(
hide
)
Description:
WIP - Patch
Filename:
MIME Type:
Creator:
Caio Lima
Created:
2019-01-02 15:37:08 PST
Size:
28.90 KB
patch
obsolete
>Subversion Revision: 239568 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 0aedd60f37b3dc092f3bc2f3b3ef81a0ec3f29fc..b7d562df8197a04e4cef31be5d342112a8723cd3 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,62 @@ >+2019-01-02 Caio Lima <ticaiolima@gmail.com> >+ >+ [BigInt] Add ValueBitRShift into DFG >+ https://bugs.webkit.org/show_bug.cgi?id=192663 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ We are introducing a new node called ValueBitRShift that is >+ responsible to handle speculation of UntypedUse and BigIntUse during >+ DFG. Following the approach from other bitwise operations, we >+ now have 2 nodes to handle ">>" operator during JIT, mainly because >+ of the introduction of BigInt, that makes this operator result into >+ Int32 or BigInt. We renamed BitRShift node to ArithBitRShift and such >+ node handles Integers and Numbers speculation and can only return >+ Int32 values. >+ >+ * dfg/DFGAbstractInterpreterInlines.h: >+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): >+ * dfg/DFGBackwardsPropagationPhase.cpp: >+ (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwo): >+ (JSC::DFG::BackwardsPropagationPhase::propagate): >+ * dfg/DFGByteCodeParser.cpp: >+ (JSC::DFG::ByteCodeParser::parseBlock): >+ * 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::hasInt32Result): >+ (JSC::DFG::Node::hasNumberOrAnyIntResult): >+ (JSC::DFG::Node::hasNumericResult): >+ * dfg/DFGNodeType.h: >+ * dfg/DFGOperations.cpp: >+ * dfg/DFGOperations.h: >+ * dfg/DFGPredictionPropagationPhase.cpp: >+ * dfg/DFGSafeToExecute.h: >+ (JSC::DFG::safeToExecute): >+ * dfg/DFGSpeculativeJIT.cpp: >+ (JSC::DFG::SpeculativeJIT::emitUntypedRightShiftBitOp): >+ (JSC::DFG::SpeculativeJIT::compileValueBitRShift): >+ (JSC::DFG::SpeculativeJIT::compileShiftOp): >+ * dfg/DFGSpeculativeJIT.h: >+ (JSC::DFG::SpeculativeJIT::shiftOp): >+ * dfg/DFGSpeculativeJIT32_64.cpp: >+ (JSC::DFG::SpeculativeJIT::compile): >+ * dfg/DFGSpeculativeJIT64.cpp: >+ (JSC::DFG::SpeculativeJIT::compile): >+ * dfg/DFGStrengthReductionPhase.cpp: >+ (JSC::DFG::StrengthReductionPhase::handleNode): >+ * ftl/FTLCapabilities.cpp: >+ (JSC::FTL::canCompile): >+ * ftl/FTLLowerDFGToB3.cpp: >+ (JSC::FTL::DFG::LowerDFGToB3::compileNode): >+ (JSC::FTL::DFG::LowerDFGToB3::compileValueBitRShift): >+ (JSC::FTL::DFG::LowerDFGToB3::compileArithBitRShift): >+ (JSC::FTL::DFG::LowerDFGToB3::compileBitRShift): Deleted. >+ > 2019-01-01 Jeff Miller <jeffm@apple.com> > > Update user-visible copyright strings to include 2019 >diff --git a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >index 5197133ead4b2d28d1fb3ecfc547ff77f01ba905..4f76ebe38589aa9877d56c6f316ab4b70470cda5 100644 >--- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >+++ b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >@@ -397,6 +397,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi > case ValueBitXor: > case ValueBitAnd: > case ValueBitOr: >+ case ValueBitRShift: > if (node->binaryUseKind() == BigIntUse) > setTypeForNode(node, SpecBigInt); > else { >@@ -408,7 +409,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi > case ArithBitAnd: > case ArithBitOr: > case ArithBitXor: >- case BitRShift: >+ case ArithBitRShift: > case BitLShift: > case BitURShift: { > if (node->child1().useKind() == UntypedUse || node->child2().useKind() == UntypedUse) { >@@ -432,7 +433,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi > case ArithBitXor: > setConstant(node, JSValue(a ^ b)); > break; >- case BitRShift: >+ case ArithBitRShift: > setConstant(node, JSValue(a >> static_cast<uint32_t>(b))); > break; > case BitLShift: >diff --git a/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp >index 05c86ed1eb05f129ed4d00206d31e4e1f25d6159..4113ad7e62383066677576a0c8d023387dfe5152 100644 >--- a/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp >+++ b/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp >@@ -124,7 +124,8 @@ private: > return power > 31; > } > >- case BitRShift: >+ case ArithBitRShift: >+ case ValueBitRShift: > case BitURShift: { > if (power > 31) > return true; >@@ -218,7 +219,8 @@ private: > case ArithBitAnd: > case ArithBitOr: > case ArithBitXor: >- case BitRShift: >+ case ArithBitRShift: >+ case ValueBitRShift: > case BitLShift: > case BitURShift: > case ArithIMul: { >diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >index d6e3843a8d8349490154e08777274f08655f650b..519f060fb0e67f4efd165eb581eaac989d87b233 100644 >--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >@@ -4967,7 +4967,10 @@ void ByteCodeParser::parseBlock(unsigned limit) > auto bytecode = currentInstruction->as<OpRshift>(); > Node* op1 = get(bytecode.lhs); > Node* op2 = get(bytecode.rhs); >- set(bytecode.dst, addToGraph(BitRShift, op1, op2)); >+ if (op1->hasNumberOrAnyIntResult() && op2->hasNumberOrAnyIntResult()) >+ set(bytecode.dst, addToGraph(ArithBitRShift, op1, op2)); >+ else >+ set(bytecode.dst, addToGraph(ValueBitRShift, op1, op2)); > NEXT_OPCODE(op_rshift); > } > >diff --git a/Source/JavaScriptCore/dfg/DFGClobberize.h b/Source/JavaScriptCore/dfg/DFGClobberize.h >index 48c846bd3897d14de4e25b27d9570d82da871ae9..9aaea41181002f5e407379775c479b074cdeb16b 100644 >--- a/Source/JavaScriptCore/dfg/DFGClobberize.h >+++ b/Source/JavaScriptCore/dfg/DFGClobberize.h >@@ -275,7 +275,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu > case ArithBitOr: > case ArithBitXor: > case BitLShift: >- case BitRShift: >+ case ArithBitRShift: > case BitURShift: > if (node->child1().useKind() == UntypedUse || node->child2().useKind() == UntypedUse) { > read(World); >@@ -673,6 +673,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu > case ValueSub: > case ValueMul: > case ValueDiv: >+ case ValueBitRShift: > if (node->isBinaryUseKind(BigIntUse)) { > def(PureValue(node)); > return; >diff --git a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp >index df74930bdbb3864ad944bc4720712fe0f3947bd5..e0d5d4e8356c9b6e4ad0f36c2d652bcf5e495599 100644 >--- a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp >+++ b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp >@@ -72,7 +72,7 @@ bool doesGC(Graph& graph, Node* node) > case ArithBitOr: > case ArithBitXor: > case BitLShift: >- case BitRShift: >+ case ArithBitRShift: > case BitURShift: > case ValueToInt32: > case UInt32ToNumber: >@@ -100,6 +100,7 @@ bool doesGC(Graph& graph, Node* node) > case ValueBitAnd: > case ValueBitOr: > case ValueBitXor: >+ case ValueBitRShift: > case ValueAdd: > case ValueSub: > case ValueMul: >diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp >index 307632dad59da8e23250db1b4497d0341ba95292..e208d4bec992c7f5a77fbe66f6ed5e5e717bcb45 100644 >--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp >+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp >@@ -250,7 +250,28 @@ private: > break; > } > >- case BitRShift: >+ case ValueBitRShift: { >+ if (Node::shouldSpeculateBigInt(node->child1().node(), node->child2().node())) { >+ fixEdge<BigIntUse>(node->child1()); >+ fixEdge<BigIntUse>(node->child2()); >+ break; >+ } >+ >+ if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())) { >+ fixEdge<UntypedUse>(node->child1()); >+ fixEdge<UntypedUse>(node->child2()); >+ break; >+ } >+ >+ node->setOp(ArithBitRShift); >+ node->clearFlags(NodeMustGenerate); >+ node->setResult(NodeResultInt32); >+ fixIntConvertingEdge(node->child1()); >+ fixIntConvertingEdge(node->child2()); >+ break; >+ } >+ >+ case ArithBitRShift: > case BitLShift: > case BitURShift: { > if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())) { >diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h >index b8014755c7bcb50914ed39d61a53d94aca86021e..5f152ca88a7b702644883161b77e2073f1989d10 100644 >--- a/Source/JavaScriptCore/dfg/DFGNode.h >+++ b/Source/JavaScriptCore/dfg/DFGNode.h >@@ -1363,6 +1363,11 @@ public: > return !!result(); > } > >+ bool hasInt32Result() >+ { >+ return result() == NodeResultInt32; >+ } >+ > bool hasInt52Result() > { > return result() == NodeResultInt52; >@@ -1372,6 +1377,11 @@ public: > { > return result() == NodeResultNumber; > } >+ >+ bool hasNumberOrAnyIntResult() >+ { >+ return hasNumberResult() || hasInt32Result() || hasInt52Result(); >+ } > > bool hasNumericResult() > { >@@ -1382,6 +1392,7 @@ public: > case ValueBitOr: > case ValueBitXor: > case ValueNegate: >+ case ValueBitRShift: > return true; > default: > return false; >diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h >index dc2f3e16b832aac0af7f0ad63c4c8e281dcba34e..d9aebc802c6763b72ba1587f523eb2863b757286 100644 >--- a/Source/JavaScriptCore/dfg/DFGNodeType.h >+++ b/Source/JavaScriptCore/dfg/DFGNodeType.h >@@ -119,7 +119,8 @@ namespace JSC { namespace DFG { > macro(ValueBitXor, NodeResultJS | NodeMustGenerate) \ > macro(ArithBitXor, NodeResultInt32) \ > macro(BitLShift, NodeResultInt32) \ >- macro(BitRShift, NodeResultInt32) \ >+ macro(ArithBitRShift, NodeResultInt32) \ >+ macro(ValueBitRShift, NodeResultJS | NodeMustGenerate) \ > macro(BitURShift, NodeResultInt32) \ > /* Bitwise operators call ToInt32 on their operands. */\ > macro(ValueToInt32, NodeResultInt32) \ >diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp >index 1da406ba7e92767324201c788b3778b52e698819..7f5f21eeed11601691cea167467352409abeba5a 100644 >--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp >+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp >@@ -472,11 +472,22 @@ EncodedJSValue JIT_OPERATION operationValueBitRShift(ExecState* exec, EncodedJSV > JSValue op1 = JSValue::decode(encodedOp1); > JSValue op2 = JSValue::decode(encodedOp2); > >- int32_t a = op1.toInt32(exec); >+ auto leftNumeric = op1.toBigIntOrInt32(exec); > RETURN_IF_EXCEPTION(scope, encodedJSValue()); >- scope.release(); >- uint32_t b = op2.toUInt32(exec); >- return JSValue::encode(jsNumber(a >> (b & 0x1f))); >+ auto rightNumeric = op2.toBigIntOrInt32(exec); >+ RETURN_IF_EXCEPTION(scope, encodedJSValue()); >+ >+ if (WTF::holds_alternative<JSBigInt*>(leftNumeric) || WTF::holds_alternative<JSBigInt*>(rightNumeric)) { >+ if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) { >+ JSBigInt* result = JSBigInt::signedRightShift(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); >+ RETURN_IF_EXCEPTION(scope, encodedJSValue()); >+ return JSValue::encode(result); >+ } >+ >+ return throwVMTypeError(exec, scope, "Invalid mix of BigInt and other type in signed right shift operation."); >+ } >+ >+ return JSValue::encode(jsNumber(WTF::get<int32_t>(leftNumeric) >> (WTF::get<int32_t>(rightNumeric) & 0x1f))); > } > > EncodedJSValue JIT_OPERATION operationValueBitURShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) >@@ -1385,6 +1396,17 @@ JSCell* JIT_OPERATION operationAddBigInt(ExecState* exec, JSCell* op1, JSCell* o > return JSBigInt::add(exec, leftOperand, rightOperand); > } > >+JSCell* JIT_OPERATION operationBitRShiftBigInt(ExecState* exec, JSCell* op1, JSCell* op2) >+{ >+ VM* vm = &exec->vm(); >+ NativeCallFrameTracer tracer(vm, exec); >+ >+ JSBigInt* leftOperand = jsCast<JSBigInt*>(op1); >+ JSBigInt* rightOperand = jsCast<JSBigInt*>(op2); >+ >+ return JSBigInt::signedRightShift(exec, leftOperand, rightOperand); >+} >+ > JSCell* JIT_OPERATION operationBitOrBigInt(ExecState* exec, JSCell* op1, JSCell* op2) > { > VM* vm = &exec->vm(); >diff --git a/Source/JavaScriptCore/dfg/DFGOperations.h b/Source/JavaScriptCore/dfg/DFGOperations.h >index 38c116a54f91a615b81c15112148f25f94adb1ef..beab073360ea4c18ebda9ed1b3ba8f6097b762d8 100644 >--- a/Source/JavaScriptCore/dfg/DFGOperations.h >+++ b/Source/JavaScriptCore/dfg/DFGOperations.h >@@ -172,6 +172,7 @@ JSCell* JIT_OPERATION operationDivBigInt(ExecState*, JSCell* op1, JSCell* op2) W > JSCell* JIT_OPERATION operationBitAndBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL; > JSCell* JIT_OPERATION operationBitOrBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL; > JSCell* JIT_OPERATION operationAddBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL; >+JSCell* JIT_OPERATION operationBitRShiftBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL; > JSCell* JIT_OPERATION operationBitXorBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL; > size_t JIT_OPERATION operationSameValue(ExecState*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL; > JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState*, Structure*, JSScope*, SymbolTable*, EncodedJSValue); >diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp >index b3c69bcf124727bfcc676b2afadab5a88c22f93a..b167f91c6e97a34e64cc0ecf3382c875ac347599 100644 >--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp >+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp >@@ -277,11 +277,21 @@ private: > break; > } > >+ case ValueBitRShift: > case ValueBitXor: > case ValueBitOr: > case ValueBitAnd: { >- if (node->child1()->shouldSpeculateBigInt() && node->child2()->shouldSpeculateBigInt()) >- changed |= mergePrediction(SpecBigInt); >+ SpeculatedType left = node->child1()->prediction(); >+ SpeculatedType right = node->child2()->prediction(); >+ >+ if (left && right) { >+ if (isBigIntSpeculation(left) && isBigIntSpeculation(right)) >+ changed |= mergePrediction(SpecBigInt); >+ else if (isFullNumberOrBooleanSpeculationExpectingDefined(left) && isFullNumberOrBooleanSpeculationExpectingDefined(right)) >+ changed |= mergePrediction(SpecInt32Only); >+ else >+ changed |= mergePrediction(SpecBigInt | SpecInt32Only); >+ } > break; > } > >@@ -758,7 +768,7 @@ private: > case ArithBitAnd: > case ArithBitOr: > case ArithBitXor: >- case BitRShift: >+ case ArithBitRShift: > case BitLShift: > case BitURShift: > case ArithIMul: >@@ -1119,6 +1129,7 @@ private: > case ValueBitOr: > case ValueBitAnd: > case ValueBitXor: >+ case ValueBitRShift: > case ValueNegate: > case ValueAdd: > case ValueSub: >diff --git a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h >index f106982ae39ff3bcc36cfb5aee0d716c07e94316..58cb42830e638cc0d84e5f1c5f43fd7f0a85af7c 100644 >--- a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h >+++ b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h >@@ -203,7 +203,7 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node, bool igno > case ArithBitOr: > case ArithBitXor: > case BitLShift: >- case BitRShift: >+ case ArithBitRShift: > case BitURShift: > case ValueToInt32: > case UInt32ToNumber: >@@ -231,6 +231,7 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node, bool igno > case ValueBitAnd: > case ValueBitXor: > case ValueBitOr: >+ case ValueBitRShift: > case ValueNegate: > case ValueAdd: > case ValueSub: >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >index 63e09fb915ea97f04ae1f0f90e0e7f5c192bdd4f..d74072de3aff212fd35d8f8662a43b31fa9e44c7 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >@@ -3719,9 +3719,9 @@ void SpeculativeJIT::compileBitwiseOp(Node* node) > > void SpeculativeJIT::emitUntypedRightShiftBitOp(Node* node) > { >- J_JITOperation_EJJ snippetSlowPathFunction = node->op() == BitRShift >+ J_JITOperation_EJJ snippetSlowPathFunction = node->op() == ValueBitRShift > ? operationValueBitRShift : operationValueBitURShift; >- JITRightShiftGenerator::ShiftType shiftType = node->op() == BitRShift >+ JITRightShiftGenerator::ShiftType shiftType = node->op() == ValueBitRShift > ? JITRightShiftGenerator::SignedShift : JITRightShiftGenerator::UnsignedShift; > > Edge& leftChild = node->child1(); >@@ -3816,6 +3816,30 @@ void SpeculativeJIT::emitUntypedRightShiftBitOp(Node* node) > return; > } > >+void SpeculativeJIT::compileValueBitRShift(Node* node) >+{ >+ if (node->isBinaryUseKind(BigIntUse)) { >+ SpeculateCellOperand left(this, node->child1()); >+ SpeculateCellOperand right(this, node->child2()); >+ GPRReg leftGPR = left.gpr(); >+ GPRReg rightGPR = right.gpr(); >+ >+ speculateBigInt(node->child1(), leftGPR); >+ speculateBigInt(node->child2(), rightGPR); >+ >+ flushRegisters(); >+ GPRFlushedCallResult result(this); >+ GPRReg resultGPR = result.gpr(); >+ callOperation(operationBitRShiftBigInt, resultGPR, leftGPR, rightGPR); >+ m_jit.exceptionCheck(); >+ >+ cellResult(resultGPR, node); >+ return; >+ } >+ >+ emitUntypedRightShiftBitOp(node); >+} >+ > void SpeculativeJIT::compileShiftOp(Node* node) > { > NodeType op = node->op(); >@@ -3827,7 +3851,6 @@ void SpeculativeJIT::compileShiftOp(Node* node) > case BitLShift: > emitUntypedBitOp<JITLeftShiftGenerator, operationValueBitLShift>(node); > return; >- case BitRShift: > case BitURShift: > emitUntypedRightShiftBitOp(node); > return; >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >index dcdf9664fc4de580f87694d7fb78f5f8b6c6757a..e1a1331b6df411844805fee65fb3e6cf52f07e5a 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >@@ -665,7 +665,7 @@ public: > void shiftOp(NodeType op, GPRReg op1, int32_t shiftAmount, GPRReg result) > { > switch (op) { >- case BitRShift: >+ case ArithBitRShift: > m_jit.rshift32(op1, Imm32(shiftAmount), result); > break; > case BitLShift: >@@ -681,7 +681,7 @@ public: > void shiftOp(NodeType op, GPRReg op1, GPRReg shiftAmount, GPRReg result) > { > switch (op) { >- case BitRShift: >+ case ArithBitRShift: > m_jit.rshift32(op1, shiftAmount, result); > break; > case BitLShift: >@@ -1338,6 +1338,7 @@ public: > void compileValueBitwiseOp(Node*); > > void emitUntypedRightShiftBitOp(Node*); >+ void compileValueBitRShift(Node*); > void compileShiftOp(Node*); > > template <typename Generator, typename RepatchingFunction, typename NonRepatchingFunction> >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp >index fcda6a61f8bc74e7136982422476949f68a085eb..b90ea497cf1efcaf4506a25e2d617c55eae3a29d 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp >@@ -1995,7 +1995,11 @@ void SpeculativeJIT::compile(Node* node) > compileBitwiseNot(node); > break; > >- case BitRShift: >+ case ValueBitRShift: >+ compileValueBitRShift(node); >+ break; >+ >+ case ArithBitRShift: > case BitLShift: > case BitURShift: > compileShiftOp(node); >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >index 553f86f50675840823a16e5e58386f79bcac4f2e..26c8ede644f53bf85026e5d57f51fdb74cec92bf 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >@@ -2090,7 +2090,11 @@ void SpeculativeJIT::compile(Node* node) > compileBitwiseOp(node); > break; > >- case BitRShift: >+ case ValueBitRShift: >+ compileValueBitRShift(node); >+ break; >+ >+ case ArithBitRShift: > case BitLShift: > case BitURShift: > compileShiftOp(node); >diff --git a/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp b/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp >index 18bec693e2d0f70cd6dd5e90cb01a7c086d350b9..5020e9e3aaead922c8c329453163c330ae7e761d 100644 >--- a/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp >+++ b/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp >@@ -93,7 +93,7 @@ private: > break; > > case BitLShift: >- case BitRShift: >+ case ArithBitRShift: > case BitURShift: > if (m_node->child1().useKind() != UntypedUse && m_node->child2()->isInt32Constant() && !(m_node->child2()->asInt32() & 0x1f)) { > convertToIdentityOverChild1(); >diff --git a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp >index 23c9396f4d69e04f6f0cb5f491ba04e6ccfad10a..6086cac7f74fb39ddc085c62c4ace2ffc1b4c614 100644 >--- a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp >+++ b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp >@@ -62,7 +62,7 @@ inline CapabilityLevel canCompile(Node* node) > case ArithBitAnd: > case ArithBitOr: > case ArithBitXor: >- case BitRShift: >+ case ArithBitRShift: > case BitLShift: > case BitURShift: > case CheckStructure: >@@ -91,6 +91,7 @@ inline CapabilityLevel canCompile(Node* node) > case ValueBitAnd: > case ValueBitXor: > case ValueBitOr: >+ case ValueBitRShift: > case ValueNegate: > case ValueAdd: > case ValueSub: >diff --git a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >index 4130bd1ddb4d46f7fff9e1086309d55e5c9922c2..5f846e39d5e7d6f759ce79f8b773c6d087b73897 100644 >--- a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >+++ b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >@@ -680,8 +680,11 @@ private: > case ValueBitXor: > compileValueBitXor(); > break; >- case BitRShift: >- compileBitRShift(); >+ case ValueBitRShift: >+ compileValueBitRShift(); >+ break; >+ case ArithBitRShift: >+ compileArithBitRShift(); > break; > case BitLShift: > compileBitLShift(); >@@ -2950,12 +2953,22 @@ private: > setInt32(m_out.bitXor(lowInt32(m_node->child1()), lowInt32(m_node->child2()))); > } > >- void compileBitRShift() >+ void compileValueBitRShift() > { >- if (m_node->isBinaryUseKind(UntypedUse)) { >- emitRightShiftSnippet(JITRightShiftGenerator::SignedShift); >+ if (m_node->isBinaryUseKind(BigIntUse)) { >+ LValue left = lowBigInt(m_node->child1()); >+ LValue right = lowBigInt(m_node->child2()); >+ >+ LValue result = vmCall(pointerType(), m_out.operation(operationBitRShiftBigInt), m_callFrame, left, right); >+ setJSValue(result); > return; > } >+ >+ emitRightShiftSnippet(JITRightShiftGenerator::SignedShift); >+ } >+ >+ void compileArithBitRShift() >+ { > setInt32(m_out.aShr( > lowInt32(m_node->child1()), > m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31)))); >diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog >index 8cd88133220b2253c6fdae49e5c4d622389e9b9e..dcb4645806b95f4a4a3943cd8a66e22e12cd9a1b 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,14 @@ >+2019-01-02 Caio Lima <ticaiolima@gmail.com> >+ >+ [BigInt] Add ValueBitRShift into DFG >+ https://bugs.webkit.org/show_bug.cgi?id=192663 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * stress/big-int-right-shift-jit-osr.js: Added. >+ * stress/big-int-right-shift-jit-untyped.js: Added. >+ * stress/big-int-right-shift-jit.js: Added. >+ > 2018-12-30 Yusuke Suzuki <yusukesuzuki@slowstart.org> > > Unreviewed, JSTests gardening with memoryLimited >diff --git a/JSTests/stress/big-int-right-shift-jit-osr.js b/JSTests/stress/big-int-right-shift-jit-osr.js >new file mode 100644 >index 0000000000000000000000000000000000000000..248fc8d9fe2ec7a14dbd2c56e5c483af98ae765d >--- /dev/null >+++ b/JSTests/stress/big-int-right-shift-jit-osr.js >@@ -0,0 +1,25 @@ >+//@ runBigIntEnabled >+ >+let assert = { >+ sameValue: function(i, e, m) { >+ if (i !== e) >+ throw new Error(m); >+ } >+} >+ >+function bigIntRShift(x, y) { >+ return x >> y; >+} >+noInline(bigIntRShift); >+ >+for (let i = 0; i < 10000; i++) { >+ let r = bigIntRShift(0b100111n, 2n); >+ assert.sameValue(r, 0b1001n, 0b100111n + " >> " + 2n + " = " + r); >+} >+ >+let r = bigIntRShift(3, 10); >+assert.sameValue(r, 0, 3 + " >> " + 10 + " = " + r); >+ >+r = bigIntRShift("3", "10"); >+assert.sameValue(r, 0, 3 + " >> " + 10 + " = " + r); >+ >diff --git a/JSTests/stress/big-int-right-shift-jit-untyped.js b/JSTests/stress/big-int-right-shift-jit-untyped.js >new file mode 100644 >index 0000000000000000000000000000000000000000..b0d61318993725591b3e9bac568f6dd4236daf8b >--- /dev/null >+++ b/JSTests/stress/big-int-right-shift-jit-untyped.js >@@ -0,0 +1,36 @@ >+//@ runBigIntEnabled >+ >+let assert = { >+ sameValue: function(i, e, m) { >+ if (i !== e) >+ throw new Error(m); >+ } >+} >+ >+function bigIntRShift(x, y) { >+ return x >> y; >+} >+noInline(bigIntRShift); >+ >+let o = {valueOf: () => 4n}; >+ >+for (let i = 0; i < 10000; i++) { >+ let r = bigIntRShift(0b10001n, o); >+ assert.sameValue(r, 1n, 0b10001n + " >> {valueOf: () => 4n} = " + r); >+} >+ >+o2 = {valueOf: () => 0b10000n}; >+ >+for (let i = 0; i < 10000; i++) { >+ let r = bigIntRShift(o2, o); >+ assert.sameValue(r, 1n, "{valueOf: () => 0b10000n} >> {valueOf: () => 4n} = " + r); >+} >+ >+o = Object(0b10n); >+let r = bigIntRShift(0b11n, o); >+assert.sameValue(r, 0n, 0b11n + " >> Object(0b10n) = " + r); >+ >+o2 = Object(0b1100001n); >+r = bigIntRShift(o2, o); >+assert.sameValue(r, 0b11000n, "Object(0b1100001n) * Object(10n) = " + r); >+ >diff --git a/JSTests/stress/big-int-right-shift-jit.js b/JSTests/stress/big-int-right-shift-jit.js >new file mode 100644 >index 0000000000000000000000000000000000000000..6bc3f846d0993548279d0def2013aa5df5e2b6e9 >--- /dev/null >+++ b/JSTests/stress/big-int-right-shift-jit.js >@@ -0,0 +1,19 @@ >+//@ runBigIntEnabled >+ >+let assert = { >+ sameValue: function(i, e, m) { >+ if (i !== e) >+ throw new Error(m); >+ } >+} >+ >+function bigIntRShift(x, y) { >+ return x >> y; >+} >+noInline(bigIntRShift); >+ >+for (let i = 0; i < 10000; i++) { >+ let r = bigIntRShift(0b10001n, 4n); >+ assert.sameValue(r, 1n, 0b10001n + " >> " + 4n + " = " + r); >+} >+ >diff --git a/PerformanceTests/BigIntBench/big-int-simple-rshift.js b/PerformanceTests/BigIntBench/big-int-simple-rshift.js >new file mode 100644 >index 0000000000000000000000000000000000000000..a385fe67114cf9c38b1f785d6c3a2d8e1d5e759d >--- /dev/null >+++ b/PerformanceTests/BigIntBench/big-int-simple-rshift.js >@@ -0,0 +1,15 @@ >+function bigInt(a, b) { >+ let c = a >> b; >+ return (a >> c) - b; >+} >+noInline(bigInt); >+ >+for (let i = 0; i < 100000; i++) { >+ bigInt(0b1111n, 2n); >+} >+ >+let out; >+for (let i = 0; i < 100000; i++) { >+ out = bigInt(0xffffffffffffffffffn, 64n); >+} >+ >diff --git a/PerformanceTests/ChangeLog b/PerformanceTests/ChangeLog >index e3244041bc49a8815d701b362cb647c454178d54..6f97a7a379c14b31f750395ebcb2850ceb5ea877 100644 >--- a/PerformanceTests/ChangeLog >+++ b/PerformanceTests/ChangeLog >@@ -1,3 +1,12 @@ >+2019-01-02 Caio Lima <ticaiolima@gmail.com> >+ >+ [BigInt] Add ValueBitRShift into DFG >+ https://bugs.webkit.org/show_bug.cgi?id=192663 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * BigIntBench/big-int-simple-rshift.js: Added. >+ > 2018-12-20 Caio Lima <ticaiolima@gmail.com> > > [BigInt] We should enable CSE into arithmetic operations that speculate BigIntUse
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 192663
:
358218
|
359607
|
359608
|
374914
|
375408
|
378570
|
378660