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