Line data Source code
1 : /* src/vm/jit/jit.cpp - Just-In-Time compiler
2 :
3 : Copyright (C) 1996-2014
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 <cassert> // for assert
26 : #include <stdint.h> // for uintptr_t
27 : #include "config.h" // for ENABLE_JIT, etc
28 : #include "md.hpp" // for md_cacheflush
29 : #include "mm/dumpmemory.hpp" // for DumpMemory, DumpMemoryArea
30 : #include "native/native.hpp" // for NativeMethods
31 : #include "threads/mutex.hpp" // for Mutex
32 : #include "toolbox/logging.hpp" // for log_message_method, etc
33 : #include "vm/class.hpp" // for classinfo
34 : #include "vm/global.hpp" // for functionptr
35 : #include "vm/globals.hpp"
36 : #include "vm/hook.hpp" // for jit_generated
37 : #include "vm/initialize.hpp" // for initialize_class
38 : #include "vm/jit/jit.hpp"
39 : #include "vm/jit/allocator/simplereg.hpp" // for regalloc, etc
40 : #include "vm/jit/cfg.hpp" // for cfg_build
41 : #include "vm/jit/code.hpp" // for codeinfo, etc
42 : #include "vm/jit/codegen-common.hpp" // for codegen_setup, etc
43 : #include "vm/jit/disass.hpp"
44 : #include "vm/jit/dseg.hpp" // for dseg_display
45 : #include "vm/jit/ir/bytecode.hpp"
46 : #include "vm/jit/ir/icmd.hpp" // for ::ICMD_IFNONNULL, etc
47 : #include "vm/jit/optimizing/ifconv.hpp" // for ifconv_static
48 : #include "vm/jit/optimizing/reorder.hpp"
49 : #include "vm/jit/parse.hpp" // for parse
50 : #include "vm/jit/reg.hpp" // for reg_setup, registerdata
51 : #include "vm/jit/replace.hpp" // for replace_activate_replacement_points
52 : #include "vm/jit/show.hpp" // for show_filters_apply, etc
53 : #include "vm/jit/stack.hpp" // for stack_analyse, stack_init
54 : #include "vm/jit/stubs.hpp" // for NativeStub
55 : #include "vm/jit/verify/typecheck.hpp" // for typecheck
56 : #include "vm/method.hpp" // for methodinfo, method_print
57 : #include "vm/options.hpp" // for compileverbose, etc
58 : #include "vm/rt-timing.hpp"
59 : #include "vm/statistics.hpp" // for StatSumGroup, StatVar, etc
60 : #include "vm/types.hpp" // for u1, s4, ptrint
61 : #include "vm/vm.hpp" // for VM, vm_abort
62 :
63 : #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
64 : # include "vm/jit/allocator/lsra.hpp"
65 : #endif
66 :
67 : #if defined(ENABLE_SSA)
68 : # include "vm/jit/optimizing/lsra.hpp"
69 : # include "vm/jit/optimizing/ssa.hpp"
70 : #endif
71 :
72 : #if defined(ENABLE_INLINING)
73 : # include "vm/jit/inline/inline.hpp"
74 : #endif
75 :
76 : #if defined(ENABLE_IFCONV)
77 : # include "vm/jit/optimizing/ifconv.hpp"
78 : #endif
79 :
80 : #if defined(ENABLE_LOOP)
81 : # include "vm/jit/loop/loop.hpp"
82 : #endif
83 :
84 : #if defined(ENABLE_COMPILER2)
85 : #include "vm/jit/compiler2/Compiler.hpp"
86 : #include "vm/jit/compiler2/JITData.hpp"
87 : #include "vm/jit/compiler2/ObjectFileWriterPass.hpp"
88 : #endif
89 :
90 : /* debug macros ***************************************************************/
91 :
92 : #if !defined(NDEBUG)
93 : #define DEBUG_JIT_COMPILEVERBOSE(x) \
94 : do { \
95 : if (compileverbose) { \
96 : log_message_method(x, m); \
97 : } \
98 : } while (0)
99 : #else
100 : #define DEBUG_JIT_COMPILEVERBOSE(x) /* nothing */
101 : #endif
102 :
103 : #if !defined(NDEBUG)
104 : # define TRACECOMPILERCALLS() \
105 : do { \
106 : if (opt_TraceCompilerCalls) { \
107 : log_start(); \
108 : log_print("[JIT compiler started: method="); \
109 : method_print(m); \
110 : log_print("]"); \
111 : log_finish(); \
112 : } \
113 : } while (0)
114 : #else
115 : # define TRACECOMPILERCALLS()
116 : #endif
117 :
118 : STAT_REGISTER_VAR(int,count_jit_calls,0,"jit calls","Number of JIT compiler calls")
119 : STAT_REGISTER_VAR(int,count_methods,0,"compiled methods","Number of compiled methods")
120 : // TODO regression: old framework also printed (count_javacodesize - count_methods * 18)
121 : STAT_REGISTER_VAR(int,count_javacodesize,0,"java code size","Size of compiled JavaVM instructions")
122 : STAT_REGISTER_VAR(int,count_javaexcsize,0,"java exc.tbl. size","Size of compiled Exception Tables")
123 : STAT_REGISTER_VAR(int,count_tryblocks,0,"try blocks","Number of Try-Blocks")
124 : STAT_REGISTER_VAR(int,count_methods_allocated_by_lsra,0,"meth. alloc. lsra","Methods allocated by LSRA")
125 :
126 : STAT_REGISTER_VAR_EXTERN(int,count_interface_size,0,"interface size","Number of interface slots")
127 : STAT_REGISTER_VAR_EXTERN(int,count_locals_conflicts,0,"locals conflicts","Conflicts between local Variables")
128 : STAT_REGISTER_VAR_EXTERN(int,count_locals_spilled,0,"locals spilled","Local Variables held in Memory")
129 : STAT_REGISTER_VAR_EXTERN(int,count_locals_register,0,"locals register","Local Variables held in Registers")
130 : STAT_REGISTER_VAR_EXTERN(int,count_ss_spilled,0,"ss spilled","Stackslots held in Memory")
131 : STAT_REGISTER_VAR_EXTERN(int,count_ss_register,0,"ss register","Stackslots held in Registers")
132 : STAT_REGISTER_VAR_EXTERN(int,count_argument_reg_ss,0,"argument reg ss","Number of Argument stack slots in register")
133 : STAT_REGISTER_VAR_EXTERN(int,count_argument_mem_ss,0,"argument mem ss","Number of Argument stack slots in memory")
134 :
135 : STAT_REGISTER_SUM_GROUP(spill_write_stat,"spills write","Number of Spills (write to memory)")
136 : STAT_REGISTER_GROUP_VAR_EXTERN(int,count_spills_write_ila,0,"spill write i/l/a","Int, Long, Array Spills (write to memory)",spill_write_stat)
137 : STAT_REGISTER_GROUP_VAR_EXTERN(int,count_spills_write_flt,0,"spill write float","Float Spills (write to memory)",spill_write_stat)
138 : STAT_REGISTER_GROUP_VAR_EXTERN(int,count_spills_write_dbl,0,"spill write double","Double Spills (write to memory)",spill_write_stat)
139 :
140 : STAT_REGISTER_SUM_GROUP(spill_read_stat,"spills read","Number of Spills (read from memory)")
141 : STAT_REGISTER_GROUP_VAR_EXTERN(int,count_spills_read_ila,0,"spill read i/l/a","Int, Long, Array Spills (read from memory)",spill_read_stat)
142 : STAT_REGISTER_GROUP_VAR_EXTERN(int,count_spills_read_flt,0,"spill read float","Float Spills (read from memory)",spill_read_stat)
143 : STAT_REGISTER_GROUP_VAR_EXTERN(int,count_spills_read_dbl,0,"spill read double","Double Spills (read from memory)",spill_read_stat)
144 :
145 : /* jit_init ********************************************************************
146 :
147 : Initializes the JIT subsystem.
148 :
149 : *******************************************************************************/
150 :
151 163 : void jit_init(void)
152 : {
153 163 : TRACESUBSYSTEMINITIALIZATION("jit_init");
154 :
155 : #if defined(ENABLE_JIT)
156 : /* initialize stack analysis subsystem */
157 :
158 163 : (void) stack_init();
159 : #endif
160 :
161 : /* initialize show subsystem */
162 :
163 : #if !defined(NDEBUG)
164 163 : (void) show_init();
165 : #endif
166 :
167 : /* initialize codegen subsystem */
168 :
169 163 : codegen_init();
170 :
171 : /* initialize code subsystem */
172 :
173 163 : (void) code_init();
174 :
175 : /* Machine dependent initialization. */
176 :
177 : #if defined(ENABLE_JIT)
178 : # if defined(ENABLE_INTRP)
179 : if (opt_intrp)
180 : intrp_md_init();
181 : else
182 : # endif
183 163 : md_init();
184 : #else
185 : intrp_md_init();
186 : #endif
187 163 : }
188 :
189 : #define DEBUG_NAME "jit"
190 :
191 : /* jit_close *******************************************************************
192 :
193 : Close the JIT subsystem.
194 :
195 : *******************************************************************************/
196 :
197 0 : void jit_close(void)
198 : {
199 : /* nop */
200 0 : }
201 :
202 :
203 : /* dummy function, used when there is no JavaVM code available */
204 :
205 0 : static u1 *do_nothing_function(void)
206 : {
207 0 : return NULL;
208 : }
209 :
210 :
211 : /* jit_jitdata_new *************************************************************
212 :
213 : Allocates and initalizes a new jitdata structure.
214 :
215 : *******************************************************************************/
216 :
217 105324 : jitdata *jit_jitdata_new(methodinfo *m)
218 : {
219 : jitdata *jd;
220 : codeinfo *code;
221 :
222 : /* allocate jitdata structure and fill it */
223 :
224 105324 : jd = (jitdata*) DumpMemory::allocate(sizeof(jitdata));
225 :
226 105324 : jd->m = m;
227 105324 : jd->cd = (codegendata*) DumpMemory::allocate(sizeof(codegendata));
228 105324 : jd->rd = (registerdata*) DumpMemory::allocate(sizeof(registerdata));
229 : #if defined(ENABLE_LOOP)
230 : if (opt_loops)
231 : jd->ld = new MethodLoopData;
232 : #endif
233 :
234 : /* Allocate codeinfo memory from the heap as we need to keep them. */
235 :
236 105324 : code = code_codeinfo_new(m);
237 :
238 : /* Set codeinfo flags. */
239 :
240 105323 : if (checksync && (m->flags & ACC_SYNCHRONIZED))
241 3231 : code_flag_synchronized(code);
242 :
243 108554 : if (checksync && (m->flags & ACC_SYNCHRONIZED))
244 3231 : code_unflag_leafmethod(code);
245 : else
246 102092 : code_flag_leafmethod(code);
247 :
248 : /* initialize variables */
249 :
250 105324 : jd->code = code;
251 105324 : jd->flags = 0;
252 105324 : jd->exceptiontable = NULL;
253 105324 : jd->exceptiontablelength = 0;
254 105324 : jd->returncount = 0;
255 105324 : jd->branchtoentry = false;
256 105324 : jd->branchtoend = false;
257 105324 : jd->returncount = 0;
258 105324 : jd->returnblock = NULL;
259 105324 : jd->maxlocals = m->maxlocals;
260 :
261 105324 : return jd;
262 : }
263 :
264 : STAT_REGISTER_VAR_EXTERN(std::size_t, compiler_last_codesize, 0, "last-code-size", "code size of the last compiled method")
265 :
266 : /* jit_compile *****************************************************************
267 :
268 : Translates one method to machine code.
269 :
270 : *******************************************************************************/
271 :
272 : static u1 *jit_compile_intern(jitdata *jd);
273 :
274 136284 : u1 *jit_compile(methodinfo *m)
275 : {
276 : u1 *r;
277 : jitdata *jd;
278 :
279 : STATISTICS(count_jit_calls++);
280 :
281 : /* Initialize the static function's class. */
282 :
283 : /* ATTENTION: This MUST be done before the method lock is aquired,
284 : otherwise we could run into a deadlock with <clinit>'s that
285 : call static methods of it's own class. */
286 :
287 136284 : if ((m->flags & ACC_STATIC) && !(m->clazz->state & CLASS_INITIALIZED)) {
288 : #if !defined(NDEBUG)
289 13784 : if (initverbose)
290 0 : log_message_class("Initialize class ", m->clazz);
291 : #endif
292 :
293 13784 : if (!initialize_class(m->clazz))
294 1 : return NULL;
295 :
296 : /* check if the method has been compiled during initialization */
297 :
298 13783 : if ((m->code != NULL) && (m->code->entrypoint != NULL))
299 737 : return m->code->entrypoint;
300 : }
301 :
302 : /* enter a monitor on the method */
303 :
304 135546 : m->mutex->lock();
305 :
306 : /* if method has been already compiled return immediately */
307 :
308 135546 : if (m->code != NULL) {
309 43279 : m->mutex->unlock();
310 :
311 43279 : assert(m->code->entrypoint);
312 43279 : return m->code->entrypoint;
313 : }
314 :
315 92267 : TRACECOMPILERCALLS();
316 :
317 : STATISTICS(count_methods++);
318 :
319 : #if defined(ENABLE_STATISTICS)
320 : /* measure time */
321 :
322 : if (opt_getcompilingtime)
323 : compilingtime_start();
324 : #endif
325 :
326 : // Create new dump memory area.
327 92267 : DumpMemoryArea dma;
328 :
329 : /* create jitdata structure */
330 :
331 92267 : jd = jit_jitdata_new(m);
332 :
333 : /* set the flags for the current JIT run */
334 :
335 92267 : jd->flags = JITDATA_FLAG_PARSE;
336 :
337 : #if defined(ENABLE_VERIFIER)
338 92267 : if (opt_verify)
339 92267 : jd->flags |= JITDATA_FLAG_VERIFY;
340 : #endif
341 :
342 : #if defined(ENABLE_PROFILING)
343 : if (opt_prof)
344 : jd->flags |= JITDATA_FLAG_INSTRUMENT;
345 : #endif
346 :
347 : #if defined(ENABLE_IFCONV)
348 92267 : if (opt_ifconv)
349 0 : jd->flags |= JITDATA_FLAG_IFCONV;
350 : #endif
351 :
352 : #if defined(ENABLE_INLINING) && defined(ENABLE_INLINING_DEBUG)
353 : if (opt_Inline && opt_InlineAll)
354 : jd->flags |= JITDATA_FLAG_INLINE;
355 : #endif
356 :
357 92267 : if (opt_showintermediate)
358 0 : jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
359 :
360 92267 : if (opt_showdisassemble)
361 0 : jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
362 :
363 92267 : if (opt_verbosecall)
364 0 : jd->flags |= JITDATA_FLAG_VERBOSECALL;
365 :
366 : #if defined(ENABLE_REPLACEMENT) && defined(ENABLE_INLINING) && defined(ENABLE_INLINING_DEBUG) && !defined(NDEBUG)
367 : if (opt_Inline && (jd->m->hitcountdown > 0) && (jd->code->optlevel == 0)) {
368 : if (!opt_InlineMethod) {
369 : jd->flags |= JITDATA_FLAG_COUNTDOWN;
370 : } else {
371 : if (!opt_InlineMethodUtf) {
372 : opt_InlineMethodUtf = Utf8String::from_utf8(opt_InlineMethod);
373 : }
374 : LOG2("name: " << jd->m->name << " hash: " << jd->m->name.hash() << cacao::nl);
375 : LOG2(/*"name: " << opt_InlineMethodUtf << " "*/"hash: " << opt_InlineMethodUtf.hash() << cacao::nl);
376 : if ( jd->m->name.hash() == opt_InlineMethodUtf.hash() ) {
377 : jd->flags |= JITDATA_FLAG_COUNTDOWN;
378 : }
379 : }
380 : }
381 : #endif
382 :
383 : #if defined(ENABLE_JIT)
384 : # if defined(ENABLE_INTRP)
385 : if (!opt_intrp)
386 : # endif
387 : /* initialize the register allocator */
388 : {
389 92267 : reg_setup(jd);
390 : }
391 : #endif
392 :
393 : /* setup the codegendata memory */
394 :
395 92267 : codegen_setup(jd);
396 :
397 : /* now call internal compile function */
398 :
399 92267 : r = jit_compile_intern(jd);
400 : #if defined(ENABLE_COMPILER2)
401 92267 : if (method_matches(m,opt_CompileMethod)) {
402 : using namespace cacao::jit::compiler2;
403 0 : JITData JD(jd);
404 0 : ObjectFileWriterPass pass;
405 0 : pass.initialize();
406 0 : pass.run(JD);
407 0 : pass.finalize();
408 : }
409 : #endif
410 :
411 92267 : if (r == NULL) {
412 : /* We had an exception! Finish stuff here if necessary. */
413 :
414 : /* release codeinfo */
415 :
416 37 : code_codeinfo_free(jd->code);
417 : }
418 : else {
419 92230 : DEBUG_JIT_COMPILEVERBOSE("Running: ");
420 : }
421 :
422 : #if defined(ENABLE_STATISTICS)
423 : /* measure time */
424 :
425 : if (opt_getcompilingtime)
426 : compilingtime_stop();
427 : #endif
428 :
429 : // Hook point just after code was generated.
430 92267 : Hook::jit_generated(m, m->code);
431 :
432 : /* leave the monitor */
433 :
434 92267 : m->mutex->unlock();
435 :
436 : #if defined(ENABLE_STATISTICS)
437 : if (m && m->code)
438 : compiler_last_codesize = m->code->mcodelength;
439 : #endif
440 :
441 : /* return pointer to the methods entry point */
442 :
443 92267 : return r;
444 : }
445 :
446 :
447 : /* jit_recompile ***************************************************************
448 :
449 : Recompiles a Java method.
450 :
451 : *******************************************************************************/
452 :
453 0 : u1 *jit_recompile(methodinfo *m)
454 : {
455 : u1 *r;
456 : jitdata *jd;
457 : u1 optlevel;
458 :
459 : /* check for max. optimization level */
460 :
461 0 : optlevel = (m->code) ? m->code->optlevel : 0;
462 :
463 : #if 0
464 : if (optlevel == 1) {
465 : /* log_message_method("not recompiling: ", m); */
466 : return NULL;
467 : }
468 : #endif
469 :
470 0 : DEBUG_JIT_COMPILEVERBOSE("Recompiling start: ");
471 :
472 :
473 : #if defined(ENABLE_STATISTICS)
474 : /* measure time */
475 :
476 : if (opt_getcompilingtime)
477 : compilingtime_start();
478 : #endif
479 :
480 : // Create new dump memory area.
481 0 : DumpMemoryArea dma;
482 :
483 : /* create jitdata structure */
484 :
485 0 : jd = jit_jitdata_new(m);
486 :
487 : /* set the current optimization level to the previous one plus 1 */
488 :
489 0 : jd->code->optlevel = optlevel + 1;
490 :
491 : /* get the optimization flags for the current JIT run */
492 :
493 : #if defined(ENABLE_VERIFIER)
494 0 : jd->flags |= JITDATA_FLAG_VERIFY;
495 : #endif
496 :
497 : /* jd->flags |= JITDATA_FLAG_REORDER; */
498 0 : if (opt_showintermediate)
499 0 : jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
500 0 : if (opt_showdisassemble)
501 0 : jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
502 0 : if (opt_verbosecall)
503 0 : jd->flags |= JITDATA_FLAG_VERBOSECALL;
504 :
505 : #if defined(ENABLE_INLINING)
506 : // XXX #warning Inlining currently disabled (broken)
507 : #if 0
508 : if (opt_Inline)
509 : jd->flags |= JITDATA_FLAG_INLINE;
510 : #endif
511 : #endif
512 :
513 : #if defined(ENABLE_JIT)
514 : # if defined(ENABLE_INTRP)
515 : if (!opt_intrp)
516 : # endif
517 : /* initialize the register allocator */
518 :
519 0 : reg_setup(jd);
520 : #endif
521 :
522 : /* setup the codegendata memory */
523 :
524 0 : codegen_setup(jd);
525 :
526 : /* now call internal compile function */
527 :
528 0 : r = jit_compile_intern(jd);
529 :
530 0 : if (r == NULL) {
531 : /* We had an exception! Finish stuff here if necessary. */
532 :
533 : /* release codeinfo */
534 :
535 0 : code_codeinfo_free(jd->code);
536 : }
537 :
538 : #if defined(ENABLE_STATISTICS)
539 : /* measure time */
540 :
541 : if (opt_getcompilingtime)
542 : compilingtime_stop();
543 : #endif
544 :
545 : // Hook point just after code was generated.
546 0 : Hook::jit_generated(m, m->code);
547 :
548 0 : DEBUG_JIT_COMPILEVERBOSE("Recompiling done: ");
549 :
550 : /* return pointer to the methods entry point */
551 :
552 0 : return r;
553 : }
554 :
555 : #if defined(ENABLE_PM_HACKS)
556 : #include "vm/jit/jit_pm_1.inc"
557 : #endif
558 :
559 : // register compiler real-time group
560 : RT_REGISTER_GROUP(compiler_group,"compiler","baseline compiler")
561 :
562 : // register real-time timers
563 : RT_REGISTER_GROUP_TIMER(checks_timer, "compiler","checks at beginning", compiler_group)
564 : RT_REGISTER_GROUP_TIMER(parse_timer, "compiler","parse", compiler_group)
565 : RT_REGISTER_GROUP_TIMER(stack_timer, "compiler","analyse_stack", compiler_group)
566 : RT_REGISTER_GROUP_TIMER(typechecker_timer, "compiler","typecheck", compiler_group)
567 : RT_REGISTER_GROUP_TIMER(loop_timer, "compiler","loop", compiler_group)
568 : RT_REGISTER_GROUP_TIMER(ifconversion_timer, "compiler","if conversion", compiler_group)
569 : RT_REGISTER_GROUP_TIMER(ra_timer, "compiler","register allocation", compiler_group)
570 : RT_REGISTER_GROUP_TIMER(codegen_timer, "compiler","codegen", compiler_group)
571 :
572 : /* jit_compile_intern **********************************************************
573 :
574 : Static internal function which does the actual compilation.
575 :
576 : *******************************************************************************/
577 :
578 92267 : static u1 *jit_compile_intern(jitdata *jd)
579 : {
580 : methodinfo *m;
581 : //codegendata *cd;
582 : codeinfo *code;
583 :
584 : RT_TIMER_START(checks_timer);
585 :
586 : /* get required compiler data */
587 :
588 : #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
589 : jd->ls = NULL;
590 : #endif
591 92267 : m = jd->m;
592 92267 : code = jd->code;
593 : //cd = jd->cd;
594 :
595 : #if defined(ENABLE_DEBUG_FILTER)
596 92267 : show_filters_apply(jd->m);
597 : #endif
598 :
599 : // Handle native methods and create a native stub.
600 92267 : if (m->flags & ACC_NATIVE) {
601 5832 : NativeMethods& nm = VM::get_current()->get_nativemethods();
602 5832 : void* f = nm.resolve_method(m);
603 :
604 5832 : if (f == NULL)
605 1 : return NULL;
606 :
607 : // XXX reinterpret_cast is used to prevend a compiler warning
608 : // The Native* framework requires a rework to make it type safer
609 : // and to get rid of this hack
610 5831 : code = NativeStub::generate(m, *reinterpret_cast<functionptr*>(&f));
611 :
612 : /* Native methods are never recompiled. */
613 :
614 5831 : assert(!m->code);
615 :
616 5831 : m->code = code;
617 :
618 5831 : return code->entrypoint;
619 : }
620 :
621 : /* if there is no javacode, print error message and return empty method */
622 :
623 86435 : if (m->jcode == NULL) {
624 0 : DEBUG_JIT_COMPILEVERBOSE("No code given for: ");
625 :
626 0 : code->entrypoint = (u1 *) (ptrint) do_nothing_function;
627 0 : m->code = code;
628 :
629 0 : return code->entrypoint; /* return empty method */
630 : }
631 :
632 : STATISTICS(count_javacodesize += m->jcodelength + 18);
633 : STATISTICS(count_tryblocks += jd->exceptiontablelength);
634 : STATISTICS(count_javaexcsize += jd->exceptiontablelength * SIZEOF_VOID_P);
635 :
636 : RT_TIMER_STOPSTART(checks_timer,parse_timer);
637 :
638 : #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
639 : /* Code for Sun's OpenJDK (see
640 : hotspot/src/share/vm/classfile/verifier.cpp
641 : (Verifier::is_eligible_for_verification)): Don't verify
642 : dynamically-generated bytecodes. */
643 :
644 : # if defined(ENABLE_VERIFIER)
645 : if (class_issubclass(m->clazz, class_sun_reflect_MagicAccessorImpl))
646 : jd->flags &= ~JITDATA_FLAG_VERIFY;
647 : # endif
648 : #endif
649 :
650 : /* call the compiler passes ***********************************************/
651 :
652 86435 : DEBUG_JIT_COMPILEVERBOSE("Parsing: ");
653 :
654 : /* call parse pass */
655 :
656 86435 : if (!parse(jd)) {
657 3 : DEBUG_JIT_COMPILEVERBOSE("Exception while parsing: ");
658 :
659 3 : return NULL;
660 : }
661 : RT_TIMER_STOP(parse_timer);
662 :
663 86432 : DEBUG_JIT_COMPILEVERBOSE("Parsing done: ");
664 :
665 : #if defined(ENABLE_JIT)
666 : # if defined(ENABLE_INTRP)
667 : if (!opt_intrp) {
668 : # endif
669 : RT_TIMER_START(stack_timer);
670 86432 : DEBUG_JIT_COMPILEVERBOSE("Analysing: ");
671 :
672 : /* call stack analysis pass */
673 :
674 86432 : if (!stack_analyse(jd)) {
675 16 : DEBUG_JIT_COMPILEVERBOSE("Exception while analysing: ");
676 :
677 16 : return NULL;
678 : }
679 : RT_TIMER_STOPSTART(stack_timer,typechecker_timer);
680 :
681 86416 : DEBUG_JIT_COMPILEVERBOSE("Analysing done: ");
682 :
683 : #ifdef ENABLE_VERIFIER
684 86416 : if (JITDATA_HAS_FLAG_VERIFY(jd)) {
685 86416 : DEBUG_JIT_COMPILEVERBOSE("Typechecking: ");
686 :
687 : /* call typecheck pass */
688 86416 : if (!typecheck(jd)) {
689 17 : DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking: ");
690 :
691 17 : return NULL;
692 : }
693 :
694 86399 : DEBUG_JIT_COMPILEVERBOSE("Typechecking done: ");
695 : }
696 : #endif
697 : RT_TIMER_STOPSTART(typechecker_timer,loop_timer);
698 :
699 : #if defined(ENABLE_IFCONV)
700 86399 : if (JITDATA_HAS_FLAG_IFCONV(jd)) {
701 0 : if (!ifconv_static(jd))
702 0 : return NULL;
703 0 : jit_renumber_basicblocks(jd);
704 : }
705 : #endif
706 : RT_TIMER_STOPSTART(ifconversion_timer,ra_timer);
707 :
708 : /* inlining */
709 :
710 : #if defined(ENABLE_INLINING) && (!defined(ENABLE_ESCAPE) || 1)
711 : if (JITDATA_HAS_FLAG_INLINE(jd)) {
712 : if (!inline_inline(jd))
713 : return NULL;
714 : }
715 : #endif
716 :
717 : #if defined(ENABLE_SSA)
718 : if (opt_lsra) {
719 : fix_exception_handlers(jd);
720 : }
721 : #endif
722 :
723 : /* Build the CFG. This has to be done after stack_analyse, as
724 : there happens the JSR elimination. */
725 :
726 86399 : if (!cfg_build(jd))
727 0 : return NULL;
728 :
729 : #if defined(ENABLE_LOOP)
730 : if (opt_loops)
731 : {
732 : removeArrayBoundChecks(jd);
733 : jit_renumber_basicblocks(jd);
734 :
735 : cfg_clear(jd);
736 : if (!cfg_build(jd))
737 : return NULL;
738 : }
739 : #endif
740 : RT_TIMER_STOPSTART(ra_timer,loop_timer);
741 :
742 : #if defined(ENABLE_PROFILING)
743 : /* Basic block reordering. I think this should be done after
744 : if-conversion, as we could lose the ability to do the
745 : if-conversion. */
746 :
747 : if (JITDATA_HAS_FLAG_REORDER(jd)) {
748 : if (!reorder(jd))
749 : return NULL;
750 : jit_renumber_basicblocks(jd);
751 : }
752 : #endif
753 :
754 : #if defined(ENABLE_PM_HACKS)
755 : #include "vm/jit/jit_pm_2.inc"
756 : #endif
757 86399 : DEBUG_JIT_COMPILEVERBOSE("Allocating registers: ");
758 :
759 : #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
760 : /* allocate registers */
761 : if (opt_lsra) {
762 : if (!lsra(jd))
763 : return NULL;
764 :
765 : STATISTICS(count_methods_allocated_by_lsra++);
766 :
767 : } else
768 : # endif /* defined(ENABLE_LSRA) && !defined(ENABLE_SSA) */
769 : #if defined(ENABLE_SSA)
770 : /* allocate registers */
771 : if (
772 : (opt_lsra &&
773 : jd->code->optlevel > 0)
774 : /* strncmp(UTF_TEXT(jd->m->name), "hottie", 6) == 0*/
775 : /*&& jd->exceptiontablelength == 0*/
776 : ) {
777 : /*printf("=== %s ===\n", UTF_TEXT(jd->m->name));*/
778 : jd->ls = (lsradata*) DumpMemory::allocate(sizeof(lsradata));
779 : jd->ls = NULL;
780 : ssa(jd);
781 : /*lsra(jd);*/ regalloc(jd);
782 : /*eliminate_subbasicblocks(jd);*/
783 : STATISTICS(count_methods_allocated_by_lsra++);
784 :
785 : } else
786 : # endif /* defined(ENABLE_SSA) */
787 : {
788 : STATISTICS(count_locals_conflicts += (jd->maxlocals - 1) * (jd->maxlocals));
789 :
790 86399 : regalloc(jd);
791 : }
792 :
793 : STATISTICS(simplereg_make_statistics(jd));
794 :
795 : RT_TIMER_STOP(ra_timer);
796 86399 : DEBUG_JIT_COMPILEVERBOSE("Allocating registers done: ");
797 : # if defined(ENABLE_INTRP)
798 : }
799 : # endif
800 : #endif /* defined(ENABLE_JIT) */
801 : RT_TIMER_START(codegen_timer);
802 :
803 : #if defined(ENABLE_PROFILING)
804 : /* Allocate memory for basic block profiling information. This
805 : _must_ be done after loop optimization and register allocation,
806 : since they can change the basic block count. */
807 :
808 : if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
809 : code->basicblockcount = jd->basicblockcount;
810 : code->bbfrequency = MNEW(u4, jd->basicblockcount);
811 : }
812 : #endif
813 :
814 86399 : DEBUG_JIT_COMPILEVERBOSE("Generating code: ");
815 :
816 : /* now generate the machine code */
817 :
818 : #if defined(ENABLE_JIT)
819 : # if defined(ENABLE_INTRP)
820 : if (opt_intrp) {
821 : #if defined(ENABLE_VERIFIER)
822 : if (opt_verify) {
823 : DEBUG_JIT_COMPILEVERBOSE("Typechecking (stackbased): ");
824 :
825 : if (!typecheck_stackbased(jd)) {
826 : DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking (stackbased): ");
827 : return NULL;
828 : }
829 : }
830 : #endif
831 : if (!intrp_codegen(jd)) {
832 : DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
833 :
834 : return NULL;
835 : }
836 : } else
837 : # endif
838 : {
839 86399 : if (!codegen_generate(jd)) {
840 0 : DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
841 :
842 0 : return NULL;
843 : }
844 : }
845 : #else
846 : if (!intrp_codegen(jd)) {
847 : DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
848 :
849 : return NULL;
850 : }
851 : #endif
852 : RT_TIMER_STOP(codegen_timer);
853 :
854 86399 : DEBUG_JIT_COMPILEVERBOSE("Generating code done: ");
855 :
856 : #if !defined(NDEBUG) && defined(ENABLE_REPLACEMENT)
857 : /* activate replacement points inside newly created code */
858 :
859 : if (opt_TestReplacement)
860 : replace_activate_replacement_points(code, false);
861 : #endif
862 :
863 : #if !defined(NDEBUG)
864 : #if defined(ENABLE_DEBUG_FILTER)
865 86399 : if (jd->m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
866 : #endif
867 : {
868 : /* intermediate and assembly code listings */
869 :
870 86399 : if (JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)) {
871 0 : show_method(jd, SHOW_CODE);
872 : }
873 86399 : else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
874 : # if defined(ENABLE_DISASSEMBLER)
875 : DISASSEMBLE(code->entrypoint,
876 : code->entrypoint + (code->mcodelength - jd->cd->dseglen));
877 : # endif
878 : }
879 :
880 86399 : if (opt_showddatasegment)
881 0 : dseg_display(jd);
882 : }
883 : #endif
884 :
885 : /* switch to the newly generated code */
886 :
887 86399 : assert(code);
888 86399 : assert(code->entrypoint);
889 :
890 : /* add the current compile version to the methodinfo */
891 :
892 86399 : code->prev = m->code;
893 86399 : m->code = code;
894 :
895 : /* return pointer to the methods entry point */
896 :
897 86399 : return code->entrypoint;
898 : }
899 :
900 :
901 : /* jit_invalidate_code *********************************************************
902 :
903 : Mark the compiled code of the given method as invalid and take care that
904 : it is replaced if necessary.
905 :
906 : XXX Not fully implemented, yet.
907 :
908 : *******************************************************************************/
909 :
910 0 : void jit_invalidate_code(methodinfo *m)
911 : {
912 : codeinfo *code;
913 :
914 0 : code = m->code;
915 :
916 0 : if (code == NULL || code_is_invalid(code))
917 0 : return;
918 :
919 0 : code_flag_invalid(code);
920 :
921 : /* activate mappable replacement points */
922 :
923 : #if defined(ENABLE_REPLACEMENT)
924 : replace_activate_replacement_points(code, true);
925 : #else
926 0 : vm_abort("invalidating code only works with ENABLE_REPLACEMENT");
927 : #endif
928 : }
929 :
930 :
931 : /* jit_request_optimization ****************************************************
932 :
933 : Request optimization of the given method. If the code of the method is
934 : unoptimized, it will be invalidated, so the next jit_get_current_code(m)
935 : triggers an optimized recompilation.
936 : If the method is already optimized, this function does nothing.
937 :
938 : IN:
939 : m................the method
940 :
941 : *******************************************************************************/
942 :
943 0 : void jit_request_optimization(methodinfo *m)
944 : {
945 : codeinfo *code;
946 :
947 0 : code = m->code;
948 :
949 0 : if (code && code->optlevel == 0)
950 0 : jit_invalidate_code(m);
951 0 : }
952 :
953 :
954 : /* jit_get_current_code ********************************************************
955 :
956 : Get the currently valid code for the given method. If there is no valid
957 : code, (re)compile the method.
958 :
959 : IN:
960 : m................the method
961 :
962 : RETURN VALUE:
963 : the codeinfo* for the current code, or
964 : NULL if an exception has been thrown during recompilation.
965 :
966 : *******************************************************************************/
967 :
968 0 : codeinfo *jit_get_current_code(methodinfo *m)
969 : {
970 0 : assert(m);
971 :
972 : /* if we have valid code, return it */
973 :
974 0 : if (m->code && !code_is_invalid(m->code))
975 0 : return m->code;
976 :
977 : /* otherwise: recompile */
978 :
979 : #if defined(ENABLE_COMPILER2)
980 0 : if (!cacao::jit::compiler2::compile(m))
981 0 : return NULL;
982 : #else
983 : if (!jit_recompile(m))
984 : return NULL;
985 : #endif
986 :
987 0 : assert(m->code);
988 :
989 0 : return m->code;
990 : }
991 :
992 :
993 : /* jit_asm_compile *************************************************************
994 :
995 : This method is called from asm_vm_call_method and does:
996 :
997 : - create stackframe info for exceptions
998 : - compile the method
999 : - patch the entrypoint of the method into the calculated address in
1000 : the JIT code
1001 : - flushes the instruction cache.
1002 :
1003 : *******************************************************************************/
1004 :
1005 : #if defined(ENABLE_JIT)
1006 : #if !defined(JIT_COMPILER_VIA_SIGNAL)
1007 : extern "C" {
1008 : void* jit_asm_compile(methodinfo *m, void* mptr, void* sp, void* ra)
1009 : {
1010 : stackframeinfo_t sfi;
1011 : void *entrypoint;
1012 : void *pa;
1013 : uintptr_t *p;
1014 :
1015 : /* create the stackframeinfo (subtract 1 from RA as it points to the */
1016 : /* instruction after the call) */
1017 :
1018 : stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ((uint8_t*) ra) - 1);
1019 :
1020 : /* actually compile the method */
1021 :
1022 : entrypoint = jit_compile(m);
1023 :
1024 : /* remove the stackframeinfo */
1025 :
1026 : stacktrace_stackframeinfo_remove(&sfi);
1027 :
1028 : /* there was a problem during compilation */
1029 :
1030 : if (entrypoint == NULL)
1031 : return NULL;
1032 :
1033 : /* get the method patch address */
1034 :
1035 : pa = md_jit_method_patch_address(sfi.pv, (void *) ra, mptr);
1036 :
1037 : /* patch the method entry point */
1038 :
1039 : p = (uintptr_t*) pa;
1040 :
1041 : *p = (uintptr_t) entrypoint;
1042 :
1043 : /* flush the instruction cache */
1044 :
1045 : md_icacheflush(pa, SIZEOF_VOID_P);
1046 :
1047 : return entrypoint;
1048 : }
1049 : }
1050 : #endif
1051 :
1052 : /* jit_compile_handle **********************************************************
1053 :
1054 : This method is called from the appropriate signal handler which
1055 : handles compiler-traps and does the following:
1056 :
1057 : - compile the method
1058 : - patch the entrypoint of the method into the calculated address in
1059 : the JIT code
1060 : - flush the instruction cache
1061 :
1062 : *******************************************************************************/
1063 :
1064 126223 : void *jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr)
1065 : {
1066 : void *newpv; /* new compiled method PV */
1067 : void *pa; /* patch address */
1068 : uintptr_t *p; /* convenience pointer */
1069 :
1070 : /* Compile the method. */
1071 :
1072 126223 : newpv = jit_compile(m);
1073 :
1074 : /* There was a problem during compilation. */
1075 :
1076 126223 : if (newpv == NULL)
1077 4 : return NULL;
1078 :
1079 : /* Get the method patch address. */
1080 :
1081 126219 : pa = md_jit_method_patch_address(pv, ra, mptr);
1082 :
1083 : /* Patch the method entry point. */
1084 :
1085 126219 : p = (uintptr_t *) pa;
1086 :
1087 126219 : *p = (uintptr_t) newpv;
1088 :
1089 : /* Flush both caches. */
1090 :
1091 126219 : md_cacheflush(pa, SIZEOF_VOID_P);
1092 :
1093 126219 : return newpv;
1094 : }
1095 : #endif /* defined(ENABLE_JIT) */
1096 :
1097 :
1098 : /* jit_complement_condition ****************************************************
1099 :
1100 : Returns the complement of the passed conditional instruction.
1101 :
1102 : We use the order of the different conditions, e.g.:
1103 :
1104 : ICMD_IFEQ 153
1105 : ICMD_IFNE 154
1106 :
1107 : If the passed opcode is odd, we simply add 1 to get the complement.
1108 : If the opcode is even, we subtract 1.
1109 :
1110 : Exception:
1111 :
1112 : ICMD_IFNULL 198
1113 : ICMD_IFNONNULL 199
1114 :
1115 : *******************************************************************************/
1116 :
1117 0 : ICMD jit_complement_condition(ICMD opcode)
1118 : {
1119 0 : switch (opcode) {
1120 : case ICMD_IFNULL:
1121 0 : return ICMD_IFNONNULL;
1122 :
1123 : case ICMD_IFNONNULL:
1124 0 : return ICMD_IFNULL;
1125 :
1126 : default:
1127 : /* check if opcode is odd */
1128 :
1129 0 : if (opcode & 0x1)
1130 0 : return ICMD(opcode + 1);
1131 : else
1132 0 : return ICMD(opcode - 1);
1133 : }
1134 : }
1135 :
1136 :
1137 : /* jit_renumber_basicblocks ****************************************************
1138 :
1139 : Set the ->nr of all blocks so it increases when traversing ->next.
1140 :
1141 : IN:
1142 : jitdata..........the current jitdata
1143 :
1144 : *******************************************************************************/
1145 :
1146 0 : void jit_renumber_basicblocks(jitdata *jd)
1147 : {
1148 : s4 nr;
1149 : basicblock *bptr;
1150 :
1151 0 : nr = 0;
1152 0 : for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1153 0 : bptr->nr = nr++;
1154 : }
1155 :
1156 : /* we have one block more than jd->basicblockcount (the end marker) */
1157 :
1158 0 : assert(nr == jd->basicblockcount + 1);
1159 0 : }
1160 :
1161 :
1162 : /* jit_check_basicblock_numbers ************************************************
1163 :
1164 : Assert that the ->nr of the first block is zero and increases by 1 each
1165 : time ->next is traversed.
1166 : This function should be called before any analysis that relies on
1167 : the basicblock numbers.
1168 :
1169 : IN:
1170 : jitdata..........the current jitdata
1171 :
1172 : NOTE: Aborts with an assertion if the condition is not met!
1173 :
1174 : *******************************************************************************/
1175 :
1176 : #if !defined(NDEBUG)
1177 86416 : void jit_check_basicblock_numbers(jitdata *jd)
1178 : {
1179 : s4 nr;
1180 : basicblock *bptr;
1181 :
1182 86416 : nr = 0;
1183 492156 : for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1184 405740 : assert(bptr->nr == nr);
1185 405740 : nr++;
1186 : }
1187 :
1188 : /* we have one block more than jd->basicblockcount (the end marker) */
1189 :
1190 86416 : assert(nr == jd->basicblockcount + 1);
1191 86416 : }
1192 : #endif /* !defined(NDEBUG) */
1193 :
1194 :
1195 : /*
1196 : * These are local overrides for various environment variables in Emacs.
1197 : * Please do not remove this and leave it at the end of the file, where
1198 : * Emacs will automagically detect them.
1199 : * ---------------------------------------------------------------------
1200 : * Local variables:
1201 : * mode: c++
1202 : * indent-tabs-mode: t
1203 : * c-basic-offset: 4
1204 : * tab-width: 4
1205 : * End:
1206 : * vim:noexpandtab:sw=4:ts=4:
1207 : */
|