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