WebKit Bugzilla
Attachment 360941 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-20190202000526.patch (text/plain), 41.12 KB, created by
Caio Lima
on 2019-02-01 18:05:30 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Caio Lima
Created:
2019-02-01 18:05:30 PST
Size:
41.12 KB
patch
obsolete
>Subversion Revision: 240887 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index d021748c656098946963b214db46718f6b85a03b..7a5fce73e622e7332b0c364fafb5d7b36fb83cfe 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,69 @@ >+2019-02-01 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-01 Mark Lam <mark.lam@apple.com> > > Remove invalid assertion in DFG's compileDoubleRep(). >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 cd10a4583a7a50f2ef4853a09da3faf63d59deac..dee6ceb22c960dee826ae85bdce83d70e6a90ac3 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 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 7581a1a7746e9870e79f92e2178fbd2c9759226d..423dd76669a088128b04e6f6ac6295dbc651c1d4 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 b1dc25b1b878f0b5d4f4d41d41df1fdad92362a4..26cffe64860f9f6d4cdf1c98b3cea50bfa648afc 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 7e9b0d8969aceaa0fca1039b0bcc746beb7b9533..49b49f6e495b8a9b2079276dfd9502f58d083363 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 191f26b1a8e76b4589a8c0937159e68be6b6d213..a9be07107652268d3108adb8f0d2199d21078f8b 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: >@@ -376,6 +376,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 d2d4fbfb44b35715358ca71e46f1ed20c68e2be2..120b74db43f918fc47c308fe0c836e54252d63e0 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 bd3bfe2fd40d2d0bd3b1d307a43a122935284e43..d24d78a50e007e4e2d3d86411d5f3510259a242b 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 22750b7997af9c9a6b0eea3a5acfced1458c7f2e..56abf0785ff498ed864f2a31d2993e0254e8d567 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) >@@ -1371,6 +1353,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 9ec916f2ea05972f666a9b2132806fee4aef595d..bc43f1e76052cf40bb16c43f48c36ca0222e2d2a 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 7f9e381b755d264ca75e3e7dcaca80c8741dde66..f6946b0311ddff40473ccf910be566d8503dba5b 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 1ff0c337da8c95ce94c56f8ebe3a9b6a4e4dab15..c09062a5e9e9602e8635a5a331bd02a68dcdd795 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 4f3a5a054b58b145c70c8a4a6a4af6cc0f5a0807..887f6691e3338bb27d667ea335a9c8b03f81c857 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 bbbadab67fdf6fcad4cac0664cdc8e60bf5e4b2e..49e248240d15089ea47de9439fc6a43d8896cb98 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 8d03fbcb633452c30d9f27c318942f57c9641de6..08d3bb25ce648919da192caa87d9311d2d4e2225 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,13 @@ >+2019-02-01 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-01 Mark Lam <mark.lam@apple.com> > > Remove invalid assertion in DFG's compileDoubleRep(). >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 7aac53b9ed32ec6aee94df7a627a250224cb90e2..95c1333ac38472f51357246474090614489f215a 100644 >--- a/PerformanceTests/ChangeLog >+++ b/PerformanceTests/ChangeLog >@@ -1,3 +1,13 @@ >+2019-02-01 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. >+ (bigInt): >+ > 2019-01-31 Sihui Liu <sihui_liu@apple.com> > > REGRESSION (r240358): IndexedDB/large-binary-keys.html and IndexedDB/large-string-keys.html perf tests failing
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