CACAO
Compiler.cpp
Go to the documentation of this file.
1 /* src/vm/jit/compiler2/Compiler.cpp - 2nd stage Just-In-Time compiler
2 
3  Copyright (C) 2013
4  CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 
6  This file is part of CACAO.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2, or (at
11  your option) any later version.
12 
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  02110-1301, USA.
22 
23 */
24 
25 #include "config.h"
26 #include <assert.h>
27 
28 #include "vm/hook.hpp"
29 #include "vm/rt-timing.hpp"
30 #include "vm/statistics.hpp"
31 #include "vm/jit/cfg.hpp"
32 #include "vm/jit/code.hpp"
33 #include "vm/jit/jit.hpp"
34 #include "vm/jit/parse.hpp"
35 #include "vm/jit/show.hpp"
36 #include "vm/jit/stubs.hpp"
37 
39 
40 #if defined(ENABLE_IFCONV)
42 #endif
44 
45 #include "toolbox/OStream.hpp"
46 
50 
55 # if defined(ENABLE_VERIFIER)
57 #endif
82 
84 
85 #include "vm/options.hpp"
86 
87 #include "mm/dumpmemory.hpp"
88 
89 #if 0
90 RT_REGISTER_GROUP(compiler2_group,"compiler2","second-stage compiler")
91 
92 RT_REGISTER_GROUP_TIMER(checks_timer, "compiler2","checks at beginning", compiler2_group)
93 RT_REGISTER_GROUP_TIMER(parse_timer, "compiler2","parse", compiler2_group)
94 RT_REGISTER_GROUP_TIMER(stack_timer, "compiler2","analyse_stack", compiler2_group)
95 RT_REGISTER_GROUP_TIMER(typechecker_timer, "compiler2","typecheck", compiler2_group)
96 RT_REGISTER_GROUP_TIMER(loop_timer, "compiler2","loop", compiler2_group)
97 RT_REGISTER_GROUP_TIMER(ifconversion_timer, "compiler2","if conversion", compiler2_group)
98 RT_REGISTER_GROUP_TIMER(ra_timer, "compiler2","register allocation", compiler2_group)
99 RT_REGISTER_GROUP_TIMER(rp_timer, "compiler2","replacement point generation", compiler2_group)
100 RT_REGISTER_GROUP_TIMER(codegen_timer, "compiler2","codegen", compiler2_group)
101 #endif
102 
103 STAT_REGISTER_GROUP(compiler2_stat,"compiler2","statistics for compiler2")
104 
105 namespace {
106 
107 /* dummy function, used when there is no JavaVM code available */
108 
109 u1 *do_nothing_function(void)
110 {
111  return NULL;
112 }
113 } // end anonymous namespace
114 
115 namespace cacao {
116 namespace jit {
117 namespace compiler2 {
118 
119 #define DEBUG_NAME "compiler2"
120 
121 Option<bool> enabled("DebugCompiler2","compiler with compiler2",false,option::xx_root());
122 
124 {
125 
126  // reset instructions
128 
129  LOG(bold << bold << "Compiler Start: " << reset_color << *m << nl);
130 
131  // Create new dump memory area.
132  DumpMemoryArea dma;
133 
134  /* create jitdata structure */
135 
136  jitdata *jd = jit_jitdata_new(m);
139  JITData JD(jd);
140 
141  /* set the current optimization level to the previous one plus 1 */
142 
143  u1 optlevel = (jd->m->code) ? jd->m->code->optlevel : 0;
144  jd->code->optlevel = optlevel + 1;
145 
146  /* now call internal compile function */
147 
148  bool bak = opt_RegallocSpillAll;
149  opt_RegallocSpillAll = true;
150 
151 /*****************************************************************************/
152 /** prolog start jit_compile_intern **/
153 /*****************************************************************************/
154 
155  //codegendata *cd;
156  codeinfo *code;
157 
158  //RT_TIMER_START(checks_timer);
159 
160  /* get required compiler data */
161 
162 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
163  JD.get_jitdata()->ls = NULL;
164 #endif
165  code = JD.get_jitdata()->code;
166  //cd = JD.get_jitdata()->cd;
167 
168 #if defined(ENABLE_DEBUG_FILTER)
170 #endif
171 
172  // Handle native methods and create a native stub.
173  if (m->flags & ACC_NATIVE) {
175  void* f = nm.resolve_method(m);
176 
177  if (f == NULL)
178  return NULL;
179 
180  code = NativeStub::generate(m, *reinterpret_cast<functionptr*>(&f));
181 
182  /* Native methods are never recompiled. */
183 
184  assert(!m->code);
185 
186  m->code = code;
187 
188  return code->entrypoint;
189  }
190 
191  /* if there is no javacode, print error message and return empty method */
192 
193  if (m->jcode == NULL) {
194  //DEBUG_JIT_COMPILEVERBOSE("No code given for: ");
195 
196  code->entrypoint = (u1 *) (ptrint) do_nothing_function;
197  m->code = code;
198 
199  return code->entrypoint; /* return empty method */
200  }
201 
202 #if 0 && defined(ENABLE_STATISTICS)
203  if (opt_stat) {
204  count_javacodesize += m->jcodelength + 18;
205  count_tryblocks += JD.get_jitdata()->exceptiontablelength;
206  count_javaexcsize += JD.get_jitdata()->exceptiontablelength * SIZEOF_VOID_P;
207  }
208 #endif
209 
210 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
211  /* Code for Sun's OpenJDK (see
212  hotspot/src/share/vm/classfile/verifier.cpp
213  (Verifier::is_eligible_for_verification)): Don't verify
214  dynamically-generated bytecodes. */
215 
216 # if defined(ENABLE_VERIFIER)
217  if (class_issubclass(m->clazz, class_sun_reflect_MagicAccessorImpl))
219 # endif
220 #endif
221 
222 /*****************************************************************************/
223 /** prolog end jit_compile_intern **/
224 /*****************************************************************************/
225 
226  /* set the previous code version */
227 
228  code->prev = m->code;
229 
230  /* run the compiler2 passes */
231 
232  PassRunner runner;
233  runner.runPasses(JD);
234 
235  assert(code);
236  assert(code->entrypoint);
237 
238 
239  m->code = code;
240  u1 *entrypoint = JD.get_jitdata()->code->entrypoint;
241 /*****************************************************************************/
242 /** epilog start jit_compile **/
243 /*****************************************************************************/
244  opt_RegallocSpillAll = bak;
245 
246  if (entrypoint == NULL) {
247  /* We had an exception! Finish stuff here if necessary. */
248 
249  /* release codeinfo */
250 
252  }
253 
254 #if 0 && defined(ENABLE_STATISTICS)
255  /* measure time */
256 
257  if (opt_getcompilingtime)
259 #endif
260 
261  // Hook point just after code was generated.
262  Hook::jit_generated(m, m->code);
263 
264  LOG(bold << bold << "Compiler End: " << reset_color << *m << nl);
265 
266  /* return pointer to the methods entry point */
267 
268  return entrypoint;
269 }
270 
271 } // end namespace cacao
272 } // end namespace jit
273 } // end namespace compiler2
274 
275 /*
276  * These are local overrides for various environment variables in Emacs.
277  * Please do not remove this and leave it at the end of the file, where
278  * Emacs will automagically detect them.
279  * ---------------------------------------------------------------------
280  * Local variables:
281  * mode: c++
282  * indent-tabs-mode: t
283  * c-basic-offset: 4
284  * tab-width: 4
285  * End:
286  * vim:noexpandtab:sw=4:ts=4:
287  */
s4 exceptiontablelength
Definition: jit.hpp:167
void code_codeinfo_free(codeinfo *code)
Definition: code.cpp:213
Definition: jit.hpp:126
Table containing all native methods registered with the VM.
Definition: native.hpp:132
NativeMethods & get_nativemethods()
Definition: vm.hpp:128
Each instance of PassRunner represents a single run of the compiler2.
s4 jcodelength
Definition: method.hpp:85
#define JITDATA_FLAG_DEOPTIMIZE
Definition: jit.hpp:197
void jit_jitdata_init_for_recompilation(jitdata *jd)
Definition: jit.cpp:442
codeinfo * code
Definition: jit.hpp:128
u1 optlevel
Definition: code.hpp:79
MachineLoop * loop
bool typecheck(jitdata *jd)
Definition: typecheck.cpp:684
u4 flags
Definition: jit.hpp:138
#define JITDATA_FLAG_VERIFY
Definition: jit.hpp:185
MachineCode * compile(methodinfo *m)
Definition: Compiler.cpp:123
uint8_t u1
Definition: types.hpp:40
Second stage compiler class.
static u1 * do_nothing_function(void)
Definition: jit.cpp:205
jitdata * get_jitdata() const
Definition: JITData.hpp:51
#define RT_REGISTER_GROUP(var, name, description)
Register a new (toplevel) group.
Definition: rt-timing.hpp:683
Bold bold
Definition: OStream.cpp:62
#define RT_REGISTER_GROUP_TIMER(var, name, description, group)
Register a new timer.
Definition: rt-timing.hpp:682
Dump memory area.
Definition: dumpmemory.hpp:90
jitdata * jit_jitdata_new(methodinfo *m)
Definition: jit.cpp:217
classinfo * clazz
Definition: method.hpp:80
Option< bool > enabled("DebugCompiler2","compiler with compiler2", false, option::xx_root())
Definition: Compiler.hpp:115
This file contains the statistics framework.
u1 * jcode
Definition: method.hpp:86
#define STAT_REGISTER_GROUP(var, name, description)
Register a statistics group.
Definition: statistics.hpp:971
void jit_generated(methodinfo *m, codeinfo *code)
Hook point just after code was generated.
Definition: hook.hpp:102
ResetColor reset_color
Definition: OStream.cpp:61
codeinfo * code
Definition: method.hpp:103
bool class_issubclass(classinfo *sub, classinfo *super)
Definition: class.cpp:1404
static void reset()
Reset static infos (run by Compiler)
This file contains the real-time timing utilities.
void * resolve_method(methodinfo *m)
Resolves a native method, maybe from a dynamic library.
Definition: native.cpp:271
#define LOG(STMT)
Analogous to DEBUG.
Definition: logging.hpp:91
methodinfo * m
Definition: jit.hpp:127
void show_filters_apply(methodinfo *m)
Definition: show.cpp:1516
bool parse(jitdata *jd)
Definition: parse.cpp:604
OptionPrefix & xx_root()
Definition: Option.cpp:39
s4 flags
Definition: method.hpp:70
uintptr_t ptrint
Definition: types.hpp:54
int opt_RegallocSpillAll
Definition: options.cpp:202
static codeinfo * generate(methodinfo *m, functionptr f)
Wrapper for codegen_emit_stub_native.
Definition: stubs.cpp:282
Nl nl
Definition: OStream.cpp:56
void runPasses(JITData &JD)
run passes
Definition: PassManager.cpp:91
void compilingtime_stop(void)
Definition: statistics.cpp:96
static VM * get_current()
Definition: vm.hpp:99
u1 * entrypoint
Definition: code.hpp:83