<https://webkit.org/b/119806> [Mac] Add a way to easily test attributed string generation
[WebKit-https.git] / Source / JavaScriptCore / jit / JITDriver.h
1 /*
2  * Copyright (C) 2012, 2013 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 JITDriver_h
27 #define JITDriver_h
28
29 #include <wtf/Platform.h>
30
31 #if ENABLE(JIT)
32
33 #include "BytecodeGenerator.h"
34 #include "CompilationResult.h"
35 #include "DFGDriver.h"
36 #include "JIT.h"
37 #include "LLIntEntrypoints.h"
38
39 namespace JSC {
40
41 template<typename CodeBlockType>
42 inline CompilationResult jitCompileIfAppropriateImpl(
43     ExecState* exec, CodeBlockType* codeBlock, RefPtr<JITCode>& jitCode,
44     JITCode::JITType jitType, unsigned bytecodeIndex, JITCompilationEffort effort)
45 {
46     VM& vm = exec->vm();
47     
48     if (jitType == codeBlock->jitType())
49         return CompilationNotNeeded;
50     
51     if (!vm.canUseJIT())
52         return CompilationNotNeeded; // FIXME: Investigate if this is right. https://bugs.webkit.org/show_bug.cgi?id=116246
53     
54     codeBlock->unlinkIncomingCalls();
55     
56     RefPtr<JITCode> oldJITCode = jitCode;
57     
58     if (JITCode::isOptimizingJIT(jitType)) {
59         CompilationResult result =
60             DFG::tryCompile(exec, codeBlock, jitCode, bytecodeIndex);
61         if (result == CompilationSuccessful)
62             codeBlock->alternative()->unlinkIncomingCalls();
63         else {
64             ASSERT(oldJITCode == jitCode);
65             return result;
66         }
67     } else {
68         RefPtr<JITCode> result = JIT::compile(&vm, codeBlock, effort);
69         if (result)
70             jitCode = result;
71         else
72             return CompilationFailed;
73     }
74     
75     return CompilationSuccessful;
76 }
77
78 inline CompilationResult jitCompileFunctionIfAppropriateImpl(
79     ExecState* exec, FunctionCodeBlock* codeBlock, RefPtr<JITCode>& jitCode,
80     MacroAssemblerCodePtr& jitCodeWithArityCheck, JITCode::JITType jitType,
81     unsigned bytecodeIndex, JITCompilationEffort effort)
82 {
83     VM& vm = exec->vm();
84     
85     if (jitType == codeBlock->jitType())
86         return CompilationNotNeeded;
87     
88     if (!vm.canUseJIT())
89         return CompilationNotNeeded; // FIXME: Investigate if this is right. https://bugs.webkit.org/show_bug.cgi?id=116246
90     
91     codeBlock->unlinkIncomingCalls();
92     
93     RefPtr<JITCode> oldJITCode = jitCode;
94     MacroAssemblerCodePtr oldJITCodeWithArityCheck = jitCodeWithArityCheck;
95     
96     if (JITCode::isOptimizingJIT(jitType)) {
97         CompilationResult result = DFG::tryCompileFunction(
98             exec, codeBlock, jitCode, jitCodeWithArityCheck, bytecodeIndex);
99         if (result == CompilationSuccessful)
100             codeBlock->alternative()->unlinkIncomingCalls();
101         else {
102             ASSERT(oldJITCode == jitCode);
103             ASSERT_UNUSED(oldJITCodeWithArityCheck, oldJITCodeWithArityCheck == jitCodeWithArityCheck);
104             return result;
105         }
106     } else {
107         RefPtr<JITCode> result =
108             JIT::compile(&vm, codeBlock, effort, &jitCodeWithArityCheck);
109         if (result)
110             jitCode = result;
111         else {
112             ASSERT_UNUSED(oldJITCodeWithArityCheck, oldJITCodeWithArityCheck == jitCodeWithArityCheck);
113             return CompilationFailed;
114         }
115     }
116
117     return CompilationSuccessful;
118 }
119
120 template<typename CodeBlockType>
121 inline CompilationResult jitCompileIfAppropriate(
122     ExecState* exec, CodeBlockType* codeBlock, RefPtr<JITCode>& jitCode,
123     JITCode::JITType jitType, unsigned bytecodeIndex, JITCompilationEffort effort)
124 {
125     CompilationResult result = jitCompileIfAppropriateImpl(
126         exec, codeBlock, jitCode, jitType, bytecodeIndex, effort);
127     if (result == CompilationSuccessful) {
128         codeBlock->setJITCode(jitCode, MacroAssemblerCodePtr());
129         codeBlock->vm()->heap.reportExtraMemoryCost(jitCode->size());
130     }
131     return result;
132 }    
133
134 inline CompilationResult jitCompileFunctionIfAppropriate(
135     ExecState* exec, FunctionCodeBlock* codeBlock, RefPtr<JITCode>& jitCode,
136     MacroAssemblerCodePtr& jitCodeWithArityCheck, JITCode::JITType jitType,
137     unsigned bytecodeIndex, JITCompilationEffort effort)
138 {
139     CompilationResult result = jitCompileFunctionIfAppropriateImpl(
140         exec, codeBlock, jitCode, jitCodeWithArityCheck, jitType, bytecodeIndex, effort);
141     if (result == CompilationSuccessful) {
142         codeBlock->setJITCode(jitCode, jitCodeWithArityCheck);
143         codeBlock->vm()->heap.reportExtraMemoryCost(jitCode->size());
144     }
145     return result;
146 }
147
148 } // namespace JSC
149
150 #endif // ENABLE(JIT)
151
152 #endif // JITDriver_h
153