We should support CreateThis in the FTL
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGDoesGC.cpp
1 /*
2  * Copyright (C) 2014-2017 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 "DFGDoesGC.h"
28
29 #if ENABLE(DFG_JIT)
30
31 #include "DFGClobberize.h"
32 #include "DFGGraph.h"
33 #include "DFGNode.h"
34 #include "Operations.h"
35
36 namespace JSC { namespace DFG {
37
38 bool doesGC(Graph& graph, Node* node)
39 {
40     if (clobbersHeap(graph, node))
41         return true;
42     
43     // Now consider nodes that don't clobber the world but that still may GC. This includes all
44     // nodes. By convention we put world-clobbering nodes in the block of "false" cases but we can
45     // put them anywhere.
46     switch (node->op()) {
47     case JSConstant:
48     case DoubleConstant:
49     case Int52Constant:
50     case LazyJSConstant:
51     case Identity:
52     case IdentityWithProfile:
53     case GetCallee:
54     case SetCallee:
55     case GetArgumentCountIncludingThis:
56     case SetArgumentCountIncludingThis:
57     case GetRestLength:
58     case GetLocal:
59     case SetLocal:
60     case MovHint:
61     case InitializeEntrypointArguments:
62     case ZombieHint:
63     case ExitOK:
64     case Phantom:
65     case Upsilon:
66     case Phi:
67     case Flush:
68     case PhantomLocal:
69     case SetArgument:
70     case BitAnd:
71     case BitOr:
72     case BitXor:
73     case BitLShift:
74     case BitRShift:
75     case BitURShift:
76     case ValueToInt32:
77     case UInt32ToNumber:
78     case DoubleAsInt32:
79     case ArithAdd:
80     case ArithClz32:
81     case ArithSub:
82     case ArithNegate:
83     case ArithMul:
84     case ArithIMul:
85     case ArithDiv:
86     case ArithMod:
87     case ArithAbs:
88     case ArithMin:
89     case ArithMax:
90     case ArithPow:
91     case ArithSqrt:
92     case ArithRandom:
93     case ArithRound:
94     case ArithFloor:
95     case ArithCeil:
96     case ArithTrunc:
97     case ArithFRound:
98     case ArithUnary:
99     case ValueAdd:
100     case ValueNegate:
101     case TryGetById:
102     case GetById:
103     case GetByIdFlush:
104     case GetByIdWithThis:
105     case GetByIdDirect:
106     case GetByIdDirectFlush:
107     case PutById:
108     case PutByIdFlush:
109     case PutByIdWithThis:
110     case PutByValWithThis:
111     case PutByIdDirect:
112     case PutGetterById:
113     case PutSetterById:
114     case PutGetterSetterById:
115     case PutGetterByVal:
116     case PutSetterByVal:
117     case DefineDataProperty:
118     case DefineAccessorProperty:
119     case DeleteById:
120     case DeleteByVal:
121     case CheckStructure:
122     case CheckStructureOrEmpty:
123     case CheckStructureImmediate:
124     case GetExecutable:
125     case GetButterfly:
126     case CheckSubClass:
127     case CheckArray:
128     case GetScope:
129     case SkipScope:
130     case GetGlobalObject:
131     case GetGlobalThis:
132     case GetClosureVar:
133     case PutClosureVar:
134     case GetRegExpObjectLastIndex:
135     case SetRegExpObjectLastIndex:
136     case RecordRegExpCachedResult:
137     case GetGlobalVar:
138     case GetGlobalLexicalVariable:
139     case PutGlobalVariable:
140     case CheckCell:
141     case CheckNotEmpty:
142     case AssertNotEmpty:
143     case CheckStringIdent:
144     case RegExpExec:
145     case RegExpExecNonGlobalOrSticky:
146     case RegExpTest:
147     case RegExpMatchFast:
148     case RegExpMatchFastGlobal:
149     case CompareLess:
150     case CompareLessEq:
151     case CompareGreater:
152     case CompareGreaterEq:
153     case CompareBelow:
154     case CompareBelowEq:
155     case CompareEq:
156     case CompareStrictEq:
157     case CompareEqPtr:
158     case SameValue:
159     case Call:
160     case DirectCall:
161     case TailCallInlinedCaller:
162     case DirectTailCallInlinedCaller:
163     case Construct:
164     case DirectConstruct:
165     case CallVarargs:
166     case CallEval:
167     case TailCallVarargsInlinedCaller:
168     case ConstructVarargs:
169     case LoadVarargs:
170     case CallForwardVarargs:
171     case ConstructForwardVarargs:
172     case TailCallForwardVarargs:
173     case TailCallForwardVarargsInlinedCaller:
174     case ProfileType:
175     case ProfileControlFlow:
176     case OverridesHasInstance:
177     case InstanceOf:
178     case InstanceOfCustom:
179     case IsEmpty:
180     case IsUndefined:
181     case IsBoolean:
182     case IsNumber:
183     case NumberIsInteger:
184     case IsObject:
185     case IsObjectOrNull:
186     case IsFunction:
187     case IsCellWithType:
188     case IsTypedArrayView:
189     case TypeOf:
190     case LogicalNot:
191     case ToPrimitive:
192     case ToNumber:
193     case ToString:
194     case CallStringConstructor:
195     case NumberToStringWithRadix:
196     case NumberToStringWithValidRadixConstant:
197     case InByVal:
198     case InById:
199     case HasOwnProperty:
200     case Jump:
201     case Branch:
202     case Switch:
203     case EntrySwitch:
204     case Return:
205     case TailCall:
206     case DirectTailCall:
207     case TailCallVarargs:
208     case Throw:
209     case CountExecution:
210     case SuperSamplerBegin:
211     case SuperSamplerEnd:
212     case ForceOSRExit:
213     case CPUIntrinsic:
214     case CheckTraps:
215     case StringFromCharCode:
216     case NormalizeMapKey:
217     case GetMapBucket:
218     case GetMapBucketHead:
219     case GetMapBucketNext:
220     case LoadKeyFromMapBucket:
221     case LoadValueFromMapBucket:
222     case ExtractValueFromWeakMapGet:
223     case WeakMapGet:
224     case WeakSetAdd:
225     case WeakMapSet:
226     case Unreachable:
227     case ExtractOSREntryLocal:
228     case ExtractCatchLocal:
229     case ClearCatchLocals:
230     case CheckTierUpInLoop:
231     case CheckTierUpAtReturn:
232     case CheckTierUpAndOSREnter:
233     case LoopHint:
234     case StoreBarrier:
235     case FencedStoreBarrier:
236     case InvalidationPoint:
237     case NotifyWrite:
238     case CheckInBounds:
239     case ConstantStoragePointer:
240     case Check:
241     case CheckVarargs:
242     case CheckTypeInfoFlags:
243     case MultiGetByOffset:
244     case ValueRep:
245     case DoubleRep:
246     case Int52Rep:
247     case GetGetter:
248     case GetSetter:
249     case GetByVal:
250     case GetByValWithThis:
251     case GetIndexedPropertyStorage:
252     case GetArrayLength:
253     case GetVectorLength:
254     case ArrayPush:
255     case ArrayPop:
256     case StringCharAt:
257     case StringCharCodeAt:
258     case GetTypedArrayByteOffset:
259     case GetPrototypeOf:
260     case PutByValDirect:
261     case PutByVal:
262     case PutByValAlias:
263     case PutStructure:
264     case GetByOffset:
265     case GetGetterSetterByOffset:
266     case PutByOffset:
267     case GetEnumerableLength:
268     case HasGenericProperty:
269     case HasStructureProperty:
270     case HasIndexedProperty:
271     case GetDirectPname:
272     case FiatInt52:
273     case BooleanToNumber:
274     case CheckBadCell:
275     case BottomValue:
276     case PhantomNewObject:
277     case PhantomNewFunction:
278     case PhantomNewGeneratorFunction:
279     case PhantomNewAsyncFunction:
280     case PhantomNewAsyncGeneratorFunction:
281     case PhantomCreateActivation:
282     case PhantomDirectArguments:
283     case PhantomCreateRest:
284     case PhantomNewArrayWithSpread:
285     case PhantomNewArrayBuffer:
286     case PhantomSpread:
287     case PhantomClonedArguments:
288     case PhantomNewRegexp:
289     case GetMyArgumentByVal:
290     case GetMyArgumentByValOutOfBounds:
291     case ForwardVarargs:
292     case PutHint:
293     case PutStack:
294     case KillStack:
295     case GetStack:
296     case GetFromArguments:
297     case PutToArguments:
298     case GetArgument:
299     case LogShadowChickenPrologue:
300     case LogShadowChickenTail:
301     case GetDynamicVar:
302     case PutDynamicVar:
303     case ResolveScopeForHoistingFuncDeclInEval:
304     case ResolveScope:
305     case NukeStructureAndSetButterfly:
306     case AtomicsAdd:
307     case AtomicsAnd:
308     case AtomicsCompareExchange:
309     case AtomicsExchange:
310     case AtomicsLoad:
311     case AtomicsOr:
312     case AtomicsStore:
313     case AtomicsSub:
314     case AtomicsXor:
315     case AtomicsIsLockFree:
316     case MatchStructure:
317     case FilterCallLinkStatus:
318     case FilterGetByIdStatus:
319     case FilterPutByIdStatus:
320     case FilterInByIdStatus:
321         return false;
322
323     case PushWithScope:
324     case CreateActivation:
325     case CreateDirectArguments:
326     case CreateScopedArguments:
327     case CreateClonedArguments:
328     case CallObjectConstructor:
329     case ToObject:
330     case ToThis:
331     case CreateThis:
332     case ObjectCreate:
333     case AllocatePropertyStorage:
334     case ReallocatePropertyStorage:
335     case Arrayify:
336     case ArrayifyToStructure:
337     case NewObject:
338     case NewArray:
339     case NewArrayWithSpread:
340     case Spread:
341     case NewArrayWithSize:
342     case NewArrayBuffer:
343     case NewRegexp:
344     case NewStringObject:
345     case MakeRope:
346     case NewFunction:
347     case NewGeneratorFunction:
348     case NewAsyncGeneratorFunction:
349     case NewAsyncFunction:
350     case NewTypedArray:
351     case ThrowStaticError:
352     case GetPropertyEnumerator:
353     case GetEnumeratorStructurePname:
354     case GetEnumeratorGenericPname:
355     case ToIndexString:
356     case MaterializeNewObject:
357     case MaterializeCreateActivation:
358     case SetFunctionName:
359     case StrCat:
360     case StringReplace:
361     case StringReplaceRegExp:
362     case StringSlice:
363     case CreateRest:
364     case ToLowerCase:
365     case CallDOMGetter:
366     case CallDOM:
367     case ArraySlice:
368     case ArrayIndexOf:
369     case ParseInt: // We might resolve a rope even though we don't clobber anything.
370     case SetAdd:
371     case MapSet:
372         return true;
373
374     case MapHash:
375         switch (node->child1().useKind()) {
376         case BooleanUse:
377         case Int32Use:
378         case SymbolUse:
379         case ObjectUse:
380             return false;
381         default:
382             // We might resolve a rope.
383             return true;
384         }
385         
386     case MultiPutByOffset:
387         return node->multiPutByOffsetData().reallocatesStorage();
388
389     case LastNodeType:
390         RELEASE_ASSERT_NOT_REACHED();
391         return true;
392     }
393     
394     RELEASE_ASSERT_NOT_REACHED();
395     return true;
396 }
397
398 } } // namespace JSC::DFG
399
400 #endif // ENABLE(DFG_JIT)