source: webkit/trunk/Source/JavaScriptCore/dfg/DFGMayExit.cpp

Last change on this file was 285525, checked in by [email protected], 4 years ago

When inlining NewSymbol in the DFG don't universally call ToString on the input
https://bugs.webkit.org/show_bug.cgi?id=232754

Reviewed by Robin Morisset.

JSTests:

  • stress/inline-new-symbol-dfg-undefined-first-arg.js: Added.

(assert):
(foo):

Source/JavaScriptCore:

When inlining Symbol(x) in the DFG, we were always calling ToString on x.
However, this is wrong spec wise. If x is undefined, the symbol should
produce a description value of undefined, but calling ToString on x was causing
us to produce a description with the string "undefined".

  • dfg/DFGAbstractInterpreterInlines.h:

(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):

  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::handleConstantInternalFunction):

  • dfg/DFGClobberize.h:

(JSC::DFG::clobberize):

  • dfg/DFGClobbersExitState.cpp:

(JSC::DFG::clobbersExitState):

  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGMayExit.cpp:
  • dfg/DFGNodeType.h:
  • dfg/DFGOperations.cpp:

(JSC::DFG::JSC_DEFINE_JIT_OPERATION):

  • dfg/DFGOperations.h:
  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileNewSymbol):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::compileNewSymbol):

File size: 6.9 KB
Line 
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 "DFGNode.h"
33#include "DFGNullAbstractState.h"
34#include "JSCJSValueInlines.h"
35
36namespace JSC { namespace DFG {
37
38namespace {
39
40template<typename StateType>
41ExitMode mayExitImpl(Graph& graph, Node* node, StateType& state)
42{
43 ExitMode result = DoesNotExit;
44
45 switch (node->op()) {
46 // This is a carefully curated list of nodes that definitely do not exit. We try to be very
47 // conservative when maintaining this list, because adding new node types to it doesn't
48 // generally make things a lot better but it might introduce subtle bugs.
49 case SetArgumentDefinitely:
50 case SetArgumentMaybe:
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 CheckVarargs:
62 case Identity:
63 case IdentityWithProfile:
64 case GetLocal:
65 case LoopHint:
66 case Phi:
67 case Upsilon:
68 case ExitOK:
69 case BottomValue:
70 case PutHint:
71 case PhantomNewObject:
72 case PhantomNewInternalFieldObject:
73 case PutStack:
74 case KillStack:
75 case GetStack:
76 case GetCallee:
77 case SetCallee:
78 case GetArgumentCountIncludingThis:
79 case SetArgumentCountIncludingThis:
80 case GetRestLength:
81 case GetScope:
82 case PhantomLocal:
83 case CountExecution:
84 case SuperSamplerBegin:
85 case SuperSamplerEnd:
86 case Jump:
87 case EntrySwitch:
88 case Branch:
89 case Unreachable:
90 case DoubleRep:
91 case Int52Rep:
92 case ValueRep:
93 case ExtractOSREntryLocal:
94 case ExtractCatchLocal:
95 case ClearCatchLocals:
96 case ToBoolean:
97 case LogicalNot:
98 case NotifyWrite:
99 case PutStructure:
100 case StoreBarrier:
101 case FencedStoreBarrier:
102 case PutByOffset:
103 case PutClosureVar:
104 case PutInternalField:
105 case RecordRegExpCachedResult:
106 case NukeStructureAndSetButterfly:
107 case FilterCallLinkStatus:
108 case FilterGetByStatus:
109 case FilterPutByStatus:
110 case FilterInByStatus:
111 case FilterDeleteByStatus:
112 case FilterCheckPrivateBrandStatus:
113 case FilterSetPrivateBrandStatus:
114 case EnumeratorNextExtractMode:
115 case EnumeratorNextExtractIndex:
116 break;
117
118 case EnumeratorNextUpdatePropertyName:
119 case StrCat:
120 case Call:
121 case Construct:
122 case CallVarargs:
123 case CallEval:
124 case ConstructVarargs:
125 case CallForwardVarargs:
126 case ConstructForwardVarargs:
127 case CreateActivation:
128 case MaterializeCreateActivation:
129 case MaterializeNewObject:
130 case MaterializeNewInternalFieldObject:
131 case NewFunction:
132 case NewGeneratorFunction:
133 case NewAsyncFunction:
134 case NewAsyncGeneratorFunction:
135 case NewStringObject:
136 case NewInternalFieldObject:
137 case NewRegexp:
138 case ToNumber:
139 case ToNumeric:
140 case ToObject:
141 case RegExpExecNonGlobalOrSticky:
142 case RegExpMatchFastGlobal:
143 result = ExitsForExceptions;
144 break;
145
146 case SetRegExpObjectLastIndex:
147 if (node->ignoreLastIndexIsWritable())
148 break;
149 return Exits;
150
151 default:
152 // If in doubt, return true.
153 return Exits;
154 }
155
156 graph.doToChildren(
157 node,
158 [&] (Edge& edge) {
159 if (state) {
160 // Ignore the Check flag on the edge. This is important because that flag answers
161 // the question: "would this edge have had a check if it executed wherever it
162 // currently resides in control flow?" But when a state is passed, we want to ask a
163 // different question: "would this edge have a check if it executed wherever this
164 // state is?" Using the Check flag for this purpose wouldn't even be conservatively
165 // correct. It would be wrong in both directions.
166 if (mayHaveTypeCheck(edge.useKind())
167 && (state.forNode(edge).m_type & ~typeFilterFor(edge.useKind()))) {
168 result = Exits;
169 return;
170 }
171 } else {
172 // FIXME: Maybe this should call mayHaveTypeCheck(edge.useKind()) instead.
173 // https://bugs.webkit.org/show_bug.cgi?id=148545
174 if (edge.willHaveCheck()) {
175 result = Exits;
176 return;
177 }
178 }
179
180 switch (edge.useKind()) {
181 // These are shady because nodes that have these use kinds will typically exit for
182 // unrelated reasons. For example CompareEq doesn't usually exit, but if it uses
183 // ObjectUse then it will.
184 case ObjectUse:
185 case ObjectOrOtherUse:
186 result = Exits;
187 break;
188
189 default:
190 break;
191 }
192 });
193
194 return result;
195}
196
197} // anonymous namespace
198
199ExitMode mayExit(Graph& graph, Node* node)
200{
201 NullAbstractState state;
202 return mayExitImpl(graph, node, state);
203}
204
205ExitMode mayExit(Graph& graph, Node* node, AtTailAbstractState& state)
206{
207 return mayExitImpl(graph, node, state);
208}
209
210} } // namespace JSC::DFG
211
212namespace WTF {
213
214using namespace JSC::DFG;
215
216void printInternal(PrintStream& out, ExitMode mode)
217{
218 switch (mode) {
219 case DoesNotExit:
220 out.print("DoesNotExit");
221 return;
222 case ExitsForExceptions:
223 out.print("ExitsForExceptions");
224 return;
225 case Exits:
226 out.print("Exits");
227 return;
228 }
229 RELEASE_ASSERT_NOT_REACHED();
230}
231
232} // namespace WTF
233
234#endif // ENABLE(DFG_JIT)
Note: See TracBrowser for help on using the repository browser.