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