We should support CreateThis in the FTL
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGClobbersExitState.cpp
1 /*
2  * Copyright (C) 2015 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 "DFGClobbersExitState.h"
28
29 #if ENABLE(DFG_JIT)
30
31 #include "DFGClobberize.h"
32 #include "DFGGraph.h"
33 #include "DFGNode.h"
34 #include "JSCInlines.h"
35
36 namespace JSC { namespace DFG {
37
38 bool clobbersExitState(Graph& graph, Node* node)
39 {
40     // There are certain nodes whose effect on the exit state has nothing to do with what they
41     // normally clobber.
42     switch (node->op()) {
43     case InitializeEntrypointArguments:
44     case MovHint:
45     case ZombieHint:
46     case PutHint:
47     case KillStack:
48         return true;
49
50     case SetLocal:
51     case PutStack:
52         // These nodes write to the stack, but they may only do so after we have already had a MovHint
53         // for the exact same value and the same stack location. Hence, they have no further effect on
54         // exit state.
55         return false;
56
57     case ArrayifyToStructure:
58     case Arrayify:
59     case NewObject:
60     case NewRegexp:
61     case NewStringObject:
62     case PhantomNewObject:
63     case MaterializeNewObject:
64     case PhantomNewFunction:
65     case PhantomNewGeneratorFunction:
66     case PhantomNewAsyncGeneratorFunction:
67     case PhantomNewAsyncFunction:
68     case PhantomCreateActivation:
69     case MaterializeCreateActivation:
70     case PhantomNewRegexp:
71     case CountExecution:
72     case SuperSamplerBegin:
73     case SuperSamplerEnd:
74     case StoreBarrier:
75     case FencedStoreBarrier:
76     case AllocatePropertyStorage:
77     case ReallocatePropertyStorage:
78     case FilterCallLinkStatus:
79     case FilterGetByIdStatus:
80     case FilterPutByIdStatus:
81     case FilterInByIdStatus:
82         // These do clobber memory, but nothing that is observable. It may be nice to separate the
83         // heaps into those that are observable and those that aren't, but we don't do that right now.
84         // FIXME: https://bugs.webkit.org/show_bug.cgi?id=148440
85         return false;
86
87     case CreateActivation:
88         // Like above, but with the activation allocation caveat.
89         return node->castOperand<SymbolTable*>()->singletonScope()->isStillValid();
90
91     case NewFunction:
92     case NewGeneratorFunction:
93     case NewAsyncGeneratorFunction:
94     case NewAsyncFunction:
95         // Like above, but with the JSFunction allocation caveat.
96         return node->castOperand<FunctionExecutable*>()->singletonFunction()->isStillValid();
97
98     default:
99         // For all other nodes, we just care about whether they write to something other than SideState.
100         bool result = false;
101         clobberize(
102             graph, node, NoOpClobberize(),
103             [&] (const AbstractHeap& heap) {
104                 // There shouldn't be such a thing as a strict subtype of SideState. That's what allows
105                 // us to use a fast != check, below.
106                 ASSERT(!heap.isStrictSubtypeOf(SideState));
107
108                 if (heap != SideState)
109                     result = true;
110             },
111             NoOpClobberize());
112         return result;
113     }
114 }
115
116 } } // namespace JSC::DFG
117
118 #endif // ENABLE(DFG_JIT)