cf3d93922399a78c68e2c75496d448859116c188
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGDesiredWatchpoints.h
1 /*
2  * Copyright (C) 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef DFGDesiredWatchpoints_h
27 #define DFGDesiredWatchpoints_h
28
29 #include <wtf/Platform.h>
30
31 #if ENABLE(DFG_JIT)
32
33 #include "Watchpoint.h"
34 #include <wtf/HashMap.h>
35 #include <wtf/Noncopyable.h>
36 #include <wtf/Vector.h>
37
38 namespace JSC { namespace DFG {
39
40 template<typename WatchpointSetType>
41 struct WatchpointForGenericWatchpointSet {
42     WatchpointForGenericWatchpointSet()
43         : m_watchpoint(0)
44         , m_set(0)
45     {
46     }
47     
48     WatchpointForGenericWatchpointSet(Watchpoint* watchpoint, WatchpointSetType* set)
49         : m_watchpoint(watchpoint)
50         , m_set(set)
51     {
52     }
53     
54     Watchpoint* m_watchpoint;
55     WatchpointSetType* m_set;
56 };
57
58 typedef WatchpointForGenericWatchpointSet<WatchpointSet> WatchpointForWatchpointSet;
59 typedef WatchpointForGenericWatchpointSet<InlineWatchpointSet> WatchpointForInlineWatchpointSet;
60
61 template<typename WatchpointSetType>
62 class GenericDesiredWatchpoints {
63     WTF_MAKE_NONCOPYABLE(GenericDesiredWatchpoints);
64 #if !ASSERT_DISABLED
65     typedef HashMap<WatchpointSetType*, bool> StateMap;
66 #endif
67 public:
68     GenericDesiredWatchpoints()
69         : m_reallyAdded(false)
70     {
71     }
72     
73     void addLazily(const WatchpointForGenericWatchpointSet<WatchpointSetType>& watchpoint)
74     {
75         m_watchpoints.append(watchpoint);
76     }
77     
78     void reallyAdd()
79     {
80         RELEASE_ASSERT(!m_reallyAdded);
81         for (unsigned i = m_watchpoints.size(); i--;)
82             m_watchpoints[i].m_set->add(m_watchpoints[i].m_watchpoint);
83         m_reallyAdded = true;
84     }
85     
86     bool areStillValid() const
87     {
88         for (unsigned i = m_watchpoints.size(); i--;) {
89             if (m_watchpoints[i].m_set->hasBeenInvalidated())
90                 return false;
91         }
92         return true;
93     }
94     
95 #if ASSERT_DISABLED
96     bool isStillValid(WatchpointSetType* set)
97     {
98         return set->isStillValid();
99     }
100     
101     bool shouldAssumeMixedState(WatchpointSetType*)
102     {
103         return true;
104     }
105 #else
106     bool isStillValid(WatchpointSetType* set)
107     {
108         bool result = set->isStillValid();
109         m_firstKnownState.add(set, result);
110         return result;
111     }
112     
113     bool shouldAssumeMixedState(WatchpointSetType* set)
114     {
115         typename StateMap::iterator iter = m_firstKnownState.find(set);
116         if (iter == m_firstKnownState.end())
117             return false;
118         
119         WTF::loadLoadFence();
120         return iter->value != set->isStillValid();
121     }
122 #endif
123     
124     bool isValidOrMixed(WatchpointSetType* set)
125     {
126         return isStillValid(set) || shouldAssumeMixedState(set);
127     }
128
129 private:
130     Vector<WatchpointForGenericWatchpointSet<WatchpointSetType> > m_watchpoints;
131 #if !ASSERT_DISABLED
132     StateMap m_firstKnownState;
133 #endif
134     bool m_reallyAdded;
135 };
136
137 class DesiredWatchpoints {
138 public:
139     DesiredWatchpoints();
140     ~DesiredWatchpoints();
141     
142     void addLazily(Watchpoint*, WatchpointSet*);
143     void addLazily(Watchpoint*, InlineWatchpointSet&);
144     
145     void reallyAdd();
146     
147     bool areStillValid() const;
148     
149     bool isStillValid(WatchpointSet* set)
150     {
151         return m_sets.isStillValid(set);
152     }
153     bool isStillValid(InlineWatchpointSet& set)
154     {
155         return m_inlineSets.isStillValid(&set);
156     }
157     bool shouldAssumeMixedState(WatchpointSet* set)
158     {
159         return m_sets.shouldAssumeMixedState(set);
160     }
161     bool shouldAssumeMixedState(InlineWatchpointSet& set)
162     {
163         return m_inlineSets.shouldAssumeMixedState(&set);
164     }
165     bool isValidOrMixed(WatchpointSet* set)
166     {
167         return m_sets.isValidOrMixed(set);
168     }
169     bool isValidOrMixed(InlineWatchpointSet& set)
170     {
171         return m_inlineSets.isValidOrMixed(&set);
172     }
173     
174 private:
175     GenericDesiredWatchpoints<WatchpointSet> m_sets;
176     GenericDesiredWatchpoints<InlineWatchpointSet> m_inlineSets;
177 };
178
179 } } // namespace JSC::DFG
180
181 #endif // ENABLE(DFG_JIT)
182
183 #endif // DFGDesiredWatchpoints_h
184