WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
it's done?
blah.patch (text/plain), 58.44 KB, created by
Filip Pizlo
on 2013-10-28 21:48:00 PDT
(
hide
)
Description:
it's done?
Filename:
MIME Type:
Creator:
Filip Pizlo
Created:
2013-10-28 21:48:00 PDT
Size:
58.44 KB
patch
obsolete
>Index: Source/JavaScriptCore/bytecode/CodeBlock.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/CodeBlock.cpp (revision 158167) >+++ Source/JavaScriptCore/bytecode/CodeBlock.cpp (working copy) >@@ -2821,7 +2821,9 @@ void CodeBlock::jettison() > { > DeferGC deferGC(*m_heap); > ASSERT(JITCode::isOptimizingJIT(jitType())); >- ASSERT(this == replacement()); >+ dfgCommon()->invalidate(); >+ if (this != replacement()) >+ return; > alternative()->optimizeAfterWarmUp(); > tallyFrequentExitSites(); > if (DFG::shouldShowDisassembly()) >Index: Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.cpp (revision 0) >+++ Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.cpp (working copy) >@@ -0,0 +1,37 @@ >+/* >+ * Copyright (C) 2013 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 "CodeBlockJettisoningWatchpoint.h" >+ >+namespace JSC { >+ >+void CodeBlockJettisoningWatchpoint::fireInternal() >+{ >+ m_codeBlock->jettison(); >+} >+ >+} // namespace JSC >+ >Index: Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h >=================================================================== >--- Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h (revision 0) >+++ Source/JavaScriptCore/bytecode/CodeBlockJettisoningWatchpoint.h (working copy) >@@ -0,0 +1,55 @@ >+/* >+ * Copyright (C) 2013 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. >+ */ >+ >+#ifndef CodeBlockJettisoningWatchpoint_h >+#define CodeBlockJettisoningWatchpoint_h >+ >+#include "Watchpoint.h" >+ >+namespace JSC { >+ >+class CodeBlockJettisoningWatchpoint : public Watchpoint { >+public: >+ CodeBlockJettisoningWatchpoint() >+ : m_codeBlock(0) >+ { >+ } >+ >+ CodeBlockJettisoningWatchpoint(CodeBlock* codeBlock) >+ : m_codeBlock(codeBlock) >+ { >+ } >+ >+protected: >+ virtual void fireInternal() OVERRIDE; >+ >+private: >+ CodeBlock* m_codeBlock; >+}; >+ >+} // namespace JSC >+ >+#endif // CodeBlockJettisoningWatchpoint_h >+ >Index: Source/JavaScriptCore/bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp >=================================================================== >--- Source/JavaScriptCore/bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp (revision 0) >+++ Source/JavaScriptCore/bytecode/ProfiledCodeBlockJettisoningWatchpoint.cpp (working copy) >@@ -0,0 +1,41 @@ >+/* >+ * Copyright (C) 2013 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 "ProfiledCodeBlockJettisoningWatchpoint.h" >+ >+namespace JSC { >+ >+void ProfiledCodeBlockJettisoningWatchpoint::fireInternal() >+{ >+ baselineCodeBlockForOriginAndBaselineCodeBlock( >+ m_codeOrigin, m_codeBlock->baselineVersion())->addFrequentExitSite( >+ FrequentExitSite(m_codeOrigin.bytecodeIndex, m_exitKind)); >+ >+ m_codeBlock->jettison(); >+} >+ >+} // namespace JSC >+ >Index: Source/JavaScriptCore/bytecode/ProfiledCodeBlockJettisoningWatchpoint.h >=================================================================== >--- Source/JavaScriptCore/bytecode/ProfiledCodeBlockJettisoningWatchpoint.h (revision 0) >+++ Source/JavaScriptCore/bytecode/ProfiledCodeBlockJettisoningWatchpoint.h (working copy) >@@ -0,0 +1,61 @@ >+/* >+ * Copyright (C) 2013 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. >+ */ >+ >+#ifndef ProfilingCodeBlockJettisoningWatchpoint_h >+#define ProfilingCodeBlockJettisoningWatchpoint_h >+ >+#include "Watchpoint.h" >+ >+namespace JSC { >+ >+class ProfiledCodeBlockJettisoningWatchpoint : public Watchpoint { >+public: >+ ProfiledCodeBlockJettisoningWatchpoint() >+ : m_exitKind(ExitKindUnset) >+ , m_codeBlock(0) >+ { >+ } >+ >+ ProfiledCodeBlockJettisoningWatchpoint( >+ CodeOrigin codeOrigin, ExitKind exitKind, ProfilingCodeBlock* codeBlock) >+ : m_codeOrigin(codeOrigin) >+ , m_exitKind(exitKind) >+ , m_codeBlock(codeBlock) >+ { >+ } >+ >+protected: >+ virtual void fireInternal() OVERRIDE; >+ >+private: >+ CodeOrigin m_codeOrigin; >+ ExitKind m_exitKind; >+ ProfilingCodeBlock* m_codeBlock; >+}; >+ >+} // namespace JSC >+ >+#endif // ProfilingCodeBlockJettisoningWatchpoint_h >+ >Index: Source/JavaScriptCore/dfg/DFGAbstractHeap.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGAbstractHeap.h (revision 158167) >+++ Source/JavaScriptCore/dfg/DFGAbstractHeap.h (working copy) >@@ -71,6 +71,8 @@ namespace JSC { namespace DFG { > macro(RegExpState) \ > macro(InternalState) \ > macro(Absolute) \ >+ /* Use this for writes only, to indicate that this may fire watchpoints. Usually this is never directly written but instead we test to see if a node clobbers this; it just so happens that you have to write world to clobber it. */\ >+ macro(Watchpoint_fire) \ > /* Use this for reads only, just to indicate that if the world got clobbered, then this operation will not work. */\ > macro(MiscFields) \ > /* Use this for writes only, just to indicate that hoisting the node is invalid. This works because we don't hoist anything that has any side effects at all. */\ >Index: Source/JavaScriptCore/dfg/DFGClobberize.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGClobberize.cpp (revision 158167) >+++ Source/JavaScriptCore/dfg/DFGClobberize.cpp (working copy) >@@ -40,6 +40,14 @@ bool doesWrites(Graph& graph, Node* node > return addWrite.result(); > } > >+bool writesOverlap(Graph& graph, Node* node, AbstractHeap heap) >+{ >+ NoOpClobberize addRead; >+ AbstractHeapOverlaps addWrite(heap); >+ clobberize(graph, node, addRead, addWrite); >+ return addWrite.result(); >+} >+ > } } // namespace JSC::DFG > > #endif // ENABLE(DFG_JIT) >Index: Source/JavaScriptCore/dfg/DFGClobberize.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGClobberize.h (revision 158167) >+++ Source/JavaScriptCore/dfg/DFGClobberize.h (working copy) >@@ -669,6 +669,30 @@ private: > > bool doesWrites(Graph&, Node*); > >+class AbstractHeapOverlaps { >+public: >+ AbstractHeapOverlaps(AbstractHeap heap) >+ : m_heap(heap) >+ , m_result(false) >+ { >+ } >+ >+ void operator()(AbstractHeap otherHeap) >+ { >+ if (m_result) >+ return; >+ m_result = heap.overlaps(otherHeap); >+ } >+ >+ bool result() const { return m_result; } >+ >+private: >+ AbstractHeap m_heap; >+ bool m_result; >+}; >+ >+bool writesOverlap(Graph&, Node*, AbstractHeap); >+ > } } // namespace JSC::DFG > > #endif // ENABLE(DFG_JIT) >Index: Source/JavaScriptCore/dfg/DFGCommonData.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGCommonData.cpp (revision 158167) >+++ Source/JavaScriptCore/dfg/DFGCommonData.cpp (working copy) >@@ -62,6 +62,15 @@ void CommonData::shrinkToFit() > transitions.shrinkToFit(); > } > >+void CommonData::invalidate() >+{ >+ if (!isStillValid) >+ return; >+ for (unsigned i = jumpReplacements.size(); i--;) >+ jumpReplacements[i].fire(); >+ isStillValid = false; >+} >+ > } } // namespace JSC::DFG > > #endif // ENABLE(DFG_JIT) >Index: Source/JavaScriptCore/dfg/DFGCommonData.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGCommonData.h (revision 158167) >+++ Source/JavaScriptCore/dfg/DFGCommonData.h (working copy) >@@ -69,13 +69,16 @@ class CommonData { > WTF_MAKE_NONCOPYABLE(CommonData); > public: > CommonData() >- : machineCaptureStart(std::numeric_limits<int>::max()) >+ : isStillValid(true) >+ , machineCaptureStart(std::numeric_limits<int>::max()) > { } > > void notifyCompilingStructureTransition(Plan&, CodeBlock*, Node*); > unsigned addCodeOrigin(CodeOrigin codeOrigin); > > void shrinkToFit(); >+ >+ void invalidate(); > > OwnPtr<InlineCallFrameSet> inlineCallFrames; > Vector<CodeOrigin, 0, UnsafeVectorOverflow> codeOrigins; >@@ -83,10 +86,14 @@ public: > Vector<Identifier> dfgIdentifiers; > Vector<WeakReferenceTransition> transitions; > Vector<WriteBarrier<JSCell>> weakReferences; >+ SegmentedVector<CodeBlockJettisoningWatchpoint, 1, 0> watchpoints; >+ SegmentedVector<ProfiledCodeBlockJettisoningWatchpoint, 1, 0> profiledWatchpoints; >+ Vector<JumpReplacement> jumpReplacements; > > RefPtr<Profiler::Compilation> compilation; > bool livenessHasBeenProved; // Initialized and used on every GC. > bool allTransitionsHaveBeenMarked; // Initialized and used on every GC. >+ bool isStillValid; > > int machineCaptureStart; > std::unique_ptr<SlowArgument[]> slowArguments; >Index: Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp (revision 158167) >+++ Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.cpp (working copy) >@@ -33,20 +33,30 @@ namespace JSC { namespace DFG { > DesiredWatchpoints::DesiredWatchpoints() { } > DesiredWatchpoints::~DesiredWatchpoints() { } > >-void DesiredWatchpoints::addLazily(Watchpoint* watchpoint, WatchpointSet* set) >+void DesiredWatchpoints::addLazily(WatchpointSet* set) > { >- m_sets.addLazily(WatchpointForWatchpointSet(watchpoint, set)); >+ m_sets.addLazily(set); > } > >-void DesiredWatchpoints::addLazily(Watchpoint* watchpoint, InlineWatchpointSet& set) >+void DesiredWatchpoints::addLazily(InlineWatchpointSet& set) > { >- m_inlineSets.addLazily(WatchpointForInlineWatchpointSet(watchpoint, &set)); >+ m_inlineSets.addLazily(&set); > } > >-void DesiredWatchpoints::reallyAdd() >+void DesiredWatchpoints::addLazily(CodeOrigin codeOrigin, ExitKind exitKind, WatchpointSet* set) > { >- m_sets.reallyAdd(); >- m_inlineSets.reallyAdd(); >+ m_sets.addLazily(codeOrigin, exitKind, set); >+} >+ >+void DesiredWatchpoints::addLazily(CodeOrigin codeOrigin, ExitKind exitKind, InlineWatchpointSet& set) >+{ >+ m_inlineSets.addLazily(codeOrigin, exitKind, &set); >+} >+ >+void DesiredWatchpoints::reallyAdd(CodeBlock* codeBlock, CommonData& commonData) >+{ >+ m_sets.reallyAdd(codeBlock, commonData); >+ m_inlineSets.reallyAdd(codeBlock, commonData); > } > > bool DesiredWatchpoints::areStillValid() const >Index: Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.h (revision 158167) >+++ Source/JavaScriptCore/dfg/DFGDesiredWatchpoints.h (working copy) >@@ -40,24 +40,24 @@ namespace JSC { namespace DFG { > template<typename WatchpointSetType> > struct WatchpointForGenericWatchpointSet { > WatchpointForGenericWatchpointSet() >- : m_watchpoint(0) >+ : m_exitKind(ExitKindUnset) > , m_set(0) > { > } > >- WatchpointForGenericWatchpointSet(Watchpoint* watchpoint, WatchpointSetType* set) >- : m_watchpoint(watchpoint) >+ WatchpointForGenericWatchpointSet( >+ CodeOrigin codeOrigin, ExitKind exitKind, WatchpointSetType* set) >+ : m_codeOrigin(codeOrigin) >+ , m_exitKind(exitKind) > , m_set(set) > { > } > >- Watchpoint* m_watchpoint; >+ CodeOrigin m_codeOrigin; >+ ExitKind m_exitKind; > WatchpointSetType* m_set; > }; > >-typedef WatchpointForGenericWatchpointSet<WatchpointSet> WatchpointForWatchpointSet; >-typedef WatchpointForGenericWatchpointSet<InlineWatchpointSet> WatchpointForInlineWatchpointSet; >- > template<typename WatchpointSetType> > class GenericDesiredWatchpoints { > WTF_MAKE_NONCOPYABLE(GenericDesiredWatchpoints); >@@ -70,25 +70,53 @@ public: > { > } > >- void addLazily(const WatchpointForGenericWatchpointSet<WatchpointSetType>& watchpoint) >+ void addLazily(WatchpointSetType* set) >+ { >+ m_sets.add(set); >+ } >+ >+ void addLazily(CodeOrigin codeOrigin, ExitKind exitKind, WatchpointSetType* set) > { >- m_watchpoints.append(watchpoint); >+ m_profiledWatchpoints.add( >+ WatchpointForGenericWatchpointSet<WatchpointSetType>(codeOrigin, exitKind, set)); > } > >- void reallyAdd() >+ void reallyAdd(CodeBlock* codeBlock, CommonData& common) > { > RELEASE_ASSERT(!m_reallyAdded); >- for (unsigned i = m_watchpoints.size(); i--;) >- m_watchpoints[i].m_set->add(m_watchpoints[i].m_watchpoint); >+ >+ HashSet<WatchpointSetType*>::iterator iter = m_sets.begin(); >+ HashSet<WatchpointSetType*>::iterator end = m_sets.end(); >+ for (; iter != end; ++iter) { >+ common.watchpoints.append(CodeBlockJettisoningWatchpoint(codeBlock)); >+ (*iter)->add(&common.watchpoints.last()); >+ } >+ >+ for (unsigned i = m_profiledWatchpoints.size(); i--;) { >+ WatchpointForGenericWatchpointSet<WatchpointSetType> watchpoint = >+ m_profiledWatchpoints[i]; >+ common.profiledWatchpoints.append( >+ ProfiledCodeBlockJettisoningWatchpoint(watchpoint.m_codeOrigin, watchpoint.m_exitKind, codeBlock)); >+ watchpoint.m_set->add(&common.profiledWatchpoints.last()); >+ } >+ > m_reallyAdded = true; > } > > bool areStillValid() const > { >- for (unsigned i = m_watchpoints.size(); i--;) { >- if (m_watchpoints[i].m_set->hasBeenInvalidated()) >+ HashSet<WatchpointSetType*>::iterator iter = m_sets.begin(); >+ HashSet<WatchpointSetType*>::iterator end = m_sets.end(); >+ for (; iter != end; ++iter) { >+ if ((*iter)->hasBeenInvalidated()) >+ return false; >+ } >+ >+ for (unsigned i = m_profiledWatchpoints.size(); i--;) { >+ if (m_profiledWatchpoints[i].m_set->hasBeenInvalidated()) > return false; > } >+ > return true; > } > >@@ -126,7 +154,8 @@ public: > } > > private: >- Vector<WatchpointForGenericWatchpointSet<WatchpointSetType>> m_watchpoints; >+ Vector<WatchpointForGenericWatchpointSet<WatchpointSetType>> m_profiledWatchpoints; >+ HashSet<WatchpointSetType*> m_sets; > #if !ASSERT_DISABLED > StateMap m_firstKnownState; > #endif >@@ -138,10 +167,12 @@ public: > DesiredWatchpoints(); > ~DesiredWatchpoints(); > >- void addLazily(Watchpoint*, WatchpointSet*); >- void addLazily(Watchpoint*, InlineWatchpointSet&); >+ void addLazily(WatchpointSet*); >+ void addLazily(InlineWatchpointSet&); >+ void addLazily(CodeOrigin, ExitKind, WatchpointSet*); >+ void addLazily(CodeOrigin, ExitKind, InlineWatchpointSet&); > >- void reallyAdd(); >+ void reallyAdd(CodeBlock*, CommonData&); > > bool areStillValid() const; > >Index: Source/JavaScriptCore/dfg/DFGInvalidationPointInjectionPhase.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGInvalidationPointInjectionPhase.cpp (revision 0) >+++ Source/JavaScriptCore/dfg/DFGInvalidationPointInjectionPhase.cpp (working copy) >@@ -0,0 +1,112 @@ >+/* >+ * Copyright (C) 2013 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 "DFGInvalidationPointInjectionPhase.h" >+ >+#if ENABLE(DFG_JIT) >+ >+#include "DFGClobberize.h" >+#include "DFGGraph.h" >+#include "DFGPhase.h" >+#include "Operations.h" >+ >+namespace JSC { namespace DFG { >+ >+class InvalidationPointInjectionPhase : public Phase { >+ static const bool verbose = false; >+ >+public: >+ InvalidationPointInjectionPhase(Graph& graph) >+ : Phase(graph, "invalidation point injection") >+ , m_insertionSet(graph) >+ { >+ } >+ >+ bool run() >+ { >+ ASSERT(m_graph.m_form != SSA); >+ >+ BitVector blocksThatNeedInvalidationPoints; >+ >+ for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) { >+ BasicBlock* block = m_graph.block(blockIndex); >+ if (!block) >+ continue; >+ >+ for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) >+ handle(nodeIndex, block->at(nodeIndex)); >+ >+ // Note: this assumes that control flow occurs at bytecode instruction boundaries. >+ if (m_originThatHadFire.isSet()) { >+ for (unsigned i = block->numSuccessors(); i--;) >+ blocksThatNeedInvalidationPoints.set(block->successor(i)->index); >+ } >+ >+ m_insertionSet.execute(block); >+ } >+ >+ for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) { >+ if (!blocksThatNeedInvalidationPoints.get(blockIndex)) >+ continue; >+ >+ BasicBlock* block = m_graph.block(blockIndex); >+ insertInvalidationCheck(0, block->at(0)); >+ m_insertionSet.execute(block); >+ } >+ >+ return true; >+ } >+ >+private: >+ void handle(unsigned nodeIndex, Node* node) >+ { >+ if (m_originThatHadFire.isSet() && m_originThatHasFire != node->codeOrigin) { >+ insertInvalidationCheck(nodeIndex, node); >+ m_originThatHadFire = CodeOrigin(); >+ } >+ >+ if (writesOverlap(m_graph, node, Watchpoint_fire)) >+ m_originThatHadFire = node->codeOrigin; >+ } >+ >+ void insertInvalidationCheck(unsigned nodeIndex, Node* node) >+ { >+ m_insertionSet.insertNode(nodeIndex, SpecNone, InvalidationPoint, node->codeOrigin); >+ } >+ >+ CodeOrigin m_originThatHadFire; >+}; >+ >+bool performInvalidationPointInjection(Graph& graph) >+{ >+ SamplingRegion samplingRegion("DFG Invalidation Point Injection Phase"); >+ return runPhase<InvalidationPointInjectionPhase>(graph); >+} >+ >+} } // namespace JSC::DFG >+ >+#endif // ENABLE(DFG_JIT) >+ >Index: Source/JavaScriptCore/dfg/DFGInvalidationPointInjectionPhase.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGInvalidationPointInjectionPhase.h (revision 0) >+++ Source/JavaScriptCore/dfg/DFGInvalidationPointInjectionPhase.h (working copy) >@@ -0,0 +1,47 @@ >+/* >+ * Copyright (C) 2013 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. >+ */ >+ >+#ifndef DFGInvalidationPointInjectionPhase_h >+#define DFGInvalidationPointInjectionPhase_h >+ >+#include <wtf/Platform.h> >+ >+#if ENABLE(DFG_JIT) >+ >+namespace JSC { namespace DFG { >+ >+class Graph; >+ >+// Inserts an invalidation check at the beginning of any CodeOrigin that follows a CodeOrigin >+// that had a call (clobbered World). >+ >+bool performInvalidationPointInjection(Graph&); >+ >+} } // namespace JSC::DFG >+ >+#endif // ENABLE(DFG_JIT) >+ >+#endif // DFGInvalidationPointInjectionPhase_h >+ >Index: Source/JavaScriptCore/dfg/DFGJITCompiler.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGJITCompiler.cpp (revision 158167) >+++ Source/JavaScriptCore/dfg/DFGJITCompiler.cpp (working copy) >@@ -66,11 +66,11 @@ void JITCompiler::linkOSRExits() > for (unsigned i = 0; i < m_jitCode->osrExit.size(); ++i) { > OSRExitCompilationInfo& info = m_exitCompilationInfo[i]; > Vector<Label> labels; >- if (info.m_watchpointIndex == std::numeric_limits<unsigned>::max()) { >+ if (!info.m_failureJumps.empty()) { > for (unsigned j = 0; j < info.m_failureJumps.jumps().size(); ++j) > labels.append(info.m_failureJumps.jumps()[j].label()); > } else >- labels.append(m_jitCode->watchpoints[info.m_watchpointIndex].sourceLabel()); >+ labels.append(info.m_replacementSource); > m_exitSiteLabels.append(labels); > } > } >@@ -80,10 +80,10 @@ void JITCompiler::linkOSRExits() > OSRExitCompilationInfo& info = m_exitCompilationInfo[i]; > JumpList& failureJumps = info.m_failureJumps; > ASSERT(failureJumps.empty() == (info.m_watchpointIndex != std::numeric_limits<unsigned>::max())); >- if (info.m_watchpointIndex == std::numeric_limits<unsigned>::max()) >+ if (!failureJumps.empty()) > failureJumps.link(this); > else >- m_jitCode->watchpoints[info.m_watchpointIndex].setDestination(label()); >+ info.m_replacementDestination = label(); > jitAssertHasValidCallFrame(); > store32(TrustedImm32(i), &vm()->osrExitIndex); > exit.setPatchableCodeOffset(patchableJump()); >@@ -257,8 +257,11 @@ void JITCompiler::link(LinkBuffer& linkB > OSRExitCompilationInfo& info = m_exitCompilationInfo[i]; > linkBuffer.link(exit.getPatchableCodeOffsetAsJump(), target); > exit.correctJump(linkBuffer); >- if (info.m_watchpointIndex != std::numeric_limits<unsigned>::max()) >- m_jitCode->watchpoints[info.m_watchpointIndex].correctLabels(linkBuffer); >+ if (info.m_failureJumps.empty()) { >+ m_jitCode->common.jumpReplacements.append(JumpReplacement( >+ linkBuffer.locationOf(info.m_replacementSource), >+ linkBuffer.locationOf(info.m_replacementDestination))); >+ } > } > > if (m_graph.compilation()) { >Index: Source/JavaScriptCore/dfg/DFGJumpReplacement.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGJumpReplacement.cpp (revision 0) >+++ Source/JavaScriptCore/dfg/DFGJumpReplacement.cpp (working copy) >@@ -0,0 +1,46 @@ >+/* >+ * Copyright (C) 2013 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 "DFGJumpReplacement.h" >+ >+#if ENABLE(DFG_JIT) >+ >+#include "MacroAssembler.h" >+#include "Options.h" >+ >+namespace JSC { namespace DFG { >+ >+void JumpReplacement::fire() >+{ >+ if (Options::showDisassembly()) >+ dataLogF("Firing jump replacement watchpoint from %p, to %p.\n", source.dataLocation(), destination.dataLocation()); >+ MacroAssembler::replaceWithJump(source, destination); >+} >+ >+} } // namespace JSC::DFG >+ >+#endif // ENABLE(DFG_JIT) >+ >Index: Source/JavaScriptCore/dfg/DFGJumpReplacement.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGJumpReplacement.h (revision 0) >+++ Source/JavaScriptCore/dfg/DFGJumpReplacement.h (working copy) >@@ -0,0 +1,55 @@ >+/* >+ * Copyright (C) 2013 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. >+ */ >+ >+#ifndef DFGJumpReplacement_h >+#define DFGJumpReplacement_h >+ >+#if ENABLE(DFG_JIT) >+ >+#include "CodeLocation.h" >+ >+namespace JSC { namespace DFG { >+ >+class JumpReplacement { >+public: >+ JumpReplacement(CodeLocationLabel source, CodeLocationLabel destination) >+ : m_source(source) >+ , m_destination(destination) >+ { >+ } >+ >+ void fire(); >+ >+private: >+ CodeLocationLabel m_source; >+ CodeLocationLabel m_destination; >+}; >+ >+} } // namespace JSC::DFG >+ >+#endif // ENABLE(DFG_JIT) >+ >+#endif // DFGJumpReplacement_h >+ >Index: Source/JavaScriptCore/dfg/DFGNodeType.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGNodeType.h (revision 158167) >+++ Source/JavaScriptCore/dfg/DFGNodeType.h (working copy) >@@ -89,7 +89,11 @@ namespace JSC { namespace DFG { > macro(GetLocalUnlinked, NodeResultJS) \ > \ > /* Marker for an argument being set at the prologue of a function. */\ >- macro(SetArgument, 0 | NodeDoesNotExit) \ >+ macro(SetArgument, NodeDoesNotExit) \ >+ \ >+ /* Marker of location in the IR where we may possibly perform jump replacement to */\ >+ /* invalidate this code block. */\ >+ macro(InvalidationPoint, NodeMustGenerate) \ > \ > /* Nodes for bitwise operations. */\ > macro(BitAnd, NodeResultInt32 | NodeMustGenerate) \ >Index: Source/JavaScriptCore/dfg/DFGOSRExitCompilationInfo.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGOSRExitCompilationInfo.h (revision 158167) >+++ Source/JavaScriptCore/dfg/DFGOSRExitCompilationInfo.h (working copy) >@@ -37,13 +37,9 @@ > namespace JSC { namespace DFG { > > struct OSRExitCompilationInfo { >- OSRExitCompilationInfo() >- : m_watchpointIndex(std::numeric_limits<unsigned>::max()) >- { >- } >- > MacroAssembler::JumpList m_failureJumps; >- unsigned m_watchpointIndex; >+ MacroAssembler::Label m_replacementSource; >+ MacroAssembler::Label m_replacementDestination; > }; > > } } // namespace JSC::DFG >Index: Source/JavaScriptCore/dfg/DFGPlan.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGPlan.cpp (revision 158167) >+++ Source/JavaScriptCore/dfg/DFGPlan.cpp (working copy) >@@ -187,6 +187,7 @@ Plan::CompilationPath Plan::compileInThr > performBackwardsPropagation(dfg); > performPredictionPropagation(dfg); > performFixup(dfg); >+ performInvalidationCheckInjection(dfg); > performTypeCheckHoisting(dfg); > > unsigned count = 1; >@@ -228,7 +229,24 @@ Plan::CompilationPath Plan::compileInThr > switch (mode) { > case DFGMode: { > performTierUpCheckInjection(dfg); >- break; >+ >+ performCPSRethreading(dfg); >+ performDCE(dfg); >+ performStackLayout(dfg); >+ performVirtualRegisterAllocation(dfg); >+ performWatchpointCollection(dfg); >+ dumpAndVerifyGraph(dfg, "Graph after optimization:"); >+ >+ JITCompiler dataFlowJIT(dfg); >+ if (codeBlock->codeType() == FunctionCode) { >+ dataFlowJIT.compileFunction(); >+ dataFlowJIT.linkFunction(); >+ } else { >+ dataFlowJIT.compile(); >+ dataFlowJIT.link(); >+ } >+ >+ return DFGPath; > } > > case FTLMode: >@@ -253,6 +271,7 @@ Plan::CompilationPath Plan::compileInThr > performLivenessAnalysis(dfg); > performFlushLivenessAnalysis(dfg); > performOSRAvailabilityAnalysis(dfg); >+ performWatchpointCollection(dfg); > > dumpAndVerifyGraph(dfg, "Graph just before FTL lowering:"); > >@@ -280,31 +299,14 @@ Plan::CompilationPath Plan::compileInThr > return FTLPath; > #else > RELEASE_ASSERT_NOT_REACHED(); >- break; >+ return FailPath; > #endif // ENABLE(FTL_JIT) > } > > default: > RELEASE_ASSERT_NOT_REACHED(); >- break; >- } >- >- performCPSRethreading(dfg); >- performDCE(dfg); >- performStackLayout(dfg); >- performVirtualRegisterAllocation(dfg); >- dumpAndVerifyGraph(dfg, "Graph after optimization:"); >- >- JITCompiler dataFlowJIT(dfg); >- if (codeBlock->codeType() == FunctionCode) { >- dataFlowJIT.compileFunction(); >- dataFlowJIT.linkFunction(); >- } else { >- dataFlowJIT.compile(); >- dataFlowJIT.link(); >+ return FailPath; > } >- >- return DFGPath; > } > > bool Plan::isStillValid() >Index: Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (revision 158167) >+++ Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (working copy) >@@ -264,8 +264,6 @@ void SpeculativeJIT::nonSpeculativeNonPe > if (!isKnownCell(operand.node())) > notCell = m_jit.branchTest64(MacroAssembler::NonZero, argGPR, GPRInfo::tagMaskRegister); > >- speculationWatchpointForMasqueradesAsUndefined(); >- > m_jit.move(invert ? TrustedImm32(1) : TrustedImm32(0), resultGPR); > notMasqueradesAsUndefined = m_jit.jump(); > } else { >@@ -331,8 +329,6 @@ void SpeculativeJIT::nonSpeculativePeeph > if (!isKnownCell(operand.node())) > notCell = m_jit.branchTest64(MacroAssembler::NonZero, argGPR, GPRInfo::tagMaskRegister); > >- speculationWatchpointForMasqueradesAsUndefined(); >- > jump(invert ? taken : notTaken, ForceJump); > } else { > GPRTemporary localGlobalObject(this); >@@ -1519,7 +1515,6 @@ void SpeculativeJIT::compileObjectEquali > GPRReg resultGPR = result.gpr(); > > if (masqueradesAsUndefinedWatchpointIsStillValid()) { >- speculationWatchpointForMasqueradesAsUndefined(); > DFG_TYPE_CHECK( > JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchPtr( > MacroAssembler::Equal, >@@ -1593,7 +1588,6 @@ void SpeculativeJIT::compileObjectToObje > } > > if (masqueradesAsUndefinedWatchpointValid) { >- speculationWatchpointForMasqueradesAsUndefined(); > DFG_TYPE_CHECK( > JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr( > MacroAssembler::Equal, >@@ -1620,7 +1614,6 @@ void SpeculativeJIT::compileObjectToObje > > // We know that within this branch, rightChild must be a cell. > if (masqueradesAsUndefinedWatchpointValid) { >- speculationWatchpointForMasqueradesAsUndefined(); > DFG_TYPE_CHECK( > JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchPtr( > MacroAssembler::Equal, >@@ -1698,7 +1691,6 @@ void SpeculativeJIT::compilePeepHoleObje > } > > if (masqueradesAsUndefinedWatchpointValid) { >- speculationWatchpointForMasqueradesAsUndefined(); > DFG_TYPE_CHECK( > JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchPtr( > MacroAssembler::Equal, >@@ -1725,7 +1717,6 @@ void SpeculativeJIT::compilePeepHoleObje > > // We know that within this branch, rightChild must be a cell. > if (masqueradesAsUndefinedWatchpointValid) { >- speculationWatchpointForMasqueradesAsUndefined(); > DFG_TYPE_CHECK( > JSValueRegs(op2GPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchPtr( > MacroAssembler::Equal, >@@ -1872,7 +1863,6 @@ void SpeculativeJIT::compileObjectOrOthe > > MacroAssembler::Jump notCell = m_jit.branchTest64(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister); > if (masqueradesAsUndefinedWatchpointValid) { >- speculationWatchpointForMasqueradesAsUndefined(); > DFG_TYPE_CHECK( > JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchPtr( > MacroAssembler::Equal, >@@ -2016,8 +2006,6 @@ void SpeculativeJIT::emitObjectOrOtherBr > > MacroAssembler::Jump notCell = m_jit.branchTest64(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister); > if (masqueradesAsUndefinedWatchpointIsStillValid()) { >- speculationWatchpointForMasqueradesAsUndefined(); >- > DFG_TYPE_CHECK( > JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchPtr( > MacroAssembler::Equal, >@@ -2738,17 +2726,6 @@ void SpeculativeJIT::compile(Node* node) > > case Array::Double: { > if (node->arrayMode().isInBounds()) { >- if (node->arrayMode().isSaneChain()) { >- JSGlobalObject* globalObject = m_jit.globalObjectFor(node->codeOrigin); >- ASSERT(globalObject->arrayPrototypeChainIsSane()); >- m_jit.addLazily( >- speculationWatchpoint(), >- globalObject->arrayPrototype()->structure()->transitionWatchpointSet()); >- m_jit.addLazily( >- speculationWatchpoint(), >- globalObject->objectPrototype()->structure()->transitionWatchpointSet()); >- } >- > SpeculateStrictInt32Operand property(this, node->child2()); > StorageOperand storage(this, node->child3()); > >@@ -3524,10 +3501,6 @@ void SpeculativeJIT::compile(Node* node) > case NewArray: { > JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->codeOrigin); > if (!globalObject->isHavingABadTime() && !hasArrayStorage(node->indexingType())) { >- m_jit.addLazily( >- speculationWatchpoint(), >- globalObject->havingABadTimeWatchpoint()); >- > Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()); > RELEASE_ASSERT(structure->indexingType() == node->indexingType()); > ASSERT( >@@ -3699,10 +3672,6 @@ void SpeculativeJIT::compile(Node* node) > case NewArrayWithSize: { > JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->codeOrigin); > if (!globalObject->isHavingABadTime() && !hasArrayStorage(node->indexingType())) { >- m_jit.addLazily( >- speculationWatchpoint(), >- globalObject->havingABadTimeWatchpoint()); >- > SpeculateStrictInt32Operand size(this, node->child1()); > GPRTemporary result(this); > GPRTemporary storage(this); >@@ -3774,10 +3743,6 @@ void SpeculativeJIT::compile(Node* node) > JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->codeOrigin); > IndexingType indexingType = node->indexingType(); > if (!globalObject->isHavingABadTime() && !hasArrayStorage(indexingType)) { >- m_jit.addLazily( >- speculationWatchpoint(), >- globalObject->havingABadTimeWatchpoint()); >- > unsigned numElements = node->numConstants(); > > GPRTemporary result(this); >@@ -3920,9 +3885,6 @@ void SpeculativeJIT::compile(Node* node) > } > > case AllocationProfileWatchpoint: { >- m_jit.addLazily( >- speculationWatchpoint(), >- jsCast<JSFunction*>(node->function())->allocationProfileWatchpointSet()); > noResult(node); > break; > } >@@ -4195,10 +4157,6 @@ void SpeculativeJIT::compile(Node* node) > // quite a hint already. > > m_jit.addWeakReference(node->structure()); >- m_jit.addLazily( >- speculationWatchpoint( >- node->child1()->op() == WeakJSConstant ? BadWeakConstantCacheWatchpoint : BadCacheWatchpoint), >- node->structure()->transitionWatchpointSet()); > > #if !ASSERT_DISABLED > SpeculateCellOperand op1(this, node->child1()); >@@ -4368,10 +4326,6 @@ void SpeculativeJIT::compile(Node* node) > } > > case GlobalVarWatchpoint: { >- WatchpointSet* set = m_jit.globalObjectFor(node->codeOrigin)->symbolTable()->get( >- identifierUID(node->identifierNumberForCheck())).watchpointSet(); >- m_jit.addLazily(speculationWatchpoint(), set); >- > #if DFG_ENABLE(JIT_ASSERT) > GPRTemporary scratch(this); > GPRReg scratchGPR = scratch.gpr(); >@@ -4388,9 +4342,6 @@ void SpeculativeJIT::compile(Node* node) > } > > case VarInjectionWatchpoint: { >- WatchpointSet* set = m_jit.globalObjectFor(node->codeOrigin)->varInjectionWatchpoint(); >- m_jit.addLazily(speculationWatchpoint(), set); >- > noResult(node); > break; > } >@@ -4426,7 +4377,6 @@ void SpeculativeJIT::compile(Node* node) > isCell.link(&m_jit); > JITCompiler::Jump notMasqueradesAsUndefined; > if (masqueradesAsUndefinedWatchpointIsStillValid()) { >- speculationWatchpointForMasqueradesAsUndefined(); > m_jit.move(TrustedImm32(0), result.gpr()); > notMasqueradesAsUndefined = m_jit.jump(); > } else { >@@ -4958,6 +4908,10 @@ void SpeculativeJIT::compile(Node* node) > terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0); > break; > } >+ >+ case InvalidationPoint: >+ emitInvalidationPoint(node); >+ break; > > case CheckWatchdogTimer: > speculationCheck( >Index: Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (revision 158167) >+++ Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (working copy) >@@ -200,26 +200,19 @@ void SpeculativeJIT::speculationCheck(Ex > speculationCheck(kind, jsValueSource, edge.node(), jumpToFail, recovery); > } > >-JumpReplacementWatchpoint* SpeculativeJIT::speculationWatchpoint(ExitKind kind, JSValueSource jsValueSource, Node* node) >+void SpeculativeJIT::emitInvalidationPoint(Node* node) > { > if (!m_compileOkay) > return 0; >- ASSERT(m_isCheckingArgumentTypes || m_canExit); >+ ASSERT(m_canExit); >+ ASSERT(m_speculationDirection == BackwardSpeculation); > OSRExitCompilationInfo& info = m_jit.appendExitInfo(JITCompiler::JumpList()); > m_jit.jitCode()->appendOSRExit(OSRExit( > kind, jsValueSource, > m_jit.graph().methodOfGettingAValueProfileFor(node), > this, m_stream->size())); >- info.m_watchpointIndex = m_jit.jitCode()->appendWatchpoint( >- JumpReplacementWatchpoint(m_jit.watchpointLabel())); >- if (m_speculationDirection == ForwardSpeculation) >- convertLastOSRExitToForward(); >- return &m_jit.jitCode()->watchpoints[info.m_watchpointIndex]; >-} >- >-JumpReplacementWatchpoint* SpeculativeJIT::speculationWatchpoint(ExitKind kind) >-{ >- return speculationWatchpoint(kind, JSValueSource(), 0); >+ info.m_replacementSource = m_jit.watchpointLabel(); >+ noResult(node); > } > > void SpeculativeJIT::convertLastOSRExitToForward(const ValueRecovery& valueRecovery) >@@ -1353,8 +1346,6 @@ void SpeculativeJIT::compilePeepHoleObje > GPRReg op2GPR = op2.gpr(); > > if (masqueradesAsUndefinedWatchpointIsStillValid()) { >- speculationWatchpointForMasqueradesAsUndefined(); >- > if (m_state.forNode(node->child1()).m_type & ~SpecObject) { > speculationCheck( > BadType, JSValueSource::unboxedCell(op1GPR), node->child1(), >@@ -2004,18 +1995,6 @@ void SpeculativeJIT::compileGetByValOnSt > } > #endif > >- if (node->arrayMode().isOutOfBounds()) { >- JSGlobalObject* globalObject = m_jit.globalObjectFor(node->codeOrigin); >- if (globalObject->stringPrototypeChainIsSane()) { >- m_jit.addLazily( >- speculationWatchpoint(), >- globalObject->stringPrototype()->structure()->transitionWatchpointSet()); >- m_jit.addLazily( >- speculationWatchpoint(), >- globalObject->objectPrototype()->structure()->transitionWatchpointSet()); >- } >- } >- > ASSERT(ArrayMode(Array::String).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1()))); > > // unsigned comparison so we can filter out negative indices and indices that are too large >Index: Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (revision 158167) >+++ Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h (working copy) >@@ -284,20 +284,10 @@ public: > { > return m_jit.graph().masqueradesAsUndefinedWatchpointIsStillValid(codeOrigin); > } >- void speculationWatchpointForMasqueradesAsUndefined(const CodeOrigin& codeOrigin) >- { >- m_jit.addLazily( >- speculationWatchpoint(), >- m_jit.graph().globalObjectFor(codeOrigin)->masqueradesAsUndefinedWatchpoint()); >- } > bool masqueradesAsUndefinedWatchpointIsStillValid() > { > return masqueradesAsUndefinedWatchpointIsStillValid(m_currentNode->codeOrigin); > } >- void speculationWatchpointForMasqueradesAsUndefined() >- { >- speculationWatchpointForMasqueradesAsUndefined(m_currentNode->codeOrigin); >- } > > void writeBarrier(GPRReg ownerGPR, GPRReg valueGPR, Edge valueUse, WriteBarrierUseKind, GPRReg scratchGPR1 = InvalidGPRReg, GPRReg scratchGPR2 = InvalidGPRReg); > void writeBarrier(GPRReg ownerGPR, JSCell* value, WriteBarrierUseKind, GPRReg scratchGPR1 = InvalidGPRReg, GPRReg scratchGPR2 = InvalidGPRReg); >@@ -2131,16 +2121,8 @@ public: > // Add a speculation check with additional recovery. > void backwardSpeculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&); > void backwardSpeculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&); >- // Use this like you would use speculationCheck(), except that you don't pass it a jump >- // (because you don't have to execute a branch; that's kind of the whole point), and you >- // must register the returned Watchpoint with something relevant. In general, this should >- // be used with extreme care. Use speculationCheck() unless you've got an amazing reason >- // not to. >- JumpReplacementWatchpoint* speculationWatchpoint(ExitKind, JSValueSource, Node*); >- // The default for speculation watchpoints is that they're uncounted, because the >- // act of firing a watchpoint invalidates it. So, future recompilations will not >- // attempt to set this watchpoint again. >- JumpReplacementWatchpoint* speculationWatchpoint(ExitKind = UncountableWatchpoint); >+ >+ void emitInvalidationPoint(Node*); > > // It is generally a good idea to not use this directly. > void convertLastOSRExitToForward(const ValueRecovery& = ValueRecovery()); >Index: Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp >=================================================================== >--- Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp (revision 0) >+++ Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp (working copy) >@@ -0,0 +1,173 @@ >+/* >+ * Copyright (C) 2013 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 "DFGWatchpointCollectionPhase.h" >+ >+#if ENABLE(DFG_JIT) >+ >+#include "DFGClobberize.h" >+#include "DFGGraph.h" >+#include "DFGPhase.h" >+#include "Operations.h" >+ >+namespace JSC { namespace DFG { >+ >+class WatchpointCollectionPhase : public Phase { >+ static const bool verbose = false; >+ >+public: >+ WatchpointCollectionPhase(Graph& graph) >+ : Phase(graph, "watchpoint collection") >+ { >+ } >+ >+ bool run() >+ { >+ for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) { >+ BasicBlock* block = m_graph.block(blockIndex); >+ if (!block) >+ continue; >+ >+ for (unsigned nodeIndex = block->size(); nodeIndex--;) { >+ m_node = block->at(nodeIndex); >+ handle(); >+ } >+ } >+ >+ return true; >+ } >+ >+private: >+ void handle() >+ { >+ switch (m_node->op()) { >+ case CompareEqConstant: >+ case IsUndefined: >+ handleMasqueradesAsUndefined(); >+ break; >+ >+ case CompareEq: >+ if (m_node->isBinaryUseKind(ObjectUse) >+ || (m_node->child1().useKind() == ObjectUse && m_node->child2().useKind() == ObjectOrOtherUse) >+ || (m_node->child1().useKind() == ObjectOrOtherUse && m_node->child2().useKind() == ObjectUse)) >+ handleMasqueradesAsUndefined(); >+ break; >+ >+ case LogicalNot: >+ case Branch: >+ if (m_node->child1().useKind() == ObjectOrOtherUse) >+ handleMasqueradesAsUndefined(); >+ break; >+ >+ case GetByVal: >+ if (m_node->arrayMode().type() == Array::Double >+ && m_node->arrayMode().isSaneChain()) { >+ addLazily(globalObject()->arrayPrototype()->structure()->transitionWatchpointSet()); >+ addLazily(glboalObject()->objectPrototype()->structure()->transitionWatchpointSet()); >+ } >+ >+ if (m_node->arrayMode().type() == Array::String) >+ handleStringGetByVal(); >+ break; >+ >+ case StringCharAt: >+ handleStringGetByVal(); >+ break; >+ >+ case NewArray: >+ case NewArrayWithSize: >+ case NewArrayBuffer: >+ if (!globalObject()->isHavingABadTime() && !hasArrayStorage(_node->indexingType())) >+ addLazily(globalObject()->havingABadTimeWatchpoint()); >+ break; >+ >+ case AllocationProfileWatchpoint: >+ addLazily(jsCast<JSFunction*>(m_node->function())->allocationProfileWatchpoint()); >+ break; >+ >+ case StructureTransitionWatchpoint: >+ m_graph.watchpoints().addLazily( >+ m_node->codeOrigin, >+ m_node->child1()->op() == WeakJSConstant ? BadWeakConstantCacheWatchpoint : BadCacheWatchpoint, >+ m_node->structure()->transitionWatchpointSet()); >+ break; >+ >+ case GlobalVarWatchpoint: >+ addLazily( >+ globalObject()->symbolTable->get( >+ m_graph.identifiers()[node->identifierNumberForCheck()]).watchpointSet()); >+ break; >+ >+ case VarInjectionWatchpoint: >+ addLazily(globalObject()->varInjectionWatchpoint()); >+ break; >+ >+ default: >+ break; >+ } >+ } >+ >+ void handleMasqueradesAsUndefined() >+ { >+ if (m_graph.masqueradesAsUndefinedWatchpointIsStillValid(m_node->codeOrigin)) >+ addLazily(globalObject()->masqueradesAsUndefinedWatchpoint()); >+ } >+ >+ void handleStringGetByVal() >+ { >+ if (!m_node->arrayMode().isOutOfBounds()) >+ return; >+ if (!globalObject()->stringPrototypeChainIsSane()) >+ return; >+ addLazily(globalObject()->stringPrototype()->structure()->transitionWatchpointSet()); >+ addLazily(globalObject()->objectPrototype()->structure()->transitionWatchpointSet()); >+ } >+ >+ void addLazily(WatchpointSet* set) >+ { >+ m_graph.watchpoints().addLazily(set); >+ } >+ void addLazily(InlineWatchpointSet& set) >+ { >+ m_graph.watchpoints().addLazily(set); >+ } >+ >+ JSGlobalObject* globalObject() >+ { >+ return m_graph.globalObjectFor(m_node->codeOrigin); >+ } >+}; >+ >+bool performWatchpointCollection(Graph& graph) >+{ >+ SamplingRegion samplingRegion("DFG Watchpoint Collection Phase"); >+ return runPhase<WatchpointCollectionPhase>(graph); >+} >+ >+} } // namespace JSC::DFG >+ >+#endif // ENABLE(DFG_JIT) >+ >Index: Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.h >=================================================================== >--- Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.h (revision 0) >+++ Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.h (working copy) >@@ -0,0 +1,46 @@ >+/* >+ * Copyright (C) 2013 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. >+ */ >+ >+#ifndef DFGWatchpointCollectionPhase_h >+#define DFGWatchpointCollectionPhase_h >+ >+#include <wtf/Platform.h> >+ >+#if ENABLE(DFG_JIT) >+ >+namespace JSC { namespace DFG { >+ >+class Graph; >+ >+// Collects all desired watchpoints into the Graph::watchpoints() data structure. >+ >+bool performWatchpointCollection(Graph&); >+ >+} } // namespace JSC::DFG >+ >+#endif // ENABLE(DFG_JIT) >+ >+#endif // DFGWatchpointCollectionPhase_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
Flags:
buildbot
:
commit-queue-
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 113647
:
215360
|
215362
|
215363
|
215398
|
215407
|
215414
|
215608
|
215671