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