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