dd4d06f5a66f3a3c218f89d18f4ca8597bca322d
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGCapabilities.h
1 /*
2  * Copyright (C) 2011-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 #pragma once
27
28 #include "CodeBlock.h"
29 #include "DFGCommon.h"
30 #include "Interpreter.h"
31 #include "Intrinsic.h"
32 #include "Options.h"
33
34 namespace JSC { namespace DFG {
35
36 #if ENABLE(DFG_JIT)
37 // Fast check functions; if they return true it is still necessary to
38 // check opcodes.
39 bool isSupported();
40 bool isSupportedForInlining(CodeBlock*);
41 bool mightCompileEval(CodeBlock*);
42 bool mightCompileProgram(CodeBlock*);
43 bool mightCompileFunctionForCall(CodeBlock*);
44 bool mightCompileFunctionForConstruct(CodeBlock*);
45 bool mightInlineFunctionForCall(CodeBlock*);
46 bool mightInlineFunctionForClosureCall(CodeBlock*);
47 bool mightInlineFunctionForConstruct(CodeBlock*);
48 bool canUseOSRExitFuzzing(CodeBlock*);
49
50 inline CapabilityLevel capabilityLevel(OpcodeID opcodeID, CodeBlock* codeBlock, Instruction* pc);
51
52 CapabilityLevel capabilityLevel(CodeBlock*);
53 #else // ENABLE(DFG_JIT)
54 inline bool mightCompileEval(CodeBlock*) { return false; }
55 inline bool mightCompileProgram(CodeBlock*) { return false; }
56 inline bool mightCompileFunctionForCall(CodeBlock*) { return false; }
57 inline bool mightCompileFunctionForConstruct(CodeBlock*) { return false; }
58 inline bool mightInlineFunctionForCall(CodeBlock*) { return false; }
59 inline bool mightInlineFunctionForClosureCall(CodeBlock*) { return false; }
60 inline bool mightInlineFunctionForConstruct(CodeBlock*) { return false; }
61 inline bool canUseOSRExitFuzzing(CodeBlock*) { return false; }
62
63 inline CapabilityLevel capabilityLevel(OpcodeID, CodeBlock*, Instruction*) { return CannotCompile; }
64 inline CapabilityLevel capabilityLevel(CodeBlock*) { return CannotCompile; }
65 #endif // ENABLE(DFG_JIT)
66
67 inline CapabilityLevel evalCapabilityLevel(CodeBlock* codeBlock)
68 {
69     if (!mightCompileEval(codeBlock))
70         return CannotCompile;
71     
72     return capabilityLevel(codeBlock);
73 }
74
75 inline CapabilityLevel programCapabilityLevel(CodeBlock* codeBlock)
76 {
77     if (!mightCompileProgram(codeBlock))
78         return CannotCompile;
79     
80     return capabilityLevel(codeBlock);
81 }
82
83 inline CapabilityLevel functionCapabilityLevel(bool mightCompile, bool mightInline, CapabilityLevel computedCapabilityLevel)
84 {
85     if (mightCompile && mightInline)
86         return leastUpperBound(CanCompileAndInline, computedCapabilityLevel);
87     if (mightCompile && !mightInline)
88         return leastUpperBound(CanCompile, computedCapabilityLevel);
89     if (!mightCompile)
90         return CannotCompile;
91     RELEASE_ASSERT_NOT_REACHED();
92     return CannotCompile;
93 }
94
95 inline CapabilityLevel functionForCallCapabilityLevel(CodeBlock* codeBlock)
96 {
97     return functionCapabilityLevel(
98         mightCompileFunctionForCall(codeBlock),
99         mightInlineFunctionForCall(codeBlock),
100         capabilityLevel(codeBlock));
101 }
102
103 inline CapabilityLevel functionForConstructCapabilityLevel(CodeBlock* codeBlock)
104 {
105     return functionCapabilityLevel(
106         mightCompileFunctionForConstruct(codeBlock),
107         mightInlineFunctionForConstruct(codeBlock),
108         capabilityLevel(codeBlock));
109 }
110
111 inline CapabilityLevel inlineFunctionForCallCapabilityLevel(CodeBlock* codeBlock)
112 {
113     if (!mightInlineFunctionForCall(codeBlock))
114         return CannotCompile;
115     
116     return capabilityLevel(codeBlock);
117 }
118
119 inline CapabilityLevel inlineFunctionForClosureCallCapabilityLevel(CodeBlock* codeBlock)
120 {
121     if (!mightInlineFunctionForClosureCall(codeBlock))
122         return CannotCompile;
123     
124     return capabilityLevel(codeBlock);
125 }
126
127 inline CapabilityLevel inlineFunctionForConstructCapabilityLevel(CodeBlock* codeBlock)
128 {
129     if (!mightInlineFunctionForConstruct(codeBlock))
130         return CannotCompile;
131     
132     return capabilityLevel(codeBlock);
133 }
134
135 inline bool mightInlineFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind kind)
136 {
137     if (kind == CodeForCall)
138         return mightInlineFunctionForCall(codeBlock);
139     ASSERT(kind == CodeForConstruct);
140     return mightInlineFunctionForConstruct(codeBlock);
141 }
142
143 inline bool mightCompileFunctionFor(CodeBlock* codeBlock, CodeSpecializationKind kind)
144 {
145     if (kind == CodeForCall)
146         return mightCompileFunctionForCall(codeBlock);
147     ASSERT(kind == CodeForConstruct);
148     return mightCompileFunctionForConstruct(codeBlock);
149 }
150
151 inline bool mightInlineFunction(CodeBlock* codeBlock)
152 {
153     return mightInlineFunctionFor(codeBlock, codeBlock->specializationKind());
154 }
155
156 inline CapabilityLevel inlineFunctionForCapabilityLevel(CodeBlock* codeBlock, CodeSpecializationKind kind, bool isClosureCall)
157 {
158     if (isClosureCall) {
159         if (kind != CodeForCall)
160             return CannotCompile;
161         return inlineFunctionForClosureCallCapabilityLevel(codeBlock);
162     }
163     if (kind == CodeForCall)
164         return inlineFunctionForCallCapabilityLevel(codeBlock);
165     ASSERT(kind == CodeForConstruct);
166     return inlineFunctionForConstructCapabilityLevel(codeBlock);
167 }
168
169 inline bool isSmallEnoughToInlineCodeInto(CodeBlock* codeBlock)
170 {
171     return codeBlock->instructionCount() <= Options::maximumInliningCallerSize();
172 }
173
174 } } // namespace JSC::DFG