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