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