GetIndexedPropertyStorage can GC.
[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 ArithBitAnd:
71     case ArithBitOr:
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 ValueBitAnd:
100     case ValueBitOr:
101     case ValueAdd:
102     case ValueNegate:
103     case TryGetById:
104     case GetById:
105     case GetByIdFlush:
106     case GetByIdWithThis:
107     case GetByIdDirect:
108     case GetByIdDirectFlush:
109     case PutById:
110     case PutByIdFlush:
111     case PutByIdWithThis:
112     case PutByValWithThis:
113     case PutByIdDirect:
114     case PutGetterById:
115     case PutSetterById:
116     case PutGetterSetterById:
117     case PutGetterByVal:
118     case PutSetterByVal:
119     case DefineDataProperty:
120     case DefineAccessorProperty:
121     case DeleteById:
122     case DeleteByVal:
123     case CheckStructure:
124     case CheckStructureOrEmpty:
125     case CheckStructureImmediate:
126     case GetExecutable:
127     case GetButterfly:
128     case CheckSubClass:
129     case CheckArray:
130     case GetScope:
131     case SkipScope:
132     case GetGlobalObject:
133     case GetGlobalThis:
134     case GetClosureVar:
135     case PutClosureVar:
136     case GetRegExpObjectLastIndex:
137     case SetRegExpObjectLastIndex:
138     case RecordRegExpCachedResult:
139     case GetGlobalVar:
140     case GetGlobalLexicalVariable:
141     case PutGlobalVariable:
142     case CheckCell:
143     case CheckNotEmpty:
144     case AssertNotEmpty:
145     case CheckStringIdent:
146     case RegExpExec:
147     case RegExpExecNonGlobalOrSticky:
148     case RegExpTest:
149     case RegExpMatchFast:
150     case RegExpMatchFastGlobal:
151     case CompareLess:
152     case CompareLessEq:
153     case CompareGreater:
154     case CompareGreaterEq:
155     case CompareBelow:
156     case CompareBelowEq:
157     case CompareEq:
158     case CompareStrictEq:
159     case CompareEqPtr:
160     case SameValue:
161     case Call:
162     case DirectCall:
163     case TailCallInlinedCaller:
164     case DirectTailCallInlinedCaller:
165     case Construct:
166     case DirectConstruct:
167     case CallVarargs:
168     case CallEval:
169     case TailCallVarargsInlinedCaller:
170     case ConstructVarargs:
171     case LoadVarargs:
172     case CallForwardVarargs:
173     case ConstructForwardVarargs:
174     case TailCallForwardVarargs:
175     case TailCallForwardVarargsInlinedCaller:
176     case ProfileType:
177     case ProfileControlFlow:
178     case OverridesHasInstance:
179     case InstanceOf:
180     case InstanceOfCustom:
181     case IsEmpty:
182     case IsUndefined:
183     case IsBoolean:
184     case IsNumber:
185     case NumberIsInteger:
186     case IsObject:
187     case IsObjectOrNull:
188     case IsFunction:
189     case IsCellWithType:
190     case IsTypedArrayView:
191     case TypeOf:
192     case LogicalNot:
193     case ToPrimitive:
194     case ToNumber:
195     case ToString:
196     case CallStringConstructor:
197     case NumberToStringWithRadix:
198     case NumberToStringWithValidRadixConstant:
199     case InByVal:
200     case InById:
201     case HasOwnProperty:
202     case Jump:
203     case Branch:
204     case Switch:
205     case EntrySwitch:
206     case Return:
207     case TailCall:
208     case DirectTailCall:
209     case TailCallVarargs:
210     case Throw:
211     case CountExecution:
212     case SuperSamplerBegin:
213     case SuperSamplerEnd:
214     case ForceOSRExit:
215     case CPUIntrinsic:
216     case CheckTraps:
217     case StringFromCharCode:
218     case NormalizeMapKey:
219     case GetMapBucket:
220     case GetMapBucketHead:
221     case GetMapBucketNext:
222     case LoadKeyFromMapBucket:
223     case LoadValueFromMapBucket:
224     case ExtractValueFromWeakMapGet:
225     case WeakMapGet:
226     case WeakSetAdd:
227     case WeakMapSet:
228     case Unreachable:
229     case ExtractOSREntryLocal:
230     case ExtractCatchLocal:
231     case ClearCatchLocals:
232     case CheckTierUpInLoop:
233     case CheckTierUpAtReturn:
234     case CheckTierUpAndOSREnter:
235     case LoopHint:
236     case StoreBarrier:
237     case FencedStoreBarrier:
238     case InvalidationPoint:
239     case NotifyWrite:
240     case CheckInBounds:
241     case ConstantStoragePointer:
242     case Check:
243     case CheckVarargs:
244     case CheckTypeInfoFlags:
245     case MultiGetByOffset:
246     case ValueRep:
247     case DoubleRep:
248     case Int52Rep:
249     case GetGetter:
250     case GetSetter:
251     case GetByVal:
252     case GetByValWithThis:
253     case GetArrayLength:
254     case GetVectorLength:
255     case ArrayPush:
256     case ArrayPop:
257     case StringCharAt:
258     case StringCharCodeAt:
259     case GetTypedArrayByteOffset:
260     case GetPrototypeOf:
261     case PutByValDirect:
262     case PutByVal:
263     case PutByValAlias:
264     case PutStructure:
265     case GetByOffset:
266     case GetGetterSetterByOffset:
267     case PutByOffset:
268     case GetEnumerableLength:
269     case HasGenericProperty:
270     case HasStructureProperty:
271     case HasIndexedProperty:
272     case GetDirectPname:
273     case FiatInt52:
274     case BooleanToNumber:
275     case CheckBadCell:
276     case BottomValue:
277     case PhantomNewObject:
278     case PhantomNewFunction:
279     case PhantomNewGeneratorFunction:
280     case PhantomNewAsyncFunction:
281     case PhantomNewAsyncGeneratorFunction:
282     case PhantomCreateActivation:
283     case PhantomDirectArguments:
284     case PhantomCreateRest:
285     case PhantomNewArrayWithSpread:
286     case PhantomNewArrayBuffer:
287     case PhantomSpread:
288     case PhantomClonedArguments:
289     case PhantomNewRegexp:
290     case GetMyArgumentByVal:
291     case GetMyArgumentByValOutOfBounds:
292     case ForwardVarargs:
293     case PutHint:
294     case PutStack:
295     case KillStack:
296     case GetStack:
297     case GetFromArguments:
298     case PutToArguments:
299     case GetArgument:
300     case LogShadowChickenPrologue:
301     case LogShadowChickenTail:
302     case GetDynamicVar:
303     case PutDynamicVar:
304     case ResolveScopeForHoistingFuncDeclInEval:
305     case ResolveScope:
306     case NukeStructureAndSetButterfly:
307     case AtomicsAdd:
308     case AtomicsAnd:
309     case AtomicsCompareExchange:
310     case AtomicsExchange:
311     case AtomicsLoad:
312     case AtomicsOr:
313     case AtomicsStore:
314     case AtomicsSub:
315     case AtomicsXor:
316     case AtomicsIsLockFree:
317     case MatchStructure:
318     case FilterCallLinkStatus:
319     case FilterGetByIdStatus:
320     case FilterPutByIdStatus:
321     case FilterInByIdStatus:
322     case DataViewGetInt:
323     case DataViewGetFloat:
324     case DataViewSet:
325         return false;
326
327     case PushWithScope:
328     case CreateActivation:
329     case CreateDirectArguments:
330     case CreateScopedArguments:
331     case CreateClonedArguments:
332     case CallObjectConstructor:
333     case ToObject:
334     case ToThis:
335     case CreateThis:
336     case ObjectCreate:
337     case AllocatePropertyStorage:
338     case ReallocatePropertyStorage:
339     case Arrayify:
340     case ArrayifyToStructure:
341     case NewObject:
342     case NewArray:
343     case NewArrayWithSpread:
344     case Spread:
345     case NewArrayWithSize:
346     case NewArrayBuffer:
347     case NewRegexp:
348     case NewStringObject:
349     case MakeRope:
350     case NewFunction:
351     case NewGeneratorFunction:
352     case NewAsyncGeneratorFunction:
353     case NewAsyncFunction:
354     case NewTypedArray:
355     case ThrowStaticError:
356     case GetPropertyEnumerator:
357     case GetEnumeratorStructurePname:
358     case GetEnumeratorGenericPname:
359     case ToIndexString:
360     case MaterializeNewObject:
361     case MaterializeCreateActivation:
362     case SetFunctionName:
363     case StrCat:
364     case StringReplace:
365     case StringReplaceRegExp:
366     case StringSlice:
367     case StringValueOf:
368     case CreateRest:
369     case ToLowerCase:
370     case CallDOMGetter:
371     case CallDOM:
372     case ArraySlice:
373     case ArrayIndexOf:
374     case ParseInt: // We might resolve a rope even though we don't clobber anything.
375     case SetAdd:
376     case MapSet:
377         return true;
378
379     case GetIndexedPropertyStorage:
380         if (node->arrayMode().type() == Array::String)
381             return true;
382         return false;
383
384     case MapHash:
385         switch (node->child1().useKind()) {
386         case BooleanUse:
387         case Int32Use:
388         case SymbolUse:
389         case ObjectUse:
390             return false;
391         default:
392             // We might resolve a rope.
393             return true;
394         }
395         
396     case MultiPutByOffset:
397         return node->multiPutByOffsetData().reallocatesStorage();
398
399     case LastNodeType:
400         RELEASE_ASSERT_NOT_REACHED();
401         return true;
402     }
403     
404     RELEASE_ASSERT_NOT_REACHED();
405     return true;
406 }
407
408 } } // namespace JSC::DFG
409
410 #endif // ENABLE(DFG_JIT)