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