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