[JSC] Do not check isValid() in op_new_regexp
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGMayExit.cpp
1 /*
2  * Copyright (C) 2014-2016 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 #include "config.h"
27 #include "DFGMayExit.h"
28
29 #if ENABLE(DFG_JIT)
30
31 #include "DFGAtTailAbstractState.h"
32 #include "DFGGraph.h"
33 #include "DFGNode.h"
34 #include "DFGNullAbstractState.h"
35 #include "Operations.h"
36
37 namespace JSC { namespace DFG {
38
39 namespace {
40
41 template<typename StateType>
42 ExitMode mayExitImpl(Graph& graph, Node* node, StateType& state)
43 {
44     ExitMode result = DoesNotExit;
45     
46     switch (node->op()) {
47     // This is a carefully curated list of nodes that definitely do not exit. We try to be very
48     // conservative when maintaining this list, because adding new node types to it doesn't
49     // generally make things a lot better but it might introduce subtle bugs.
50     case SetArgument:
51     case JSConstant:
52     case DoubleConstant:
53     case LazyJSConstant:
54     case Int52Constant:
55     case MovHint:
56     case InitializeEntrypointArguments:
57     case SetLocal:
58     case Flush:
59     case Phantom:
60     case Check:
61     case Identity:
62     case IdentityWithProfile:
63     case GetLocal:
64     case LoopHint:
65     case Phi:
66     case Upsilon:
67     case ZombieHint:
68     case ExitOK:
69     case BottomValue:
70     case PutHint:
71     case PhantomNewObject:
72     case PutStack:
73     case KillStack:
74     case GetStack:
75     case GetCallee:
76     case GetArgumentCountIncludingThis:
77     case GetRestLength:
78     case GetScope:
79     case PhantomLocal:
80     case CountExecution:
81     case SuperSamplerBegin:
82     case SuperSamplerEnd:
83     case Jump:
84     case EntrySwitch:
85     case Branch:
86     case Unreachable:
87     case DoubleRep:
88     case Int52Rep:
89     case ValueRep:
90     case ExtractOSREntryLocal:
91     case ExtractCatchLocal:
92     case LogicalNot:
93     case NotifyWrite:
94     case PutStructure:
95     case StoreBarrier:
96     case FencedStoreBarrier:
97     case PutByOffset:
98     case PutClosureVar:
99     case RecordRegExpCachedResult:
100     case NukeStructureAndSetButterfly:
101         break;
102
103     case StrCat:
104     case Call:
105     case Construct:
106     case CallVarargs:
107     case CallEval:
108     case ConstructVarargs:
109     case CallForwardVarargs:
110     case ConstructForwardVarargs:
111     case CreateActivation:
112     case MaterializeCreateActivation:
113     case MaterializeNewObject:
114     case NewFunction:
115     case NewGeneratorFunction:
116     case NewAsyncFunction:
117     case NewAsyncGeneratorFunction:
118     case NewStringObject:
119     case NewRegexp:
120     case ToNumber:
121         result = ExitsForExceptions;
122         break;
123
124     default:
125         // If in doubt, return true.
126         return Exits;
127     }
128     
129     graph.doToChildren(
130         node,
131         [&] (Edge& edge) {
132             if (state) {
133                 // Ignore the Check flag on the edge. This is important because that flag answers
134                 // the question: "would this edge have had a check if it executed wherever it
135                 // currently resides in control flow?" But when a state is passed, we want to ask a
136                 // different question: "would this edge have a check if it executed wherever this
137                 // state is?" Using the Check flag for this purpose wouldn't even be conservatively
138                 // correct. It would be wrong in both directions.
139                 if (mayHaveTypeCheck(edge.useKind())
140                     && (state.forNode(edge).m_type & ~typeFilterFor(edge.useKind()))) {
141                     result = Exits;
142                     return;
143                 }
144             } else {
145                 // FIXME: Maybe this should call mayHaveTypeCheck(edge.useKind()) instead.
146                 // https://bugs.webkit.org/show_bug.cgi?id=148545
147                 if (edge.willHaveCheck()) {
148                     result = Exits;
149                     return;
150                 }
151             }
152             
153             switch (edge.useKind()) {
154             // These are shady because nodes that have these use kinds will typically exit for
155             // unrelated reasons. For example CompareEq doesn't usually exit, but if it uses
156             // ObjectUse then it will.
157             case ObjectUse:
158             case ObjectOrOtherUse:
159                 result = Exits;
160                 break;
161                 
162             // These are shady because they check the structure even if the type of the child node
163             // passes the StringObject type filter.
164             case StringObjectUse:
165             case StringOrStringObjectUse:
166                 result = Exits;
167                 break;
168                 
169             default:
170                 break;
171             }
172         });
173
174     return result;
175 }
176
177 } // anonymous namespace
178
179 ExitMode mayExit(Graph& graph, Node* node)
180 {
181     NullAbstractState state;
182     return mayExitImpl(graph, node, state);
183 }
184
185 ExitMode mayExit(Graph& graph, Node* node, AtTailAbstractState& state)
186 {
187     return mayExitImpl(graph, node, state);
188 }
189
190 } } // namespace JSC::DFG
191
192 namespace WTF {
193
194 using namespace JSC::DFG;
195
196 void printInternal(PrintStream& out, ExitMode mode)
197 {
198     switch (mode) {
199     case DoesNotExit:
200         out.print("DoesNotExit");
201         return;
202     case ExitsForExceptions:
203         out.print("ExitsForExceptions");
204         return;
205     case Exits:
206         out.print("Exits");
207         return;
208     }
209     RELEASE_ASSERT_NOT_REACHED();
210 }
211
212 } // namespace WTF
213
214 #endif // ENABLE(DFG_JIT)