* src/mm/dumpmemory.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.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 = (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 u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
981 {
982         stackframeinfo_t  sfi;
983         u1               *entrypoint;
984         u1               *pa;
985         ptrint           *p;
986
987         /* create the stackframeinfo (subtract 1 from RA as it points to the */
988         /* instruction after the call)                                       */
989
990         stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra-1);
991
992         /* actually compile the method */
993
994         entrypoint = jit_compile(m);
995
996         /* remove the stackframeinfo */
997
998         stacktrace_stackframeinfo_remove(&sfi);
999
1000         /* there was a problem during compilation */
1001
1002         if (entrypoint == NULL)
1003                 return NULL;
1004
1005         /* get the method patch address */
1006
1007         pa = md_jit_method_patch_address(sfi.pv, (void *) ra, mptr);
1008
1009         /* patch the method entry point */
1010
1011         p = (ptrint *) pa;
1012
1013         *p = (ptrint) entrypoint;
1014
1015         /* flush the instruction cache */
1016
1017         md_icacheflush(pa, SIZEOF_VOID_P);
1018
1019         return entrypoint;
1020 }
1021 #endif
1022
1023 /* jit_compile_handle **********************************************************
1024
1025    This method is called from the appropriate signal handler which
1026    handles compiler-traps and does the following:
1027
1028      - compile the method
1029      - patch the entrypoint of the method into the calculated address in
1030        the JIT code
1031      - flush the instruction cache
1032
1033 *******************************************************************************/
1034
1035 void *jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr)
1036 {
1037         void      *newpv;                               /* new compiled method PV */
1038         void      *pa;                                           /* patch address */
1039         uintptr_t *p;                                      /* convenience pointer */
1040
1041         /* Compile the method. */
1042
1043         newpv = jit_compile(m);
1044
1045         /* There was a problem during compilation. */
1046
1047         if (newpv == NULL)
1048                 return NULL;
1049
1050         /* Get the method patch address. */
1051
1052         pa = md_jit_method_patch_address(pv, ra, mptr);
1053
1054         /* Patch the method entry point. */
1055
1056         p = (uintptr_t *) pa;
1057
1058         *p = (uintptr_t) newpv;
1059
1060         /* Flush both caches. */
1061
1062         md_cacheflush(pa, SIZEOF_VOID_P);
1063
1064         return newpv;
1065 }
1066 #endif /* defined(ENABLE_JIT) */
1067
1068
1069 /* jit_complement_condition ****************************************************
1070
1071    Returns the complement of the passed conditional instruction.
1072
1073    We use the order of the different conditions, e.g.:
1074
1075    ICMD_IFEQ         153
1076    ICMD_IFNE         154
1077
1078    If the passed opcode is odd, we simply add 1 to get the complement.
1079    If the opcode is even, we subtract 1.
1080
1081    Exception:
1082
1083    ICMD_IFNULL       198
1084    ICMD_IFNONNULL    199
1085
1086 *******************************************************************************/
1087
1088 s4 jit_complement_condition(s4 opcode)
1089 {
1090         switch (opcode) {
1091         case ICMD_IFNULL:
1092                 return ICMD_IFNONNULL;
1093
1094         case ICMD_IFNONNULL:
1095                 return ICMD_IFNULL;
1096
1097         default:
1098                 /* check if opcode is odd */
1099
1100                 if (opcode & 0x1)
1101                         return opcode + 1;
1102                 else
1103                         return opcode - 1;
1104         }
1105 }
1106
1107
1108 /* jit_renumber_basicblocks ****************************************************
1109
1110    Set the ->nr of all blocks so it increases when traversing ->next.
1111
1112    IN:
1113        jitdata..........the current jitdata
1114
1115 *******************************************************************************/
1116
1117 void jit_renumber_basicblocks(jitdata *jd)
1118 {
1119         s4          nr;
1120         basicblock *bptr;
1121
1122         nr = 0;
1123         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1124                 bptr->nr = nr++;
1125         }
1126
1127         /* we have one block more than jd->basicblockcount (the end marker) */
1128
1129         assert(nr == jd->basicblockcount + 1);
1130 }
1131
1132
1133 /* jit_check_basicblock_numbers ************************************************
1134
1135    Assert that the ->nr of the first block is zero and increases by 1 each
1136    time ->next is traversed.
1137    This function should be called before any analysis that relies on
1138    the basicblock numbers.
1139
1140    IN:
1141        jitdata..........the current jitdata
1142
1143    NOTE: Aborts with an assertion if the condition is not met!
1144
1145 *******************************************************************************/
1146
1147 #if !defined(NDEBUG)
1148 void jit_check_basicblock_numbers(jitdata *jd)
1149 {
1150         s4          nr;
1151         basicblock *bptr;
1152
1153         nr = 0;
1154         for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1155                 assert(bptr->nr == nr);
1156                 nr++;
1157         }
1158
1159         /* we have one block more than jd->basicblockcount (the end marker) */
1160
1161         assert(nr == jd->basicblockcount + 1);
1162 }
1163 #endif /* !defined(NDEBUG) */
1164
1165
1166 /*
1167  * These are local overrides for various environment variables in Emacs.
1168  * Please do not remove this and leave it at the end of the file, where
1169  * Emacs will automagically detect them.
1170  * ---------------------------------------------------------------------
1171  * Local variables:
1172  * mode: c++
1173  * indent-tabs-mode: t
1174  * c-basic-offset: 4
1175  * tab-width: 4
1176  * End:
1177  * vim:noexpandtab:sw=4:ts=4:
1178  */