blob: 09ec8aab7faaa255413a9c32e1cf1bf3628ddf44 [file] [log] [blame]
oliver@apple.com9397e002013-07-25 03:58:49 +00001/*
fpizlo@apple.com3a2fa4c2015-04-13 22:13:12 +00002 * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
oliver@apple.com9397e002013-07-25 03:58:49 +00003 *
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
oliver@apple.com9397e002013-07-25 03:58:49 +000029#if ENABLE(DFG_JIT)
30
fpizlo@apple.comd84425d2013-10-30 19:58:08 +000031#include "CodeOrigin.h"
32#include "DFGCommonData.h"
fpizlo@apple.com12835772015-09-21 20:49:04 +000033#include "DFGDesiredInferredType.h"
fpizlo@apple.com3a2fa4c2015-04-13 22:13:12 +000034#include "InferredValue.h"
fpizlo@apple.comee327c82013-12-05 02:05:35 +000035#include "JSArrayBufferView.h"
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +000036#include "ObjectPropertyCondition.h"
oliver@apple.com9397e002013-07-25 03:58:49 +000037#include "Watchpoint.h"
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +000038#include <wtf/CommaPrinter.h>
fpizlo@apple.comd84425d2013-10-30 19:58:08 +000039#include <wtf/HashSet.h>
oliver@apple.com9397e002013-07-25 03:58:49 +000040
41namespace JSC { namespace DFG {
42
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +000043class Graph;
oliver@apple.com9397e002013-07-25 03:58:49 +000044
fpizlo@apple.comee327c82013-12-05 02:05:35 +000045template<typename T>
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +000046struct SetPointerAdaptor {
47 static void add(CodeBlock* codeBlock, T set, CommonData& common)
fpizlo@apple.comee327c82013-12-05 02:05:35 +000048 {
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +000049 return set->add(common.watchpoints.add(codeBlock));
fpizlo@apple.comee327c82013-12-05 02:05:35 +000050 }
fpizlo@apple.com117408c2015-07-11 06:41:25 +000051 static bool hasBeenInvalidated(T set) { return set->hasBeenInvalidated(); }
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +000052 static void dumpInContext(PrintStream& out, T set, DumpContext*)
53 {
54 out.print(RawPointer(set));
55 }
fpizlo@apple.comee327c82013-12-05 02:05:35 +000056};
57
fpizlo@apple.com3a2fa4c2015-04-13 22:13:12 +000058struct InferredValueAdaptor {
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +000059 static void add(CodeBlock*, InferredValue*, CommonData&);
fpizlo@apple.com3a2fa4c2015-04-13 22:13:12 +000060 static bool hasBeenInvalidated(InferredValue* inferredValue)
61 {
62 return inferredValue->hasBeenInvalidated();
63 }
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +000064 static void dumpInContext(PrintStream& out, InferredValue* inferredValue, DumpContext*)
fpizlo@apple.comee327c82013-12-05 02:05:35 +000065 {
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +000066 out.print(RawPointer(inferredValue));
fpizlo@apple.comee327c82013-12-05 02:05:35 +000067 }
68};
69
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +000070struct ArrayBufferViewWatchpointAdaptor {
71 static void add(CodeBlock*, JSArrayBufferView*, CommonData&);
72 static bool hasBeenInvalidated(JSArrayBufferView* view)
73 {
74 return !view->length();
75 }
76 static void dumpInContext(PrintStream& out, JSArrayBufferView* view, DumpContext* context)
77 {
78 out.print(inContext(JSValue(view), context));
79 }
80};
81
82struct AdaptiveStructureWatchpointAdaptor {
83 static void add(CodeBlock*, const ObjectPropertyCondition&, CommonData&);
84 static bool hasBeenInvalidated(const ObjectPropertyCondition& key)
85 {
86 return !key.isWatchable();
87 }
88 static void dumpInContext(
89 PrintStream& out, const ObjectPropertyCondition& key, DumpContext* context)
90 {
91 out.print(inContext(key, context));
92 }
93};
94
fpizlo@apple.com12835772015-09-21 20:49:04 +000095struct InferredTypeAdaptor {
96 static void add(CodeBlock*, const DesiredInferredType&, CommonData&);
97 static bool hasBeenInvalidated(const DesiredInferredType& key)
98 {
99 return !key.isStillValid();
100 }
101 static void dumpInContext(PrintStream& out, const DesiredInferredType& key, DumpContext* context)
102 {
103 out.print(inContext(key, context));
104 }
105};
106
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +0000107template<typename WatchpointSetType, typename Adaptor = SetPointerAdaptor<WatchpointSetType>>
oliver@apple.com9397e002013-07-25 03:58:49 +0000108class GenericDesiredWatchpoints {
oliver@apple.com67e0f332013-07-25 03:59:00 +0000109#if !ASSERT_DISABLED
fpizlo@apple.com117408c2015-07-11 06:41:25 +0000110 typedef HashMap<WatchpointSetType, bool> StateMap;
oliver@apple.com67e0f332013-07-25 03:59:00 +0000111#endif
oliver@apple.com9397e002013-07-25 03:58:49 +0000112public:
113 GenericDesiredWatchpoints()
114 : m_reallyAdded(false)
115 {
116 }
117
fpizlo@apple.com117408c2015-07-11 06:41:25 +0000118 void addLazily(const WatchpointSetType& set)
oliver@apple.com9397e002013-07-25 03:58:49 +0000119 {
fpizlo@apple.comd84425d2013-10-30 19:58:08 +0000120 m_sets.add(set);
oliver@apple.com9397e002013-07-25 03:58:49 +0000121 }
122
fpizlo@apple.comd84425d2013-10-30 19:58:08 +0000123 void reallyAdd(CodeBlock* codeBlock, CommonData& common)
oliver@apple.com9397e002013-07-25 03:58:49 +0000124 {
125 RELEASE_ASSERT(!m_reallyAdded);
fpizlo@apple.comd84425d2013-10-30 19:58:08 +0000126
fpizlo@apple.com117408c2015-07-11 06:41:25 +0000127 for (auto& set : m_sets)
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +0000128 Adaptor::add(codeBlock, set, common);
fpizlo@apple.comd84425d2013-10-30 19:58:08 +0000129
oliver@apple.com9397e002013-07-25 03:58:49 +0000130 m_reallyAdded = true;
131 }
132
133 bool areStillValid() const
134 {
fpizlo@apple.com117408c2015-07-11 06:41:25 +0000135 for (auto& set : m_sets) {
136 if (Adaptor::hasBeenInvalidated(set))
oliver@apple.com9397e002013-07-25 03:58:49 +0000137 return false;
138 }
fpizlo@apple.comd84425d2013-10-30 19:58:08 +0000139
oliver@apple.com9397e002013-07-25 03:58:49 +0000140 return true;
141 }
oliver@apple.com67e0f332013-07-25 03:59:00 +0000142
fpizlo@apple.com117408c2015-07-11 06:41:25 +0000143 bool isWatched(const WatchpointSetType& set) const
oliver@apple.com67e0f332013-07-25 03:59:00 +0000144 {
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +0000145 return m_sets.contains(set);
oliver@apple.com67e0f332013-07-25 03:59:00 +0000146 }
oliver@apple.com9397e002013-07-25 03:58:49 +0000147
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +0000148 void dumpInContext(PrintStream& out, DumpContext* context) const
149 {
150 CommaPrinter comma;
151 for (const WatchpointSetType& entry : m_sets) {
152 out.print(comma);
153 Adaptor::dumpInContext(out, entry, context);
154 }
155 }
156
oliver@apple.com9397e002013-07-25 03:58:49 +0000157private:
fpizlo@apple.com117408c2015-07-11 06:41:25 +0000158 HashSet<WatchpointSetType> m_sets;
oliver@apple.com9397e002013-07-25 03:58:49 +0000159 bool m_reallyAdded;
160};
161
162class DesiredWatchpoints {
163public:
164 DesiredWatchpoints();
165 ~DesiredWatchpoints();
166
fpizlo@apple.comd84425d2013-10-30 19:58:08 +0000167 void addLazily(WatchpointSet*);
168 void addLazily(InlineWatchpointSet&);
fpizlo@apple.com3a2fa4c2015-04-13 22:13:12 +0000169 void addLazily(InferredValue*);
fpizlo@apple.comee327c82013-12-05 02:05:35 +0000170 void addLazily(JSArrayBufferView*);
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +0000171
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +0000172 // It's recommended that you don't call this directly. Use Graph::watchCondition(), which does
173 // the required GC magic as well as some other bookkeeping.
174 void addLazily(const ObjectPropertyCondition&);
fpizlo@apple.com12835772015-09-21 20:49:04 +0000175
176 // It's recommended that you don't call this directly. Use Graph::inferredTypeFor(), which does
177 // the required GC magic.
178 void addLazily(const DesiredInferredType&);
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +0000179
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +0000180 bool consider(Structure*);
oliver@apple.com9397e002013-07-25 03:58:49 +0000181
fpizlo@apple.comd84425d2013-10-30 19:58:08 +0000182 void reallyAdd(CodeBlock*, CommonData&);
oliver@apple.com9397e002013-07-25 03:58:49 +0000183
184 bool areStillValid() const;
185
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +0000186 bool isWatched(WatchpointSet* set)
oliver@apple.com67e0f332013-07-25 03:59:00 +0000187 {
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +0000188 return m_sets.isWatched(set);
oliver@apple.com67e0f332013-07-25 03:59:00 +0000189 }
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +0000190 bool isWatched(InlineWatchpointSet& set)
oliver@apple.com67e0f332013-07-25 03:59:00 +0000191 {
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +0000192 return m_inlineSets.isWatched(&set);
oliver@apple.com67e0f332013-07-25 03:59:00 +0000193 }
fpizlo@apple.com3a2fa4c2015-04-13 22:13:12 +0000194 bool isWatched(InferredValue* inferredValue)
195 {
196 return m_inferredValues.isWatched(inferredValue);
197 }
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +0000198 bool isWatched(JSArrayBufferView* view)
fpizlo@apple.comee327c82013-12-05 02:05:35 +0000199 {
fpizlo@apple.com0728b8a2014-07-23 01:19:50 +0000200 return m_bufferViews.isWatched(view);
fpizlo@apple.comee327c82013-12-05 02:05:35 +0000201 }
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +0000202 bool isWatched(const ObjectPropertyCondition& key)
203 {
204 return m_adaptiveStructureSets.isWatched(key);
205 }
fpizlo@apple.com12835772015-09-21 20:49:04 +0000206 bool isWatched(const DesiredInferredType& key)
207 {
208 return m_inferredTypes.isWatched(key);
209 }
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +0000210
211 void dumpInContext(PrintStream&, DumpContext*) const;
212 void dump(PrintStream&) const;
oliver@apple.com67e0f332013-07-25 03:59:00 +0000213
oliver@apple.com9397e002013-07-25 03:58:49 +0000214private:
fpizlo@apple.com117408c2015-07-11 06:41:25 +0000215 GenericDesiredWatchpoints<WatchpointSet*> m_sets;
216 GenericDesiredWatchpoints<InlineWatchpointSet*> m_inlineSets;
217 GenericDesiredWatchpoints<InferredValue*, InferredValueAdaptor> m_inferredValues;
218 GenericDesiredWatchpoints<JSArrayBufferView*, ArrayBufferViewWatchpointAdaptor> m_bufferViews;
fpizlo@apple.com6b62eaf2015-08-03 23:13:56 +0000219 GenericDesiredWatchpoints<ObjectPropertyCondition, AdaptiveStructureWatchpointAdaptor> m_adaptiveStructureSets;
fpizlo@apple.com12835772015-09-21 20:49:04 +0000220 GenericDesiredWatchpoints<DesiredInferredType, InferredTypeAdaptor> m_inferredTypes;
oliver@apple.com9397e002013-07-25 03:58:49 +0000221};
222
223} } // namespace JSC::DFG
224
225#endif // ENABLE(DFG_JIT)
226
227#endif // DFGDesiredWatchpoints_h
228