WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
bug-180015-20171219234844.patch (text/plain), 29.38 KB, created by
Yusuke Suzuki
on 2017-12-19 06:48:45 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Yusuke Suzuki
Created:
2017-12-19 06:48:45 PST
Size:
29.38 KB
patch
obsolete
>Subversion Revision: 226034 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 5d2011e18a0455f1d11c9e81e7f02ba99980e4e0..89b166b66a0c1f85174b19ecdfabfb30c86f16ae 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,57 @@ >+2017-12-19 Yusuke Suzuki <utatane.tea@gmail.com> >+ >+ [DFG][FTL] WeakMap#set should have DFG node >+ https://bugs.webkit.org/show_bug.cgi?id=180015 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch adds WeakMapSet and WeakSetAdd DFG nodes to handle them efficiently in DFG and FTL. >+ We also define CSE rules for them. Now, WeakMapSet and WeakSetAdd can offer the results of >+ the subsequent WeakMapGet if CSE allows. >+ >+ * dfg/DFGAbstractInterpreterInlines.h: >+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): >+ * dfg/DFGByteCodeParser.cpp: >+ (JSC::DFG::ByteCodeParser::addVarArgChild): >+ (JSC::DFG::ByteCodeParser::handleIntrinsicCall): >+ * dfg/DFGClobberize.h: >+ (JSC::DFG::clobberize): >+ * dfg/DFGDoesGC.cpp: >+ (JSC::DFG::doesGC): >+ WeakMap operations do not cause GC. >+ >+ * dfg/DFGFixupPhase.cpp: >+ (JSC::DFG::FixupPhase::fixupNode): >+ * dfg/DFGNodeType.h: >+ * dfg/DFGOperations.cpp: >+ * dfg/DFGOperations.h: >+ * dfg/DFGPredictionPropagationPhase.cpp: >+ * dfg/DFGSafeToExecute.h: >+ (JSC::DFG::safeToExecute): >+ * dfg/DFGSpeculativeJIT.cpp: >+ (JSC::DFG::SpeculativeJIT::compileWeakSetAdd): >+ (JSC::DFG::SpeculativeJIT::compileWeakMapSet): >+ * dfg/DFGSpeculativeJIT.h: >+ (JSC::DFG::SpeculativeJIT::callOperation): >+ * dfg/DFGSpeculativeJIT32_64.cpp: >+ (JSC::DFG::SpeculativeJIT::compile): >+ * dfg/DFGSpeculativeJIT64.cpp: >+ (JSC::DFG::SpeculativeJIT::compile): >+ * ftl/FTLCapabilities.cpp: >+ (JSC::FTL::canCompile): >+ * ftl/FTLLowerDFGToB3.cpp: >+ (JSC::FTL::DFG::LowerDFGToB3::compileNode): >+ (JSC::FTL::DFG::LowerDFGToB3::compileWeakSetAdd): >+ (JSC::FTL::DFG::LowerDFGToB3::compileWeakMapSet): >+ * jit/JITOperations.h: >+ * runtime/Intrinsic.cpp: >+ (JSC::intrinsicName): >+ * runtime/Intrinsic.h: >+ * runtime/WeakMapPrototype.cpp: >+ (JSC::WeakMapPrototype::finishCreation): >+ * runtime/WeakSetPrototype.cpp: >+ (JSC::WeakSetPrototype::finishCreation): >+ > 2017-12-17 Yusuke Suzuki <utatane.tea@gmail.com> > > [FTL] NewArrayBuffer should be sinked if it is only used for spreading >diff --git a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >index 640155349f859ef666e195f20f089ce241d756df..aaa0413e3eac5a8f6c5f9698d110e98ec190cd7f 100644 >--- a/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >+++ b/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >@@ -1157,6 +1157,10 @@ bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimi > case MapSet: > break; > >+ case WeakSetAdd: >+ case WeakMapSet: >+ break; >+ > case WeakMapGet: > forNode(node).makeBytecodeTop(); > break; >diff --git a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >index 79e6658802f000aa0069fb3c4898efce00b0fa9e..89ccc41a5f03ed4574f210b7ffbfd61f15cc059c 100644 >--- a/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >+++ b/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >@@ -756,6 +756,12 @@ class ByteCodeParser { > m_graph.m_varArgChildren.append(Edge(child)); > m_numPassedVarArgs++; > } >+ >+ void addVarArgChild(Edge child) >+ { >+ m_graph.m_varArgChildren.append(child); >+ m_numPassedVarArgs++; >+ } > > Node* addCallWithoutSettingResult( > NodeType op, OpInfo opInfo, Node* callee, int argCount, int registerOffset, >@@ -2975,6 +2981,47 @@ bool ByteCodeParser::handleIntrinsicCall(Node* callee, int resultOperand, Intrin > return true; > } > >+ case JSWeakSetAddIntrinsic: { >+ if (argumentCountIncludingThis != 2) >+ return false; >+ >+ if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType)) >+ return false; >+ >+ insertChecks(); >+ Node* base = get(virtualRegisterForArgument(0, registerOffset)); >+ Node* key = get(virtualRegisterForArgument(1, registerOffset)); >+ addToGraph(Check, Edge(key, ObjectUse)); >+ Node* hash = addToGraph(MapHash, key); >+ addToGraph(WeakSetAdd, Edge(base, WeakSetObjectUse), Edge(key, ObjectUse), Edge(hash, Int32Use)); >+ set(VirtualRegister(resultOperand), base); >+ return true; >+ } >+ >+ case JSWeakMapSetIntrinsic: { >+ if (argumentCountIncludingThis != 3) >+ return false; >+ >+ if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadType)) >+ return false; >+ >+ insertChecks(); >+ Node* base = get(virtualRegisterForArgument(0, registerOffset)); >+ Node* key = get(virtualRegisterForArgument(1, registerOffset)); >+ Node* value = get(virtualRegisterForArgument(2, registerOffset)); >+ >+ addToGraph(Check, Edge(key, ObjectUse)); >+ Node* hash = addToGraph(MapHash, key); >+ >+ addVarArgChild(Edge(base, WeakMapObjectUse)); >+ addVarArgChild(Edge(key, ObjectUse)); >+ addVarArgChild(Edge(value)); >+ addVarArgChild(Edge(hash, Int32Use)); >+ addToGraph(Node::VarArg, WeakMapSet, OpInfo(0), OpInfo(0)); >+ set(VirtualRegister(resultOperand), base); >+ return true; >+ } >+ > case HasOwnPropertyIntrinsic: { > if (argumentCountIncludingThis != 2) > return false; >diff --git a/Source/JavaScriptCore/dfg/DFGClobberize.h b/Source/JavaScriptCore/dfg/DFGClobberize.h >index 130d0a06dbc5e679b38e5595b0d8d004cc6b9774..6cb5ba73365bd581c6789ff196a6267e5efc7b99 100644 >--- a/Source/JavaScriptCore/dfg/DFGClobberize.h >+++ b/Source/JavaScriptCore/dfg/DFGClobberize.h >@@ -1663,6 +1663,23 @@ void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFu > return; > } > >+ case WeakSetAdd: { >+ Edge& mapEdge = node->child1(); >+ Edge& keyEdge = node->child2(); >+ write(JSWeakSetFields); >+ def(HeapLocation(WeakMapGetLoc, JSWeakSetFields, mapEdge, keyEdge), LazyNode(keyEdge.node())); >+ return; >+ } >+ >+ case WeakMapSet: { >+ Edge& mapEdge = graph.varArgChild(node, 0); >+ Edge& keyEdge = graph.varArgChild(node, 1); >+ Edge& valueEdge = graph.varArgChild(node, 2); >+ write(JSWeakMapFields); >+ def(HeapLocation(WeakMapGetLoc, JSWeakMapFields, mapEdge, keyEdge), LazyNode(valueEdge.node())); >+ return; >+ } >+ > case ExtractValueFromWeakMapGet: > def(PureValue(node)); > return; >diff --git a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp >index cb0bbc4dc2df397a94a99eb2006f9c093a7c44e5..7dcdd103ee7492253a71cbf8836adb5db35cdc77 100644 >--- a/Source/JavaScriptCore/dfg/DFGDoesGC.cpp >+++ b/Source/JavaScriptCore/dfg/DFGDoesGC.cpp >@@ -210,6 +210,8 @@ bool doesGC(Graph& graph, Node* node) > case LoadValueFromMapBucket: > case ExtractValueFromWeakMapGet: > case WeakMapGet: >+ case WeakSetAdd: >+ case WeakMapSet: > case Unreachable: > case ExtractCatchLocal: > case ExtractOSREntryLocal: >diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp >index 5a3466f79c4c3957f2b5eeb92e80dea69a2f7f34..bd42c897f61df2b97935b7d3bb4c0c1d49a38601 100644 >--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp >+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp >@@ -1969,6 +1969,20 @@ class FixupPhase : public Phase { > break; > } > >+ case WeakSetAdd: { >+ fixEdge<WeakSetObjectUse>(node->child1()); >+ fixEdge<ObjectUse>(node->child2()); >+ fixEdge<Int32Use>(node->child3()); >+ break; >+ } >+ >+ case WeakMapSet: { >+ fixEdge<WeakMapObjectUse>(m_graph.varArgChild(node, 0)); >+ fixEdge<ObjectUse>(m_graph.varArgChild(node, 1)); >+ fixEdge<Int32Use>(m_graph.varArgChild(node, 3)); >+ break; >+ } >+ > case DefineDataProperty: { > fixEdge<CellUse>(m_graph.varArgChild(node, 0)); > Edge& propertyEdge = m_graph.varArgChild(node, 1); >diff --git a/Source/JavaScriptCore/dfg/DFGNodeType.h b/Source/JavaScriptCore/dfg/DFGNodeType.h >index 64606d554bc75c712fc78a62a0da9ae61b300c93..9ca67e33b1699ee859fb0844277fb8c2d369607d 100644 >--- a/Source/JavaScriptCore/dfg/DFGNodeType.h >+++ b/Source/JavaScriptCore/dfg/DFGNodeType.h >@@ -445,6 +445,8 @@ namespace JSC { namespace DFG { > macro(MapSet, NodeMustGenerate | NodeHasVarArgs) \ > /* Nodes for JSWeakMap and JSWeakSet */ \ > macro(WeakMapGet, NodeResultJS) \ >+ macro(WeakSetAdd, NodeMustGenerate) \ >+ macro(WeakMapSet, NodeMustGenerate | NodeHasVarArgs) \ > macro(ExtractValueFromWeakMapGet, NodeResultJS) \ > \ > macro(StringSlice, NodeResultJS) \ >diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp >index 671f94d77faa6ac442ac9f5201a0ef04f87ae4c9..b1896f002ae1089824d5cc3b59d19bfadd90940d 100644 >--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp >+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp >@@ -56,6 +56,8 @@ > #include "JSLexicalEnvironment.h" > #include "JSMap.h" > #include "JSSet.h" >+#include "JSWeakMap.h" >+#include "JSWeakSet.h" > #include "ObjectConstructor.h" > #include "Operations.h" > #include "ParseInt.h" >@@ -2587,6 +2589,20 @@ void JIT_OPERATION operationMapSet(ExecState* exec, JSCell* map, EncodedJSValue > jsCast<JSMap*>(map)->addNormalized(exec, JSValue::decode(key), JSValue::decode(value), hash); > } > >+void JIT_OPERATION operationWeakSetAdd(ExecState* exec, JSCell* set, JSCell* key, int32_t hash) >+{ >+ VM& vm = exec->vm(); >+ NativeCallFrameTracer tracer(&vm, exec); >+ jsCast<JSWeakSet*>(set)->add(vm, asObject(key), JSValue(), hash); >+} >+ >+void JIT_OPERATION operationWeakMapSet(ExecState* exec, JSCell* map, JSCell* key, EncodedJSValue value, int32_t hash) >+{ >+ VM& vm = exec->vm(); >+ NativeCallFrameTracer tracer(&vm, exec); >+ jsCast<JSWeakMap*>(map)->add(vm, asObject(key), JSValue::decode(value), hash); >+} >+ > EncodedJSValue JIT_OPERATION operationGetPrototypeOfObject(ExecState* exec, JSObject* thisObject) > { > VM& vm = exec->vm(); >diff --git a/Source/JavaScriptCore/dfg/DFGOperations.h b/Source/JavaScriptCore/dfg/DFGOperations.h >index 5bec9b7abae579bf2b226cdb466684869f8dcd14..c8414ddbc2dffbaa1752b4fd83e446d0658b616c 100644 >--- a/Source/JavaScriptCore/dfg/DFGOperations.h >+++ b/Source/JavaScriptCore/dfg/DFGOperations.h >@@ -140,6 +140,8 @@ void JIT_OPERATION operationDefineAccessorPropertyStringIdent(ExecState*, JSObje > void JIT_OPERATION operationDefineAccessorPropertySymbol(ExecState*, JSObject*, Symbol*, JSObject*, JSObject*, int32_t) WTF_INTERNAL; > void JIT_OPERATION operationSetAdd(ExecState*, JSCell*, EncodedJSValue, int32_t) WTF_INTERNAL; > void JIT_OPERATION operationMapSet(ExecState*, JSCell*, EncodedJSValue, EncodedJSValue, int32_t) WTF_INTERNAL; >+void JIT_OPERATION operationWeakSetAdd(ExecState*, JSCell*, JSCell*, int32_t) WTF_INTERNAL; >+void JIT_OPERATION operationWeakMapSet(ExecState*, JSCell*, JSCell*, EncodedJSValue, int32_t) WTF_INTERNAL; > EncodedJSValue JIT_OPERATION operationArrayPush(ExecState*, EncodedJSValue encodedValue, JSArray*) WTF_INTERNAL; > EncodedJSValue JIT_OPERATION operationArrayPushMultiple(ExecState*, JSArray*, void* buffer, int32_t elementCount) WTF_INTERNAL; > EncodedJSValue JIT_OPERATION operationArrayPushDouble(ExecState*, double value, JSArray*) WTF_INTERNAL; >diff --git a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp >index dd8d8e0263dba5dfaa44c1c7837ffda8540e2d4f..a7593de774c96a6b6ce2adf635672895f1c92bfa 100644 >--- a/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp >+++ b/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp >@@ -1183,6 +1183,8 @@ class PredictionPropagationPhase : public Phase { > case InitializeEntrypointArguments: > case SetAdd: > case MapSet: >+ case WeakSetAdd: >+ case WeakMapSet: > break; > > // This gets ignored because it only pretends to produce a value. >diff --git a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h >index c632c969821bef8ac40ba15513ed3eebd4f3b464..06c6ef2a96a5efff22934e71fbcda491465ccd4e 100644 >--- a/Source/JavaScriptCore/dfg/DFGSafeToExecute.h >+++ b/Source/JavaScriptCore/dfg/DFGSafeToExecute.h >@@ -426,6 +426,8 @@ bool safeToExecute(AbstractStateType& state, Graph& graph, Node* node) > case LoadValueFromMapBucket: > case ExtractValueFromWeakMapGet: > case WeakMapGet: >+ case WeakSetAdd: >+ case WeakMapSet: > case AtomicsAdd: > case AtomicsAnd: > case AtomicsCompareExchange: >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >index b70991a3806aea8fbb1dbbfc325599961daa6755..021e477c3c0cbf41aa218371155ac027669e30b0 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >@@ -11079,6 +11079,46 @@ void SpeculativeJIT::compileWeakMapGet(Node* node) > jsValueResult(resultRegs, node); > } > >+void SpeculativeJIT::compileWeakSetAdd(Node* node) >+{ >+ SpeculateCellOperand set(this, node->child1()); >+ SpeculateCellOperand key(this, node->child2()); >+ SpeculateInt32Operand hash(this, node->child3()); >+ >+ GPRReg setGPR = set.gpr(); >+ GPRReg keyGPR = key.gpr(); >+ GPRReg hashGPR = hash.gpr(); >+ >+ speculateWeakSetObject(node->child1(), setGPR); >+ speculateObject(node->child2(), keyGPR); >+ >+ flushRegisters(); >+ callOperation(operationWeakSetAdd, setGPR, keyGPR, hashGPR); >+ m_jit.exceptionCheck(); >+ noResult(node); >+} >+ >+void SpeculativeJIT::compileWeakMapSet(Node* node) >+{ >+ SpeculateCellOperand map(this, m_jit.graph().varArgChild(node, 0)); >+ SpeculateCellOperand key(this, m_jit.graph().varArgChild(node, 1)); >+ JSValueOperand value(this, m_jit.graph().varArgChild(node, 2)); >+ SpeculateInt32Operand hash(this, m_jit.graph().varArgChild(node, 3)); >+ >+ GPRReg mapGPR = map.gpr(); >+ GPRReg keyGPR = key.gpr(); >+ JSValueRegs valueRegs = value.jsValueRegs(); >+ GPRReg hashGPR = hash.gpr(); >+ >+ speculateWeakMapObject(m_jit.graph().varArgChild(node, 0), mapGPR); >+ speculateObject(m_jit.graph().varArgChild(node, 1), keyGPR); >+ >+ flushRegisters(); >+ callOperation(operationWeakMapSet, mapGPR, keyGPR, valueRegs, hashGPR); >+ m_jit.exceptionCheck(); >+ noResult(node); >+} >+ > void SpeculativeJIT::compileGetPrototypeOf(Node* node) > { > switch (node->child1().useKind()) { >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >index 974fc41c883e0e8751b153c17c95b5979ae5b8b6..fcc45f256eadd0c1f2889aef8dc1332c0b6af4ba 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >@@ -1262,6 +1262,11 @@ class SpeculativeJIT { > m_jit.setupArgumentsWithExecState(TrustedImmPtr::weakPointer(m_jit.graph(), arg1), arg2); > return appendCall(operation); > } >+ JITCompiler::Call callOperation(V_JITOperation_ECCZ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3) >+ { >+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3); >+ return appendCall(operation); >+ } > > JITCompiler::Call callOperationWithCallFrameRollbackOnException(V_JITOperation_ECb operation, void* pointer) > { >@@ -1953,6 +1958,11 @@ class SpeculativeJIT { > m_jit.setupArgumentsWithExecState(arg1, arg2, arg3.payloadGPR()); > return appendCall(operation); > } >+ JITCompiler::Call callOperation(V_JITOperation_ECCJZ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3, GPRReg arg4) >+ { >+ m_jit.setupArgumentsWithExecState(arg1, arg2, arg3.payloadGPR(), arg4); >+ return appendCall(operation); >+ } > > JITCompiler::Call callOperation(Z_JITOperation_EJ operation, GPRReg result, JSValueRegs arg1) > { >@@ -2523,6 +2533,11 @@ class SpeculativeJIT { > m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3.payloadGPR(), arg3.tagGPR()); > return appendCall(operation); > } >+ JITCompiler::Call callOperation(V_JITOperation_ECCJZ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3, GPRReg arg4) >+ { >+ m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3.payloadGPR(), arg3.tagGPR(), arg4); >+ return appendCall(operation); >+ } > > JITCompiler::Call callOperation(V_JITOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, JSValueRegs arg3) > { >@@ -2896,6 +2911,8 @@ class SpeculativeJIT { > void compileSetAdd(Node*); > void compileMapSet(Node*); > void compileWeakMapGet(Node*); >+ void compileWeakSetAdd(Node*); >+ void compileWeakMapSet(Node*); > void compileLoadKeyFromMapBucket(Node*); > void compileLoadValueFromMapBucket(Node*); > void compileExtractValueFromWeakMapGet(Node*); >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp >index 913717bf05ee72cddd58df08773bcb23ca1120ec..83fc592630bc32a7e1d542086876796ac04b4ab3 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp >@@ -4886,6 +4886,14 @@ void SpeculativeJIT::compile(Node* node) > compileWeakMapGet(node); > break; > >+ case WeakSetAdd: >+ compileWeakSetAdd(node); >+ break; >+ >+ case WeakMapSet: >+ compileWeakMapSet(node); >+ break; >+ > case Flush: > break; > >diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >index 37f2aaf835636937149132dd3de4f6bd6ffe7b56..66ee07a0ac3ede2911073abe704a25e898bdc701 100644 >--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >@@ -5268,6 +5268,14 @@ void SpeculativeJIT::compile(Node* node) > compileWeakMapGet(node); > break; > >+ case WeakSetAdd: >+ compileWeakSetAdd(node); >+ break; >+ >+ case WeakMapSet: >+ compileWeakMapSet(node); >+ break; >+ > case StringSlice: { > compileStringSlice(node); > break; >diff --git a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp >index d878f6e8ba1ffc7c357cfaa2e1fc65a02407c909..f6ddb77b5a35b251f4f223f37d5ee03202746388 100644 >--- a/Source/JavaScriptCore/ftl/FTLCapabilities.cpp >+++ b/Source/JavaScriptCore/ftl/FTLCapabilities.cpp >@@ -211,6 +211,8 @@ inline CapabilityLevel canCompile(Node* node) > case SetAdd: > case MapSet: > case WeakMapGet: >+ case WeakSetAdd: >+ case WeakMapSet: > case IsEmpty: > case IsUndefined: > case IsBoolean: >diff --git a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >index 3e31a2290767f6691ed7b95cb39c445f94774172..ab7412cd17f308489329cf352a0e3551569c3ece 100644 >--- a/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >+++ b/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp >@@ -1085,6 +1085,12 @@ class LowerDFGToB3 { > case WeakMapGet: > compileWeakMapGet(); > break; >+ case WeakSetAdd: >+ compileWeakSetAdd(); >+ break; >+ case WeakMapSet: >+ compileWeakMapSet(); >+ break; > case IsObject: > compileIsObject(); > break; >@@ -9063,6 +9069,25 @@ class LowerDFGToB3 { > setJSValue(result); > } > >+ void compileWeakSetAdd() >+ { >+ LValue set = lowWeakSetObject(m_node->child1()); >+ LValue key = lowObject(m_node->child2()); >+ LValue hash = lowInt32(m_node->child3()); >+ >+ vmCall(Void, m_out.operation(operationWeakSetAdd), m_callFrame, set, key, hash); >+ } >+ >+ void compileWeakMapSet() >+ { >+ LValue map = lowWeakMapObject(m_graph.varArgChild(m_node, 0)); >+ LValue key = lowObject(m_graph.varArgChild(m_node, 1)); >+ LValue value = lowJSValue(m_graph.varArgChild(m_node, 2)); >+ LValue hash = lowInt32(m_graph.varArgChild(m_node, 3)); >+ >+ vmCall(Void, m_out.operation(operationWeakMapSet), m_callFrame, map, key, value, hash); >+ } >+ > void compileIsObjectOrNull() > { > JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic); >diff --git a/Source/JavaScriptCore/jit/JITOperations.h b/Source/JavaScriptCore/jit/JITOperations.h >index 74791467395791fb28287e7f78f3962c6981c495..a71731a20c05048d14f1f6ac465559f2f82570f6 100644 >--- a/Source/JavaScriptCore/jit/JITOperations.h >+++ b/Source/JavaScriptCore/jit/JITOperations.h >@@ -274,6 +274,8 @@ typedef void (JIT_OPERATION *V_JITOperation_ECZ)(ExecState*, JSCell*, int32_t); > typedef void (JIT_OPERATION *V_JITOperation_ECC)(ExecState*, JSCell*, JSCell*); > typedef void (JIT_OPERATION *V_JITOperation_ECliJsf)(ExecState*, CallLinkInfo*, JSFunction*); > typedef void (JIT_OPERATION *V_JITOperation_ECCJ)(ExecState*, JSCell*, JSCell*, EncodedJSValue); >+typedef void (JIT_OPERATION *V_JITOperation_ECCZ)(ExecState*, JSCell*, JSCell*, int32_t); >+typedef void (JIT_OPERATION *V_JITOperation_ECCJZ)(ExecState*, JSCell*, JSCell*, EncodedJSValue, int32_t); > typedef void (JIT_OPERATION *V_JITOperation_EZSymtabJ)(ExecState*, int32_t, SymbolTable*, EncodedJSValue); > typedef void (JIT_OPERATION *V_JITOperation_EJ)(ExecState*, EncodedJSValue); > typedef void (JIT_OPERATION *V_JITOperation_EJCI)(ExecState*, EncodedJSValue, JSCell*, UniquedStringImpl*); >diff --git a/Source/JavaScriptCore/runtime/Intrinsic.cpp b/Source/JavaScriptCore/runtime/Intrinsic.cpp >index ca1559106aae8c4012c9d73b053fc367e675ce4a..953ee15b7c2b70cd2511fae270d2f8d1ddba216a 100644 >--- a/Source/JavaScriptCore/runtime/Intrinsic.cpp >+++ b/Source/JavaScriptCore/runtime/Intrinsic.cpp >@@ -167,8 +167,12 @@ const char* intrinsicName(Intrinsic intrinsic) > return "JSWeakMapGetIntrinsic"; > case JSWeakMapHasIntrinsic: > return "JSWeakMapHasIntrinsic"; >+ case JSWeakMapSetIntrinsic: >+ return "JSWeakMapSetIntrinsic"; > case JSWeakSetHasIntrinsic: > return "JSWeakSetHasIntrinsic"; >+ case JSWeakSetAddIntrinsic: >+ return "JSWeakSetAddIntrinsic"; > case HasOwnPropertyIntrinsic: > return "HasOwnPropertyIntrinsic"; > case AtomicsAddIntrinsic: >diff --git a/Source/JavaScriptCore/runtime/Intrinsic.h b/Source/JavaScriptCore/runtime/Intrinsic.h >index 390def849ee8e839e83e0adfa068bd8eaeb4e41f..85544c227fa3ab4d3ce7e189cd885c80391f615e 100644 >--- a/Source/JavaScriptCore/runtime/Intrinsic.h >+++ b/Source/JavaScriptCore/runtime/Intrinsic.h >@@ -96,7 +96,9 @@ enum Intrinsic { > JSSetBucketKeyIntrinsic, > JSWeakMapGetIntrinsic, > JSWeakMapHasIntrinsic, >+ JSWeakMapSetIntrinsic, > JSWeakSetHasIntrinsic, >+ JSWeakSetAddIntrinsic, > HasOwnPropertyIntrinsic, > AtomicsAddIntrinsic, > AtomicsAndIntrinsic, >diff --git a/Source/JavaScriptCore/runtime/WeakMapPrototype.cpp b/Source/JavaScriptCore/runtime/WeakMapPrototype.cpp >index 9caeb59122404f7a90442323f2aec2fc0df7c4cb..f607636daffe346798727e695cd53f3b5d5195be 100644 >--- a/Source/JavaScriptCore/runtime/WeakMapPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/WeakMapPrototype.cpp >@@ -47,7 +47,7 @@ void WeakMapPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject) > JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->deleteKeyword, protoFuncWeakMapDelete, static_cast<unsigned>(PropertyAttribute::DontEnum), 1); > JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->get, protoFuncWeakMapGet, static_cast<unsigned>(PropertyAttribute::DontEnum), 1, JSWeakMapGetIntrinsic); > JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->has, protoFuncWeakMapHas, static_cast<unsigned>(PropertyAttribute::DontEnum), 1, JSWeakMapHasIntrinsic); >- JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->set, protoFuncWeakMapSet, static_cast<unsigned>(PropertyAttribute::DontEnum), 2); >+ JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->set, protoFuncWeakMapSet, static_cast<unsigned>(PropertyAttribute::DontEnum), 2, JSWeakMapSetIntrinsic); > > putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "WeakMap"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly); > } >diff --git a/Source/JavaScriptCore/runtime/WeakSetPrototype.cpp b/Source/JavaScriptCore/runtime/WeakSetPrototype.cpp >index 563e86c9afb2d4959b5cc014dc3cb72de45f3820..6486d2138e2f57a20e187b460e29243496204976 100644 >--- a/Source/JavaScriptCore/runtime/WeakSetPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/WeakSetPrototype.cpp >@@ -45,7 +45,7 @@ void WeakSetPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject) > > JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->deleteKeyword, protoFuncWeakSetDelete, static_cast<unsigned>(PropertyAttribute::DontEnum), 1); > JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->has, protoFuncWeakSetHas, static_cast<unsigned>(PropertyAttribute::DontEnum), 1, JSWeakSetHasIntrinsic); >- JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->add, protoFuncWeakSetAdd, static_cast<unsigned>(PropertyAttribute::DontEnum), 1); >+ JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->add, protoFuncWeakSetAdd, static_cast<unsigned>(PropertyAttribute::DontEnum), 1, JSWeakSetAddIntrinsic); > > putDirectWithoutTransition(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "WeakSet"), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly); > } >diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog >index 5da6c29f9d593c2d75a3f13abc631873256ab18a..975025e7e5710ff62092bc071951ad2835ab50b2 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,21 @@ >+2017-12-19 Yusuke Suzuki <utatane.tea@gmail.com> >+ >+ [DFG][FTL] WeakMap#set should have DFG node >+ https://bugs.webkit.org/show_bug.cgi?id=180015 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * stress/weakmap-set-change-get.js: Added. >+ (shouldBe): >+ (test): >+ * stress/weakmap-set-cse.js: Added. >+ (shouldBe): >+ (test): >+ * stress/weakset-add-change-get.js: Added. >+ (shouldBe): >+ * stress/weakset-add-cse.js: Added. >+ (shouldBe): >+ > 2017-12-17 Yusuke Suzuki <utatane.tea@gmail.com> > > [FTL] NewArrayBuffer should be sinked if it is only used for spreading >diff --git a/JSTests/stress/weakmap-set-change-get.js b/JSTests/stress/weakmap-set-change-get.js >new file mode 100644 >index 0000000000000000000000000000000000000000..b511e580a0ace0ff7ed4d1ba7423bb18a8473a89 >--- /dev/null >+++ b/JSTests/stress/weakmap-set-change-get.js >@@ -0,0 +1,27 @@ >+function shouldBe(actual, expected) { >+ if (actual !== expected) >+ throw new Error('bad value: ' + actual); >+} >+ >+function test() >+{ >+ var key1 = {}; >+ var map = new WeakMap(); >+ var res1 = map.get(key1); >+ map.set(key1, 20); >+ var res2 = map.get(key1); >+ map.set(key1, 400); >+ var res3 = map.get(key1); >+ map.delete(key1); >+ var res4 = map.get(key1); >+ return [res1, res2, res3, res4]; >+} >+noInline(test); >+ >+for (var i = 0; i < 1e5; ++i) { >+ var [res1, res2, res3, res4] = test(); >+ shouldBe(res1, undefined); >+ shouldBe(res2, 20); >+ shouldBe(res3, 400); >+ shouldBe(res4, undefined); >+} >diff --git a/JSTests/stress/weakmap-set-cse.js b/JSTests/stress/weakmap-set-cse.js >new file mode 100644 >index 0000000000000000000000000000000000000000..f5f04936adc717f5d85d424a82136c25d5c12f23 >--- /dev/null >+++ b/JSTests/stress/weakmap-set-cse.js >@@ -0,0 +1,22 @@ >+function shouldBe(actual, expected) >+{ >+ if (actual !== expected) >+ throw new Error('bad value: ' + actual); >+} >+ >+function test() >+{ >+ var key1 = {}; >+ var map = new WeakMap(); >+ var r1 = map.get(key1); >+ map.set(key1, 42); >+ var r2 = map.get(key1); >+ return [r1, r2]; >+} >+noInline(test); >+ >+for (var i = 0; i < 1e5; ++i) { >+ let [r1, r2] = test(); >+ shouldBe(r1, undefined); >+ shouldBe(r2, 42); >+} >diff --git a/JSTests/stress/weakset-add-change-get.js b/JSTests/stress/weakset-add-change-get.js >new file mode 100644 >index 0000000000000000000000000000000000000000..78fabef8a5995f906de72452ef7fdbbdfa14acc1 >--- /dev/null >+++ b/JSTests/stress/weakset-add-change-get.js >@@ -0,0 +1,24 @@ >+function shouldBe(actual, expected) { >+ if (actual !== expected) >+ throw new Error('bad value: ' + actual); >+} >+ >+function test() >+{ >+ var key1 = {}; >+ var set = new WeakSet(); >+ var res1 = set.has(key1); >+ set.add(key1); >+ var res2 = set.has(key1); >+ set.delete(key1); >+ var res3 = set.has(key1); >+ return [res1, res2, res3]; >+} >+noInline(test); >+ >+for (var i = 0; i < 1e5; ++i) { >+ var [res1, res2, res3] = test(); >+ shouldBe(res1, false); >+ shouldBe(res2, true); >+ shouldBe(res3, false); >+} >diff --git a/JSTests/stress/weakset-add-cse.js b/JSTests/stress/weakset-add-cse.js >new file mode 100644 >index 0000000000000000000000000000000000000000..d0c4cea668f96fc7773237c066ce2876596abbde >--- /dev/null >+++ b/JSTests/stress/weakset-add-cse.js >@@ -0,0 +1,22 @@ >+function shouldBe(actual, expected) >+{ >+ if (actual !== expected) >+ throw new Error('bad value: ' + actual); >+} >+ >+function test() >+{ >+ var key1 = {}; >+ var set = new WeakSet(); >+ var r1 = set.has(key1); >+ set.add(key1); >+ var r2 = set.has(key1); >+ return [r1, r2]; >+} >+noInline(test); >+ >+for (var i = 0; i < 1e5; ++i) { >+ let [r1, r2] = test(); >+ shouldBe(r1, false); >+ shouldBe(r2, true); >+}
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
Flags:
saam
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 180015
: 329759