* m4/classpath.m4: Renamed --with-classpath* options to
[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)
394                 jd->flags |= JITDATA_FLAG_COUNTDOWN;
395 #endif
396
397 #if defined(ENABLE_JIT)
398 # if defined(ENABLE_INTRP)
399         if (!opt_intrp)
400 # endif
401                 /* initialize the register allocator */
402         {
403                 reg_setup(jd);
404         }
405 #endif
406
407         /* setup the codegendata memory */
408
409         codegen_setup(jd);
410
411         /* now call internal compile function */
412
413         r = jit_compile_intern(jd);
414
415         if (r == NULL) {
416                 /* We had an exception! Finish stuff here if necessary. */
417
418                 /* release codeinfo */
419
420                 code_codeinfo_free(jd->code);
421
422 #if defined(ENABLE_PROFILING)
423                 /* Release memory for basic block profiling information. */
424
425                 if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
426                         if (jd->code->bbfrequency != NULL)
427                                 MFREE(jd->code->bbfrequency, u4, jd->code->basicblockcount);
428 #endif
429         }
430         else {
431                 DEBUG_JIT_COMPILEVERBOSE("Running: ");
432         }
433
434         /* release dump area */
435
436         DRELEASE;
437
438 #if defined(ENABLE_STATISTICS)
439         /* measure time */
440
441         if (opt_getcompilingtime)
442                 compilingtime_stop();
443 #endif
444
445         /* leave the monitor */
446
447         LOCK_MONITOR_EXIT(m);
448
449         /* return pointer to the methods entry point */
450
451         return r;
452 }
453
454
455 /* jit_recompile ***************************************************************
456
457    Recompiles a Java method.
458
459 *******************************************************************************/
460
461 u1 *jit_recompile(methodinfo *m)
462 {
463         u1      *r;
464         jitdata *jd;
465         u1       optlevel;
466         int32_t  dumpmarker;
467
468         /* check for max. optimization level */
469
470         optlevel = (m->code) ? m->code->optlevel : 0;
471
472 #if 0
473         if (optlevel == 1) {
474 /*              log_message_method("not recompiling: ", m); */
475                 return NULL;
476         }
477 #endif
478
479         DEBUG_JIT_COMPILEVERBOSE("Recompiling start: ");
480
481         STATISTICS(count_jit_calls++);
482
483 #if defined(ENABLE_STATISTICS)
484         /* measure time */
485
486         if (opt_getcompilingtime)
487                 compilingtime_start();
488 #endif
489
490         /* mark start of dump memory area */
491
492         DMARKER;
493
494         /* create jitdata structure */
495
496         jd = jit_jitdata_new(m);
497
498         /* set the current optimization level to the previous one plus 1 */
499
500         jd->code->optlevel = optlevel + 1;
501
502         /* get the optimization flags for the current JIT run */
503
504 #if defined(ENABLE_VERIFIER)
505         jd->flags |= JITDATA_FLAG_VERIFY;
506 #endif
507
508         /* jd->flags |= JITDATA_FLAG_REORDER; */
509         if (opt_showintermediate)
510                 jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
511         if (opt_showdisassemble)
512                 jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
513         if (opt_verbosecall)
514                 jd->flags |= JITDATA_FLAG_VERBOSECALL;
515
516 #if defined(ENABLE_INLINING)
517         if (opt_Inline)
518                 jd->flags |= JITDATA_FLAG_INLINE;
519 #endif
520
521 #if defined(ENABLE_JIT)
522 # if defined(ENABLE_INTRP)
523         if (!opt_intrp)
524 # endif
525                 /* initialize the register allocator */
526
527                 reg_setup(jd);
528 #endif
529
530         /* setup the codegendata memory */
531
532         codegen_setup(jd);
533
534         /* now call internal compile function */
535
536         r = jit_compile_intern(jd);
537
538         if (r == NULL) {
539                 /* We had an exception! Finish stuff here if necessary. */
540
541                 /* release codeinfo */
542
543                 code_codeinfo_free(jd->code);
544         }
545
546         /* release dump area */
547
548         DRELEASE;
549
550 #if defined(ENABLE_STATISTICS)
551         /* measure time */
552
553         if (opt_getcompilingtime)
554                 compilingtime_stop();
555 #endif
556
557         DEBUG_JIT_COMPILEVERBOSE("Recompiling done: ");
558
559         /* return pointer to the methods entry point */
560
561         return r;
562 }
563
564 #if defined(ENABLE_PM_HACKS)
565 #include "vm/jit/jit_pm_1.inc"
566 #endif
567
568 /* jit_compile_intern **********************************************************
569
570    Static internal function which does the actual compilation.
571
572 *******************************************************************************/
573
574 static u1 *jit_compile_intern(jitdata *jd)
575 {
576         methodinfo  *m;
577         codegendata *cd;
578         codeinfo    *code;
579
580 #if defined(ENABLE_RT_TIMING)
581         struct timespec time_start,time_checks,time_parse,time_stack,
582                                         time_typecheck,time_loop,time_ifconv,time_alloc,
583                                         time_codegen;
584 #endif
585         
586         RT_TIMING_GET_TIME(time_start);
587
588         /* get required compiler data */
589
590 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
591         jd->ls = NULL;
592 #endif
593         m    = jd->m;
594         code = jd->code;
595         cd   = jd->cd;
596         
597 #if defined(ENABLE_DEBUG_FILTER)
598         show_filters_apply(jd->m);
599 #endif
600
601         /* Handle native methods and create a native stub. */
602
603         if (m->flags & ACC_NATIVE) {
604                 functionptr f;
605
606                 f = native_method_resolve(m);
607
608                 if (f == NULL)
609                         return NULL;
610
611                 code = codegen_generate_stub_native(m, f);
612
613                 /* Native methods are never recompiled. */
614                 
615                 assert(!m->code);
616
617                 m->code = code;
618                 
619                 return code->entrypoint;
620         }
621
622         /* if there is no javacode, print error message and return empty method   */
623
624         if (m->jcode == NULL) {
625                 DEBUG_JIT_COMPILEVERBOSE("No code given for: ");
626
627                 code->entrypoint = (u1 *) (ptrint) do_nothing_function;
628                 m->code = code;
629
630                 return code->entrypoint;        /* return empty method                */
631         }
632
633 #if defined(ENABLE_STATISTICS)
634         if (opt_stat) {
635                 count_javacodesize += m->jcodelength + 18;
636                 count_tryblocks    += jd->exceptiontablelength;
637                 count_javaexcsize  += jd->exceptiontablelength * SIZEOF_VOID_P;
638         }
639 #endif
640
641         RT_TIMING_GET_TIME(time_checks);
642
643 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
644         /* Code for Sun's OpenJDK (see
645            hotspot/src/share/vm/classfile/verifier.cpp
646            (Verifier::is_eligible_for_verification)): Don't verify
647            dynamically-generated bytecodes. */
648
649 # if defined(ENABLE_VERIFIER)
650         if (class_issubclass(m->clazz, class_sun_reflect_MagicAccessorImpl))
651                 jd->flags &= ~JITDATA_FLAG_VERIFY;
652 # endif
653 #endif
654
655         /* call the compiler passes ***********************************************/
656
657         DEBUG_JIT_COMPILEVERBOSE("Parsing: ");
658
659         /* call parse pass */
660
661         if (!parse(jd)) {
662                 DEBUG_JIT_COMPILEVERBOSE("Exception while parsing: ");
663
664                 return NULL;
665         }
666         RT_TIMING_GET_TIME(time_parse);
667
668         DEBUG_JIT_COMPILEVERBOSE("Parsing done: ");
669         
670 #if defined(ENABLE_JIT)
671 # if defined(ENABLE_INTRP)
672         if (!opt_intrp) {
673 # endif
674                 DEBUG_JIT_COMPILEVERBOSE("Analysing: ");
675
676                 /* call stack analysis pass */
677
678                 if (!stack_analyse(jd)) {
679                         DEBUG_JIT_COMPILEVERBOSE("Exception while analysing: ");
680
681                         return NULL;
682                 }
683                 RT_TIMING_GET_TIME(time_stack);
684
685                 DEBUG_JIT_COMPILEVERBOSE("Analysing done: ");
686
687                 /* Build the CFG.  This has to be done after stack_analyse, as
688                    there happens the JSR elimination. */
689
690                 if (!cfg_build(jd))
691                         return NULL;
692
693 #ifdef ENABLE_VERIFIER
694                 if (JITDATA_HAS_FLAG_VERIFY(jd)) {
695                         DEBUG_JIT_COMPILEVERBOSE("Typechecking: ");
696
697                         /* call typecheck pass */
698                         if (!typecheck(jd)) {
699                                 DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking: ");
700
701                                 return NULL;
702                         }
703
704                         DEBUG_JIT_COMPILEVERBOSE("Typechecking done: ");
705                 }
706 #endif
707                 RT_TIMING_GET_TIME(time_typecheck);
708
709 #if defined(ENABLE_LOOP)
710                 if (opt_loops) {
711                         depthFirst(jd);
712                         analyseGraph(jd);
713                         optimize_loops(jd);
714                         jit_renumber_basicblocks(jd);
715                 }
716 #endif
717                 RT_TIMING_GET_TIME(time_loop);
718
719 #if defined(ENABLE_IFCONV)
720                 if (JITDATA_HAS_FLAG_IFCONV(jd)) {
721                         if (!ifconv_static(jd))
722                                 return NULL;
723                         jit_renumber_basicblocks(jd);
724                 }
725 #endif
726                 RT_TIMING_GET_TIME(time_ifconv);
727
728                 /* inlining */
729
730 #if defined(ENABLE_INLINING)
731                 if (JITDATA_HAS_FLAG_INLINE(jd)) {
732                         if (!inline_inline(jd))
733                                 return NULL;
734                 }
735 #endif
736
737 #if defined(ENABLE_PROFILING)
738                 /* Basic block reordering.  I think this should be done after
739                    if-conversion, as we could lose the ability to do the
740                    if-conversion. */
741
742                 if (JITDATA_HAS_FLAG_REORDER(jd)) {
743                         if (!reorder(jd))
744                                 return NULL;
745                         jit_renumber_basicblocks(jd);
746                 }
747 #endif
748
749 #if defined(ENABLE_PM_HACKS)
750 #include "vm/jit/jit_pm_2.inc"
751 #endif
752                 DEBUG_JIT_COMPILEVERBOSE("Allocating registers: ");
753
754 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
755                 /* allocate registers */
756                 if (opt_lsra) {
757                         if (!lsra(jd))
758                                 return NULL;
759
760                         STATISTICS(count_methods_allocated_by_lsra++);
761
762                 } else
763 # endif /* defined(ENABLE_LSRA) && !defined(ENABLE_SSA) */
764 #if defined(ENABLE_SSA)
765                 /* allocate registers */
766                 if ((opt_lsra) /*&& (strcmp(jd->m->name->text, "findClass") == 0 || jd->exceptiontablelength == 0)*/) {
767                         jd->ls = DNEW(lsradata);
768                         jd->ls = NULL;
769                         ssa(jd);
770                         /*lsra(jd);*/ regalloc(jd);
771                         eliminate_subbasicblocks(jd);
772                         STATISTICS(count_methods_allocated_by_lsra++);
773
774                 } else
775 # endif /* defined(ENABLE_SSA) */
776                 {
777                         STATISTICS(count_locals_conflicts += (jd->maxlocals - 1) * (jd->maxlocals));
778
779                         regalloc(jd);
780                 }
781
782                 STATISTICS(simplereg_make_statistics(jd));
783
784                 DEBUG_JIT_COMPILEVERBOSE("Allocating registers done: ");
785 # if defined(ENABLE_INTRP)
786         }
787 # endif
788 #endif /* defined(ENABLE_JIT) */
789         RT_TIMING_GET_TIME(time_alloc);
790
791 #if defined(ENABLE_PROFILING)
792         /* Allocate memory for basic block profiling information. This
793            _must_ be done after loop optimization and register allocation,
794            since they can change the basic block count. */
795
796         if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
797                 code->bbfrequency = MNEW(u4, jd->basicblockcount);
798 #endif
799
800         DEBUG_JIT_COMPILEVERBOSE("Generating code: ");
801
802         /* now generate the machine code */
803
804 #if defined(ENABLE_JIT)
805 # if defined(ENABLE_INTRP)
806         if (opt_intrp) {
807 #if defined(ENABLE_VERIFIER)
808                 if (opt_verify) {
809                         DEBUG_JIT_COMPILEVERBOSE("Typechecking (stackbased): ");
810
811                         if (!typecheck_stackbased(jd)) {
812                                 DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking (stackbased): ");
813                                 return NULL;
814                         }
815                 }
816 #endif
817                 if (!intrp_codegen(jd)) {
818                         DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
819
820                         return NULL;
821                 }
822         } else
823 # endif
824                 {
825                         if (!codegen_generate(jd)) {
826                                 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
827
828                                 return NULL;
829                         }
830                 }
831 #else
832         if (!intrp_codegen(jd)) {
833                 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
834
835                 return NULL;
836         }
837 #endif
838         RT_TIMING_GET_TIME(time_codegen);
839
840         DEBUG_JIT_COMPILEVERBOSE("Generating code done: ");
841
842 #if !defined(NDEBUG) && defined(ENABLE_REPLACEMENT)
843         /* activate replacement points inside newly created code */
844
845         if (opt_TestReplacement)
846                 replace_activate_replacement_points(code, false);
847 #endif
848
849 #if !defined(NDEBUG)
850 #if defined(ENABLE_DEBUG_FILTER)
851         if (jd->m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
852 #endif
853         {
854                 /* intermediate and assembly code listings */
855                 
856                 if (JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)) {
857                         show_method(jd, SHOW_CODE);
858                 }
859                 else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
860 # if defined(ENABLE_DISASSEMBLER)
861                         DISASSEMBLE(code->entrypoint,
862                                                 code->entrypoint + (code->mcodelength - cd->dseglen));
863 # endif
864                 }
865
866                 if (opt_showddatasegment)
867                         dseg_display(jd);
868         }
869 #endif
870
871         /* switch to the newly generated code */
872
873         assert(code);
874         assert(code->entrypoint);
875
876         /* add the current compile version to the methodinfo */
877
878         code->prev = m->code;
879         m->code = code;
880
881         RT_TIMING_TIME_DIFF(time_start,time_checks,RT_TIMING_JIT_CHECKS);
882         RT_TIMING_TIME_DIFF(time_checks,time_parse,RT_TIMING_JIT_PARSE);
883         RT_TIMING_TIME_DIFF(time_parse,time_stack,RT_TIMING_JIT_STACK);
884         RT_TIMING_TIME_DIFF(time_stack,time_typecheck,RT_TIMING_JIT_TYPECHECK);
885         RT_TIMING_TIME_DIFF(time_typecheck,time_loop,RT_TIMING_JIT_LOOP);
886         RT_TIMING_TIME_DIFF(time_loop,time_alloc,RT_TIMING_JIT_ALLOC);
887         RT_TIMING_TIME_DIFF(time_alloc,time_codegen,RT_TIMING_JIT_CODEGEN);
888         RT_TIMING_TIME_DIFF(time_start,time_codegen,RT_TIMING_JIT_TOTAL);
889
890         /* return pointer to the methods entry point */
891
892         return code->entrypoint;
893
894
895
896 /* jit_invalidate_code *********************************************************
897
898    Mark the compiled code of the given method as invalid and take care that
899    it is replaced if necessary.
900
901    XXX Not fully implemented, yet.
902
903 *******************************************************************************/
904
905 void jit_invalidate_code(methodinfo *m)
906 {
907         codeinfo *code;
908
909         code = m->code;
910
911         if (code == NULL || code_is_invalid(code))
912                 return;
913
914         code_flag_invalid(code);
915
916         /* activate mappable replacement points */
917
918 #if defined(ENABLE_REPLACEMENT)
919         replace_activate_replacement_points(code, true);
920 #else
921         vm_abort("invalidating code only works with ENABLE_REPLACEMENT");
922 #endif
923 }
924
925
926 /* jit_request_optimization ****************************************************
927
928    Request optimization of the given method. If the code of the method is
929    unoptimized, it will be invalidated, so the next jit_get_current_code(m)
930    triggers an optimized recompilation.
931    If the method is already optimized, this function does nothing.
932
933    IN:
934        m................the method
935
936 *******************************************************************************/
937
938 void jit_request_optimization(methodinfo *m)
939 {
940         codeinfo *code;
941
942         code = m->code;
943
944         if (code && code->optlevel == 0)
945                 jit_invalidate_code(m);
946 }
947
948
949 /* jit_get_current_code ********************************************************
950
951    Get the currently valid code for the given method. If there is no valid
952    code, (re)compile the method.
953
954    IN:
955        m................the method
956
957    RETURN VALUE:
958        the codeinfo* for the current code, or
959            NULL if an exception has been thrown during recompilation.
960
961 *******************************************************************************/
962
963 codeinfo *jit_get_current_code(methodinfo *m)
964 {
965         assert(m);
966
967         /* if we have valid code, return it */
968
969         if (m->code && !code_is_invalid(m->code))
970                 return m->code;
971
972         /* otherwise: recompile */
973
974         if (!jit_recompile(m))
975                 return NULL;
976
977         assert(m->code);
978
979         return m->code;
980 }
981
982
983 /* jit_asm_compile *************************************************************
984
985    This method is called from asm_vm_call_method and does:
986
987      - create stackframe info for exceptions
988      - compile the method
989      - patch the entrypoint of the method into the calculated address in
990        the JIT code
991      - flushes the instruction cache.
992
993 *******************************************************************************/
994
995 #if defined(ENABLE_JIT)
996 #if !defined(JIT_COMPILER_VIA_SIGNAL)
997 u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
998 {
999         stackframeinfo_t  sfi;
1000         u1               *entrypoint;
1001         u1               *pa;
1002         ptrint           *p;
1003
1004         /* create the stackframeinfo (subtract 1 from RA as it points to the */
1005         /* instruction after the call)                                       */
1006
1007         stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra-1);
1008
1009         /* actually compile the method */
1010
1011         entrypoint = jit_compile(m);
1012
1013         /* remove the stackframeinfo */
1014
1015         stacktrace_stackframeinfo_remove(&sfi);
1016
1017         /* there was a problem during compilation */
1018
1019         if (entrypoint == NULL)
1020                 return NULL;
1021
1022         /* get the method patch address */
1023
1024         pa = md_jit_method_patch_address(sfi.pv, (void *) ra, mptr);
1025
1026         /* patch the method entry point */
1027
1028         p = (ptrint *) pa;
1029
1030         *p = (ptrint) entrypoint;
1031
1032         /* flush the instruction cache */
1033
1034         md_icacheflush(pa, SIZEOF_VOID_P);
1035
1036         return entrypoint;
1037 }
1038 #endif
1039
1040 /* jit_compile_handle **********************************************************
1041
1042    This method is called from the appropriate signal handler which
1043    handles compiler-traps and does the following:
1044
1045      - compile the method
1046      - patch the entrypoint of the method into the calculated address in
1047        the JIT code
1048      - flush the instruction cache
1049
1050 *******************************************************************************/
1051
1052 void *jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr)
1053 {
1054         void      *newpv;                               /* new compiled method PV */
1055         void      *pa;                                           /* patch address */
1056         uintptr_t *p;                                      /* convenience pointer */
1057
1058         /* Compile the method. */
1059
1060         newpv = jit_compile(m);
1061
1062         /* There was a problem during compilation. */
1063
1064         if (newpv == NULL)
1065                 return NULL;
1066
1067         /* Get the method patch address. */
1068
1069         pa = md_jit_method_patch_address(pv, ra, mptr);
1070
1071         /* Patch the method entry point. */
1072
1073         p = (uintptr_t *) pa;
1074
1075         *p = (uintptr_t) newpv;
1076
1077         /* Flush both caches. */
1078
1079         md_cacheflush(pa, SIZEOF_VOID_P);
1080
1081         return newpv;
1082 }
1083 #endif /* defined(ENABLE_JIT) */
1084
1085
1086 /* jit_complement_condition ****************************************************
1087
1088    Returns the complement of the passed conditional instruction.
1089
1090    We use the order of the different conditions, e.g.:
1091
1092    ICMD_IFEQ         153
1093    ICMD_IFNE         154
1094
1095    If the passed opcode is odd, we simply add 1 to get the complement.
1096    If the opcode is even, we subtract 1.
1097
1098    Exception:
1099
1100    ICMD_IFNULL       198
1101    ICMD_IFNONNULL    199
1102
1103 *******************************************************************************/
1104
1105 s4 jit_complement_condition(s4 opcode)
1106 {
1107         switch (opcode) {
1108         case ICMD_IFNULL:
1109                 return ICMD_IFNONNULL;
1110
1111         case ICMD_IFNONNULL:
1112                 return ICMD_IFNULL;
1113
1114         default:
1115                 /* check if opcode is odd */
1116
1117                 if (opcode & 0x1)
1118                         return opcode + 1;
1119                 else
1120                         return opcode - 1;
1121         }
1122 }
1123
1124
1125 /* jit_renumber_basicblocks ****************************************************
1126
1127    Set the ->nr of all blocks so it increases when traversing ->next.
1128
1129    IN:
1130        jitdata..........the current jitdata
1131
1132 *******************************************************************************/
1133
1134 void jit_renumber_basicblocks(jitdata *jd)
1135 {
1136         s4          nr;
1137         basicblock *bptr;
1138
1139         nr = 0;
1140         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1141                 bptr->nr = nr++;
1142         }
1143
1144         /* we have one block more than jd->basicblockcount (the end marker) */
1145
1146         assert(nr == jd->basicblockcount + 1);
1147 }
1148
1149
1150 /* jit_check_basicblock_numbers ************************************************
1151
1152    Assert that the ->nr of the first block is zero and increases by 1 each
1153    time ->next is traversed.
1154    This function should be called before any analysis that relies on
1155    the basicblock numbers.
1156
1157    IN:
1158        jitdata..........the current jitdata
1159
1160    NOTE: Aborts with an assertion if the condition is not met!
1161
1162 *******************************************************************************/
1163
1164 #if !defined(NDEBUG)
1165 void jit_check_basicblock_numbers(jitdata *jd)
1166 {
1167         s4          nr;
1168         basicblock *bptr;
1169
1170         nr = 0;
1171         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1172                 assert(bptr->nr == nr);
1173                 nr++;
1174         }
1175
1176         /* we have one block more than jd->basicblockcount (the end marker) */
1177
1178         assert(nr == jd->basicblockcount + 1);
1179 }
1180 #endif /* !defined(NDEBUG) */
1181
1182 methoddesc *instruction_call_site(const instruction *iptr) {
1183         if (iptr->opc == ICMD_BUILTIN) {
1184                 return iptr->sx.s23.s3.bte->md;
1185         } else if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1186                 return iptr->sx.s23.s3.um->methodref->parseddesc.md;
1187         } else {
1188                 return iptr->sx.s23.s3.fmiref->p.method->parseddesc;
1189         }
1190 }
1191
1192 /*
1193  * These are local overrides for various environment variables in Emacs.
1194  * Please do not remove this and leave it at the end of the file, where
1195  * Emacs will automagically detect them.
1196  * ---------------------------------------------------------------------
1197  * Local variables:
1198  * mode: c
1199  * indent-tabs-mode: t
1200  * c-basic-offset: 4
1201  * tab-width: 4
1202  * End:
1203  * vim:noexpandtab:sw=4:ts=4:
1204  */