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