WebKit Bugzilla
Attachment 372229 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-20190616215200.patch (text/plain), 39.53 KB, created by
Caio Lima
on 2019-06-16 17:52:04 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Caio Lima
Created:
2019-06-16 17:52:04 PDT
Size:
39.53 KB
patch
obsolete
>Subversion Revision: 246486 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index b69160bbd2a5852e0875ad425ad3eb33c3e06244..323f88d53af7fe0069daffa988a4732309364aaa 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,115 @@ >+2019-06-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 other ValueBitops is that we are >+ not using `getHeapPrediction()` during prediction propagation, because >+ it causes performance regression on Octane's zlib and mandreel. >+ >+ * bytecode/BytecodeList.rb: >+ * bytecode/CodeBlock.cpp: >+ (JSC::CodeBlock::finishCreation): >+ * bytecode/Opcode.h: >+ >+ We are adding ValueProfile on `op_lshift`. >+ >+ * dfg/DFGAbstractInterpreter.h: >+ * dfg/DFGAbstractInterpreterInlines.h: >+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::handleConstantBinaryBitwiseOp): >+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): >+ >+ We moved `BitLShift` constant fold rules to a new method >+ `handleConstantBinaryBitwiseOp` to be reused by `ArithBitLShift` and >+ `ValueBitLShift`. This also enables support of constant folding on other >+ bitwise operations like `ValueBitAnd`, `ValueBitOr` and `ValueBitXor`, when >+ their binary use kind is UntypedUse. Such cases can happen on those >+ nodes because fixup phase is conservative. >+ >+ * dfg/DFGBackwardsPropagationPhase.cpp: >+ (JSC::DFG::BackwardsPropagationPhase::isWithinPowerOfTwo): >+ (JSC::DFG::BackwardsPropagationPhase::propagate): >+ * dfg/DFGByteCodeParser.cpp: >+ (JSC::DFG::ByteCodeParser::handleIntrinsicGetter): >+ >+ We are only changing the use of `BitLShift` by `ArithBitLShift` on >+ `TypedArrayByteLengthIntrinsich`. >+ >+ (JSC::DFG::ByteCodeParser::parseBlock): >+ >+ We parse `op_lshift` as `ArithBitLShift` when its operands are numbers. >+ Otherwise, we fallback to `ValueBitLShift` and rely on fixup phase to >+ convert `ValueBitLShift` into `ArithBitLShift` when possible. >+ >+ * dfg/DFGClobberize.h: >+ (JSC::DFG::clobberize): >+ >+ `ArithBitLShift` has the same clobberize rules as former `BitLShift`. >+ `ValueBitLShift` only clobberize world when it is UntypedUse. >+ >+ * dfg/DFGDoesGC.cpp: >+ (JSC::DFG::doesGC): >+ >+ `ValueBitLShift` can GC when BigIntUse because it allocates new >+ JSBigInts to perform this operation. It also can GC on UntypedUse >+ because of observable user code. >+ >+ * dfg/DFGFixupPhase.cpp: >+ (JSC::DFG::FixupPhase::fixupNode): >+ >+ `ValueBitLShift` and `ArithBitLShift` has the same fixup rules of >+ other binary bitwise operations. In the case of `ValueBitLShift` >+ We check if we should speculate on BigInt or Untyped and fallback to >+ `ArithBitLShift` when both cheks fail. >+ >+ * dfg/DFGNodeType.h: >+ * dfg/DFGOperations.cpp: >+ >+ We updated `operationValueBitLShift` to handle BigInt cases. Also, we >+ added `operationBitLShiftBigInt` that is used when we compile >+ `ValueBitLValueBitLShift(BigIntUse)`. >+ >+ * dfg/DFGOperations.h: >+ * dfg/DFGPredictionPropagationPhase.cpp: >+ >+ `ValueBitLShift`'s prediction propagation rules differs from other >+ bitwise operations, because using heap prediction for this node causes >+ significant performance regression on Octane's zlib and mandreel. >+ >+ * 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): >+ >+ Changing code to support ValueProfile on `op_lshift`. >+ > 2019-06-14 Keith Miller <keith_miller@apple.com> > > Restore PAC based cage. >diff --git a/Source/JavaScriptCore/bytecode/BytecodeList.rb b/Source/JavaScriptCore/bytecode/BytecodeList.rb >index ea1bbe2d68d91fd4980b297c0c313f1930cf5d3c..8f769bd259327fc0296e5499a4fd6e0fbe23697c 100644 >--- a/Source/JavaScriptCore/bytecode/BytecodeList.rb >+++ b/Source/JavaScriptCore/bytecode/BytecodeList.rb >@@ -226,7 +226,6 @@ op_group :BinaryOp, > :beloweq, > :mod, > :pow, >- :lshift, > :rshift, > :urshift, > ], >@@ -261,6 +260,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 4a9bb327b66ef64d913258a5160c0f6f384060a1..a552061d5fc83182e5a874add9038a2a788bca93 100644 >--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp >+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp >@@ -545,6 +545,7 @@ bool CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, Unlink > LINK(OpBitor, profile) > LINK(OpBitnot, profile) > LINK(OpBitxor, profile) >+ LINK(OpLshift, profile) > > LINK(OpGetById, profile) > >diff --git a/Source/JavaScriptCore/bytecode/Opcode.h b/Source/JavaScriptCore/bytecode/Opcode.h >index c921dd813c65e0ccb3a86f91aa77bf8a1208143a..70ce05b72d694f07059f80da58a0b691d30e419b 100644 >--- a/Source/JavaScriptCore/bytecode/Opcode.h >+++ b/Source/JavaScriptCore/bytecode/Opcode.h >@@ -107,6 +107,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 5d5988c29af2b87491c252e55c7eb241a297d4e6..974b0cfb6441cb919e9e87e75f754a4f71f96430 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 c6368ee848eddfddf9aea5e02a89f4004ac4b792..8c5e88278cc6e3f50605170d40f1f39ef38d26fc 100644 >--- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >+++ b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >@@ -233,6 +233,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->isBinaryUseKind(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) & 0x1f))); >+ break; >+ case ValueBitLShift: >+ case ArithBitLShift: >+ setConstant(node, JSValue(a << (static_cast<uint32_t>(b) & 0x1f))); >+ break; >+ case BitURShift: >+ setConstant(node, JSValue(static_cast<uint32_t>(a) >> (static_cast<uint32_t>(b) & 0x1f))); >+ break; >+ default: >+ RELEASE_ASSERT_NOT_REACHED(); >+ break; >+ } >+ >+ return true; >+ } >+ >+ return false; >+} >+ > template<typename AbstractStateType> > bool AbstractInterpreter<AbstractStateType>::handleConstantDivOp(Node* node) > { >@@ -463,6 +508,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 { >@@ -470,12 +519,13 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi > setTypeForNode(node, SpecInt32Only | 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(); >@@ -483,36 +533,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) & 0x1f))); >- break; >- case BitLShift: >- setConstant(node, JSValue(a << (static_cast<uint32_t>(b) & 0x1f))); >- break; >- case BitURShift: >- setConstant(node, JSValue(static_cast<int32_t>(static_cast<uint32_t>(a) >> (static_cast<uint32_t>(b) & 0x1f)))); >- 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 90d575b418509e39dbe8177552efde647e239a02..0175926e26b213ddf5c863dc913d7479ad4eea4d 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; > } > >@@ -226,7 +227,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 a69b01cce2ad2fa99866e5bfba15a395f856f776..ca9ebaa7f79b1e49e3ebdf378d8983bf141d2f91 100644 >--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >@@ -3509,7 +3509,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; > } >@@ -5031,7 +5031,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 81033e9ebb312830159fd1432547a4b3d93bf1bd..5a0f1179f9cb0002066782e8f5361ee6387d9f0a 100644 >--- a/Source/JavaScriptCore/dfg/DFGClobberize.h >+++ b/Source/JavaScriptCore/dfg/DFGClobberize.h >@@ -280,7 +280,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) { >@@ -682,6 +682,7 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu > case ValueDiv: > case ValueMod: > case ValuePow: >+ 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 8d8d6cd06f7947e42caebf950c6294cb74c8b785..6e8957e4d90c067c193ad0dfe7445ddee59d9ec2 100644 >--- a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp >+++ b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp >@@ -84,7 +84,7 @@ bool doesGC(Graph& graph, Node* node) > case ArithBitAnd: > case ArithBitOr: > case ArithBitXor: >- case BitLShift: >+ case ArithBitLShift: > case BitRShift: > case BitURShift: > case ValueToInt32: >@@ -375,6 +375,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 aa177b9ebbdda8c576ca9183c990b50b8427dd76..c58aacf12ad1965f94d0d216cc25bc5884a4dd9c 100644 >--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp >+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp >@@ -215,12 +215,14 @@ private: > break; > } > >+ case ValueBitLShift: > case ValueBitXor: > case ValueBitOr: > case ValueBitAnd: { > if (Node::shouldSpeculateBigInt(node->child1().node(), node->child2().node())) { > fixEdge<BigIntUse>(node->child1()); > fixEdge<BigIntUse>(node->child2()); >+ node->clearFlags(NodeMustGenerate); > break; > } > >@@ -229,8 +231,7 @@ private: > fixEdge<UntypedUse>(node->child2()); > break; > } >- >- // In such case, we need to fallback to ArithBitOp >+ > switch (op) { > case ValueBitXor: > node->setOp(ArithBitXor); >@@ -241,6 +242,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; >@@ -277,6 +281,7 @@ private: > break; > } > >+ case ArithBitLShift: > case ArithBitXor: > case ArithBitOr: > case ArithBitAnd: { >@@ -286,7 +291,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 4194c2a40898f6dcd8cb2e1c8724c2a79b8f8f0f..c09a17662a8b9d0060493fff4842c9e88be18dd2 100644 >--- a/Source/JavaScriptCore/dfg/DFGNodeType.h >+++ b/Source/JavaScriptCore/dfg/DFGNodeType.h >@@ -121,7 +121,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 5cb276f3f19fcf81ebff3efdcd7be0153947e96b..96ec52dfb2de15a53548cfda449dba0204172907 100644 >--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp >+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp >@@ -478,18 +478,15 @@ EncodedJSValue JIT_OPERATION operationValueBitXor(ExecState* exec, EncodedJSValu > > 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."_s); > } > > EncodedJSValue JIT_OPERATION operationValueBitRShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2) >@@ -1431,6 +1428,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 7ee6c355e2d39190805c610bda4ddb46f6f267e8..91665786dc1566da3ea3290c67af9496f1dc708a 100644 >--- a/Source/JavaScriptCore/dfg/DFGOperations.h >+++ b/Source/JavaScriptCore/dfg/DFGOperations.h >@@ -176,6 +176,7 @@ JSCell* JIT_OPERATION operationPowBigInt(ExecState*, JSCell* op1, JSCell* op2) W > JSCell* JIT_OPERATION operationBitAndBigInt(ExecState*, JSCell* op1, JSCell* op2) WTF_INTERNAL; > JSCell* JIT_OPERATION operationBitNotBigInt(ExecState*, JSCell* op1) 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 9537ce062407c022caa1a87b726101c3075e73c1..6a8237c984a507683de43a2e8cfb1b8318a86a71 100644 >--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp >+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp >@@ -179,6 +179,22 @@ private: > break; > } > >+ case ValueBitLShift: { >+ 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(); >@@ -768,7 +784,7 @@ private: > case ArithBitOr: > case ArithBitXor: > case BitRShift: >- case BitLShift: >+ case ArithBitLShift: > case BitURShift: > case ArithIMul: > case ArithClz32: { >@@ -1137,6 +1153,7 @@ private: > case ValueDiv: > case ValueMod: > case ValuePow: >+ case ValueBitLShift: > case ArithAdd: > case ArithSub: > case ArithNegate: >diff --git a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h >index 72ca69a595a2cddb55171246454709a56a5c36d5..38c29edc73c1ed2914591767e602630d759885e1 100644 >--- a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h >+++ b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h >@@ -203,7 +203,7 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node, bool igno > case ArithBitAnd: > case ArithBitOr: > case ArithBitXor: >- case BitLShift: >+ case ArithBitLShift: > case BitRShift: > case BitURShift: > case ValueToInt32: >@@ -233,6 +233,7 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node, bool igno > case ValueBitXor: > case ValueBitOr: > case ValueBitNot: >+ case ValueBitLShift: > case ValueNegate: > case ValueAdd: > case ValueSub: >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >index ec2b3c82e42819e2a684319472450778b5066604..481583511ffe8c2cc72f2eb55d670d99426cb39e 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >@@ -3861,6 +3861,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(); >@@ -3869,9 +3897,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 9f1d893b87c15cea4559ed775b09941aa0101a3a..2ac06729a75fb6c7fd3719ff6c37b64e128aa615 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >@@ -663,7 +663,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: >@@ -679,7 +679,7 @@ public: > case BitRShift: > m_jit.rshift32(op1, shiftAmount, result); > break; >- case BitLShift: >+ case ArithBitLShift: > m_jit.lshift32(op1, shiftAmount, result); > break; > case BitURShift: >@@ -1334,6 +1334,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 9d382cf616d9d32775be9750899d0c9ae853dd8b..98e6d414c701f12698927f7045fcc76ec5d75c48 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp >@@ -2001,8 +2001,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 2d62faa8c33ac9499f503fdb240476db63a61e92..29cc10937c7bfcc50cadb9b9d84b313bc94ea900 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >@@ -2100,8 +2100,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 d1cde134133ec302f94f4fac8f12c71c7839fd94..6c7448660270725b9e9c8543a14d3336dcc45b3d 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 a22c117e44c8616e3de1222d704ccf9ca5cb2990..e3ab8e2ab781bead91d338f98e769a66ebd6b373 100644 >--- a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp >+++ b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp >@@ -64,7 +64,7 @@ inline CapabilityLevel canCompile(Node* node) > case ArithBitOr: > case ArithBitXor: > case BitRShift: >- case BitLShift: >+ case ArithBitLShift: > case BitURShift: > case CheckStructure: > case CheckStructureOrEmpty: >@@ -93,6 +93,7 @@ inline CapabilityLevel canCompile(Node* node) > case ValueBitXor: > case ValueBitOr: > case ValueBitNot: >+ case ValueBitLShift: > case ValueNegate: > case ValueAdd: > case ValueSub: >diff --git a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >index 24ea97da75939781022d5fa3697cc6c43f1dc1a3..141c5bc14fa5ca284302715b20adedf7b1921ce7 100644 >--- a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >+++ b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >@@ -853,8 +853,11 @@ private: > case BitRShift: > compileBitRShift(); > break; >- case BitLShift: >- compileBitLShift(); >+ case ArithBitLShift: >+ compileArithBitLShift(); >+ break; >+ case ValueBitLShift: >+ compileValueBitLShift(); > break; > case BitURShift: > compileBitURShift(); >@@ -3184,17 +3187,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 c350c018e5028c9cf1239ac6dc0a58b91fccad71..37ef2791c15b63708196ca9fc69b1ec8e50a9155 100644 >--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm >+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm >@@ -1170,7 +1170,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 903635af525a8b1f447060314307d1083d3635ad..46e2abee81e7776ca51a289d18a60d5f77d03870 100644 >--- a/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm >@@ -1147,7 +1147,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 29b2022338aac3e88f2a33e2b8937a5832ad90e2..cfa112cd3bd15f984d884b926362a511e468d8be 100644 >--- a/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >+++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.cpp >@@ -674,13 +674,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 c64efc71170c2abb45edc2b59ac5ac0c4e016ecb..9edd6b9a029bd37ed74e33aec574e0b8466dd5af 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,19 @@ >+2019-06-16 Caio Lima <ticaiolima@gmail.com> >+ >+ [BigInt] Add ValueBitLShift into DFG >+ https://bugs.webkit.org/show_bug.cgi?id=192664 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ We are adding tests to cover ValueBitwise operations AI changes. >+ >+ * stress/big-int-left-shift-untyped.js: Added. >+ * stress/bit-op-with-object-returning-int32.js: >+ * stress/value-bit-and-ai-rule.js: Added. >+ * stress/value-bit-lshift-ai-rule.js: Added. >+ * stress/value-bit-or-ai-rule.js: Added. >+ * stress/value-bit-xor-ai-rule.js: Added. >+ > 2019-06-13 Yusuke Suzuki <ysuzuki@apple.com> > > Yarr bytecode compilation failure should be gracefully handled >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 1749afbc50a4f47a93cfc6e66e5729761c24bb27..609d9f28b38a1b4a9cd00ca44d4e1eebb8bd0eb1 100644 >--- a/JSTests/stress/bit-op-with-object-returning-int32.js >+++ b/JSTests/stress/bit-op-with-object-returning-int32.js >@@ -46,3 +46,13 @@ for (var i = 0; i < 10000; i++) > > assert(numberOfDFGCompiles(bitNot) <= 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/JSTests/stress/value-bit-and-ai-rule.js b/JSTests/stress/value-bit-and-ai-rule.js >new file mode 100644 >index 0000000000000000000000000000000000000000..bb9ba9b981196e295d7efc20d5411fbc42e367ca >--- /dev/null >+++ b/JSTests/stress/value-bit-and-ai-rule.js >@@ -0,0 +1,22 @@ >+//@ runBigIntEnabled >+ >+function assert(a, e) { >+ if (a !== e) >+ throw new Error("Expected: " + e + " bug got: " + a); >+} >+ >+let predicate = true; >+function foo(a) { >+ let v = a; >+ if (predicate) >+ v = 0b1010; >+ >+ let c = v & 0b11; >+ return c; >+} >+noInline(foo); >+ >+for (let i = 0; i < 10000; i++) { >+ assert(foo(0b1010n), 0b10); >+} >+ >diff --git a/JSTests/stress/value-bit-lshift-ai-rule.js b/JSTests/stress/value-bit-lshift-ai-rule.js >new file mode 100644 >index 0000000000000000000000000000000000000000..4b15fb20944e4f1a4fb3242c3b343fa12b10a7f7 >--- /dev/null >+++ b/JSTests/stress/value-bit-lshift-ai-rule.js >@@ -0,0 +1,22 @@ >+//@ runBigIntEnabled >+ >+function assert(a, e) { >+ if (a !== e) >+ throw new Error("Expected: " + e + " bug got: " + a); >+} >+ >+let predicate = true; >+function foo(a) { >+ let v = a; >+ if (predicate) >+ v = 1; >+ >+ let c = v << 4; >+ return c; >+} >+noInline(foo); >+ >+for (let i = 0; i < 10000; i++) { >+ assert(foo(1n), 16); >+} >+ >diff --git a/JSTests/stress/value-bit-or-ai-rule.js b/JSTests/stress/value-bit-or-ai-rule.js >new file mode 100644 >index 0000000000000000000000000000000000000000..b12f554b1ba2ba596f50e755d58ef05c9361959a >--- /dev/null >+++ b/JSTests/stress/value-bit-or-ai-rule.js >@@ -0,0 +1,22 @@ >+//@ runBigIntEnabled >+ >+function assert(a, e) { >+ if (a !== e) >+ throw new Error("Expected: " + e + " bug got: " + a); >+} >+ >+let predicate = true; >+function foo(a) { >+ let v = a; >+ if (predicate) >+ v = 0b1000; >+ >+ let c = v | 0b11; >+ return c; >+} >+noInline(foo); >+ >+for (let i = 0; i < 10000; i++) { >+ assert(foo(0b1000n), 0b1011); >+} >+ >diff --git a/JSTests/stress/value-bit-xor-ai-rule.js b/JSTests/stress/value-bit-xor-ai-rule.js >new file mode 100644 >index 0000000000000000000000000000000000000000..13c1fa3579d78ba126b00a45226265dd8232c995 >--- /dev/null >+++ b/JSTests/stress/value-bit-xor-ai-rule.js >@@ -0,0 +1,22 @@ >+//@ runBigIntEnabled >+ >+function assert(a, e) { >+ if (a !== e) >+ throw new Error("Expected: " + e + " bug got: " + a); >+} >+ >+let predicate = true; >+function foo(a) { >+ let v = a; >+ if (predicate) >+ v = 0b1010; >+ >+ let c = v ^ 0b0101; >+ return c; >+} >+noInline(foo); >+ >+for (let i = 0; i < 10000; i++) { >+ assert(foo(0b1010n), 0b1111); >+} >+ >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 e35516fc0f589a48e5e5e9215005af1edd844abe..8e4e850bbffe07390fa6bb50c610ecc597df8c1c 100644 >--- a/PerformanceTests/ChangeLog >+++ b/PerformanceTests/ChangeLog >@@ -1,3 +1,12 @@ >+2019-06-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-05-08 Caio Lima <ticaiolima@gmail.com> > > [BigInt] Add ValueMod into DFG
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