ToString node actually does GC.
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGDoesGC.cpp
1 /*
2  * Copyright (C) 2014-2019 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 ArithBitNot:
71     case ArithBitAnd:
72     case ArithBitOr:
73     case ArithBitXor:
74     case BitLShift:
75     case BitRShift:
76     case BitURShift:
77     case ValueToInt32:
78     case UInt32ToNumber:
79     case DoubleAsInt32:
80     case ArithAdd:
81     case ArithClz32:
82     case ArithSub:
83     case ArithNegate:
84     case ArithMul:
85     case ArithIMul:
86     case ArithDiv:
87     case ArithMod:
88     case ArithAbs:
89     case ArithMin:
90     case ArithMax:
91     case ArithPow:
92     case ArithSqrt:
93     case ArithRandom:
94     case ArithRound:
95     case ArithFloor:
96     case ArithCeil:
97     case ArithTrunc:
98     case ArithFRound:
99     case ArithUnary:
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 IsUndefinedOrNull:
182     case IsBoolean:
183     case IsNumber:
184     case NumberIsInteger:
185     case IsObject:
186     case IsObjectOrNull:
187     case IsFunction:
188     case IsCellWithType:
189     case IsTypedArrayView:
190     case TypeOf:
191     case LogicalNot:
192     case ToPrimitive:
193     case ToNumber:
194     case NumberToStringWithRadix:
195     case NumberToStringWithValidRadixConstant:
196     case InByVal:
197     case InById:
198     case HasOwnProperty:
199     case Jump:
200     case Branch:
201     case Switch:
202     case EntrySwitch:
203     case Return:
204     case TailCall:
205     case DirectTailCall:
206     case TailCallVarargs:
207     case Throw:
208     case CountExecution:
209     case SuperSamplerBegin:
210     case SuperSamplerEnd:
211     case ForceOSRExit:
212     case CPUIntrinsic:
213     case CheckTraps:
214     case StringFromCharCode:
215     case NormalizeMapKey:
216     case GetMapBucket:
217     case GetMapBucketHead:
218     case GetMapBucketNext:
219     case LoadKeyFromMapBucket:
220     case LoadValueFromMapBucket:
221     case ExtractValueFromWeakMapGet:
222     case WeakMapGet:
223     case WeakSetAdd:
224     case WeakMapSet:
225     case Unreachable:
226     case ExtractOSREntryLocal:
227     case ExtractCatchLocal:
228     case ClearCatchLocals:
229     case CheckTierUpInLoop:
230     case CheckTierUpAtReturn:
231     case CheckTierUpAndOSREnter:
232     case LoopHint:
233     case StoreBarrier:
234     case FencedStoreBarrier:
235     case InvalidationPoint:
236     case NotifyWrite:
237     case CheckInBounds:
238     case ConstantStoragePointer:
239     case Check:
240     case CheckVarargs:
241     case CheckTypeInfoFlags:
242     case MultiGetByOffset:
243     case ValueRep:
244     case DoubleRep:
245     case Int52Rep:
246     case GetGetter:
247     case GetSetter:
248     case GetByVal:
249     case GetByValWithThis:
250     case GetArrayLength:
251     case GetVectorLength:
252     case ArrayPush:
253     case ArrayPop:
254     case StringCharAt:
255     case StringCharCodeAt:
256     case GetTypedArrayByteOffset:
257     case GetPrototypeOf:
258     case PutByValDirect:
259     case PutByVal:
260     case PutByValAlias:
261     case PutStructure:
262     case GetByOffset:
263     case GetGetterSetterByOffset:
264     case PutByOffset:
265     case GetEnumerableLength:
266     case HasGenericProperty:
267     case HasStructureProperty:
268     case HasIndexedProperty:
269     case GetDirectPname:
270     case FiatInt52:
271     case BooleanToNumber:
272     case CheckBadCell:
273     case BottomValue:
274     case PhantomNewObject:
275     case PhantomNewFunction:
276     case PhantomNewGeneratorFunction:
277     case PhantomNewAsyncFunction:
278     case PhantomNewAsyncGeneratorFunction:
279     case PhantomCreateActivation:
280     case PhantomDirectArguments:
281     case PhantomCreateRest:
282     case PhantomNewArrayWithSpread:
283     case PhantomNewArrayBuffer:
284     case PhantomSpread:
285     case PhantomClonedArguments:
286     case PhantomNewRegexp:
287     case GetMyArgumentByVal:
288     case GetMyArgumentByValOutOfBounds:
289     case ForwardVarargs:
290     case PutHint:
291     case PutStack:
292     case KillStack:
293     case GetStack:
294     case GetFromArguments:
295     case PutToArguments:
296     case GetArgument:
297     case LogShadowChickenPrologue:
298     case LogShadowChickenTail:
299     case GetDynamicVar:
300     case PutDynamicVar:
301     case ResolveScopeForHoistingFuncDeclInEval:
302     case ResolveScope:
303     case NukeStructureAndSetButterfly:
304     case AtomicsAdd:
305     case AtomicsAnd:
306     case AtomicsCompareExchange:
307     case AtomicsExchange:
308     case AtomicsLoad:
309     case AtomicsOr:
310     case AtomicsStore:
311     case AtomicsSub:
312     case AtomicsXor:
313     case AtomicsIsLockFree:
314     case MatchStructure:
315     case FilterCallLinkStatus:
316     case FilterGetByIdStatus:
317     case FilterPutByIdStatus:
318     case FilterInByIdStatus:
319     case DataViewGetInt:
320     case DataViewGetFloat:
321     case DataViewSet:
322         return false;
323
324     case PushWithScope:
325     case CreateActivation:
326     case CreateDirectArguments:
327     case CreateScopedArguments:
328     case CreateClonedArguments:
329     case CallObjectConstructor:
330     case ToObject:
331     case ToThis:
332     case CreateThis:
333     case ObjectCreate:
334     case ObjectKeys:
335     case AllocatePropertyStorage:
336     case ReallocatePropertyStorage:
337     case Arrayify:
338     case ArrayifyToStructure:
339     case NewObject:
340     case NewArray:
341     case NewArrayWithSpread:
342     case Spread:
343     case NewArrayWithSize:
344     case NewArrayBuffer:
345     case NewRegexp:
346     case NewStringObject:
347     case NewSymbol:
348     case MakeRope:
349     case NewFunction:
350     case NewGeneratorFunction:
351     case NewAsyncGeneratorFunction:
352     case NewAsyncFunction:
353     case NewTypedArray:
354     case ThrowStaticError:
355     case GetPropertyEnumerator:
356     case GetEnumeratorStructurePname:
357     case GetEnumeratorGenericPname:
358     case ToIndexString:
359     case MaterializeNewObject:
360     case MaterializeCreateActivation:
361     case SetFunctionName:
362     case StrCat:
363     case StringReplace:
364     case StringReplaceRegExp:
365     case StringSlice:
366     case StringValueOf:
367     case CreateRest:
368     case ToLowerCase:
369     case CallDOMGetter:
370     case CallDOM:
371     case ArraySlice:
372     case ArrayIndexOf:
373     case ParseInt: // We might resolve a rope even though we don't clobber anything.
374     case SetAdd:
375     case MapSet:
376     case ValueBitAnd:
377     case ValueBitOr:
378     case ValueBitXor:
379     case ValueAdd:
380     case ValueSub:
381     case ValueMul:
382     case ValueDiv:
383         return true;
384
385     case CallStringConstructor:
386     case ToString:
387         switch (node->child1().useKind()) {
388         case StringObjectUse:
389         case StringOrStringObjectUse:
390             return false;
391         default:
392             break;
393         }
394         return true;
395
396     case GetIndexedPropertyStorage:
397         if (node->arrayMode().type() == Array::String)
398             return true;
399         return false;
400
401     case MapHash:
402         switch (node->child1().useKind()) {
403         case BooleanUse:
404         case Int32Use:
405         case SymbolUse:
406         case ObjectUse:
407             return false;
408         default:
409             // We might resolve a rope.
410             return true;
411         }
412         
413     case MultiPutByOffset:
414         return node->multiPutByOffsetData().reallocatesStorage();
415
416     case LastNodeType:
417         RELEASE_ASSERT_NOT_REACHED();
418         return true;
419     }
420     
421     RELEASE_ASSERT_NOT_REACHED();
422     return true;
423 }
424
425 } } // namespace JSC::DFG
426
427 #endif // ENABLE(DFG_JIT)