Watchpoints and jump replacement should be decoupled
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 Jul 2012 23:12:35 +0000 (23:12 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 11 Jul 2012 23:12:35 +0000 (23:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=91016

Reviewed by Oliver Hunt.

* CMakeLists.txt:
* GNUmakefile.list.am:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Target.pri:
* assembler/AbstractMacroAssembler.h:
(JSC):
(Label):
* bytecode/CodeBlock.h:
(JSC::CodeBlock::appendWatchpoint):
(JSC::CodeBlock::watchpoint):
(DFGData):
* bytecode/Watchpoint.cpp:
(JSC):
* bytecode/Watchpoint.h:
(JSC::Watchpoint::Watchpoint):
(Watchpoint):
(JSC::Watchpoint::fire):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::speculationWatchpoint):
* jit/JumpReplacementWatchpoint.cpp: Added.
(JSC):
(JSC::JumpReplacementWatchpoint::correctLabels):
(JSC::JumpReplacementWatchpoint::fireInternal):
* jit/JumpReplacementWatchpoint.h: Added.
(JSC):
(JumpReplacementWatchpoint):
(JSC::JumpReplacementWatchpoint::JumpReplacementWatchpoint):
(JSC::JumpReplacementWatchpoint::setDestination):

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

13 files changed:
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/GNUmakefile.list.am
Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/Target.pri
Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
Source/JavaScriptCore/bytecode/CodeBlock.h
Source/JavaScriptCore/bytecode/Watchpoint.cpp
Source/JavaScriptCore/bytecode/Watchpoint.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
Source/JavaScriptCore/jit/JumpReplacementWatchpoint.cpp [new file with mode: 0644]
Source/JavaScriptCore/jit/JumpReplacementWatchpoint.h [new file with mode: 0644]

index 412be29..9350240 100644 (file)
@@ -143,6 +143,7 @@ SET(JavaScriptCore_SOURCES
     jit/JITPropertyAccess.cpp
     jit/JITStubRoutine.cpp
     jit/JITStubs.cpp
+    jit/JumpReplacementWatchpoint.cpp
     jit/ThunkGenerators.cpp
 
     parser/Lexer.cpp
index e7bc437..577ed98 100644 (file)
@@ -1,3 +1,40 @@
+2012-07-11  Filip Pizlo  <fpizlo@apple.com>
+
+        Watchpoints and jump replacement should be decoupled
+        https://bugs.webkit.org/show_bug.cgi?id=91016
+
+        Reviewed by Oliver Hunt.
+
+        * CMakeLists.txt:
+        * GNUmakefile.list.am:
+        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * Target.pri:
+        * assembler/AbstractMacroAssembler.h:
+        (JSC):
+        (Label):
+        * bytecode/CodeBlock.h:
+        (JSC::CodeBlock::appendWatchpoint):
+        (JSC::CodeBlock::watchpoint):
+        (DFGData):
+        * bytecode/Watchpoint.cpp:
+        (JSC):
+        * bytecode/Watchpoint.h:
+        (JSC::Watchpoint::Watchpoint):
+        (Watchpoint):
+        (JSC::Watchpoint::fire):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::speculationWatchpoint):
+        * jit/JumpReplacementWatchpoint.cpp: Added.
+        (JSC):
+        (JSC::JumpReplacementWatchpoint::correctLabels):
+        (JSC::JumpReplacementWatchpoint::fireInternal):
+        * jit/JumpReplacementWatchpoint.h: Added.
+        (JSC):
+        (JumpReplacementWatchpoint):
+        (JSC::JumpReplacementWatchpoint::JumpReplacementWatchpoint):
+        (JSC::JumpReplacementWatchpoint::setDestination):
+
 2012-07-11  Kevin Ollivier  <kevino@theolliviers.com>
 
         [wx] Unreviewed build fix. Don't try to build udis86_itab.c since it's included by 
index 7e6056e..ff5ef46 100644 (file)
@@ -383,6 +383,8 @@ javascriptcore_sources += \
        Source/JavaScriptCore/jit/JITStubs.h \
        Source/JavaScriptCore/jit/JITWriteBarrier.h \
        Source/JavaScriptCore/jit/JSInterfaceJIT.h \
+       Source/JavaScriptCore/jit/JumpReplacementWatchpoint.cpp \
+       Source/JavaScriptCore/jit/JumpReplacementWatchpoint.h \
        Source/JavaScriptCore/jit/SpecializedThunkJIT.h \
        Source/JavaScriptCore/jit/ThunkGenerators.cpp \
        Source/JavaScriptCore/jit/ThunkGenerators.h \
index 92749eb..cf4196f 100644 (file)
                                >
                        </File>
                        <File
+                               RelativePath="..\..\jit\JumpReplacementWatchpoint.cpp"
+                               >
+                       </File>
+                       <File
+                               RelativePath="..\..\jit\JumpReplacementWatchpoint.h"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\jit\JSInterfaceJIT.h"
                                >
                        </File>
index 188c1ff..c8dd98d 100644 (file)
                0F766D2F15A8DCE0008F363E /* GCAwareJITStubRoutine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D2D15A8DCDD008F363E /* GCAwareJITStubRoutine.cpp */; };
                0F766D3015A8DCE2008F363E /* GCAwareJITStubRoutine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D2E15A8DCDD008F363E /* GCAwareJITStubRoutine.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F766D3115AA8112008F363E /* JITStubRoutine.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D1C15A5028D008F363E /* JITStubRoutine.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0F766D3415AE2538008F363E /* JumpReplacementWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F766D3215AE2535008F363E /* JumpReplacementWatchpoint.cpp */; };
+               0F766D3515AE253B008F363E /* JumpReplacementWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F766D3315AE2535008F363E /* JumpReplacementWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F7700921402FF3C0078EB39 /* SamplingCounter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7700911402FF280078EB39 /* SamplingCounter.cpp */; };
                0F7B294A14C3CD29007C3DB1 /* DFGCCallHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7B294814C3CD23007C3DB1 /* DFGCCallHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD82E1F14172C2F00179C94 /* DFGCapabilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0F766D2A15A8CC34008F363E /* JITStubRoutineSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITStubRoutineSet.h; sourceTree = "<group>"; };
                0F766D2D15A8DCDD008F363E /* GCAwareJITStubRoutine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GCAwareJITStubRoutine.cpp; sourceTree = "<group>"; };
                0F766D2E15A8DCDD008F363E /* GCAwareJITStubRoutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GCAwareJITStubRoutine.h; sourceTree = "<group>"; };
+               0F766D3215AE2535008F363E /* JumpReplacementWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JumpReplacementWatchpoint.cpp; sourceTree = "<group>"; };
+               0F766D3315AE2535008F363E /* JumpReplacementWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JumpReplacementWatchpoint.h; sourceTree = "<group>"; };
                0F77008E1402FDD60078EB39 /* SamplingCounter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingCounter.h; sourceTree = "<group>"; };
                0F7700911402FF280078EB39 /* SamplingCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingCounter.cpp; sourceTree = "<group>"; };
                0F7B294814C3CD23007C3DB1 /* DFGCCallHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGCCallHelpers.h; path = dfg/DFGCCallHelpers.h; sourceTree = "<group>"; };
                                14A6581A0F4E36F4000150FD /* JITStubs.h */,
                                A76F54A213B28AAB00EF2BCE /* JITWriteBarrier.h */,
                                A76C51741182748D00715B05 /* JSInterfaceJIT.h */,
+                               0F766D3215AE2535008F363E /* JumpReplacementWatchpoint.cpp */,
+                               0F766D3315AE2535008F363E /* JumpReplacementWatchpoint.h */,
                                A7386551118697B400540279 /* SpecializedThunkJIT.h */,
                                A7386552118697B400540279 /* ThunkGenerators.cpp */,
                                A7386553118697B400540279 /* ThunkGenerators.h */,
                                0F766D2C15A8CC3A008F363E /* JITStubRoutineSet.h in Headers */,
                                0F766D3015A8DCE2008F363E /* GCAwareJITStubRoutine.h in Headers */,
                                0F766D3115AA8112008F363E /* JITStubRoutine.h in Headers */,
+                               0F766D3515AE253B008F363E /* JumpReplacementWatchpoint.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                0F766D2815A8CC1E008F363E /* JITStubRoutine.cpp in Sources */,
                                0F766D2B15A8CC38008F363E /* JITStubRoutineSet.cpp in Sources */,
                                0F766D2F15A8DCE0008F363E /* GCAwareJITStubRoutine.cpp in Sources */,
+                               0F766D3415AE2538008F363E /* JumpReplacementWatchpoint.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index b019e41..6355039 100644 (file)
@@ -151,6 +151,7 @@ SOURCES += \
     jit/JITPropertyAccess32_64.cpp \
     jit/JITStubRoutine.cpp \
     jit/JITStubs.cpp \
+    jit/JumpReplacementWatchpoint.cpp \
     jit/ThunkGenerators.cpp \
     parser/Lexer.cpp \
     parser/Nodes.cpp \
index a24f757..ef1808f 100644 (file)
@@ -46,6 +46,7 @@
 
 namespace JSC {
 
+class JumpReplacementWatchpoint;
 class LinkBuffer;
 class RepatchBuffer;
 class Watchpoint;
@@ -277,6 +278,7 @@ public:
         friend class AbstractMacroAssembler;
         friend class DFG::CorrectableJumpPoint;
         friend class Jump;
+        friend class JumpReplacementWatchpoint;
         friend class MacroAssemblerCodeRef;
         friend class LinkBuffer;
         friend class Watchpoint;
index ed072f8..b817a64 100644 (file)
@@ -55,6 +55,7 @@
 #include "JITCode.h"
 #include "JITWriteBarrier.h"
 #include "JSGlobalObject.h"
+#include "JumpReplacementWatchpoint.h"
 #include "JumpTable.h"
 #include "LLIntCallLinkInfo.h"
 #include "LazyOperandValueProfile.h"
@@ -328,7 +329,7 @@ namespace JSC {
             return result;
         }
         
-        unsigned appendWatchpoint(const Watchpoint& watchpoint)
+        unsigned appendWatchpoint(const JumpReplacementWatchpoint& watchpoint)
         {
             createDFGDataIfNecessary();
             unsigned result = m_dfgData->watchpoints.size();
@@ -367,7 +368,7 @@ namespace JSC {
             return m_dfgData->speculationRecovery[index];
         }
         
-        Watchpoint& watchpoint(unsigned index)
+        JumpReplacementWatchpoint& watchpoint(unsigned index)
         {
             return m_dfgData->watchpoints[index];
         }
@@ -1299,7 +1300,7 @@ namespace JSC {
             Vector<DFG::OSREntryData> osrEntry;
             SegmentedVector<DFG::OSRExit, 8> osrExit;
             Vector<DFG::SpeculationRecovery> speculationRecovery;
-            SegmentedVector<Watchpoint, 1, 0> watchpoints;
+            SegmentedVector<JumpReplacementWatchpoint, 1, 0> watchpoints;
             Vector<WeakReferenceTransition> transitions;
             Vector<WriteBarrier<JSCell> > weakReferences;
             DFG::VariableEventStream variableEventStream;
index 1dd633f..24aca67 100644 (file)
@@ -39,30 +39,6 @@ Watchpoint::~Watchpoint()
         remove();
 }
 
-#if ENABLE(JIT)
-void Watchpoint::correctLabels(LinkBuffer& linkBuffer)
-{
-    MacroAssembler::Label label;
-    label.m_label.m_offset = m_source;
-    m_source = bitwise_cast<uintptr_t>(linkBuffer.locationOf(label).dataLocation());
-    label.m_label.m_offset = m_destination;
-    m_destination = bitwise_cast<uintptr_t>(linkBuffer.locationOf(label).dataLocation());
-}
-#endif
-
-void Watchpoint::fire()
-{
-#if ENABLE(JIT)
-    MacroAssembler::replaceWithJump(
-        CodeLocationLabel(bitwise_cast<void*>(m_source)),
-        CodeLocationLabel(bitwise_cast<void*>(m_destination)));
-    if (isOnList())
-        remove();
-#else
-    UNREACHABLE_FOR_PLATFORM();
-#endif
-}
-
 WatchpointSet::WatchpointSet(InitialWatchpointSetMode mode)
     : m_isWatched(mode == InitializedWatching)
     , m_isInvalidated(false)
index 0055bf6..d0995c9 100644 (file)
@@ -29,8 +29,6 @@
 #ifndef Watchpoint_h
 #define Watchpoint_h
 
-#include "CodeLocation.h"
-#include "MacroAssembler.h"
 #include <wtf/RefCounted.h>
 #include <wtf/SentinelLinkedList.h>
 
@@ -39,33 +37,15 @@ namespace JSC {
 class Watchpoint : public BasicRawSentinelNode<Watchpoint> {
 public:
     Watchpoint()
-        : m_source(std::numeric_limits<uintptr_t>::max())
-        , m_destination(std::numeric_limits<uintptr_t>::max())
     {
     }
-
-#if ENABLE(JIT)
-    Watchpoint(MacroAssembler::Label source)
-        : m_source(source.m_label.m_offset)
-        , m_destination(std::numeric_limits<uintptr_t>::max())
-    {
-    }
-    
-    void setDestination(MacroAssembler::Label destination)
-    {
-        m_destination = destination.m_label.m_offset;
-    }
-    
-    void correctLabels(LinkBuffer&);
-#endif
-    
-    ~Watchpoint();
     
-    void fire();
+    virtual ~Watchpoint();
+
+    void fire() { fireInternal(); }
     
-private:
-    uintptr_t m_source;
-    uintptr_t m_destination;
+protected:
+    virtual void fireInternal() = 0;
 };
 
 enum InitialWatchpointSetMode { InitializedWatching, InitializedBlind };
index 57bc84a..3b2df7e 100644 (file)
@@ -2165,7 +2165,7 @@ public:
     // 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.
-    Watchpoint* speculationWatchpoint(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex)
+    JumpReplacementWatchpoint* speculationWatchpoint(ExitKind kind, JSValueSource jsValueSource, NodeIndex nodeIndex)
     {
         if (!m_compileOkay)
             return 0;
@@ -2176,13 +2176,13 @@ public:
                         m_jit.graph().methodOfGettingAValueProfileFor(nodeIndex),
                         JITCompiler::Jump(), this, m_stream->size())));
         exit.m_watchpointIndex = m_jit.codeBlock()->appendWatchpoint(
-            Watchpoint(m_jit.watchpointLabel()));
+            JumpReplacementWatchpoint(m_jit.watchpointLabel()));
         return &m_jit.codeBlock()->watchpoint(exit.m_watchpointIndex);
     }
     // 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.
-    Watchpoint* speculationWatchpoint()
+    JumpReplacementWatchpoint* speculationWatchpoint()
     {
         return speculationWatchpoint(UncountableWatchpoint, JSValueSource(), NoNode);
     }
diff --git a/Source/JavaScriptCore/jit/JumpReplacementWatchpoint.cpp b/Source/JavaScriptCore/jit/JumpReplacementWatchpoint.cpp
new file mode 100644 (file)
index 0000000..174a0c2
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2012 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.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "JumpReplacementWatchpoint.h"
+
+#if ENABLE(JIT)
+
+#include "LinkBuffer.h"
+
+namespace JSC {
+
+void JumpReplacementWatchpoint::correctLabels(LinkBuffer& linkBuffer)
+{
+    MacroAssembler::Label label;
+    label.m_label.m_offset = m_source;
+    m_source = bitwise_cast<uintptr_t>(linkBuffer.locationOf(label).dataLocation());
+    label.m_label.m_offset = m_destination;
+    m_destination = bitwise_cast<uintptr_t>(linkBuffer.locationOf(label).dataLocation());
+}
+
+void JumpReplacementWatchpoint::fireInternal()
+{
+    MacroAssembler::replaceWithJump(
+        CodeLocationLabel(bitwise_cast<void*>(m_source)),
+        CodeLocationLabel(bitwise_cast<void*>(m_destination)));
+    if (isOnList())
+        remove();
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
diff --git a/Source/JavaScriptCore/jit/JumpReplacementWatchpoint.h b/Source/JavaScriptCore/jit/JumpReplacementWatchpoint.h
new file mode 100644 (file)
index 0000000..eb088f6
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2012 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.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 JumpReplacementWatchpoint_h
+#define JumpReplacementWatchpoint_h
+
+#include "Watchpoint.h"
+
+#if ENABLE(JIT)
+
+#include "CodeLocation.h"
+#include "MacroAssembler.h"
+
+namespace JSC {
+
+class JumpReplacementWatchpoint : public Watchpoint {
+public:
+    JumpReplacementWatchpoint()
+        : m_source(std::numeric_limits<uintptr_t>::max())
+        , m_destination(std::numeric_limits<uintptr_t>::max())
+    {
+    }
+    
+    JumpReplacementWatchpoint(MacroAssembler::Label source)
+        : m_source(source.m_label.m_offset)
+        , m_destination(std::numeric_limits<uintptr_t>::max())
+    {
+    }
+    
+    void setDestination(MacroAssembler::Label destination)
+    {
+        m_destination = destination.m_label.m_offset;
+    }
+    
+    void correctLabels(LinkBuffer&);
+
+protected:
+    void fireInternal();
+
+private:
+    uintptr_t m_source;
+    uintptr_t m_destination;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // JumpReplacementWatchpoint_h
+