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