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