We should support CreateThis in the FTL
[WebKit-https.git] / Source / JavaScriptCore / runtime / TestRunnerUtils.cpp
1 /*
2  * Copyright (C) 2013-2018 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 "TestRunnerUtils.h"
28
29 #include "CodeBlock.h"
30 #include "FunctionCodeBlock.h"
31 #include "JSCInlines.h"
32 #include "LLIntData.h"
33
34 namespace JSC {
35
36 FunctionExecutable* getExecutableForFunction(JSValue theFunctionValue)
37 {
38     if (!theFunctionValue.isCell())
39         return nullptr;
40
41     VM& vm = *theFunctionValue.asCell()->vm();
42     JSFunction* theFunction = jsDynamicCast<JSFunction*>(vm, theFunctionValue);
43     if (!theFunction)
44         return nullptr;
45     
46     FunctionExecutable* executable = jsDynamicCast<FunctionExecutable*>(vm, 
47         theFunction->executable());
48     return executable;
49 }
50
51 CodeBlock* getSomeBaselineCodeBlockForFunction(JSValue theFunctionValue)
52 {
53     FunctionExecutable* executable = getExecutableForFunction(theFunctionValue);
54     if (!executable)
55         return 0;
56     
57     CodeBlock* baselineCodeBlock = executable->baselineCodeBlockFor(CodeForCall);
58     
59     if (!baselineCodeBlock)
60         baselineCodeBlock = executable->baselineCodeBlockFor(CodeForConstruct);
61     
62     return baselineCodeBlock;
63 }
64
65 JSValue numberOfDFGCompiles(JSValue theFunctionValue)
66 {
67     bool pretendToHaveManyCompiles = false;
68 #if ENABLE(DFG_JIT)
69     if (!Options::useJIT() || !Options::useDFGJIT())
70         pretendToHaveManyCompiles = true;
71 #else
72     pretendToHaveManyCompiles = true;
73 #endif
74
75     if (CodeBlock* baselineCodeBlock = getSomeBaselineCodeBlockForFunction(theFunctionValue)) {
76         if (pretendToHaveManyCompiles)
77             return jsNumber(1000000.0);
78         return jsNumber(baselineCodeBlock->numberOfDFGCompiles());
79     }
80     
81     return jsNumber(0);
82 }
83
84 JSValue setNeverInline(JSValue theFunctionValue)
85 {
86     if (FunctionExecutable* executable = getExecutableForFunction(theFunctionValue))
87         executable->setNeverInline(true);
88     
89     return jsUndefined();
90 }
91
92 JSValue setNeverOptimize(JSValue theFunctionValue)
93 {
94     if (FunctionExecutable* executable = getExecutableForFunction(theFunctionValue))
95         executable->setNeverOptimize(true);
96     
97     return jsUndefined();
98 }
99
100 JSValue optimizeNextInvocation(JSValue theFunctionValue)
101 {
102 #if ENABLE(JIT)
103     if (CodeBlock* baselineCodeBlock = getSomeBaselineCodeBlockForFunction(theFunctionValue))
104         baselineCodeBlock->optimizeNextInvocation();
105 #else
106     UNUSED_PARAM(theFunctionValue);
107 #endif
108
109     return jsUndefined();
110 }
111
112 JSValue failNextNewCodeBlock(ExecState* exec)
113 {
114     exec->vm().setFailNextNewCodeBlock();
115
116     return jsUndefined();
117 }
118
119 JSValue numberOfDFGCompiles(ExecState* exec)
120 {
121     if (exec->argumentCount() < 1)
122         return jsUndefined();
123     return numberOfDFGCompiles(exec->uncheckedArgument(0));
124 }
125
126 JSValue setNeverInline(ExecState* exec)
127 {
128     if (exec->argumentCount() < 1)
129         return jsUndefined();
130     return setNeverInline(exec->uncheckedArgument(0));
131 }
132
133 JSValue setNeverOptimize(ExecState* exec)
134 {
135     if (exec->argumentCount() < 1)
136         return jsUndefined();
137     return setNeverOptimize(exec->uncheckedArgument(0));
138 }
139
140 JSValue setCannotUseOSRExitFuzzing(ExecState* exec)
141 {
142     if (exec->argumentCount() < 1)
143         return jsUndefined();
144
145     JSValue theFunctionValue = exec->uncheckedArgument(0);
146     if (FunctionExecutable* executable = getExecutableForFunction(theFunctionValue))
147         executable->setCanUseOSRExitFuzzing(false);
148
149     return jsUndefined();
150 }
151
152 JSValue optimizeNextInvocation(ExecState* exec)
153 {
154     if (exec->argumentCount() < 1)
155         return jsUndefined();
156     return optimizeNextInvocation(exec->uncheckedArgument(0));
157 }
158
159 // This is a hook called at the bitter end of some of our tests.
160 void finalizeStatsAtEndOfTesting()
161 {
162 }
163
164 } // namespace JSC
165