]>
Commit | Line | Data |
---|---|---|
6fe7ccc8 A |
1 | /* |
2 | * Copyright (C) 2011 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 "DFGCapabilities.h" | |
28 | ||
29 | #include "CodeBlock.h" | |
30 | #include "DFGCommon.h" | |
31 | #include "Interpreter.h" | |
32 | ||
33 | namespace JSC { namespace DFG { | |
34 | ||
35 | #if ENABLE(DFG_JIT) | |
93a37866 A |
36 | bool mightCompileEval(CodeBlock* codeBlock) |
37 | { | |
38 | return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount(); | |
39 | } | |
40 | bool mightCompileProgram(CodeBlock* codeBlock) | |
41 | { | |
42 | return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount(); | |
43 | } | |
44 | bool mightCompileFunctionForCall(CodeBlock* codeBlock) | |
45 | { | |
46 | return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount(); | |
47 | } | |
48 | bool mightCompileFunctionForConstruct(CodeBlock* codeBlock) | |
49 | { | |
50 | return codeBlock->instructionCount() <= Options::maximumOptimizationCandidateInstructionCount(); | |
51 | } | |
52 | ||
53 | bool mightInlineFunctionForCall(CodeBlock* codeBlock) | |
54 | { | |
55 | return codeBlock->instructionCount() <= Options::maximumFunctionForCallInlineCandidateInstructionCount() | |
56 | && !codeBlock->ownerExecutable()->needsActivation(); | |
57 | } | |
58 | bool mightInlineFunctionForClosureCall(CodeBlock* codeBlock) | |
59 | { | |
60 | return codeBlock->instructionCount() <= Options::maximumFunctionForClosureCallInlineCandidateInstructionCount() | |
61 | && !codeBlock->ownerExecutable()->needsActivation(); | |
62 | } | |
63 | bool mightInlineFunctionForConstruct(CodeBlock* codeBlock) | |
64 | { | |
65 | return codeBlock->instructionCount() <= Options::maximumFunctionForConstructInlineCandidateInstructionCount() | |
66 | && !codeBlock->ownerExecutable()->needsActivation(); | |
67 | } | |
6fe7ccc8 | 68 | |
93a37866 | 69 | static inline void debugFail(CodeBlock* codeBlock, OpcodeID opcodeID, bool result) |
6fe7ccc8 | 70 | { |
93a37866 | 71 | ASSERT_UNUSED(result, !result); |
6fe7ccc8 | 72 | #if DFG_ENABLE(DEBUG_VERBOSE) |
93a37866 | 73 | dataLogF("Cannot handle code block %p because of opcode %s.\n", codeBlock, opcodeNames[opcodeID]); |
6fe7ccc8 A |
74 | #else |
75 | UNUSED_PARAM(codeBlock); | |
76 | UNUSED_PARAM(opcodeID); | |
93a37866 | 77 | UNUSED_PARAM(result); |
6fe7ccc8 A |
78 | #endif |
79 | } | |
80 | ||
93a37866 | 81 | static inline void debugFail(CodeBlock* codeBlock, OpcodeID opcodeID, CapabilityLevel result) |
6fe7ccc8 | 82 | { |
93a37866 A |
83 | ASSERT(result != CanCompile); |
84 | #if DFG_ENABLE(DEBUG_VERBOSE) | |
85 | if (result == CannotCompile) | |
86 | dataLogF("Cannot handle code block %p because of opcode %s.\n", codeBlock, opcodeNames[opcodeID]); | |
87 | else { | |
88 | dataLogF("Cannot compile code block %p because of opcode %s, but inlining might be possible.\n", codeBlock, opcodeNames[opcodeID]); | |
89 | } | |
90 | #else | |
91 | UNUSED_PARAM(codeBlock); | |
92 | UNUSED_PARAM(opcodeID); | |
93 | UNUSED_PARAM(result); | |
94 | #endif | |
95 | } | |
96 | ||
97 | template<typename ReturnType, ReturnType (*canHandleOpcode)(OpcodeID, CodeBlock*, Instruction*)> | |
98 | ReturnType canHandleOpcodes(CodeBlock* codeBlock, ReturnType initialValue) | |
99 | { | |
100 | Interpreter* interpreter = codeBlock->vm()->interpreter; | |
6fe7ccc8 A |
101 | Instruction* instructionsBegin = codeBlock->instructions().begin(); |
102 | unsigned instructionCount = codeBlock->instructions().size(); | |
93a37866 | 103 | ReturnType result = initialValue; |
6fe7ccc8 A |
104 | |
105 | for (unsigned bytecodeOffset = 0; bytecodeOffset < instructionCount; ) { | |
106 | switch (interpreter->getOpcodeID(instructionsBegin[bytecodeOffset].u.opcode)) { | |
93a37866 A |
107 | #define DEFINE_OP(opcode, length) \ |
108 | case opcode: { \ | |
109 | ReturnType current = canHandleOpcode( \ | |
110 | opcode, codeBlock, instructionsBegin + bytecodeOffset); \ | |
111 | if (current < result) { \ | |
112 | result = current; \ | |
113 | debugFail(codeBlock, opcode, current); \ | |
114 | } \ | |
115 | bytecodeOffset += length; \ | |
116 | break; \ | |
117 | } | |
6fe7ccc8 A |
118 | FOR_EACH_OPCODE_ID(DEFINE_OP) |
119 | #undef DEFINE_OP | |
120 | default: | |
93a37866 | 121 | RELEASE_ASSERT_NOT_REACHED(); |
6fe7ccc8 A |
122 | break; |
123 | } | |
124 | } | |
125 | ||
93a37866 | 126 | return result; |
6fe7ccc8 A |
127 | } |
128 | ||
93a37866 | 129 | CapabilityLevel canCompileOpcodes(CodeBlock* codeBlock) |
6fe7ccc8 A |
130 | { |
131 | if (!MacroAssembler::supportsFloatingPoint()) | |
93a37866 A |
132 | return CannotCompile; |
133 | return canHandleOpcodes<CapabilityLevel, canCompileOpcode>(codeBlock, CanCompile); | |
6fe7ccc8 A |
134 | } |
135 | ||
136 | bool canInlineOpcodes(CodeBlock* codeBlock) | |
137 | { | |
93a37866 | 138 | return canHandleOpcodes<bool, canInlineOpcode>(codeBlock, true); |
6fe7ccc8 A |
139 | } |
140 | ||
141 | #endif | |
142 | ||
143 | } } // namespace JSC::DFG | |
144 |