WebKit Bugzilla
Attachment 359605 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]
Patch
bug-192664-20190119111726.patch (text/plain), 31.02 KB, created by
Caio Lima
on 2019-01-19 06:17:28 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Caio Lima
Created:
2019-01-19 06:17:28 PST
Size:
31.02 KB
patch
obsolete
>Subversion Revision: 240201 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index d6c084b72f51b6bbc9cce155c6088fde981d58bc..2188a0d49d43a03b76e3f343b4fc3c4521b0d588 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,68 @@ >+2019-01-16 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. The difference we have from ohter ValueBitops is that we are >+ not using `getHeapPrediction()` during Prediction Propagation, because >+ this cause huge performance regression on Octane's zlib and mandreel. >+ >+ * 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: >+ * dfg/DFGNodeType.h: >+ * dfg/DFGOperations.cpp: >+ * dfg/DFGOperations.h: >+ * dfg/DFGPredictionPropagationPhase.cpp: >+ * dfg/DFGSafeToExecute.h: >+ (JSC::DFG::safeToExecute): >+ * dfg/DFGSpeculativeJIT.cpp: >+ (JSC::DFG::SpeculativeJIT::compileValueLShiftOp): >+ (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): >+ > 2019-01-19 Antoine Quint <graouts@apple.com> > > Add a POINTER_EVENTS feature flag >diff --git a/Source/JavaScriptCore/bytecode/BytecodeList.rb b/Source/JavaScriptCore/bytecode/BytecodeList.rb >index bb5f1261600e5fdb194eae98c08b54647d7d3b7d..13fedb45c363c9a48f069f199ef4fd336b709f54 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 0c6345686fa1e53d53c49338597e7c1e3555e21c..85dce7de08863b5b04d1808220d6f313dea57c19 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >@@ -571,6 +571,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 b966adcbf7a50e1fd07d836118eb81088ef8b58e..496ffe32dd6e8f1c6b8d1b973ad9f97324ef5425 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 f4ce71eba58adbd5b36109e6fb6b32962cdd72f9..2183b71c57f32507dc032818ff8cd6f40cca7e98 100644 >--- a/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp >+++ b/Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp >@@ -123,7 +123,8 @@ private: > case ArithBitXor: > case ValueBitOr: > case ValueBitXor: >- case BitLShift: { >+ case ValueBitLShift: >+ case ArithBitLShift: { > return power > 31; > } > >@@ -225,7 +226,8 @@ private: > case ValueBitOr: > case ValueBitXor: > 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 4e18df703d3d216686f5859824f2ac6cb97fe00e..cd2a5e1d8d832bcc275ff4f80bed2d597aca5469 100644 >--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >@@ -3446,7 +3446,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; > } >@@ -4963,7 +4963,10 @@ void ByteCodeParser::parseBlock(unsigned limit) > auto bytecode = currentInstruction->as<OpLshift>(); > Node* op1 = get(bytecode.m_lhs); > Node* op2 = get(bytecode.m_rhs); >- set(bytecode.m_dst, addToGraph(BitLShift, op1, op2)); >+ if (op1->hasNumberOrAnyIntResult() && op2->hasNumberOrAnyIntResult()) >+ set(bytecode.m_dst, addToGraph(ArithBitLShift, op1, op2)); >+ else >+ set(bytecode.m_dst, addToGraph(ValueBitLShift, op1, op2)); > NEXT_OPCODE(op_lshift); > } > >diff --git a/Source/JavaScriptCore/dfg/DFGClobberize.h b/Source/JavaScriptCore/dfg/DFGClobberize.h >index 9c2707332c5e75acf05881bd8841a16852c715bc..f18a326219c8ee4f5274f7ba95b41321e50e8457 100644 >--- a/Source/JavaScriptCore/dfg/DFGClobberize.h >+++ b/Source/JavaScriptCore/dfg/DFGClobberize.h >@@ -271,7 +271,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) { >@@ -670,6 +670,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 4f79af6c4cc5c1d9a9581e712441ad703994cb2d..d63f041163b2d82fbf0691e68c17df22ebba7963 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 18b65a306c9659ff15f3feafe9bf8df8a989cab9..9363ad37da1b0e88fe5aae1e0c8d3de30a2244f8 100644 >--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp >+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp >@@ -196,6 +196,7 @@ private: > break; > } > >+ case ValueBitLShift: > case ValueBitXor: > case ValueBitOr: > case ValueBitAnd: { >@@ -210,8 +211,7 @@ private: > fixEdge<UntypedUse>(node->child2()); > break; > } >- >- // In such case, we need to fallback to ArithBitOp >+ > switch (op) { > case ValueBitXor: > node->setOp(ArithBitXor); >@@ -222,6 +222,9 @@ private: > case ValueBitAnd: > node->setOp(ArithBitAnd); > break; >+ case ValueBitLShift: >+ node->setOp(ArithBitLShift); >+ break; > default: > DFG_CRASH(m_graph, node, "Unexpected node during ValueBit operation fixup"); > break; >@@ -245,6 +248,7 @@ private: > break; > } > >+ case ArithBitLShift: > case ArithBitXor: > case ArithBitOr: > case ArithBitAnd: { >@@ -254,7 +258,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 4c7deb6ad68ab008c2a663b9e413f710a2ade36a..0ed9d5eaf896d29acf4b3b182bf7d5c4f7e7aa7f 100644 >--- a/Source/JavaScriptCore/dfg/DFGNode.h >+++ b/Source/JavaScriptCore/dfg/DFGNode.h >@@ -1377,7 +1377,7 @@ public: > { > return hasNumberResult() || hasInt32Result() || hasInt52Result(); > } >- >+ > bool hasNumericResult() > { > switch (op()) { >diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h >index ded0e2680b8e82018c3d4868335b4d03e4ac8fd2..b85d143c7d4d3b0e32e93c171053d31f4851482a 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 6075ea327ceb92b0b9cbb726d2af6707c4abcdcd..6642bb132b64e736a0019b8288f56c96069caef1 100644 >--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp >+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp >@@ -458,11 +458,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) >@@ -1376,6 +1387,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 8b76f4d6bf37401de2c4a97c1c3205527cc63951..bd2a2b029dc11bf33e0b4cc3a678e22e304ff470 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 b0d49e08539baafadd215df51c784938cddee2f4..80ad30c6d8eab6b18bf89e87cfa0e4f3be68fa4e 100644 >--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp >+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp >@@ -179,6 +179,24 @@ private: > break; > } > >+ case ValueBitLShift: { >+ 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; >+ } >+ > case ValueAdd: { > SpeculatedType left = node->child1()->prediction(); > SpeculatedType right = node->child2()->prediction(); >@@ -751,7 +769,7 @@ private: > case ArithBitOr: > case ArithBitXor: > case BitRShift: >- case BitLShift: >+ case ArithBitLShift: > case BitURShift: > case ArithIMul: > case ArithClz32: { >@@ -1118,6 +1136,7 @@ private: > case ValueSub: > case ValueMul: > case ValueDiv: >+ case ValueBitLShift: > case ArithAdd: > case ArithSub: > case ArithNegate: >diff --git a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h >index c4e566cb6c6ba121336b6c2e28bf70d951857fe1..f65d6d6796f3fe9cabaca8f8ebb865b0abe35ffd 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 948bb979c8e65429f4bc620a24672ece294b50ac..5f6285657c6681bc49b465b9f65f18266d3cf36e 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::compileValueLShiftOp(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 a2ad6bed487cb34d687d7bedb51b5540d6befd8a..906f2ad938cc352c1269588b00fa06c7749c1aba 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 compileValueLShiftOp(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 c299bccd61322c2ebbe8136447f34d15f6b97545..91310d8bd44858cfb1cbb5a5d57aea8467bb1997 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: >+ compileValueLShiftOp(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 32e08c99f465f006c19731bd2bb0a02b4c1488ba..3a1131945e3c14a6b0af80a8af7191062a324110 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: >+ compileValueLShiftOp(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 7db5b56d326ddad666ec69cfa4d8d186d224ff4a..669c8b79b82a3905f4fcfadde60df43bd3ee0a7f 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 edc6f0d3bc283510e5879b6ae4efa370f9aff671..a678229562bf76198c911440d708d9621f4d1fb3 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(); >@@ -2967,17 +2970,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 6f7deabc7251a8579f7e995ad20477b76a30030f..514570bedf5b7b3dea3accf1983702c78a824ca7 100644 >--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm >+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm >@@ -1156,7 +1156,7 @@ macro bitOpProfiled(opcodeName, opcodeStruct, 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 4e37a09603f73d979673498df99706ccc1a1fd93..55991788d8207154f88d4ab149b490fdc354c34d 100644 >--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >@@ -1109,7 +1109,7 @@ macro bitOpProfiled(opcodeName, opcodeStruct, operation) > commonBitOp(llintOpWithProfile, opcodeName, opcodeStruct, 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 b880458ec877e5186074c09d1275836d747c3148..7ae4642b255290197d18ccdeffa9d191fcb61291 100644 >--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >@@ -667,13 +667,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/JSTests/ChangeLog b/JSTests/ChangeLog >index 777a853bfe709f942ac64f8b41717e0a94ab67b0..2832827e8d9fe53bd0531927c1a7850031326716 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,12 @@ >+2019-01-16 Caio Lima <ticaiolima@gmail.com> >+ >+ [BigInt] Add ValueBitLShift into DFG >+ https://bugs.webkit.org/show_bug.cgi?id=192664 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * stress/bit-op-with-object-returning-int32.js: >+ > 2019-01-17 Saam barati <sbarati@apple.com> > > StringObjectUse should not be a structure check for the original string object structure >diff --git a/JSTests/stress/bit-op-with-object-returning-int32.js b/JSTests/stress/bit-op-with-object-returning-int32.js >index 7e9134498e9b751c1dbad26b157e04a520c67274..c2d726bc06b6b28ba74e34f7bc7655a565b82504 100644 >--- a/JSTests/stress/bit-op-with-object-returning-int32.js >+++ b/JSTests/stress/bit-op-with-object-returning-int32.js >@@ -36,3 +36,13 @@ for (var i = 0; i < 10000; i++) > > assert(numberOfDFGCompiles(bitXor) <= 1, true); > >+function bitLShift(a, b) { >+ return a << b; >+} >+noInline(bitLShift); >+ >+for (var i = 0; i < 10000; i++) >+ assert(bitLShift(o, 3), 0b1101000); >+ >+assert(numberOfDFGCompiles(bitLShift) <= 1, true); >+ >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 c045c1e094ce3fcf6682fdd145da510ba2f87f51..a3aedd928d0a83713328e7349de8d9128105fa2b 100644 >--- a/PerformanceTests/ChangeLog >+++ b/PerformanceTests/ChangeLog >@@ -1,3 +1,12 @@ >+2019-01-16 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. >+ > 2019-01-18 Saam Barati <sbarati@apple.com> > > Use scores everywhere in JetStream2's UI
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