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  PassManager PM;
130 
131  LOG(bold << bold << "Compiler Start: " << reset_color << *m << nl);
132 
133  // pass configuration
134  if (opt_showintermediate) {
136  }
139  }
142  }
144  PM.add_Pass<SSAPrinterPass>();
145  }
148  }
153  }
156  }
159  }
162  }
163 
164  PM.add_Pass<CodeGenPass>();
165 
166 /*****************************************************************************/
167 /** prolog start jit_compile **/
168 /*****************************************************************************/
169  u1 *r;
170  jitdata *jd;
171  u1 optlevel;
172 
173  /* check for max. optimization level */
174 
175  optlevel = (m->code) ? m->code->optlevel : 0;
176 
177 #if 0
178  if (optlevel == 1) {
179 /* log_message_method("not recompiling: ", m); */
180  return NULL;
181  }
182 #endif
183 
184  //DEBUG_JIT_COMPILEVERBOSE("Recompiling start: ");
185 
186  //STATISTICS(count_jit_calls++);
187 
188 #if 0 && defined(ENABLE_STATISTICS)
189  /* measure time */
190 
191  if (opt_getcompilingtime)
193 #endif
194 
195  // Create new dump memory area.
196  DumpMemoryArea dma;
197 
198  /* create jitdata structure */
199 
200  jd = jit_jitdata_new(m);
201 
202  /* set the current optimization level to the previous one plus 1 */
203 
204  jd->code->optlevel = optlevel + 1;
205 
206  /* get the optimization flags for the current JIT run */
207 
208 #if defined(ENABLE_VERIFIER)
209  jd->flags |= JITDATA_FLAG_VERIFY;
210 #endif
211 
212  /* jd->flags |= JITDATA_FLAG_REORDER; */
217  if (opt_verbosecall)
219 
220 #if defined(ENABLE_INLINING)
221  //XXX #warning Inlining currently disabled (broken)
222 #if 0
223  if (opt_Inline)
224  jd->flags |= JITDATA_FLAG_INLINE;
225 #endif
226 #endif
227 
228 #if defined(ENABLE_JIT)
229 # if defined(ENABLE_INTRP)
230  if (!opt_intrp)
231 # endif
232  /* initialize the register allocator */
233 
234  reg_setup(jd);
235 #endif
236 
237  /* setup the codegendata memory */
238 
239  codegen_setup(jd);
240 
241  /* now call internal compile function */
242 
243  bool bak = opt_RegallocSpillAll;
244  opt_RegallocSpillAll = true;
245 /*****************************************************************************/
246 /** prolog end jit_compile **/
247 /*****************************************************************************/
248  JITData JD(jd);
249 /*****************************************************************************/
250 /** prolog start jit_compile_intern **/
251 /*****************************************************************************/
252 
253  //codegendata *cd;
254  codeinfo *code;
255 
256  //RT_TIMER_START(checks_timer);
257 
258  /* get required compiler data */
259 
260 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
261  JD.get_jitdata()->ls = NULL;
262 #endif
263  code = JD.get_jitdata()->code;
264  //cd = JD.get_jitdata()->cd;
265 
266 #if defined(ENABLE_DEBUG_FILTER)
268 #endif
269 
270  // Handle native methods and create a native stub.
271  if (m->flags & ACC_NATIVE) {
273  void* f = nm.resolve_method(m);
274 
275  if (f == NULL)
276  return NULL;
277 
278  code = NativeStub::generate(m, *reinterpret_cast<functionptr*>(&f));
279 
280  /* Native methods are never recompiled. */
281 
282  assert(!m->code);
283 
284  m->code = code;
285 
286  return code->entrypoint;
287  }
288 
289  /* if there is no javacode, print error message and return empty method */
290 
291  if (m->jcode == NULL) {
292  //DEBUG_JIT_COMPILEVERBOSE("No code given for: ");
293 
294  code->entrypoint = (u1 *) (ptrint) do_nothing_function;
295  m->code = code;
296 
297  return code->entrypoint; /* return empty method */
298  }
299 
300 #if 0 && defined(ENABLE_STATISTICS)
301  if (opt_stat) {
302  count_javacodesize += m->jcodelength + 18;
303  count_tryblocks += JD.get_jitdata()->exceptiontablelength;
304  count_javaexcsize += JD.get_jitdata()->exceptiontablelength * SIZEOF_VOID_P;
305  }
306 #endif
307 
308 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
309  /* Code for Sun's OpenJDK (see
310  hotspot/src/share/vm/classfile/verifier.cpp
311  (Verifier::is_eligible_for_verification)): Don't verify
312  dynamically-generated bytecodes. */
313 
314 # if defined(ENABLE_VERIFIER)
315  if (class_issubclass(m->clazz, class_sun_reflect_MagicAccessorImpl))
317 # endif
318 #endif
319 
320 /*****************************************************************************/
321 /** prolog end jit_compile_intern **/
322 /*****************************************************************************/
323  PM.runPasses(JD);
324  assert(code);
325  assert(code->entrypoint);
326 
327 
328  code->prev = m->code;
329  m->code = code;
330  r = JD.get_jitdata()->code->entrypoint;
331 /*****************************************************************************/
332 /** epilog start jit_compile **/
333 /*****************************************************************************/
334  opt_RegallocSpillAll = bak;
335 
336  if (r == NULL) {
337  /* We had an exception! Finish stuff here if necessary. */
338 
339  /* release codeinfo */
340 
342  }
343 
344 #if 0 && defined(ENABLE_STATISTICS)
345  /* measure time */
346 
347  if (opt_getcompilingtime)
349 #endif
350 
351  // Hook point just after code was generated.
352  Hook::jit_generated(m, m->code);
353 
354  //DEBUG_JIT_COMPILEVERBOSE("Recompiling done: ");
355 
356  /* return pointer to the methods entry point */
357 
358 /** epilog end jit_compile **/
359 
360  LOG(bold << bold << "Compiler End: " << reset_color << *m << nl);
361 
362  //return mc;
363  return r;
364 }
365 
366 } // end namespace cacao
367 } // end namespace jit
368 } // end namespace compiler2
369 
370 /*
371  * These are local overrides for various environment variables in Emacs.
372  * Please do not remove this and leave it at the end of the file, where
373  * Emacs will automagically detect them.
374  * ---------------------------------------------------------------------
375  * Local variables:
376  * mode: c++
377  * indent-tabs-mode: t
378  * c-basic-offset: 4
379  * tab-width: 4
380  * End:
381  * vim:noexpandtab:sw=4:ts=4:
382  */
bool opt_showdisassemble
Definition: options.cpp:85
s4 exceptiontablelength
Definition: jit.hpp:167
Option< bool > schedule_printer_enabled("GlobalSchedulePrinterPass","compiler2: enable GlobalSchedulePrinterPass", false,::cacao::option::xx_root())
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
s4 jcodelength
Definition: method.hpp:85
BasicBlockPrinterPass TODO: more info.
#define JITDATA_FLAG_VERBOSECALL
Definition: jit.hpp:197
codeinfo * code
Definition: jit.hpp:128
u1 optlevel
Definition: code.hpp:80
MachineLoop * loop
bool typecheck(jitdata *jd)
Definition: typecheck.cpp:684
bool opt_intrp
Definition: options.cpp:55
u4 flags
Definition: jit.hpp:138
#define JITDATA_FLAG_VERIFY
Definition: jit.hpp:185
CodeGenPass TODO: more info.
Definition: CodeGenPass.hpp:49
MachineCode * compile(methodinfo *m)
Definition: Compiler.cpp:123
uint8_t u1
Definition: types.hpp:40
SSAPrinterPass TODO: more info.
bool opt_verbosecall
Definition: options.cpp:76
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
LoopTreePrinterPass TODO: more info.
Bold bold
Definition: OStream.cpp:62
#define JITDATA_FLAG_SHOWINTERMEDIATE
Definition: jit.hpp:195
#define RT_REGISTER_GROUP_TIMER(var, name, description, group)
Register a new timer.
Definition: rt-timing.hpp:682
ObjectFileWriterPass TODO: more info.
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:112
This file contains the statistics framework.
void reg_setup(jitdata *jd)
Definition: reg.cpp:42
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
DomTreePrinterPass TODO: more info.
ResetColor reset_color
Definition: OStream.cpp:61
codeinfo * code
Definition: method.hpp:103
bool class_issubclass(classinfo *sub, classinfo *super)
Definition: class.cpp:1404
codeinfo * prev
Definition: code.hpp:76
static void reset()
Reset static infos (run by Compiler)
Manage the execution of compiler passes.
Definition: PassManager.hpp:75
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
void compilingtime_start(void)
Definition: statistics.cpp:81
#define LOG(STMT)
Analogous to DEBUG.
Definition: logging.hpp:91
void codegen_setup(jitdata *jd)
GlobalSchedulePrinterPass TODO: more info.
bool opt_showintermediate
Definition: options.cpp:87
#define JITDATA_FLAG_INLINE
Definition: jit.hpp:191
methodinfo * m
Definition: jit.hpp:127
void show_filters_apply(methodinfo *m)
Definition: show.cpp:1525
void add_Pass()
add a compiler pass
void runPasses(JITData &JD)
run passes
Definition: PassManager.cpp:91
bool parse(jitdata *jd)
Definition: parse.cpp:604
OptionPrefix & xx_root()
Definition: Option.cpp:39
#define JITDATA_FLAG_SHOWDISASSEMBLE
Definition: jit.hpp:196
DisassemblerPass TODO: more info.
s4 flags
Definition: method.hpp:70
MachineInstructionPrinterPass TODO: more info.
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 compilingtime_stop(void)
Definition: statistics.cpp:96
static VM * get_current()
Definition: vm.hpp:99
u1 * entrypoint
Definition: code.hpp:84