[JSC] Implement optimized WeakMap and WeakSet
[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 GetArgumentCountIncludingThis:
55     case GetRestLength:
56     case GetLocal:
57     case SetLocal:
58     case MovHint:
59     case InitializeEntrypointArguments:
60     case ZombieHint:
61     case ExitOK:
62     case Phantom:
63     case Upsilon:
64     case Phi:
65     case Flush:
66     case PhantomLocal:
67     case SetArgument:
68     case BitAnd:
69     case BitOr:
70     case BitXor:
71     case BitLShift:
72     case BitRShift:
73     case BitURShift:
74     case ValueToInt32:
75     case UInt32ToNumber:
76     case DoubleAsInt32:
77     case ArithAdd:
78     case ArithClz32:
79     case ArithSub:
80     case ArithNegate:
81     case ArithMul:
82     case ArithIMul:
83     case ArithDiv:
84     case ArithMod:
85     case ArithAbs:
86     case ArithMin:
87     case ArithMax:
88     case ArithPow:
89     case ArithSqrt:
90     case ArithRandom:
91     case ArithRound:
92     case ArithFloor:
93     case ArithCeil:
94     case ArithTrunc:
95     case ArithFRound:
96     case ArithUnary:
97     case ValueAdd:
98     case TryGetById:
99     case GetById:
100     case GetByIdFlush:
101     case GetByIdWithThis:
102     case PutById:
103     case PutByIdFlush:
104     case PutByIdWithThis:
105     case PutByValWithThis:
106     case PutByIdDirect:
107     case PutGetterById:
108     case PutSetterById:
109     case PutGetterSetterById:
110     case PutGetterByVal:
111     case PutSetterByVal:
112     case DefineDataProperty:
113     case DefineAccessorProperty:
114     case DeleteById:
115     case DeleteByVal:
116     case CheckStructure:
117     case CheckStructureOrEmpty:
118     case CheckStructureImmediate:
119     case GetExecutable:
120     case GetButterfly:
121     case CheckSubClass:
122     case CheckArray:
123     case GetScope:
124     case SkipScope:
125     case GetGlobalObject:
126     case GetGlobalThis:
127     case GetClosureVar:
128     case PutClosureVar:
129     case GetRegExpObjectLastIndex:
130     case SetRegExpObjectLastIndex:
131     case RecordRegExpCachedResult:
132     case GetGlobalVar:
133     case GetGlobalLexicalVariable:
134     case PutGlobalVariable:
135     case CheckCell:
136     case CheckNotEmpty:
137     case CheckStringIdent:
138     case RegExpExec:
139     case RegExpTest:
140     case CompareLess:
141     case CompareLessEq:
142     case CompareGreater:
143     case CompareGreaterEq:
144     case CompareBelow:
145     case CompareBelowEq:
146     case CompareEq:
147     case CompareStrictEq:
148     case CompareEqPtr:
149     case Call:
150     case DirectCall:
151     case TailCallInlinedCaller:
152     case DirectTailCallInlinedCaller:
153     case Construct:
154     case DirectConstruct:
155     case CallVarargs:
156     case CallEval:
157     case TailCallVarargsInlinedCaller:
158     case ConstructVarargs:
159     case LoadVarargs:
160     case CallForwardVarargs:
161     case ConstructForwardVarargs:
162     case TailCallForwardVarargs:
163     case TailCallForwardVarargsInlinedCaller:
164     case ProfileType:
165     case ProfileControlFlow:
166     case OverridesHasInstance:
167     case InstanceOf:
168     case InstanceOfCustom:
169     case IsEmpty:
170     case IsUndefined:
171     case IsBoolean:
172     case IsNumber:
173     case IsObject:
174     case IsObjectOrNull:
175     case IsFunction:
176     case IsCellWithType:
177     case IsTypedArrayView:
178     case TypeOf:
179     case LogicalNot:
180     case ToPrimitive:
181     case ToNumber:
182     case ToString:
183     case CallStringConstructor:
184     case NumberToStringWithRadix:
185     case NumberToStringWithValidRadixConstant:
186     case In:
187     case HasOwnProperty:
188     case Jump:
189     case Branch:
190     case Switch:
191     case EntrySwitch:
192     case Return:
193     case TailCall:
194     case DirectTailCall:
195     case TailCallVarargs:
196     case Throw:
197     case CountExecution:
198     case SuperSamplerBegin:
199     case SuperSamplerEnd:
200     case ForceOSRExit:
201     case CPUIntrinsic:
202     case CheckTraps:
203     case StringFromCharCode:
204     case MapHash:
205     case NormalizeMapKey:
206     case GetMapBucket:
207     case GetMapBucketHead:
208     case GetMapBucketNext:
209     case LoadKeyFromMapBucket:
210     case LoadValueFromMapBucket:
211     case ExtractValueFromWeakMapGet:
212     case WeakMapGet:
213     case Unreachable:
214     case ExtractCatchLocal:
215     case ExtractOSREntryLocal:
216     case CheckTierUpInLoop:
217     case CheckTierUpAtReturn:
218     case CheckTierUpAndOSREnter:
219     case LoopHint:
220     case StoreBarrier:
221     case FencedStoreBarrier:
222     case InvalidationPoint:
223     case NotifyWrite:
224     case CheckInBounds:
225     case ConstantStoragePointer:
226     case Check:
227     case CheckTypeInfoFlags:
228     case MultiGetByOffset:
229     case ValueRep:
230     case DoubleRep:
231     case Int52Rep:
232     case GetGetter:
233     case GetSetter:
234     case GetByVal:
235     case GetByValWithThis:
236     case GetIndexedPropertyStorage:
237     case GetArrayLength:
238     case GetVectorLength:
239     case ArrayPush:
240     case ArrayPop:
241     case StringCharAt:
242     case StringCharCodeAt:
243     case GetTypedArrayByteOffset:
244     case GetPrototypeOf:
245     case PutByValDirect:
246     case PutByVal:
247     case PutByValAlias:
248     case PutStructure:
249     case GetByOffset:
250     case GetGetterSetterByOffset:
251     case PutByOffset:
252     case GetEnumerableLength:
253     case HasGenericProperty:
254     case HasStructureProperty:
255     case HasIndexedProperty:
256     case GetDirectPname:
257     case FiatInt52:
258     case BooleanToNumber:
259     case CheckBadCell:
260     case BottomValue:
261     case PhantomNewObject:
262     case PhantomNewFunction:
263     case PhantomNewGeneratorFunction:
264     case PhantomNewAsyncFunction:
265     case PhantomNewAsyncGeneratorFunction:
266     case PhantomCreateActivation:
267     case PhantomDirectArguments:
268     case PhantomCreateRest:
269     case PhantomNewArrayWithSpread:
270     case PhantomSpread:
271     case PhantomClonedArguments:
272     case GetMyArgumentByVal:
273     case GetMyArgumentByValOutOfBounds:
274     case ForwardVarargs:
275     case PutHint:
276     case PutStack:
277     case KillStack:
278     case GetStack:
279     case GetFromArguments:
280     case PutToArguments:
281     case GetArgument:
282     case LogShadowChickenPrologue:
283     case LogShadowChickenTail:
284     case GetDynamicVar:
285     case PutDynamicVar:
286     case ResolveScopeForHoistingFuncDeclInEval:
287     case ResolveScope:
288     case NukeStructureAndSetButterfly:
289     case AtomicsAdd:
290     case AtomicsAnd:
291     case AtomicsCompareExchange:
292     case AtomicsExchange:
293     case AtomicsLoad:
294     case AtomicsOr:
295     case AtomicsStore:
296     case AtomicsSub:
297     case AtomicsXor:
298     case AtomicsIsLockFree:
299         return false;
300
301     case PushWithScope:
302     case CreateActivation:
303     case CreateDirectArguments:
304     case CreateScopedArguments:
305     case CreateClonedArguments:
306     case CallObjectConstructor:
307     case ToObject:
308     case ToThis:
309     case CreateThis:
310     case AllocatePropertyStorage:
311     case ReallocatePropertyStorage:
312     case Arrayify:
313     case ArrayifyToStructure:
314     case NewObject:
315     case NewArray:
316     case NewArrayWithSpread:
317     case Spread:
318     case NewArrayWithSize:
319     case NewArrayBuffer:
320     case NewRegexp:
321     case NewStringObject:
322     case MakeRope:
323     case NewFunction:
324     case NewGeneratorFunction:
325     case NewAsyncGeneratorFunction:
326     case NewAsyncFunction:
327     case NewTypedArray:
328     case ThrowStaticError:
329     case GetPropertyEnumerator:
330     case GetEnumeratorStructurePname:
331     case GetEnumeratorGenericPname:
332     case ToIndexString:
333     case MaterializeNewObject:
334     case MaterializeCreateActivation:
335     case SetFunctionName:
336     case StrCat:
337     case StringReplace:
338     case StringReplaceRegExp:
339     case StringSlice:
340     case CreateRest:
341     case ToLowerCase:
342     case CallDOMGetter:
343     case CallDOM:
344     case ArraySlice:
345     case ArrayIndexOf:
346     case ParseInt: // We might resolve a rope even though we don't clobber anything.
347     case SetAdd:
348     case MapSet:
349         return true;
350         
351     case MultiPutByOffset:
352         return node->multiPutByOffsetData().reallocatesStorage();
353
354     case LastNodeType:
355         RELEASE_ASSERT_NOT_REACHED();
356         return true;
357     }
358     
359     RELEASE_ASSERT_NOT_REACHED();
360     return true;
361 }
362
363 } } // namespace JSC::DFG
364
365 #endif // ENABLE(DFG_JIT)