WebKit Bugzilla
Attachment 340724 Details for
Bug 185695
: DFG should inline InstanceOf ICs
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
a bit more
blah.patch (text/plain), 31.52 KB, created by
Filip Pizlo
on 2018-05-18 12:04:24 PDT
(
hide
)
Description:
a bit more
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2018-05-18 12:04:24 PDT
Size:
31.52 KB
patch
obsolete
>Index: Source/JavaScriptCore/bytecode/GetByIdStatus.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/GetByIdStatus.cpp (revision 231961) >+++ Source/JavaScriptCore/bytecode/GetByIdStatus.cpp (working copy) >@@ -29,6 +29,7 @@ > #include "CodeBlock.h" > #include "ComplexGetStatus.h" > #include "GetterSetterAccessCase.h" >+#include "ICStatusUtils.h" > #include "InterpreterInlines.h" > #include "IntrinsicGetterAccessCase.h" > #include "JSCInlines.h" >@@ -47,22 +48,7 @@ class GetterSetter; > > bool GetByIdStatus::appendVariant(const GetByIdVariant& variant) > { >- // Attempt to merge this variant with an already existing variant. >- for (unsigned i = 0; i < m_variants.size(); ++i) { >- if (m_variants[i].attemptToMerge(variant)) >- return true; >- } >- >- // Make sure there is no overlap. We should have pruned out opportunities for >- // overlap but it's possible that an inline cache got into a weird state. We are >- // defensive and bail if we detect crazy. >- for (unsigned i = 0; i < m_variants.size(); ++i) { >- if (m_variants[i].structureSet().overlaps(variant.structureSet())) >- return false; >- } >- >- m_variants.append(variant); >- return true; >+ return appendICStatusVariant(m_variants, variant); > } > > #if ENABLE(DFG_JIT) >@@ -432,14 +418,7 @@ void GetByIdStatus::filter(const Structu > { > if (m_state != Simple) > return; >- >- // FIXME: We could also filter the variants themselves. >- >- m_variants.removeAllMatching( >- [&] (GetByIdVariant& variant) -> bool { >- return !variant.structureSet().overlaps(set); >- }); >- >+ filterICStatusVariants(m_variants, set); > if (m_variants.isEmpty()) > m_state = NoInformation; > } >Index: Source/JavaScriptCore/bytecode/GetByIdStatus.h >=================================================================== >--- Source/JavaScriptCore/bytecode/GetByIdStatus.h (revision 231961) >+++ Source/JavaScriptCore/bytecode/GetByIdStatus.h (working copy) >@@ -93,7 +93,7 @@ public: > State state() const { return m_state; } > > bool isSet() const { return m_state != NoInformation; } >- bool operator!() const { return !isSet(); } >+ explicit operator bool() const { return isSet(); } > bool isSimple() const { return m_state == Simple; } > bool isCustom() const { return m_state == Custom; } > bool isModuleNamespace() const { return m_state == ModuleNamespace; } >Index: Source/JavaScriptCore/bytecode/GetByIdVariant.h >=================================================================== >--- Source/JavaScriptCore/bytecode/GetByIdVariant.h (revision 231961) >+++ Source/JavaScriptCore/bytecode/GetByIdVariant.h (working copy) >@@ -55,7 +55,7 @@ public: > GetByIdVariant& operator=(const GetByIdVariant&); > > bool isSet() const { return !!m_structureSet.size(); } >- bool operator!() const { return !isSet(); } >+ explicit operator bool() const { return isSet(); } > const StructureSet& structureSet() const { return m_structureSet; } > StructureSet& structureSet() { return m_structureSet; } > >Index: Source/JavaScriptCore/bytecode/ICStatusUtils.h >=================================================================== >--- Source/JavaScriptCore/bytecode/ICStatusUtils.h (nonexistent) >+++ Source/JavaScriptCore/bytecode/ICStatusUtils.h (working copy) >@@ -0,0 +1,63 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+namespace JSC { >+ >+template<typename VariantVectorType, typename VariantType> >+bool appendICStatusVariant(VariantVectorType& variants, const VariantType& variant) >+{ >+ // Attempt to merge this variant with an already existing variant. >+ for (unsigned i = 0; i < variants.size(); ++i) { >+ if (variants[i].attemptToMerge(variant)) >+ return true; >+ } >+ >+ // Make sure there is no overlap. We should have pruned out opportunities for >+ // overlap but it's possible that an inline cache got into a weird state. We are >+ // defensive and bail if we detect crazy. >+ for (unsigned i = 0; i < variants.size(); ++i) { >+ if (variants[i].structureSet().overlaps(variant.structureSet())) >+ return false; >+ } >+ >+ variants.append(variant); >+ return true; >+} >+ >+template<typename VariantVectorType> >+void filterICStatusVariants(VariantVectorType& variants, const StructureSet& set) >+{ >+ // FIXME: We could also filter the variants themselves. >+ >+ m_variants.removeAllMatching( >+ [&] (auto& variant) -> bool { >+ return !variant.structureSet().overlaps(set); >+ }); >+} >+ >+} // namespace JSC >+ >Index: Source/JavaScriptCore/bytecode/InstanceOfStatus.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/InstanceOfStatus.cpp (nonexistent) >+++ Source/JavaScriptCore/bytecode/InstanceOfStatus.cpp (working copy) >@@ -0,0 +1,122 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "InstanceOfStatus.h" >+ >+#include "ICStatusUtils.h" >+#include "JSCInlines.h" >+ >+namespace JSC { >+ >+void InstanceOfStatus::appendVariant(const InstanceOfVariant& variant) >+{ >+ return appendICStatusVariant(m_variants, variant); >+} >+ >+InstanceOfStatus InstanceOfStatus::computeFor( >+ CodeBlock* codeBlock, StubInfoMap& infoMap, unsigned bytecodeIndex) >+{ >+ ConcurrentJSLocker locker(codeBlock->m_lock); >+ >+ InstanceOfStatus result; >+#if ENABLE(DFG_JIT) >+ result = computeForStubInfo(locker, codeBlock, map.get(bytecodeIndex)); >+ >+ if (!result.takesSlowPath()) { >+ UnlinkedCodeBlock* unlinkedCodeBlock = profiledBlock->unlinkedCodeBlock(); >+ ConcurrentJSLocker locker(unlinkedCodeBlock->m_lock); >+ if (unlinkedCodeBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadCache)) >+ || unlinkedCodeBlock->hasExitSite(locker, DFG::FrequentExitSite(bytecodeIndex, BadConstantCache))) >+ return TakesSlowPath; >+ } >+#else >+ UNUSED_PARAM(infoMap); >+ UNUSED_PARAM(codeOrigin); >+#endif >+ >+ return result; >+} >+ >+#if ENABLE(DFG_JIT) >+InstanceOfStatus InstanceOfStatus::computeForStubInfo( >+ const ConcurrentJSLocker& locker, CodeBlock* codeblock, StructureStubInfo* stubInfo) >+{ >+ if (!stubInfo || !stubInfo->everConsidered) >+ return NoInformation; >+ >+ if (stubInfo->tookSlowPath) >+ return TakesSlowPath; >+ >+ if (stubInfo->cacheType != CacheType::Stub) >+ return TakesSlowPath; // This is conservative. It could be that we have no information. >+ >+ PolymorphicAccess* list = stubInfo->u.stub; >+ InstanceOfStatus result; >+ for (unsigned listIndex = 0; listIndex < list->size(); ++listIndex) { >+ const AccessCase& access = list->at(listIndex); >+ >+ if (access.type() == AccessCase::InstanceOfGeneric) >+ return TakesSlowPath; >+ >+ if (!access.conditionSet().structuresEnsureValidity()) >+ return TakesSlowPath; >+ >+ result.appendVariant(InstanceOfVariant( >+ access.structure(), >+ access.conditionSet(), >+ access.as<InstanceOfAccessCase>().prototype(), >+ access.type() == AccessCase::InstanceOfHit)); >+ } >+ >+ return result; >+} >+#endif // ENABLE(DFG_JIT) >+ >+JSObject* InstanceOfStatus::commonPrototype() const >+{ >+ JSObject* prototype = nullptr; >+ for (InstanceOfVariant& variant : m_variants) { >+ if (!prototype) { >+ prototype = variant.prototype(); >+ continue; >+ } >+ if (prototype != variant.prototype()) >+ return nullptr; >+ } >+ return prototype; >+} >+ >+void InstanceOfStatus::filter(const StructureSet& structureSet) >+{ >+ if (m_state != Simple) >+ return; >+ filterICStatusVariants(m_variants, structureSet); >+ if (m_variants.isEmpty()) >+ m_state = NoInformation; >+} >+ >+} // namespace JSC >+ >Index: Source/JavaScriptCore/bytecode/InstanceOfStatus.h >=================================================================== >--- Source/JavaScriptCore/bytecode/InstanceOfStatus.h (nonexistent) >+++ Source/JavaScriptCore/bytecode/InstanceOfStatus.h (working copy) >@@ -0,0 +1,97 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "CodeOrigin.h" >+#include "ConcurrentJSLock.h" >+#include "InstanceOfVariant.h" >+ >+namespace JSC { >+ >+class AccessCase; >+class CodeBlock; >+class StructureStubInfo; >+ >+typedef HashMap<CodeOrigin, StructureStubInfo*, CodeOriginApproximateHash> StubInfoMap; >+ >+class InstanceOfStatus { >+public: >+ enum State { >+ // It's uncached so we have no information. >+ NoInformation, >+ >+ // It's cached in a simple way. >+ Simple, >+ >+ // It's known to often take slow path. >+ TakesSlowPath >+ }; >+ >+ InstanceOfStatus() >+ : m_state(NoInformation) >+ { >+ } >+ >+ explicit InstanceOfStatus(State state) >+ : m_state(state) >+ { >+ ASSERT(state == NoInformation || state == MakesCalls); >+ } >+ >+ static InstanceOfStatus computeFor(CodeBlock*, StubInfoMap&, unsigned bytecodeIndex); >+ >+#if ENABLE(DFG_JIT) >+ static InstanceOfStatus computeForStubInfo(const ConcurrentJSLocker&, CodeBlock*, StructureStubInfo*); >+#endif >+ >+ State state() const { return m_state; } >+ >+ bool isSet() const { return m_state != NoInformation; } >+ explicit operator bool() const { return isSet(); } >+ >+ bool isSimple() const { return m_state == Simple; } >+ bool takesSlowPath() const { return m_state == TakesSlowPath; } >+ >+ JSObject* commonPrototype() const; >+ >+ size_t numVariants() const { return m_variants.size(); } >+ const Vector<InstanceOfVariant, 2>& variants() const { return m_variants; } >+ const InstanceOfVariant& at(size_t index) const { return m_variants[index]; } >+ const InstanceOfVariant& operator[](size_t index) const { return at(index); } >+ >+ void filter(const StructureSet&); >+ >+ void dump(PrintStream&) const; >+ >+private: >+ void appendVariant(const InstanceOfVariant&); >+ >+ State m_state; >+ Vector<InstanceOfVariant, 2> m_variants; >+}; >+ >+} // namespace JSC >+ >Index: Source/JavaScriptCore/bytecode/InstanceOfVariant.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/InstanceOfVariant.cpp (nonexistent) >+++ Source/JavaScriptCore/bytecode/InstanceOfVariant.cpp (working copy) >@@ -0,0 +1,81 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "InstanceOfVariant.h" >+ >+#include "JSCInlines.h" >+#include <wtf/ListDump.h> >+ >+namespace JSC { >+ >+InstanceOfVariant::InstanceOfVariant( >+ const StructureSet& structureSet, const ObjectPropertyConditionSet& conditionSet, >+ JSObject* prototype, bool isHit) >+ : m_structureSet(structureSet) >+ , m_conditionSet(conditionSet) >+ , m_prototype(prototype) >+ , m_isHit(isHit) >+{ >+} >+ >+bool InstanceOfVariant::attemptToMerge(const InstanceOfVariant& other) >+{ >+ if (m_prototype != other.m_prototype) >+ return false; >+ >+ if (m_isHit != other.m_isHit) >+ return false; >+ >+ ObjectPropertyConditionSet mergedConditionSet = m_conditionSet.mergedWith(other.m_conditionSet); >+ if (!mergedConditionSet.isValid()) >+ return false; >+ m_conditionSet = mergedConditionSet; >+ >+ m_structureSet.merge(other.m_structureSet); >+ >+ return true; >+} >+ >+void InstanceOfVariant::dump(PrintStream& out) const >+{ >+ dumpInContext(out, nullptr); >+} >+ >+void InstanceOfVariant::dumpInContext(PrintStream& out, DumpContext* context) const >+{ >+ if (!*this) { >+ out.print("<empty>"); >+ return; >+ } >+ >+ out.print( >+ "<", inContext(structureSet(), context), ", ", inContext(m_conditionSet, context), "," >+ " prototype = ", inContext(JSValue(m_prototype), context), "," >+ " isHit = ", m_isHit, ">"); >+} >+ >+} // namespace JSC >+ >Index: Source/JavaScriptCore/bytecode/InstanceOfVariant.h >=================================================================== >--- Source/JavaScriptCore/bytecode/InstanceOfVariant.h (nonexistent) >+++ Source/JavaScriptCore/bytecode/InstanceOfVariant.h (working copy) >@@ -0,0 +1,68 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "ObjectPropertyConditionSet.h" >+#include "StructureSet.h" >+ >+namespace JSC { >+ >+class InstanceOfStatus; >+ >+class InstanceOfVariant { >+public: >+ InstanceOfVariant( >+ const StructureSet& = StructureSet(), >+ const ObjectPropertyConditionSet& = ObjectPropertyConditionSet(), >+ JSObject* prototype, bool isHit); >+ >+ explicit operator bool() const { return !!m_structureSet.size(); } >+ >+ const StructureSet& structureSet() const { return m_structureSet; } >+ StructureSet& structureSet() { return m_structureSet; } >+ >+ const ObjectPropertyConditionSet& conditionSet() const { return m_conditionSet; } >+ >+ JSObject* prototype() const { return m_prototype; } >+ >+ bool isHit() const { return m_isHit; } >+ >+ bool attemptToMerge(const InstanceOfVariant& other); >+ >+ void dump(PrintStream&) const; >+ void dumpInContext(PrintStream&, DumpContext*) const; >+ >+private: >+ friend class InstanceOfStatus; >+ >+ StructureSet m_structureSet; >+ ObjectPropertyConditionSet m_conditionSet; >+ JSObject* prototype; >+ bool m_isHit; >+}; >+ >+} // namespace JSC >+ >Index: Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (revision 231961) >+++ Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (working copy) >@@ -3371,6 +3371,38 @@ bool AbstractInterpreter<AbstractStateTy > clobberWorld(); > setNonCellTypeForNode(node, SpecBoolean); > break; >+ >+ case MatchStructure: >+ AbstractValue base = forNode(node->child1()); >+ RegisteredStructureSet baseSet; >+ >+ BooleanLattice result = BooleanLattice::Bottom; >+ for (MatchStructureVariant& variant : node->matchStructureData().variants) { >+ RegisteredStructure structure = variant.structure; >+ if (!base.contains(structure)) >+ continue; >+ >+ baseSet.merge(structure); >+ result = lubBooleanLattice(result, variant.result); >+ } >+ >+ if (base.m_structure.isInfinite() || baseSet.size() < base.m_structure.size()) >+ m_state.setFoundConstants(true); >+ >+ if (forNode(node->child1()).changeStructure(m_graph, baseSet) == Contradiction) >+ m_state.setIsValid(false); >+ >+ switch (result) { >+ case BooleanLattice::False: >+ setConstant(node, jsBoolean(false)); >+ break; >+ case BooleanLattice::True: >+ setConstant(node, jsBoolean(true)); >+ break; >+ default: >+ break; >+ } >+ break; > > case Phi: > RELEASE_ASSERT(m_graph.m_form == SSA); >Index: Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (revision 231961) >+++ Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (working copy) >@@ -4783,12 +4783,40 @@ void ByteCodeParser::parseBlock(unsigned > } > > case op_instanceof: { >- // FIXME: We should turn this into either a CheckStructure followed by a constant, or >- // some kind of MultiInstanceOf thing, if the InstanceOf IC is stable. >- // https://bugs.webkit.org/show_bug.cgi?id=185695 > auto& bytecode = *reinterpret_cast<OpInstanceof*>(currentInstruction); >+ >+ InstanceOfStatus status = InstanceOfStatus::computeFor( >+ m_inlineStackTop->m_profiledBlock, m_inlineStackTop->m_stubInfos, >+ m_currentIndex); >+ > Node* value = get(VirtualRegister(bytecode.value())); > Node* prototype = get(VirtualRegister(bytecode.prototype())); >+ >+ // Only inline it if it's Simple with a commonPrototype; bottom/top or variable >+ // prototypes both get handled by the IC. This makes sense for bottom (unprofiled) >+ // instanceof ICs because the profit of this optimization is fairly low. So, in the >+ // absence of any information, it's better to avoid making this be the cause of a >+ // recompilation. >+ if (JSObject* commonPrototype = status.commonPrototype()) { >+ addToGraph(CheckCell, OpInfo(m_graph.freeze(commonPrototype)), prototype); >+ >+ MatchStructureData* data = m_graph.m_matchStructureData.add(); >+ for (InstanceOfVariant& variant : status.variants()) { >+ check(variant.conditionSet()); >+ for (Structure* structure : variant.structureSet()) { >+ MatchStructureVariant matchVariant; >+ matchVariant.structure = m_graph.register(structure); >+ matchVariant.result = variant.isHit(); >+ >+ data->append(matchVariant); >+ } >+ } >+ >+ Node* match = addToGraph(MatchStructure, OpInfo(data), value); >+ set(VirtualRegister(bytecode.dst()), match); >+ NEXT_OPCODE(op_instanceof); >+ } >+ > set(VirtualRegister(bytecode.dst()), addToGraph(InstanceOf, value, prototype)); > NEXT_OPCODE(op_instanceof); > } >Index: Source/JavaScriptCore/dfg/DFGClobberize.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGClobberize.h (revision 231961) >+++ Source/JavaScriptCore/dfg/DFGClobberize.h (working copy) >@@ -545,6 +545,10 @@ void clobberize(Graph& graph, Node* node > read(MiscFields); > def(HeapLocation(IsFunctionLoc, MiscFields, node->child1()), LazyNode(node)); > return; >+ >+ case MatchStructure: >+ read(JSCell_structureID); >+ return; > > case ArraySlice: > read(MiscFields); >Index: Source/JavaScriptCore/dfg/DFGDoesGC.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGDoesGC.cpp (revision 231961) >+++ Source/JavaScriptCore/dfg/DFGDoesGC.cpp (working copy) >@@ -310,6 +310,7 @@ bool doesGC(Graph& graph, Node* node) > case AtomicsSub: > case AtomicsXor: > case AtomicsIsLockFree: >+ case MatchStructure: > return false; > > case PushWithScope: >Index: Source/JavaScriptCore/dfg/DFGGraph.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGGraph.h (revision 231961) >+++ Source/JavaScriptCore/dfg/DFGGraph.h (working copy) >@@ -1052,6 +1052,7 @@ public: > Bag<SwitchData> m_switchData; > Bag<MultiGetByOffsetData> m_multiGetByOffsetData; > Bag<MultiPutByOffsetData> m_multiPutByOffsetData; >+ Bag<MatchStructureData> m_matchStructureData; > Bag<ObjectMaterializationData> m_objectMaterializationData; > Bag<CallVarargsData> m_callVarargsData; > Bag<LoadVarargsData> m_loadVarargsData; >Index: Source/JavaScriptCore/dfg/DFGNode.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGNode.h (revision 231961) >+++ Source/JavaScriptCore/dfg/DFGNode.h (working copy) >@@ -96,6 +96,15 @@ struct MultiPutByOffsetData { > bool reallocatesStorage() const; > }; > >+struct MatchStructureVariant { >+ RegisteredStructure structure; >+ bool result; >+}; >+ >+struct MatchStructureData { >+ Vector<MatchStructureVariant, 2> variants; >+}; >+ > struct NewArrayBufferData { > union { > struct { >@@ -1853,6 +1862,17 @@ public: > return *m_opInfo.as<MultiPutByOffsetData*>(); > } > >+ bool hasMatchStructureData() >+ { >+ return op() == MatchStructure; >+ } >+ >+ MatchStructureData& matchStructureData() >+ { >+ ASSERT(hasMatchStructureData()); >+ return *m_opInfo.as<MatchStructureData*>(); >+ } >+ > bool hasObjectMaterializationData() > { > switch (op()) { >Index: Source/JavaScriptCore/dfg/DFGNodeType.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGNodeType.h (revision 231961) >+++ Source/JavaScriptCore/dfg/DFGNodeType.h (working copy) >@@ -346,6 +346,7 @@ namespace JSC { namespace DFG { > macro(OverridesHasInstance, NodeMustGenerate | NodeResultBoolean) \ > macro(InstanceOf, NodeMustGenerate | NodeResultBoolean) \ > macro(InstanceOfCustom, NodeMustGenerate | NodeResultBoolean) \ >+ macro(MatchStructure, NodeResultBoolean) \ > \ > macro(IsCellWithType, NodeResultBoolean) \ > macro(IsEmpty, NodeResultBoolean) \ >Index: Source/JavaScriptCore/dfg/DFGSafeToExecute.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSafeToExecute.h (revision 231961) >+++ Source/JavaScriptCore/dfg/DFGSafeToExecute.h (working copy) >@@ -452,6 +452,7 @@ bool safeToExecute(AbstractStateType& st > case AtomicsXor: > case AtomicsIsLockFree: > case InitializeEntrypointArguments: >+ case MatchStructure: > return true; > > case ArraySlice: >Index: Source/WTF/WTF.xcodeproj/project.pbxproj >=================================================================== >--- Source/WTF/WTF.xcodeproj/project.pbxproj (revision 231961) >+++ Source/WTF/WTF.xcodeproj/project.pbxproj (working copy) >@@ -239,6 +239,7 @@ > 0FB14E18180FA218009B6B4D /* Bag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bag.h; sourceTree = "<group>"; }; > 0FB14E1A1810E1DA009B6B4D /* BagToHashMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BagToHashMap.h; sourceTree = "<group>"; }; > 0FB317C31C488001007E395A /* SystemTracing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SystemTracing.h; sourceTree = "<group>"; }; >+ 0FB399B820AF5A580017E213 /* BooleanLattice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BooleanLattice.h; sourceTree = "<group>"; }; > 0FB467821FDE282B003FCB09 /* ConcurrentBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConcurrentBuffer.h; sourceTree = "<group>"; }; > 0FB467831FDE282C003FCB09 /* ConcurrentVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConcurrentVector.h; sourceTree = "<group>"; }; > 0FC4488216FE9FE100844BE9 /* ProcessID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessID.h; sourceTree = "<group>"; }; >@@ -813,6 +814,7 @@ > 1A944F461C3D8814005BD28C /* BlockPtr.h */, > A8A47264151A825A004123FF /* BlockStack.h */, > A8A47265151A825A004123FF /* BloomFilter.h */, >+ 0FB399B820AF5A580017E213 /* BooleanLattice.h */, > 0F93274A1C17F4B700CF6564 /* Box.h */, > 7C3F72391D78811900674E26 /* Brigand.h */, > 0F4570441BE834410062A629 /* BubbleSort.h */, >Index: Source/WTF/wtf/BooleanLattice.h >=================================================================== >--- Source/WTF/wtf/BooleanLattice.h (nonexistent) >+++ Source/WTF/wtf/BooleanLattice.h (working copy) >@@ -0,0 +1,46 @@ >+/* >+ * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+namespace WTF { >+ >+enum class BooleanLattice : uint8_t { >+ Bottom = 0, >+ False = 1, >+ True = 2, >+ To = 3 >+}; >+ >+inline BooleanLattice lubBooleanLattice(BooleanLattice a, BooleanLattice b) >+{ >+ return static_cast<BooleanLattice>(static_cast<uint8_t>(a) | static_cast<uintptr_t>(b)); >+} >+ >+} // namespace WTF >+ >+using WTF::BooleanLattice; >+using WTF::lubBooleanLattice; >+ >Index: Source/WTF/wtf/CMakeLists.txt >=================================================================== >--- Source/WTF/wtf/CMakeLists.txt (revision 231961) >+++ Source/WTF/wtf/CMakeLists.txt (working copy) >@@ -14,6 +14,7 @@ set(WTF_PUBLIC_HEADERS > BlockPtr.h > BlockStack.h > BloomFilter.h >+ BooleanLattice.h > Box.h > Brigand.h > BubbleSort.h
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 185695
:
340714
|
340724
|
340731
|
340740
|
340748
|
340751
|
340755
|
340756
|
340759