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