* src/mm/tlh.c (tlh_alloc): Correctly zero memory.
[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_LOOP)
705                 if (opt_loops) {
706                         depthFirst(jd);
707                         analyseGraph(jd);
708                         optimize_loops(jd);
709                         jit_renumber_basicblocks(jd);
710                 }
711 #endif
712                 RT_TIMING_GET_TIME(time_loop);
713
714 #if defined(ENABLE_IFCONV)
715                 if (JITDATA_HAS_FLAG_IFCONV(jd)) {
716                         if (!ifconv_static(jd))
717                                 return NULL;
718                         jit_renumber_basicblocks(jd);
719                 }
720 #endif
721                 RT_TIMING_GET_TIME(time_ifconv);
722
723                 /* inlining */
724
725 #if defined(ENABLE_INLINING) && !defined(ENABLE_ESCAPE) || 1
726                 if (JITDATA_HAS_FLAG_INLINE(jd)) {
727                         if (!inline_inline(jd))
728                                 return NULL;
729                 }
730 #endif
731
732 #if defined(ENABLE_SSA)
733                 if (opt_lsra) {
734                         fix_exception_handlers(jd);
735                 }
736 #endif
737
738                 /* Build the CFG.  This has to be done after stack_analyse, as
739                    there happens the JSR elimination. */
740
741                 if (!cfg_build(jd))
742                         return NULL;
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                         jd->code->optlevel > 0) 
776                         /* strncmp(jd->m->name->text, "hottie", 6) == 0*/
777                         /*&& jd->exceptiontablelength == 0*/
778                 ) {
779                         /*printf("=== %s ===\n", jd->m->name->text);*/
780                         jd->ls = DNEW(lsradata);
781                         jd->ls = NULL;
782                         ssa(jd);
783                         /*lsra(jd);*/ regalloc(jd);
784                         /*eliminate_subbasicblocks(jd);*/
785                         STATISTICS(count_methods_allocated_by_lsra++);
786
787                 } else
788 # endif /* defined(ENABLE_SSA) */
789                 {
790                         STATISTICS(count_locals_conflicts += (jd->maxlocals - 1) * (jd->maxlocals));
791
792                         regalloc(jd);
793                 }
794
795                 STATISTICS(simplereg_make_statistics(jd));
796
797                 DEBUG_JIT_COMPILEVERBOSE("Allocating registers done: ");
798 # if defined(ENABLE_INTRP)
799         }
800 # endif
801 #endif /* defined(ENABLE_JIT) */
802         RT_TIMING_GET_TIME(time_alloc);
803
804 #if defined(ENABLE_PROFILING)
805         /* Allocate memory for basic block profiling information. This
806            _must_ be done after loop optimization and register allocation,
807            since they can change the basic block count. */
808
809         if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
810                 code->bbfrequency = MNEW(u4, jd->basicblockcount);
811 #endif
812
813         DEBUG_JIT_COMPILEVERBOSE("Generating code: ");
814
815         /* now generate the machine code */
816
817 #if defined(ENABLE_JIT)
818 # if defined(ENABLE_INTRP)
819         if (opt_intrp) {
820 #if defined(ENABLE_VERIFIER)
821                 if (opt_verify) {
822                         DEBUG_JIT_COMPILEVERBOSE("Typechecking (stackbased): ");
823
824                         if (!typecheck_stackbased(jd)) {
825                                 DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking (stackbased): ");
826                                 return NULL;
827                         }
828                 }
829 #endif
830                 if (!intrp_codegen(jd)) {
831                         DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
832
833                         return NULL;
834                 }
835         } else
836 # endif
837                 {
838                         if (!codegen_generate(jd)) {
839                                 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
840
841                                 return NULL;
842                         }
843                 }
844 #else
845         if (!intrp_codegen(jd)) {
846                 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
847
848                 return NULL;
849         }
850 #endif
851         RT_TIMING_GET_TIME(time_codegen);
852
853         DEBUG_JIT_COMPILEVERBOSE("Generating code done: ");
854
855 #if !defined(NDEBUG) && defined(ENABLE_REPLACEMENT)
856         /* activate replacement points inside newly created code */
857
858         if (opt_TestReplacement)
859                 replace_activate_replacement_points(code, false);
860 #endif
861
862 #if !defined(NDEBUG)
863 #if defined(ENABLE_DEBUG_FILTER)
864         if (jd->m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
865 #endif
866         {
867                 /* intermediate and assembly code listings */
868                 
869                 if (JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)) {
870                         show_method(jd, SHOW_CODE);
871                 }
872                 else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
873 # if defined(ENABLE_DISASSEMBLER)
874                         DISASSEMBLE(code->entrypoint,
875                                                 code->entrypoint + (code->mcodelength - cd->dseglen));
876 # endif
877                 }
878
879                 if (opt_showddatasegment)
880                         dseg_display(jd);
881         }
882 #endif
883
884         /* switch to the newly generated code */
885
886         assert(code);
887         assert(code->entrypoint);
888
889         /* add the current compile version to the methodinfo */
890
891         code->prev = m->code;
892         m->code = code;
893
894         RT_TIMING_TIME_DIFF(time_start,time_checks,RT_TIMING_JIT_CHECKS);
895         RT_TIMING_TIME_DIFF(time_checks,time_parse,RT_TIMING_JIT_PARSE);
896         RT_TIMING_TIME_DIFF(time_parse,time_stack,RT_TIMING_JIT_STACK);
897         RT_TIMING_TIME_DIFF(time_stack,time_typecheck,RT_TIMING_JIT_TYPECHECK);
898         RT_TIMING_TIME_DIFF(time_typecheck,time_loop,RT_TIMING_JIT_LOOP);
899         RT_TIMING_TIME_DIFF(time_loop,time_alloc,RT_TIMING_JIT_ALLOC);
900         RT_TIMING_TIME_DIFF(time_alloc,time_codegen,RT_TIMING_JIT_CODEGEN);
901         RT_TIMING_TIME_DIFF(time_start,time_codegen,RT_TIMING_JIT_TOTAL);
902
903         /* return pointer to the methods entry point */
904
905         return code->entrypoint;
906
907
908
909 /* jit_invalidate_code *********************************************************
910
911    Mark the compiled code of the given method as invalid and take care that
912    it is replaced if necessary.
913
914    XXX Not fully implemented, yet.
915
916 *******************************************************************************/
917
918 void jit_invalidate_code(methodinfo *m)
919 {
920         codeinfo *code;
921
922         code = m->code;
923
924         if (code == NULL || code_is_invalid(code))
925                 return;
926
927         code_flag_invalid(code);
928
929         /* activate mappable replacement points */
930
931 #if defined(ENABLE_REPLACEMENT)
932         replace_activate_replacement_points(code, true);
933 #else
934         vm_abort("invalidating code only works with ENABLE_REPLACEMENT");
935 #endif
936 }
937
938
939 /* jit_request_optimization ****************************************************
940
941    Request optimization of the given method. If the code of the method is
942    unoptimized, it will be invalidated, so the next jit_get_current_code(m)
943    triggers an optimized recompilation.
944    If the method is already optimized, this function does nothing.
945
946    IN:
947        m................the method
948
949 *******************************************************************************/
950
951 void jit_request_optimization(methodinfo *m)
952 {
953         codeinfo *code;
954
955         code = m->code;
956
957         if (code && code->optlevel == 0)
958                 jit_invalidate_code(m);
959 }
960
961
962 /* jit_get_current_code ********************************************************
963
964    Get the currently valid code for the given method. If there is no valid
965    code, (re)compile the method.
966
967    IN:
968        m................the method
969
970    RETURN VALUE:
971        the codeinfo* for the current code, or
972            NULL if an exception has been thrown during recompilation.
973
974 *******************************************************************************/
975
976 codeinfo *jit_get_current_code(methodinfo *m)
977 {
978         assert(m);
979
980         /* if we have valid code, return it */
981
982         if (m->code && !code_is_invalid(m->code))
983                 return m->code;
984
985         /* otherwise: recompile */
986
987         if (!jit_recompile(m))
988                 return NULL;
989
990         assert(m->code);
991
992         return m->code;
993 }
994
995
996 /* jit_asm_compile *************************************************************
997
998    This method is called from asm_vm_call_method and does:
999
1000      - create stackframe info for exceptions
1001      - compile the method
1002      - patch the entrypoint of the method into the calculated address in
1003        the JIT code
1004      - flushes the instruction cache.
1005
1006 *******************************************************************************/
1007
1008 #if defined(ENABLE_JIT)
1009 #if !defined(JIT_COMPILER_VIA_SIGNAL)
1010 u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
1011 {
1012         stackframeinfo_t  sfi;
1013         u1               *entrypoint;
1014         u1               *pa;
1015         ptrint           *p;
1016
1017         /* create the stackframeinfo (subtract 1 from RA as it points to the */
1018         /* instruction after the call)                                       */
1019
1020         stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra-1);
1021
1022         /* actually compile the method */
1023
1024         entrypoint = jit_compile(m);
1025
1026         /* remove the stackframeinfo */
1027
1028         stacktrace_stackframeinfo_remove(&sfi);
1029
1030         /* there was a problem during compilation */
1031
1032         if (entrypoint == NULL)
1033                 return NULL;
1034
1035         /* get the method patch address */
1036
1037         pa = md_jit_method_patch_address(sfi.pv, (void *) ra, mptr);
1038
1039         /* patch the method entry point */
1040
1041         p = (ptrint *) pa;
1042
1043         *p = (ptrint) entrypoint;
1044
1045         /* flush the instruction cache */
1046
1047         md_icacheflush(pa, SIZEOF_VOID_P);
1048
1049         return entrypoint;
1050 }
1051 #endif
1052
1053 /* jit_compile_handle **********************************************************
1054
1055    This method is called from the appropriate signal handler which
1056    handles compiler-traps and does the following:
1057
1058      - compile the method
1059      - patch the entrypoint of the method into the calculated address in
1060        the JIT code
1061      - flush the instruction cache
1062
1063 *******************************************************************************/
1064
1065 void *jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr)
1066 {
1067         void      *newpv;                               /* new compiled method PV */
1068         void      *pa;                                           /* patch address */
1069         uintptr_t *p;                                      /* convenience pointer */
1070
1071         /* Compile the method. */
1072
1073         newpv = jit_compile(m);
1074
1075         /* There was a problem during compilation. */
1076
1077         if (newpv == NULL)
1078                 return NULL;
1079
1080         /* Get the method patch address. */
1081
1082         pa = md_jit_method_patch_address(pv, ra, mptr);
1083
1084         /* Patch the method entry point. */
1085
1086         p = (uintptr_t *) pa;
1087
1088         *p = (uintptr_t) newpv;
1089
1090         /* Flush both caches. */
1091
1092         md_cacheflush(pa, SIZEOF_VOID_P);
1093
1094         return newpv;
1095 }
1096 #endif /* defined(ENABLE_JIT) */
1097
1098
1099 /* jit_complement_condition ****************************************************
1100
1101    Returns the complement of the passed conditional instruction.
1102
1103    We use the order of the different conditions, e.g.:
1104
1105    ICMD_IFEQ         153
1106    ICMD_IFNE         154
1107
1108    If the passed opcode is odd, we simply add 1 to get the complement.
1109    If the opcode is even, we subtract 1.
1110
1111    Exception:
1112
1113    ICMD_IFNULL       198
1114    ICMD_IFNONNULL    199
1115
1116 *******************************************************************************/
1117
1118 s4 jit_complement_condition(s4 opcode)
1119 {
1120         switch (opcode) {
1121         case ICMD_IFNULL:
1122                 return ICMD_IFNONNULL;
1123
1124         case ICMD_IFNONNULL:
1125                 return ICMD_IFNULL;
1126
1127         default:
1128                 /* check if opcode is odd */
1129
1130                 if (opcode & 0x1)
1131                         return opcode + 1;
1132                 else
1133                         return opcode - 1;
1134         }
1135 }
1136
1137
1138 /* jit_renumber_basicblocks ****************************************************
1139
1140    Set the ->nr of all blocks so it increases when traversing ->next.
1141
1142    IN:
1143        jitdata..........the current jitdata
1144
1145 *******************************************************************************/
1146
1147 void jit_renumber_basicblocks(jitdata *jd)
1148 {
1149         s4          nr;
1150         basicblock *bptr;
1151
1152         nr = 0;
1153         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1154                 bptr->nr = nr++;
1155         }
1156
1157         /* we have one block more than jd->basicblockcount (the end marker) */
1158
1159         assert(nr == jd->basicblockcount + 1);
1160 }
1161
1162
1163 /* jit_check_basicblock_numbers ************************************************
1164
1165    Assert that the ->nr of the first block is zero and increases by 1 each
1166    time ->next is traversed.
1167    This function should be called before any analysis that relies on
1168    the basicblock numbers.
1169
1170    IN:
1171        jitdata..........the current jitdata
1172
1173    NOTE: Aborts with an assertion if the condition is not met!
1174
1175 *******************************************************************************/
1176
1177 #if !defined(NDEBUG)
1178 void jit_check_basicblock_numbers(jitdata *jd)
1179 {
1180         s4          nr;
1181         basicblock *bptr;
1182
1183         nr = 0;
1184         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1185                 assert(bptr->nr == nr);
1186                 nr++;
1187         }
1188
1189         /* we have one block more than jd->basicblockcount (the end marker) */
1190
1191         assert(nr == jd->basicblockcount + 1);
1192 }
1193 #endif /* !defined(NDEBUG) */
1194
1195 methoddesc *instruction_call_site(const instruction *iptr) {
1196         if (iptr->opc == ICMD_BUILTIN) {
1197                 return iptr->sx.s23.s3.bte->md;
1198         } else if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1199                 return iptr->sx.s23.s3.um->methodref->parseddesc.md;
1200         } else {
1201                 return iptr->sx.s23.s3.fmiref->p.method->parseddesc;
1202         }
1203 }
1204
1205 /*
1206  * These are local overrides for various environment variables in Emacs.
1207  * Please do not remove this and leave it at the end of the file, where
1208  * Emacs will automagically detect them.
1209  * ---------------------------------------------------------------------
1210  * Local variables:
1211  * mode: c
1212  * indent-tabs-mode: t
1213  * c-basic-offset: 4
1214  * tab-width: 4
1215  * End:
1216  * vim:noexpandtab:sw=4:ts=4:
1217  */