Title: [258926] branches/safari-609-branch/Source/_javascript_Core
Revision
258926
Author
[email protected]
Date
2020-03-24 12:03:11 -0700 (Tue, 24 Mar 2020)

Log Message

Cherry-pick r258901. rdar://problem/60827028

    HasIndexedProperty should know about sane chain
    https://bugs.webkit.org/show_bug.cgi?id=209457

    Reviewed by Saam Barati.

    This patch makes it so HasIndexedProperty is aware of
    sane chain. This is useful because, most of the time we do an
    indexed in it is on an array. If the array has a sane chain (i.e.
    no indexed properties on it's prototypes and has the default
    prototype chain) then we can just test for the index being a hole.

    Note, we could also just convert OOB indices into false but that
    should happen in another patch.
    https://bugs.webkit.org/show_bug.cgi?id=209456

    I didn't add any tests because it turns out we already have a ton.
    I know this because I broke most of them repeatedly... >.>

    * dfg/DFGAbstractInterpreterInlines.h:
    (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
    * dfg/DFGClobberize.h:
    (JSC::DFG::clobberize):
    * dfg/DFGFixupPhase.cpp:
    (JSC::DFG::FixupPhase::fixupNode):
    (JSC::DFG::FixupPhase::setSaneChainIfPossible):
    (JSC::DFG::FixupPhase::convertToHasIndexedProperty):
    * dfg/DFGNodeType.h:
    * dfg/DFGSpeculativeJIT.cpp:
    (JSC::DFG::SpeculativeJIT::compileHasIndexedProperty):
    * ftl/FTLLowerDFGToB3.cpp:
    (JSC::FTL::DFG::LowerDFGToB3::compileHasIndexedProperty):
    (JSC::FTL::DFG::LowerDFGToB3::speculateAndJump):
    * jit/AssemblyHelpers.h:
    (JSC::AssemblyHelpers::isEmpty):

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@258901 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Diff

Modified: branches/safari-609-branch/Source/_javascript_Core/ChangeLog (258925 => 258926)


--- branches/safari-609-branch/Source/_javascript_Core/ChangeLog	2020-03-24 19:03:08 UTC (rev 258925)
+++ branches/safari-609-branch/Source/_javascript_Core/ChangeLog	2020-03-24 19:03:11 UTC (rev 258926)
@@ -1,4 +1,4 @@
-2020-03-17  Alan Coon  <[email protected]>
+b"2020-03-24  Russell Epstein  <[email protected]>\n\n        Cherry-pick r258901. rdar://problem/60827028\n\n    HasIndexedProperty should know about sane chain\n    https://bugs.webkit.org/show_bug.cgi?id=209457\n    \n    Reviewed by Saam Barati.\n    \n    This patch makes it so HasIndexedProperty is aware of\n    sane chain. This is useful because, most of the time we do an\n    indexed in it is on an array. If the array has a sane chain (i.e.\n    no indexed properties on it's prototypes and has the default\n    prototype chain) then we can just test for the index being a hole.\n    \n    Note, we could also just convert OOB indices into false but that\n    should happen in another patch.\n    https://bugs.webkit.org/show_bug.cgi?id=209456\n    \n    I didn't add any tests because it turns out we already have a ton.\n    I know this because I broke most of them repeatedly... >.>\n    \n    * dfg/DFGAbstractInterpreterInlines.h:\n    (JSC::DFG::Abst
 ractInterpreter<AbstractStateType>::executeEffects):\n    * dfg/DFGClobberize.h:\n    (JSC::DFG::clobberize):\n    * dfg/DFGFixupPhase.cpp:\n    (JSC::DFG::FixupPhase::fixupNode):\n    (JSC::DFG::FixupPhase::setSaneChainIfPossible):\n    (JSC::DFG::FixupPhase::convertToHasIndexedProperty):\n    * dfg/DFGNodeType.h:\n    * dfg/DFGSpeculativeJIT.cpp:\n    (JSC::DFG::SpeculativeJIT::compileHasIndexedProperty):\n    * ftl/FTLLowerDFGToB3.cpp:\n    (JSC::FTL::DFG::LowerDFGToB3::compileHasIndexedProperty):\n    (JSC::FTL::DFG::LowerDFGToB3::speculateAndJump):\n    * jit/AssemblyHelpers.h:\n    (JSC::AssemblyHelpers::isEmpty):\n    \n    \n    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@258901 268f45cc-cd09-0410-ab3c-d52691b4dbfc\n\n    2020-03-23  Keith Miller  <[email protected]>\n\n            HasIndexedProperty should know about sane chain\n            https://bugs.webkit.org/show_bug.cgi?id=209457\n\n            Reviewed by Saam Barati.\n\n            T
 his patch makes it so HasIndexedProperty is aware of\n            sane chain. This is useful because, most of the time we do an\n            indexed in it is on an array. If the array has a sane chain (i.e.\n            no indexed properties on it's prototypes and has the default\n            prototype chain) then we can just test for the index being a hole.\n\n            Note, we could also just convert OOB indices into false but that\n            should happen in another patch.\n            https://bugs.webkit.org/show_bug.cgi?id=209456\n\n            I didn't add any tests because it turns out we already have a ton.\n            I know this because I broke most of them repeatedly... >.>\n\n            * dfg/DFGAbstractInterpreterInlines.h:\n            (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):\n            * dfg/DFGClobberize.h:\n            (JSC::DFG::clobberize):\n            * dfg/DFGFixupPhase.cpp:\n            (JSC::DFG::FixupPhase::fix
 upNode):\n            (JSC::DFG::FixupPhase::setSaneChainIfPossible):\n            (JSC::DFG::FixupPhase::convertToHasIndexedProperty):\n            * dfg/DFGNodeType.h:\n            * dfg/DFGSpeculativeJIT.cpp:\n            (JSC::DFG::SpeculativeJIT::compileHasIndexedProperty):\n            * ftl/FTLLowerDFGToB3.cpp:\n            (JSC::FTL::DFG::LowerDFGToB3::compileHasIndexedProperty):\n            (JSC::FTL::DFG::LowerDFGToB3::speculateAndJump):\n            * jit/AssemblyHelpers.h:\n            (JSC::AssemblyHelpers::isEmpty):\n\n"2020-03-17  Alan Coon  <[email protected]>
 
         Apply patch. rdar://problem/60396286
 

Modified: branches/safari-609-branch/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (258925 => 258926)


--- branches/safari-609-branch/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2020-03-24 19:03:08 UTC (rev 258925)
+++ branches/safari-609-branch/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h	2020-03-24 19:03:11 UTC (rev 258926)
@@ -3888,7 +3888,9 @@
         case Array::Double:
         case Array::Contiguous:
         case Array::ArrayStorage: {
-            break;
+            if (mode.isInBounds())
+                break;
+            FALLTHROUGH;
         }
         default: {
             clobberWorld();

Modified: branches/safari-609-branch/Source/_javascript_Core/dfg/DFGClobberize.h (258925 => 258926)


--- branches/safari-609-branch/Source/_javascript_Core/dfg/DFGClobberize.h	2020-03-24 19:03:08 UTC (rev 258925)
+++ branches/safari-609-branch/Source/_javascript_Core/dfg/DFGClobberize.h	2020-03-24 19:03:11 UTC (rev 258926)
@@ -324,8 +324,7 @@
                 def(HeapLocation(HasIndexedPropertyLoc, IndexedInt32Properties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
                 return;
             }
-            read(Heap);
-            return;
+            break;
         }
             
         case Array::Double: {
@@ -335,8 +334,7 @@
                 def(HeapLocation(HasIndexedPropertyLoc, IndexedDoubleProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
                 return;
             }
-            read(Heap);
-            return;
+            break;
         }
             
         case Array::Contiguous: {
@@ -346,8 +344,7 @@
                 def(HeapLocation(HasIndexedPropertyLoc, IndexedContiguousProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
                 return;
             }
-            read(Heap);
-            return;
+            break;
         }
 
         case Array::ArrayStorage: {
@@ -356,17 +353,14 @@
                 read(IndexedArrayStorageProperties);
                 return;
             }
-            read(Heap);
-            return;
+            break;
         }
 
-        default: {
-            read(World);
-            write(Heap);
-            return;
+        default: 
+            break;
         }
-        }
-        RELEASE_ASSERT_NOT_REACHED();
+        read(World);
+        write(Heap);
         return;
     }
 

Modified: branches/safari-609-branch/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (258925 => 258926)


--- branches/safari-609-branch/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2020-03-24 19:03:08 UTC (rev 258925)
+++ branches/safari-609-branch/Source/_javascript_Core/dfg/DFGFixupPhase.cpp	2020-03-24 19:03:11 UTC (rev 258926)
@@ -957,18 +957,8 @@
                         break;
                     }
                     
-                    if (canDoSaneChain) {
-                        JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
-                        Structure* arrayPrototypeStructure = globalObject->arrayPrototype()->structure(vm());
-                        Structure* objectPrototypeStructure = globalObject->objectPrototype()->structure(vm());
-                        if (arrayPrototypeStructure->transitionWatchpointSetIsStillValid()
-                            && objectPrototypeStructure->transitionWatchpointSetIsStillValid()
-                            && globalObject->arrayPrototypeChainIsSane()) {
-                            m_graph.registerAndWatchStructureTransition(arrayPrototypeStructure);
-                            m_graph.registerAndWatchStructureTransition(objectPrototypeStructure);
-                            node->setArrayMode(arrayMode.withSpeculation(Array::SaneChain));
-                        }
-                    }
+                    if (canDoSaneChain)
+                        setSaneChainIfPossible(node);
                 }
                 break;
                 
@@ -1970,6 +1960,12 @@
             blessArrayOperation(m_graph.varArgChild(node, 0), m_graph.varArgChild(node, 1), m_graph.varArgChild(node, 2));
             fixEdge<CellUse>(m_graph.varArgChild(node, 0));
             fixEdge<Int32Use>(m_graph.varArgChild(node, 1));
+
+            ArrayMode arrayMode = node->arrayMode();
+            // FIXME: OutOfBounds shouldn't preclude going sane chain because OOB is just false and cannot have effects.
+            // See: https://bugs.webkit.org/show_bug.cgi?id=209456
+            if (arrayMode.isJSArrayWithOriginalStructure() && arrayMode.speculation() == Array::InBounds)
+                setSaneChainIfPossible(node);
             break;
         }
         case GetDirectPname: {
@@ -3280,6 +3276,21 @@
             m_indexInBlock, SpecNone, GetIndexedPropertyStorage, origin,
             OpInfo(arrayMode.asWord()), Edge(array, KnownCellUse));
     }
+
+    void setSaneChainIfPossible(Node* node)
+    {
+        JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
+        Structure* arrayPrototypeStructure = globalObject->arrayPrototype()->structure(vm());
+        Structure* objectPrototypeStructure = globalObject->objectPrototype()->structure(vm());
+        if (arrayPrototypeStructure->transitionWatchpointSetIsStillValid()
+            && objectPrototypeStructure->transitionWatchpointSetIsStillValid()
+            && globalObject->arrayPrototypeChainIsSane()) {
+            m_graph.registerAndWatchStructureTransition(arrayPrototypeStructure);
+            m_graph.registerAndWatchStructureTransition(objectPrototypeStructure);
+            node->setArrayMode(node->arrayMode().withSpeculation(Array::SaneChain));
+            node->clearFlags(NodeMustGenerate);
+        }
+    }
     
     void blessArrayOperation(Edge base, Edge index, Edge& storageChild)
     {
@@ -3632,7 +3643,6 @@
     void convertToHasIndexedProperty(Node* node)
     {
         node->setOp(HasIndexedProperty);
-        node->clearFlags(NodeMustGenerate);
 
         {
             unsigned firstChild = m_graph.m_varArgChildren.size();
@@ -3640,7 +3650,7 @@
             m_graph.m_varArgChildren.append(node->child1());
             m_graph.m_varArgChildren.append(node->child2());
             m_graph.m_varArgChildren.append(Edge());
-            node->mergeFlags(NodeHasVarArgs);
+            node->setFlags(defaultFlags(HasIndexedProperty));
             node->children = AdjacencyList(AdjacencyList::Variable, firstChild, numChildren);
         }
 
@@ -3653,6 +3663,11 @@
         node->setInternalMethodType(PropertySlot::InternalMethodType::HasProperty);
 
         blessArrayOperation(m_graph.varArgChild(node, 0), m_graph.varArgChild(node, 1), m_graph.varArgChild(node, 2));
+        auto arrayMode = node->arrayMode();
+        // FIXME: OutOfBounds shouldn't preclude going sane chain because OOB is just false and cannot have effects.
+        // See: https://bugs.webkit.org/show_bug.cgi?id=209456
+        if (arrayMode.isJSArrayWithOriginalStructure() && arrayMode.speculation() == Array::InBounds)
+            setSaneChainIfPossible(node);
 
         fixEdge<CellUse>(m_graph.varArgChild(node, 0));
         fixEdge<Int32Use>(m_graph.varArgChild(node, 1));

Modified: branches/safari-609-branch/Source/_javascript_Core/dfg/DFGNodeType.h (258925 => 258926)


--- branches/safari-609-branch/Source/_javascript_Core/dfg/DFGNodeType.h	2020-03-24 19:03:08 UTC (rev 258925)
+++ branches/safari-609-branch/Source/_javascript_Core/dfg/DFGNodeType.h	2020-03-24 19:03:11 UTC (rev 258926)
@@ -474,7 +474,8 @@
     \
     /* For-in enumeration opcodes */\
     macro(GetEnumerableLength, NodeMustGenerate | NodeResultJS) \
-    macro(HasIndexedProperty, NodeResultBoolean | NodeHasVarArgs) \
+    /* Must generate because of Proxies on the prototype chain */ \
+    macro(HasIndexedProperty, NodeMustGenerate | NodeResultBoolean | NodeHasVarArgs) \
     macro(HasStructureProperty, NodeResultBoolean) \
     macro(HasGenericProperty, NodeResultBoolean) \
     macro(GetDirectPname, NodeMustGenerate | NodeHasVarArgs | NodeResultJS) \

Modified: branches/safari-609-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (258925 => 258926)


--- branches/safari-609-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2020-03-24 19:03:08 UTC (rev 258925)
+++ branches/safari-609-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2020-03-24 19:03:11 UTC (rev 258926)
@@ -13545,6 +13545,7 @@
         GPRReg scratchGPR = scratch.gpr();
 
         MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
+
         if (mode.isInBounds())
             speculationCheck(OutOfBounds, JSValueRegs(), nullptr, outOfBounds);
         else
@@ -13552,11 +13553,20 @@
 
 #if USE(JSVALUE64)
         m_jit.load64(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight), scratchGPR);
-        slowCases.append(m_jit.branchIfEmpty(scratchGPR));
 #else
         m_jit.load32(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), scratchGPR);
-        slowCases.append(m_jit.branchIfEmpty(scratchGPR));
 #endif
+
+        if (mode.isSaneChain()) {
+            m_jit.isEmpty(scratchGPR, resultGPR);
+            break;
+        }
+
+        MacroAssembler::Jump isHole = m_jit.branchIfEmpty(scratchGPR);
+        if (!mode.isInBounds())
+            slowCases.append(isHole);
+        else
+            speculationCheck(LoadFromHole, JSValueRegs(), nullptr, isHole);
         m_jit.move(TrustedImm32(1), resultGPR);
         break;
     }
@@ -13568,6 +13578,7 @@
         GPRReg storageGPR = storage.gpr();
 
         MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, indexGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
+
         if (mode.isInBounds())
             speculationCheck(OutOfBounds, JSValueRegs(), nullptr, outOfBounds);
         else
@@ -13574,7 +13585,17 @@
             slowCases.append(outOfBounds);
 
         m_jit.loadDouble(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight), scratchFPR);
-        slowCases.append(m_jit.branchIfNaN(scratchFPR));
+
+        if (mode.isSaneChain()) {
+            m_jit.compareDouble(MacroAssembler::DoubleEqualAndOrdered, scratchFPR, scratchFPR, resultGPR);
+            break;
+        }
+
+        MacroAssembler::Jump isHole = m_jit.branchIfNaN(scratchFPR);
+        if (!mode.isInBounds())
+            slowCases.append(isHole);
+        else
+            speculationCheck(LoadFromHole, JSValueRegs(), nullptr, isHole);
         m_jit.move(TrustedImm32(1), resultGPR);
         break;
     }
@@ -13594,11 +13615,20 @@
 
 #if USE(JSVALUE64)
         m_jit.load64(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()), scratchGPR);
-        slowCases.append(m_jit.branchIfEmpty(scratchGPR));
 #else
         m_jit.load32(MacroAssembler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), scratchGPR);
-        slowCases.append(m_jit.branchIfEmpty(scratchGPR));
 #endif
+
+        if (mode.isSaneChain()) {
+            m_jit.isEmpty(scratchGPR, resultGPR);
+            break;
+        }
+
+        MacroAssembler::Jump isHole = m_jit.branchIfEmpty(scratchGPR);
+        if (!mode.isInBounds() || mode.isSaneChain())
+            slowCases.append(isHole);
+        else
+            speculationCheck(LoadFromHole, JSValueRegs(), nullptr, isHole);
         m_jit.move(TrustedImm32(1), resultGPR);
         break;
     }

Modified: branches/safari-609-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (258925 => 258926)


--- branches/safari-609-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2020-03-24 19:03:08 UTC (rev 258925)
+++ branches/safari-609-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2020-03-24 19:03:11 UTC (rev 258926)
@@ -11412,6 +11412,7 @@
         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
         LValue base = lowCell(m_graph.varArgChild(m_node, 0));
         LValue index = lowInt32(m_graph.varArgChild(m_node, 1));
+        ArrayMode mode = m_node->arrayMode();
 
         switch (m_node->arrayMode().type()) {
         case Array::Int32:
@@ -11419,7 +11420,7 @@
             LValue storage = lowStorage(m_graph.varArgChild(m_node, 2));
             LValue internalMethodType = m_out.constInt32(static_cast<int32_t>(m_node->internalMethodType()));
 
-            IndexedAbstractHeap& heap = m_node->arrayMode().type() == Array::Int32 ?
+            IndexedAbstractHeap& heap = mode.type() == Array::Int32 ?
                 m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties;
 
             LBasicBlock slowCase = m_out.newBlock();
@@ -11426,7 +11427,7 @@
             LBasicBlock continuation = m_out.newBlock();
             LBasicBlock lastNext = nullptr;
 
-            if (!m_node->arrayMode().isInBounds()) {
+            if (!mode.isInBounds()) {
                 LBasicBlock checkHole = m_out.newBlock();
                 m_out.branch(
                     m_out.aboveOrEqual(
@@ -11439,7 +11440,12 @@
             LValue checkHoleResultValue =
                 m_out.notZero64(m_out.load64(baseIndex(heap, storage, index, m_graph.varArgChild(m_node, 1))));
             ValueFromBlock checkHoleResult = m_out.anchor(checkHoleResultValue);
-            m_out.branch(checkHoleResultValue, usually(continuation), rarely(slowCase));
+            if (mode.isSaneChain())
+                m_out.jump(continuation);
+            else if (!mode.isInBounds())
+                m_out.branch(checkHoleResultValue, usually(continuation), rarely(slowCase));
+            else
+                speculateAndJump(continuation, LoadFromHole, noValue(), nullptr, checkHoleResultValue);
 
             m_out.appendTo(slowCase, continuation);
             ValueFromBlock slowResult = m_out.anchor(
@@ -11473,7 +11479,12 @@
             LValue doubleValue = m_out.loadDouble(baseIndex(heap, storage, index, m_graph.varArgChild(m_node, 1)));
             LValue checkHoleResultValue = m_out.doubleEqual(doubleValue, doubleValue);
             ValueFromBlock checkHoleResult = m_out.anchor(checkHoleResultValue);
-            m_out.branch(checkHoleResultValue, usually(continuation), rarely(slowCase));
+            if (mode.isSaneChain())
+                m_out.jump(continuation);
+            else if (!mode.isInBounds())
+                m_out.branch(checkHoleResultValue, usually(continuation), rarely(slowCase));
+            else
+                speculateAndJump(continuation, LoadFromHole, noValue(), nullptr, checkHoleResultValue);
             
             m_out.appendTo(slowCase, continuation);
             ValueFromBlock slowResult = m_out.anchor(
@@ -11506,7 +11517,12 @@
             LValue checkHoleResultValue =
                 m_out.notZero64(m_out.load64(baseIndex(m_heaps.ArrayStorage_vector, storage, index, m_graph.varArgChild(m_node, 1))));
             ValueFromBlock checkHoleResult = m_out.anchor(checkHoleResultValue);
-            m_out.branch(checkHoleResultValue, usually(continuation), rarely(slowCase));
+            if (mode.isSaneChain())
+                m_out.jump(continuation);
+            else if (!mode.isInBounds())
+                m_out.branch(checkHoleResultValue, usually(continuation), rarely(slowCase));
+            else
+                speculateAndJump(continuation, LoadFromHole, noValue(), nullptr, checkHoleResultValue);
 
             m_out.appendTo(slowCase, continuation);
             ValueFromBlock slowResult = m_out.anchor(
@@ -15888,6 +15904,13 @@
     {
         appendOSRExit(kind, lowValue, profile, failCondition, m_origin);
     }
+
+    template<typename... Args>
+    void speculateAndJump(B3::BasicBlock* target, Args... args)
+    {
+        speculate(args...);
+        m_out.jump(target);
+    }
     
     void terminate(ExitKind kind)
     {

Modified: branches/safari-609-branch/Source/_javascript_Core/jit/AssemblyHelpers.h (258925 => 258926)


--- branches/safari-609-branch/Source/_javascript_Core/jit/AssemblyHelpers.h	2020-03-24 19:03:08 UTC (rev 258925)
+++ branches/safari-609-branch/Source/_javascript_Core/jit/AssemblyHelpers.h	2020-03-24 19:03:11 UTC (rev 258926)
@@ -985,6 +985,15 @@
     Jump branchIfFunction(GPRReg cellGPR) { return branchIfType(cellGPR, JSFunctionType); }
     Jump branchIfNotFunction(GPRReg cellGPR) { return branchIfNotType(cellGPR, JSFunctionType); }
     
+    void isEmpty(GPRReg gpr, GPRReg dst)
+    {
+#if USE(JSVALUE64)
+        test64(NonZero, gpr, TrustedImm32(-1), dst);
+#else
+        compare32(Equal, gpr, TrustedImm32(JSValue::EmptyValueTag), dst);
+#endif
+    }
+
     Jump branchIfEmpty(GPRReg gpr)
     {
 #if USE(JSVALUE64)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to