WebKit Bugzilla
Attachment 358148 Details for
Bug 192664
: [BigInt] Add ValueBitLShift into DFG
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP - Patch
bug-192664-20181230124130.patch (text/plain), 30.19 KB, created by
Caio Lima
on 2018-12-30 07:41:33 PST
(
hide
)
Description:
WIP - Patch
Filename:
MIME Type:
Creator:
Caio Lima
Created:
2018-12-30 07:41:33 PST
Size:
30.19 KB
patch
obsolete
>Subversion Revision: 239558 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 8e5c858959c96f04584f543a187b7513029373bd..a4a08df9b542d6c16409db93dcd591b9c7193f9b 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,68 @@ >+2018-12-30 Caio Lima <ticaiolima@gmail.com> >+ >+ [BigInt] Add ValueBitLShift into DFG >+ https://bugs.webkit.org/show_bug.cgi?id=192664 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch is splitting the BitLShift into ArithBitLShift and >+ ValueBitLShift to handle BigInt speculation more efficiently during >+ DFG and FTL layers. Following the same approach of other ValueBitOps, >+ ValueBitLShift handles Untyped and BigInt speculations, while >+ ArithBitLShift handles number and boolean operands and always results into >+ Int32. >+ >+ * bytecode/BytecodeList.rb: >+ * bytecode/CodeBlock.cpp: >+ (JSC::CodeBlock::finishCreation): >+ * bytecode/Opcode.h: >+ (JSC::padOpcodeName): >+ * 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::handleIntrinsicGetter): >+ (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): >+ * dfg/DFGNodeType.h: >+ * dfg/DFGOperations.cpp: >+ * dfg/DFGOperations.h: >+ * dfg/DFGPredictionPropagationPhase.cpp: >+ * dfg/DFGSafeToExecute.h: >+ (JSC::DFG::safeToExecute): >+ * dfg/DFGSpeculativeJIT.cpp: >+ (JSC::DFG::SpeculativeJIT::compileValueShiftOp): >+ (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::compileArithBitLShift): >+ (JSC::FTL::DFG::LowerDFGToB3::compileValueBitLShift): >+ (JSC::FTL::DFG::LowerDFGToB3::compileBitLShift): Deleted. >+ * llint/LowLevelInterpreter32_64.asm: >+ * llint/LowLevelInterpreter64.asm: >+ * runtime/CommonSlowPaths.cpp: >+ (JSC::SLOW_PATH_DECL): >+ > 2018-12-28 Yusuke Suzuki <yusukesuzuki@slowstart.org> > > [JSC] Remove one indirection in JSObject::toStringName >diff --git a/Source/JavaScriptCore/bytecode/BytecodeList.rb b/Source/JavaScriptCore/bytecode/BytecodeList.rb >index a0672d5f4eb8056f55257ae89d7b1325ac9dbae3..243841f2a3e1e09d2e1b2306523db1365e671bee 100644 >--- a/Source/JavaScriptCore/bytecode/BytecodeList.rb >+++ b/Source/JavaScriptCore/bytecode/BytecodeList.rb >@@ -224,7 +224,6 @@ op_group :BinaryOp, > :beloweq, > :mod, > :pow, >- :lshift, > :rshift, > :urshift, > ], >@@ -259,6 +258,7 @@ op_group :ValueProfiledBinaryOp, > :bitand, > :bitor, > :bitxor, >+ :lshift, > ], > args: { > dst: VirtualRegister, >diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >index 7afda363172aab86f39cafa383ad87e6675c6272..e4adc02fb162bcaacdfdb39117b1da5de773dfff 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >@@ -568,6 +568,7 @@ bool CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, Unlink > LINK(OpBitor, profile) > LINK(OpBitnot, profile) > LINK(OpBitxor, profile) >+ LINK(OpLshift, profile) > > LINK(OpGetById, profile, hitCountForLLIntCaching) > >diff --git a/Source/JavaScriptCore/bytecode/Opcode.h b/Source/JavaScriptCore/bytecode/Opcode.h >index 1f39b7f9d9c32008edaeeaee64b5297691da28a5..e5fcae4d4ad8ccfe4720bd5d902d40acd6a5c567 100644 >--- a/Source/JavaScriptCore/bytecode/Opcode.h >+++ b/Source/JavaScriptCore/bytecode/Opcode.h >@@ -111,6 +111,7 @@ IGNORE_WARNINGS_END > macro(OpBitor) \ > macro(OpBitnot) \ > macro(OpBitxor) \ >+ macro(OpLshift) \ > > #define FOR_EACH_OPCODE_WITH_ARRAY_PROFILE(macro) \ > macro(OpHasIndexedProperty) \ >diff --git a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >index 5197133ead4b2d28d1fb3ecfc547ff77f01ba905..43afc3bb97a1ea856032e70dd23361cc41083f29 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 ValueBitLShift: > if (node->binaryUseKind() == BigIntUse) > setTypeForNode(node, SpecBigInt); > else { >@@ -409,7 +410,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi > case ArithBitOr: > case ArithBitXor: > case BitRShift: >- case BitLShift: >+ case ArithBitLShift: > case BitURShift: { > if (node->child1().useKind() == UntypedUse || node->child2().useKind() == UntypedUse) { > clobberWorld(); >@@ -435,7 +436,7 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi > case BitRShift: > setConstant(node, JSValue(a >> static_cast<uint32_t>(b))); > break; >- case BitLShift: >+ case ArithBitLShift: > setConstant(node, JSValue(a << static_cast<uint32_t>(b))); > break; > case BitURShift: >diff --git a/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp >index 05c86ed1eb05f129ed4d00206d31e4e1f25d6159..a6f0fb4a1f304a8311d085159dc3c870c224229b 100644 >--- a/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp >+++ b/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp >@@ -120,7 +120,8 @@ private: > > case ArithBitOr: > case ArithBitXor: >- case BitLShift: { >+ case ValueBitLShift: >+ case ArithBitLShift: { > return power > 31; > } > >@@ -219,7 +220,8 @@ private: > case ArithBitOr: > case ArithBitXor: > case BitRShift: >- case BitLShift: >+ case ValueBitLShift: >+ case ArithBitLShift: > case BitURShift: > case ArithIMul: { > flags |= NodeBytecodeUsesAsInt; >diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >index d6e3843a8d8349490154e08777274f08655f650b..779ea8a162a15b8d4235dcd2916332ab3a75d8a5 100644 >--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >@@ -3439,7 +3439,7 @@ bool ByteCodeParser::handleIntrinsicGetter(VirtualRegister result, SpeculatedTyp > // We can use a BitLShift here because typed arrays will never have a byteLength > // that overflows int32. > Node* shiftNode = jsConstant(jsNumber(logSize)); >- set(result, addToGraph(BitLShift, lengthNode, shiftNode)); >+ set(result, addToGraph(ArithBitLShift, lengthNode, shiftNode)); > > return true; > } >@@ -4975,7 +4975,10 @@ void ByteCodeParser::parseBlock(unsigned limit) > auto bytecode = currentInstruction->as<OpLshift>(); > Node* op1 = get(bytecode.lhs); > Node* op2 = get(bytecode.rhs); >- set(bytecode.dst, addToGraph(BitLShift, op1, op2)); >+ if (op1->hasNumberOrAnyIntResult() && op2->hasNumberOrAnyIntResult()) >+ set(bytecode.dst, addToGraph(ArithBitLShift, op1, op2)); >+ else >+ set(bytecode.dst, addToGraph(ValueBitLShift, op1, op2)); > NEXT_OPCODE(op_lshift); > } > >diff --git a/Source/JavaScriptCore/dfg/DFGClobberize.h b/Source/JavaScriptCore/dfg/DFGClobberize.h >index 48c846bd3897d14de4e25b27d9570d82da871ae9..c0fe3162e6f78f3eb16130448f0ed2005c9e81d7 100644 >--- a/Source/JavaScriptCore/dfg/DFGClobberize.h >+++ b/Source/JavaScriptCore/dfg/DFGClobberize.h >@@ -274,7 +274,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu > case ArithBitAnd: > case ArithBitOr: > case ArithBitXor: >- case BitLShift: >+ case ArithBitLShift: > case BitRShift: > case BitURShift: > if (node->child1().useKind() == UntypedUse || node->child2().useKind() == UntypedUse) { >@@ -673,6 +673,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu > case ValueSub: > case ValueMul: > case ValueDiv: >+ case ValueBitLShift: > if (node->isBinaryUseKind(BigIntUse)) { > def(PureValue(node)); > return; >diff --git a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp >index df74930bdbb3864ad944bc4720712fe0f3947bd5..adb48bc829a7ab9c8c8fa0df4ad393b6d87108d4 100644 >--- a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp >+++ b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp >@@ -71,7 +71,7 @@ bool doesGC(Graph& graph, Node* node) > case ArithBitAnd: > case ArithBitOr: > case ArithBitXor: >- case BitLShift: >+ case ArithBitLShift: > case BitRShift: > case BitURShift: > case ValueToInt32: >@@ -100,6 +100,7 @@ bool doesGC(Graph& graph, Node* node) > case ValueBitAnd: > case ValueBitOr: > case ValueBitXor: >+ case ValueBitLShift: > case ValueAdd: > case ValueSub: > case ValueMul: >diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp >index 307632dad59da8e23250db1b4497d0341ba95292..c8dd78bb0880928dde8461416c2487c73114bc0a 100644 >--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp >+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp >@@ -197,6 +197,28 @@ private: > break; > } > >+ >+ case ValueBitLShift: { >+ 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(ArithBitLShift); >+ node->clearFlags(NodeMustGenerate); >+ node->setResult(NodeResultInt32); >+ fixIntConvertingEdge(node->child1()); >+ fixIntConvertingEdge(node->child2()); >+ break; >+ } >+ > case ValueBitXor: > case ValueBitOr: > case ValueBitAnd: { >@@ -222,6 +244,12 @@ private: > break; > } > >+ case ArithBitLShift: { >+ fixIntConvertingEdge(node->child1()); >+ fixIntConvertingEdge(node->child2()); >+ break; >+ } >+ > case ArithBitXor: > case ArithBitOr: > case ArithBitAnd: { >@@ -251,7 +279,6 @@ private: > } > > case BitRShift: >- case BitLShift: > case BitURShift: { > if (Node::shouldSpeculateUntypedForBitOps(node->child1().node(), node->child2().node())) { > fixEdge<UntypedUse>(node->child1()); >diff --git a/Source/JavaScriptCore/dfg/DFGNode.h b/Source/JavaScriptCore/dfg/DFGNode.h >index b8014755c7bcb50914ed39d61a53d94aca86021e..d29cebe97bfca6cbe7d30a3c5c211c2ef7984d8c 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; >@@ -1373,6 +1378,11 @@ public: > return result() == NodeResultNumber; > } > >+ bool hasNumberOrAnyIntResult() >+ { >+ return hasNumberResult() || hasInt32Result() || hasInt52Result(); >+ } >+ > bool hasNumericResult() > { > switch (op()) { >diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h >index dc2f3e16b832aac0af7f0ad63c4c8e281dcba34e..0a3ca2270774cb2e74084f3fafc3450d0074628a 100644 >--- a/Source/JavaScriptCore/dfg/DFGNodeType.h >+++ b/Source/JavaScriptCore/dfg/DFGNodeType.h >@@ -118,7 +118,8 @@ namespace JSC { namespace DFG { > macro(ArithBitOr, NodeResultInt32) \ > macro(ValueBitXor, NodeResultJS | NodeMustGenerate) \ > macro(ArithBitXor, NodeResultInt32) \ >- macro(BitLShift, NodeResultInt32) \ >+ macro(ArithBitLShift, NodeResultInt32) \ >+ macro(ValueBitLShift, NodeResultJS | NodeMustGenerate) \ > macro(BitRShift, NodeResultInt32) \ > macro(BitURShift, NodeResultInt32) \ > /* Bitwise operators call ToInt32 on their operands. */\ >diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp >index 1da406ba7e92767324201c788b3778b52e698819..2e30481b3e9a7865ea835fe3937d4793a02b77f3 100644 >--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp >+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp >@@ -456,11 +456,22 @@ EncodedJSValue JIT_OPERATION operationValueBitLShift(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::bitwiseXor(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 left shift operation."); >+ } >+ >+ return JSValue::encode(jsNumber(WTF::get<int32_t>(leftNumeric) << (WTF::get<int32_t>(rightNumeric) & 0x1f))); > } > > EncodedJSValue JIT_OPERATION operationValueBitRShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) >@@ -1374,6 +1385,17 @@ JSCell* JIT_OPERATION operationBitAndBigInt(ExecState* exec, JSCell* op1, JSCell > return JSBigInt::bitwiseAnd(exec, leftOperand, rightOperand); > } > >+JSCell* JIT_OPERATION operationBitLShiftBigInt(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::leftShift(exec, leftOperand, rightOperand); >+} >+ > JSCell* JIT_OPERATION operationAddBigInt(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..bbc95a09c83e80a06caee98a4813a8c1339b8313 100644 >--- a/Source/JavaScriptCore/dfg/DFGOperations.h >+++ b/Source/JavaScriptCore/dfg/DFGOperations.h >@@ -171,6 +171,7 @@ JSCell* JIT_OPERATION operationMulBigInt(ExecState*, JSCell* op1, JSCell* op2) W > JSCell* JIT_OPERATION operationDivBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL; > 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 operationBitLShiftBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL; > JSCell* JIT_OPERATION operationAddBigInt(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; >diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp >index b3c69bcf124727bfcc676b2afadab5a88c22f93a..5a7098c95bc2b3cfc763f297c1cb90f73986901e 100644 >--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp >+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp >@@ -277,11 +277,22 @@ private: > break; > } > >+ case ValueBitLShift: > 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; > } > >@@ -759,7 +770,7 @@ private: > case ArithBitOr: > case ArithBitXor: > case BitRShift: >- case BitLShift: >+ case ArithBitLShift: > case BitURShift: > case ArithIMul: > case ArithClz32: { >@@ -1119,6 +1130,7 @@ private: > case ValueBitOr: > case ValueBitAnd: > case ValueBitXor: >+ case ValueBitLShift: > case ValueNegate: > case ValueAdd: > case ValueSub: >diff --git a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h >index f106982ae39ff3bcc36cfb5aee0d716c07e94316..897862f174b648e5d5fe9b4ccc88d2115cc1602d 100644 >--- a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h >+++ b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h >@@ -202,7 +202,7 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node, bool igno > case ArithBitAnd: > case ArithBitOr: > case ArithBitXor: >- case BitLShift: >+ case ArithBitLShift: > case BitRShift: > case BitURShift: > case ValueToInt32: >@@ -231,6 +231,7 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node, bool igno > case ValueBitAnd: > case ValueBitXor: > case ValueBitOr: >+ case ValueBitLShift: > case ValueNegate: > case ValueAdd: > case ValueSub: >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >index 63e09fb915ea97f04ae1f0f90e0e7f5c192bdd4f..d4b4d2c7467b9c76f479716d166d7f4bc38b560b 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >@@ -3816,6 +3816,34 @@ void SpeculativeJIT::emitUntypedRightShiftBitOp(Node* node) > return; > } > >+void SpeculativeJIT::compileValueShiftOp(Node* node) >+{ >+ Edge& leftChild = node->child1(); >+ Edge& rightChild = node->child2(); >+ >+ if (node->binaryUseKind() == BigIntUse) { >+ SpeculateCellOperand left(this, leftChild); >+ SpeculateCellOperand right(this, rightChild); >+ GPRReg leftGPR = left.gpr(); >+ GPRReg rightGPR = right.gpr(); >+ >+ speculateBigInt(leftChild, leftGPR); >+ speculateBigInt(rightChild, rightGPR); >+ >+ flushRegisters(); >+ GPRFlushedCallResult result(this); >+ GPRReg resultGPR = result.gpr(); >+ >+ callOperation(operationBitLShiftBigInt, resultGPR, leftGPR, rightGPR); >+ m_jit.exceptionCheck(); >+ cellResult(resultGPR, node); >+ return; >+ } >+ >+ ASSERT(leftChild.useKind() == UntypedUse && rightChild.useKind() == UntypedUse); >+ emitUntypedBitOp<JITLeftShiftGenerator, operationValueBitLShift>(node); >+} >+ > void SpeculativeJIT::compileShiftOp(Node* node) > { > NodeType op = node->op(); >@@ -3824,9 +3852,6 @@ void SpeculativeJIT::compileShiftOp(Node* node) > > if (leftChild.useKind() == UntypedUse || rightChild.useKind() == UntypedUse) { > switch (op) { >- case BitLShift: >- emitUntypedBitOp<JITLeftShiftGenerator, operationValueBitLShift>(node); >- return; > case BitRShift: > case BitURShift: > emitUntypedRightShiftBitOp(node); >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >index dcdf9664fc4de580f87694d7fb78f5f8b6c6757a..d96d02a4c151c4657b810c2b0b1eb228c4bb86c8 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >@@ -668,7 +668,7 @@ public: > case BitRShift: > m_jit.rshift32(op1, Imm32(shiftAmount), result); > break; >- case BitLShift: >+ case ArithBitLShift: > m_jit.lshift32(op1, Imm32(shiftAmount), result); > break; > case BitURShift: >@@ -684,7 +684,7 @@ public: > case BitRShift: > m_jit.rshift32(op1, shiftAmount, result); > break; >- case BitLShift: >+ case ArithBitLShift: > m_jit.lshift32(op1, shiftAmount, result); > break; > case BitURShift: >@@ -1338,6 +1338,7 @@ public: > void compileValueBitwiseOp(Node*); > > void emitUntypedRightShiftBitOp(Node*); >+ void compileValueShiftOp(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..2b5bf410914987c054e478a80e4c7cb69fcd121b 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp >@@ -1995,8 +1995,12 @@ void SpeculativeJIT::compile(Node* node) > compileBitwiseNot(node); > break; > >+ caser ValueBitLShift: >+ compileValueShiftOp(node); >+ break; >+ > case BitRShift: >- case BitLShift: >+ case ArithBitLShift: > case BitURShift: > compileShiftOp(node); > break; >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >index 553f86f50675840823a16e5e58386f79bcac4f2e..b33300b487134a6da673b3e390e5c2845a806044 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >@@ -2090,8 +2090,12 @@ void SpeculativeJIT::compile(Node* node) > compileBitwiseOp(node); > break; > >+ case ValueBitLShift: >+ compileValueShiftOp(node); >+ break; >+ > case BitRShift: >- case BitLShift: >+ case ArithBitLShift: > case BitURShift: > compileShiftOp(node); > break; >diff --git a/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp b/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp >index 18bec693e2d0f70cd6dd5e90cb01a7c086d350b9..820579d8f8ffc9e05c6282c26ef64b35167a2d6a 100644 >--- a/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp >+++ b/Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp >@@ -92,7 +92,7 @@ private: > handleCommutativity(); > break; > >- case BitLShift: >+ case ArithBitLShift: > case BitRShift: > case BitURShift: > if (m_node->child1().useKind() != UntypedUse && m_node->child2()->isInt32Constant() && !(m_node->child2()->asInt32() & 0x1f)) { >diff --git a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp >index 23c9396f4d69e04f6f0cb5f491ba04e6ccfad10a..8089814b088eb3a6368137e93492cecb353a2494 100644 >--- a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp >+++ b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp >@@ -63,7 +63,7 @@ inline CapabilityLevel canCompile(Node* node) > case ArithBitOr: > case ArithBitXor: > case BitRShift: >- case BitLShift: >+ case ArithBitLShift: > case BitURShift: > case CheckStructure: > case CheckStructureOrEmpty: >@@ -91,6 +91,7 @@ inline CapabilityLevel canCompile(Node* node) > case ValueBitAnd: > case ValueBitXor: > case ValueBitOr: >+ case ValueBitLShift: > case ValueNegate: > case ValueAdd: > case ValueSub: >diff --git a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >index 4130bd1ddb4d46f7fff9e1086309d55e5c9922c2..a70cf3db294a50b24ad7fa1629397dc26c6d9601 100644 >--- a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >+++ b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >@@ -683,8 +683,11 @@ private: > case BitRShift: > compileBitRShift(); > break; >- case BitLShift: >- compileBitLShift(); >+ case ArithBitLShift: >+ compileArithBitLShift(); >+ break; >+ case ValueBitLShift: >+ compileValueBitLShift(); > break; > case BitURShift: > compileBitURShift(); >@@ -2961,17 +2964,28 @@ private: > m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31)))); > } > >- void compileBitLShift() >+ void compileArithBitLShift() > { >- if (m_node->isBinaryUseKind(UntypedUse)) { >- emitBinaryBitOpSnippet<JITLeftShiftGenerator>(operationValueBitLShift); >- return; >- } > setInt32(m_out.shl( > lowInt32(m_node->child1()), > m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31)))); > } > >+ void compileValueBitLShift() >+ { >+ if (m_node->isBinaryUseKind(BigIntUse)) { >+ LValue left = lowBigInt(m_node->child1()); >+ LValue right = lowBigInt(m_node->child2()); >+ >+ LValue result = vmCall(pointerType(), m_out.operation(operationBitLShiftBigInt), m_callFrame, left, right); >+ setJSValue(result); >+ return; >+ } >+ >+ ASSERT(m_node->isBinaryUseKind(UntypedUse)); >+ emitBinaryBitOpSnippet<JITLeftShiftGenerator>(operationValueBitLShift); >+ } >+ > void compileBitURShift() > { > if (m_node->isBinaryUseKind(UntypedUse)) { >diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm >index bb22057deaddb2c865e26965a3750a535c3549c3..19fec5d3db95c7f53a153d82c32cba751500b66e 100644 >--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm >+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm >@@ -1146,7 +1146,7 @@ macro bitOpProfiled(name, op, operation) > end > > >-bitOp(lshift, OpLshift, >+bitOpProfiled(lshift, OpLshift, > macro (left, right) lshifti left, right end) > > >diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >index 2e7ed9ecb6c4d62762565f40c20f4cea083600f7..5259488e0a6f33a4bbecfac00eaf32925d7665eb 100644 >--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >@@ -1100,7 +1100,7 @@ macro bitOpProfiled(name, op, operation) > commonBitOp(llintOpWithProfile, name, op, operation) > end > >-bitOp(lshift, OpLshift, >+bitOpProfiled(lshift, OpLshift, > macro (left, right) lshifti left, right end) > > >diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >index 3118b315a8cb8c5df2218d823381886cef582819..b1e7d88107c0b0381b537047b6c1e0c76c0e8689 100644 >--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >@@ -666,13 +666,13 @@ SLOW_PATH_DECL(slow_path_lshift) > if (WTF::holds_alternative<JSBigInt*>(leftNumeric) && WTF::holds_alternative<JSBigInt*>(rightNumeric)) { > JSBigInt* result = JSBigInt::leftShift(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)); > CHECK_EXCEPTION(); >- RETURN(result); >+ RETURN_PROFILED(result); > } > > THROW(createTypeError(exec, "Invalid mix of BigInt and other type in left shift operation.")); > } > >- RETURN(jsNumber(WTF::get<int32_t>(leftNumeric) << (WTF::get<int32_t>(rightNumeric) & 31))); >+ RETURN_PROFILED(jsNumber(WTF::get<int32_t>(leftNumeric) << (WTF::get<int32_t>(rightNumeric) & 31))); > } > > SLOW_PATH_DECL(slow_path_rshift) >diff --git a/PerformanceTests/BigIntBench/big-int-simple-lshift.js b/PerformanceTests/BigIntBench/big-int-simple-lshift.js >new file mode 100644 >index 0000000000000000000000000000000000000000..533e799bacaa37b9a107435d93b76f7dca261c1e >--- /dev/null >+++ b/PerformanceTests/BigIntBench/big-int-simple-lshift.js >@@ -0,0 +1,15 @@ >+function bigInt(a, b) { >+ let c = a << b; >+ return c + b; >+} >+noInline(bigInt); >+ >+for (let i = 0; i < 100000; i++) { >+ bigInt(0b1111n, 0x100n); >+} >+ >+let out; >+for (let i = 0; i < 100000; i++) { >+ out = bigInt(0xfffffffffffffffffffffffn, 10n); >+} >+ >diff --git a/PerformanceTests/ChangeLog b/PerformanceTests/ChangeLog >index e3244041bc49a8815d701b362cb647c454178d54..9d257ea0200af92dcd46ce99c0093c7ff0463380 100644 >--- a/PerformanceTests/ChangeLog >+++ b/PerformanceTests/ChangeLog >@@ -1,3 +1,12 @@ >+2018-12-30 Caio Lima <ticaiolima@gmail.com> >+ >+ [BigInt] Add ValueBitLShift into DFG >+ https://bugs.webkit.org/show_bug.cgi?id=192664 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * BigIntBench/big-int-simple-lshift.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 192664
:
358148
|
358149
|
359271
|
359272
|
359605
|
359976
|
360009
|
360941
|
362256
|
364993
|
372229
|
372240
|
373741
|
373840
|
373841
|
374006