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