WebKit Bugzilla
Attachment 362256 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-20190217200226.patch (text/plain), 41.08 KB, created by
Caio Lima
on 2019-02-17 15:02:32 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Caio Lima
Created:
2019-02-17 15:02:32 PST
Size:
41.08 KB
patch
obsolete
>Subversion Revision: 241651 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 165c1820f75845e5e77b2981132b8a8ff9decd53..aea1d0f04723fed451d04588a38124a140d943a8 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,69 @@ >+2019-02-17 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: >+ * dfg/DFGAbstractInterpreter.h: >+ * dfg/DFGAbstractInterpreterInlines.h: >+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::handleConstantBinaryBitwiseOp): >+ (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/DFGNodeType.h: >+ * dfg/DFGOperations.cpp: >+ (JSC::DFG::bitwiseBinaryOp): >+ * 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-02-17 Commit Queue <commit-queue@webkit.org> > > Unreviewed, rolling out r241612. >diff --git a/Source/JavaScriptCore/bytecode/BytecodeList.rb b/Source/JavaScriptCore/bytecode/BytecodeList.rb >index 115bd3b065d65031773cc1f3126d33fd5575423c..f2a5ad15f7390378313f8833278392d92e339da1 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 23527e4bb113ebd1227aad2ddf25280fe0ec5cb8..69d3d1bae97192774dafb574357121d9ba234774 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >@@ -550,6 +550,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 feeb4427f6859541e578fe509dafb5c3ccf5a8f6..4d86994f6f8a5cfba3009b7707bd43401e499b33 100644 >--- a/Source/JavaScriptCore/bytecode/Opcode.h >+++ b/Source/JavaScriptCore/bytecode/Opcode.h >@@ -103,6 +103,7 @@ extern const unsigned opcodeLengths[]; > macro(OpBitor) \ > macro(OpBitnot) \ > macro(OpBitxor) \ >+ macro(OpLshift) \ > > #define FOR_EACH_OPCODE_WITH_ARRAY_PROFILE(macro) \ > macro(OpHasIndexedProperty) \ >diff --git a/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h b/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h >index fba129968994ebf0da26b6e72b8a13c8fbaa74e6..4cb3bd5ee755ba8ea228251867087898f6f65fec 100644 >--- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h >+++ b/Source/JavaScriptCore/dfg/DFGAbstractInterpreter.h >@@ -218,6 +218,8 @@ private: > void clobberWorld(); > void didFoldClobberWorld(); > >+ bool handleConstantBinaryBitwiseOp(Node*); >+ > template<typename Functor> > void forAllValues(unsigned indexInBlock, Functor&); > >diff --git a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >index 67e5a87cb3880dfe5bfca58615ef3bbab3d08ad6..d713e9800305dc1a95820e8ac0ec03bd8668f409 100644 >--- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >+++ b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >@@ -232,6 +232,51 @@ inline ToThisResult isToThisAnIdentity(VM& vm, bool isStrictMode, AbstractValue& > return ToThisResult::Dynamic; > } > >+template<typename AbstractStateType> >+bool AbstractInterpreter<AbstractStateType>::handleConstantBinaryBitwiseOp(Node* node) >+{ >+ JSValue left = forNode(node->child1()).value(); >+ JSValue right = forNode(node->child2()).value(); >+ if (left && right && left.isInt32() && right.isInt32()) { >+ int32_t a = left.asInt32(); >+ int32_t b = right.asInt32(); >+ if (node->binaryUseKind() == UntypedUse) >+ didFoldClobberWorld(); >+ NodeType op = node->op(); >+ switch (op) { >+ case ValueBitAnd: >+ case ArithBitAnd: >+ setConstant(node, JSValue(a & b)); >+ break; >+ case ValueBitOr: >+ case ArithBitOr: >+ setConstant(node, JSValue(a | b)); >+ break; >+ case ValueBitXor: >+ case ArithBitXor: >+ setConstant(node, JSValue(a ^ b)); >+ break; >+ case BitRShift: >+ setConstant(node, JSValue(a >> static_cast<uint32_t>(b))); >+ break; >+ case ValueBitLShift: >+ case ArithBitLShift: >+ setConstant(node, JSValue(a << static_cast<uint32_t>(b))); >+ break; >+ case BitURShift: >+ setConstant(node, JSValue(static_cast<uint32_t>(a) >> static_cast<uint32_t>(b))); >+ break; >+ default: >+ RELEASE_ASSERT_NOT_REACHED(); >+ break; >+ } >+ >+ return true; >+ } >+ >+ return false; >+} >+ > template<typename AbstractStateType> > bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimit, Node* node) > { >@@ -397,6 +442,10 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi > case ValueBitXor: > case ValueBitAnd: > case ValueBitOr: >+ case ValueBitLShift: { >+ if (handleConstantBinaryBitwiseOp(node)) >+ break; >+ > if (node->binaryUseKind() == BigIntUse) > setTypeForNode(node, SpecBigInt); > else { >@@ -404,12 +453,13 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi > setTypeForNode(node, SpecBoolInt32 | SpecBigInt); > } > break; >+ } > > case ArithBitAnd: > case ArithBitOr: > case ArithBitXor: > case BitRShift: >- case BitLShift: >+ case ArithBitLShift: > case BitURShift: { > if (node->child1().useKind() == UntypedUse || node->child2().useKind() == UntypedUse) { > clobberWorld(); >@@ -417,36 +467,8 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi > break; > } > >- JSValue left = forNode(node->child1()).value(); >- JSValue right = forNode(node->child2()).value(); >- if (left && right && left.isInt32() && right.isInt32()) { >- int32_t a = left.asInt32(); >- int32_t b = right.asInt32(); >- switch (node->op()) { >- case ArithBitAnd: >- setConstant(node, JSValue(a & b)); >- break; >- case ArithBitOr: >- setConstant(node, JSValue(a | b)); >- break; >- case ArithBitXor: >- setConstant(node, JSValue(a ^ b)); >- break; >- case BitRShift: >- setConstant(node, JSValue(a >> static_cast<uint32_t>(b))); >- break; >- case BitLShift: >- setConstant(node, JSValue(a << static_cast<uint32_t>(b))); >- break; >- case BitURShift: >- setConstant(node, JSValue(static_cast<uint32_t>(a) >> static_cast<uint32_t>(b))); >- break; >- default: >- RELEASE_ASSERT_NOT_REACHED(); >- break; >- } >+ if (handleConstantBinaryBitwiseOp(node)) > break; >- } > > if (node->op() == ArithBitAnd > && (isBoolInt32Speculation(forNode(node->child1()).m_type) || >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 77840e89c54e81e287fb3f653ce758ea8d20a080..2accdaf91b3a0d1b6d303e6fd5fa2cb7e1dcee72 100644 >--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >@@ -3454,7 +3454,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; > } >@@ -4971,7 +4971,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 add1499e8a69ae192a13d1761ffbd27b72bd8f7a..b6f476bb2fdcb58a388d86adfe9508d39c9dd2ec 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 1598f7e85809bd769c9891958aeaff69e66a0386..a989c12e1dbf1a7754fa2a3cbcf0efe64a7898bc 100644 >--- a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp >+++ b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp >@@ -83,7 +83,7 @@ bool doesGC(Graph& graph, Node* node) > case ArithBitAnd: > case ArithBitOr: > case ArithBitXor: >- case BitLShift: >+ case ArithBitLShift: > case BitRShift: > case BitURShift: > case ValueToInt32: >@@ -380,6 +380,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 c68d6e2dd8d4e7ea338a6a7b54be5150588f3df2..77abc7db46ad6d9ee6be3e43544c5ce234dfa896 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/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h >index ef63cdb446c74af9c66631ef3b17b28469590d59..424deaf50e694661a89045dd73b7b4dae05fe82f 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 6a578266eb4a128327e53cdaacb7d861577c49ef..b4f6abdf27d245803307edd86c5d7c6338b20994 100644 >--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp >+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp >@@ -212,6 +212,33 @@ static ALWAYS_INLINE void putWithThis(ExecState* exec, EncodedJSValue encodedBas > baseValue.putInline(exec, ident, putValue, slot); > } > >+template<typename BigIntOperation, typename Int32Operation> >+static ALWAYS_INLINE EncodedJSValue bitwiseBinaryOp(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2, BigIntOperation&& bigIntOp, Int32Operation&& int32Op, const char* errorMessage) >+{ >+ VM* vm = &exec->vm(); >+ NativeCallFrameTracer tracer(vm, exec); >+ auto scope = DECLARE_THROW_SCOPE(*vm); >+ >+ JSValue op1 = JSValue::decode(encodedOp1); >+ JSValue op2 = JSValue::decode(encodedOp2); >+ >+ auto leftNumeric = op1.toBigIntOrInt32(exec); >+ RETURN_IF_EXCEPTION(scope, encodedJSValue()); >+ 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)) >+ RELEASE_AND_RETURN(scope, JSValue::encode(bigIntOp(exec, WTF::get<JSBigInt*>(leftNumeric), WTF::get<JSBigInt*>(rightNumeric)))); >+ >+ return throwVMTypeError(exec, scope, errorMessage); >+ } >+ >+ scope.release(); >+ >+ return JSValue::encode(jsNumber(int32Op(WTF::get<int32_t>(leftNumeric), WTF::get<int32_t>(rightNumeric)))); >+} >+ > static ALWAYS_INLINE EncodedJSValue parseIntResult(double input) > { > int asInt = static_cast<int>(input); >@@ -368,99 +395,54 @@ EncodedJSValue JIT_OPERATION operationValueBitNot(ExecState* exec, EncodedJSValu > > EncodedJSValue JIT_OPERATION operationValueBitAnd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) > { >- VM* vm = &exec->vm(); >- NativeCallFrameTracer tracer(vm, exec); >- auto scope = DECLARE_THROW_SCOPE(*vm); >+ auto bigIntOp = [] (ExecState* exec, JSBigInt* left, JSBigInt* right) -> JSBigInt* { >+ return JSBigInt::bitwiseAnd(exec, left, right); >+ }; > >- JSValue op1 = JSValue::decode(encodedOp1); >- JSValue op2 = JSValue::decode(encodedOp2); >- >- auto leftNumeric = op1.toBigIntOrInt32(exec); >- RETURN_IF_EXCEPTION(scope, encodedJSValue()); >- auto rightNumeric = op2.toBigIntOrInt32(exec); >- RETURN_IF_EXCEPTION(scope, encodedJSValue()); >+ auto int32Op = [] (int32_t left, int32_t right) -> int32_t { >+ return left & right; >+ }; > >- 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::bitwiseAnd(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 bitwise 'and' operation."); >- } >- >- return JSValue::encode(jsNumber(WTF::get<int32_t>(leftNumeric) & WTF::get<int32_t>(rightNumeric))); >+ return bitwiseBinaryOp(exec, encodedOp1, encodedOp2, bigIntOp, int32Op, "Invalid mix of BigInt and other type in bitwise 'and' operation."); > } > > EncodedJSValue JIT_OPERATION operationValueBitOr(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) > { >- VM* vm = &exec->vm(); >- NativeCallFrameTracer tracer(vm, exec); >- auto scope = DECLARE_THROW_SCOPE(*vm); >+ auto bigIntOp = [] (ExecState* exec, JSBigInt* left, JSBigInt* right) -> JSBigInt* { >+ return JSBigInt::bitwiseOr(exec, left, right); >+ }; > >- JSValue op1 = JSValue::decode(encodedOp1); >- JSValue op2 = JSValue::decode(encodedOp2); >+ auto int32Op = [] (int32_t left, int32_t right) -> int32_t { >+ return left | right; >+ }; > >- auto leftNumeric = op1.toBigIntOrInt32(exec); >- RETURN_IF_EXCEPTION(scope, encodedJSValue()); >- 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::bitwiseOr(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 bitwise 'or' operation."); >- } >- >- return JSValue::encode(jsNumber(WTF::get<int32_t>(leftNumeric) | WTF::get<int32_t>(rightNumeric))); >+ return bitwiseBinaryOp(exec, encodedOp1, encodedOp2, bigIntOp, int32Op, "Invalid mix of BigInt and other type in bitwise 'or' operation."); > } > > EncodedJSValue JIT_OPERATION operationValueBitXor(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) > { >- VM* vm = &exec->vm(); >- NativeCallFrameTracer tracer(vm, exec); >- auto scope = DECLARE_THROW_SCOPE(*vm); >- >- JSValue op1 = JSValue::decode(encodedOp1); >- JSValue op2 = JSValue::decode(encodedOp2); >- >- auto leftNumeric = op1.toBigIntOrInt32(exec); >- RETURN_IF_EXCEPTION(scope, encodedJSValue()); >- 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); >- } >+ auto bigIntOp = [] (ExecState* exec, JSBigInt* left, JSBigInt* right) -> JSBigInt* { >+ return JSBigInt::bitwiseXor(exec, left, right); >+ }; > >- return throwVMTypeError(exec, scope, "Invalid mix of BigInt and other type in bitwise 'xor' operation."); >- } >+ auto int32Op = [] (int32_t left, int32_t right) -> int32_t { >+ return left ^ right; >+ }; > >- return JSValue::encode(jsNumber(WTF::get<int32_t>(leftNumeric) ^ WTF::get<int32_t>(rightNumeric))); >+ return bitwiseBinaryOp(exec, encodedOp1, encodedOp2, bigIntOp, int32Op, "Invalid mix of BigInt and other type in bitwise 'xor' operation."); > } > > EncodedJSValue JIT_OPERATION operationValueBitLShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) > { >- VM* vm = &exec->vm(); >- NativeCallFrameTracer tracer(vm, exec); >- auto scope = DECLARE_THROW_SCOPE(*vm); >+ auto bigIntOp = [] (ExecState* exec, JSBigInt* left, JSBigInt* right) -> JSBigInt* { >+ return JSBigInt::leftShift(exec, left, right); >+ }; > >- JSValue op1 = JSValue::decode(encodedOp1); >- JSValue op2 = JSValue::decode(encodedOp2); >+ auto int32Op = [] (int32_t left, int32_t right) -> int32_t { >+ return left << (right & 0x1f); >+ }; > >- int32_t a = op1.toInt32(exec); >- RETURN_IF_EXCEPTION(scope, encodedJSValue()); >- scope.release(); >- uint32_t b = op2.toUInt32(exec); >- return JSValue::encode(jsNumber(a << (b & 0x1f))); >+ return bitwiseBinaryOp(exec, encodedOp1, encodedOp2, bigIntOp, int32Op, "Invalid mix of BigInt and other type in left shift operation."); > } > > EncodedJSValue JIT_OPERATION operationValueBitRShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) >@@ -1366,6 +1348,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 c2afe5b378add7ae4d1e9bd4fd8320ae27687065..55cee82ee581bef5581618f009b7ceb23f1e8bb2 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: { >@@ -1117,6 +1135,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 883f79988bd6a4a4c2735173bc5c598c5a77666d..a37079d3b10d6b18f76c7772832f40c2c59abc5d 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 2911288ede8d5699066d0d11ff2b7fd4b29de121..0ec03084e6d19dc62bdd0713775fecafca7b47ed 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >@@ -3814,6 +3814,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(); >@@ -3822,9 +3850,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 8ed85f6311f14a940530e2f146288ab612b10b3d..d298a4d578cdeaf0b659516b9480e3dbed85c1ed 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 4dfe9c92321d753d178148f4ed35f8973f3e6f52..9d61c3eb2eaabf7b9d1e3628680c0d6339e49ceb 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; > >+ case 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 63052becc0508d6d2927cb0060b4be87626976a1..f544234f307d951ca5a4fe023e7559a172a78e03 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 c7fd52a8eb9755ad1b1b29957f13f4bbe16c48c1..0768da85d1c2c7171face6114bdbf2e043fa3051 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 535721296925a9009042f111048a9986f8b7d220..a439a567e86fb5db9cc56c36127c3eda905a9684 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 a17f95421f7c30b5704e77d2ffd8a6a90317e1b1..9b5ab2b16fc2df92c4a3dd7a1ff5a434dc913cac 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(); >@@ -2964,17 +2967,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 ff1ce5869e3691f44499861712dddb7e6dcfb7f3..ed1485d81d8a16e0dff529532afa37c99bde9197 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 45825401a78b680fae0a8f0962cdc3501599aa1f..e5533a58a82b94b78285cab51aa60d7f487f4b43 100644 >--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >@@ -1106,7 +1106,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 5871c930bbc8e06636110ea4c6769b202340751d..9d0ade3c0ced758afcf6f9f06b640f5c4d142443 100644 >--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >@@ -659,13 +659,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 1c9bc23e4b40e5abcc4f8259e6abe2734f8fe86d..5341366eeb2bd785a39f312b3a2d83ac3b7e2d4f 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,13 @@ >+2019-02-17 Caio Lima <ticaiolima@gmail.com> >+ >+ [BigInt] Add ValueBitLShift into DFG >+ https://bugs.webkit.org/show_bug.cgi?id=192664 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * stress/big-int-left-shift-untyped.js: Added. >+ * stress/bit-op-with-object-returning-int32.js: >+ > 2019-02-15 Michael Saboff <msaboff@apple.com> > > RELEASE_ASSERT at com.apple.JavaScriptCore: JSC::jsSubstringOfResolved >diff --git a/JSTests/stress/big-int-left-shift-untyped.js b/JSTests/stress/big-int-left-shift-untyped.js >new file mode 100644 >index 0000000000000000000000000000000000000000..b7c72e4a04253b0beaeffcc7904c3cd3b8f67b5c >--- /dev/null >+++ b/JSTests/stress/big-int-left-shift-untyped.js >@@ -0,0 +1,17 @@ >+//@ runBigIntEnabled >+ >+function assert(a, e) { >+ if (a !== e) >+ throw new Error("Expected: " + e + " but got: " + a); >+} >+ >+function untypedLShift(a, b) { >+ return a << b; >+} >+noInline(untypedLShift); >+ >+for (var i = 0; i < 10000; i++) { >+ assert(untypedLShift(0b11101n, 10n), 0b111010000000000n); >+ assert(untypedLShift(0b11101, 10), 0b111010000000000); >+} >+ >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 d6d63135d0f5d951ad9f968eb3991e3ca70f4a1b..b2959415848aa5eabeb503f8361a1f5ec6c7cb29 100644 >--- a/PerformanceTests/ChangeLog >+++ b/PerformanceTests/ChangeLog >@@ -1,3 +1,12 @@ >+2019-02-17 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-02-08 Saam barati <sbarati@apple.com> > > Update JetStream2 CLI to not print "ms" since we now just print the score values
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