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