1 /* src/vm/jit/jit.c - calls the code generation functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
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.
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.
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
35 #include "mm/memory.h"
37 #include "native/native.h"
39 #include "toolbox/logging.h"
41 #include "threads/lock-common.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"
53 #include "vm/jit/asmpart.h"
55 #include "vm/jit/cfg.h"
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"
64 #include "vm/jit/show.h"
65 #include "vm/jit/stack.h"
67 #if defined(ENABLE_JITCACHE)
68 # include "vm/jit/jitcache.h"
71 #if defined(ENABLE_OPAGENT)
72 #include "vm/jit/oprofile-agent.hpp"
75 #include "vm/jit/allocator/simplereg.h"
76 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
77 # include "vm/jit/allocator/lsra.h"
80 #if defined(ENABLE_SSA)
81 # include "vm/jit/optimizing/lsra.h"
82 # include "vm/jit/optimizing/ssa.h"
85 #if defined(ENABLE_INLINING)
86 # include "vm/jit/inline/inline.h"
89 #include "vm/jit/ir/bytecode.h"
91 #include "vm/jit/loop/analyze.h"
92 #include "vm/jit/loop/graph.h"
93 #include "vm/jit/loop/loop.h"
95 #if defined(ENABLE_IFCONV)
96 # include "vm/jit/optimizing/ifconv.h"
99 #include "vm/jit/optimizing/reorder.h"
101 #if defined(ENABLE_PYTHON)
102 # include "vm/jit/python.h"
105 #include "vm/jit/verify/typecheck.h"
108 /* debug macros ***************************************************************/
111 #define DEBUG_JIT_COMPILEVERBOSE(x) \
113 if (compileverbose) { \
114 log_message_method(x, m); \
118 #define DEBUG_JIT_COMPILEVERBOSE(x) /* nothing */
122 # define TRACECOMPILERCALLS() \
124 if (opt_TraceCompilerCalls) { \
126 log_print("[JIT compiler started: method="); \
133 # define TRACECOMPILERCALLS()
137 /* the ICMD table ************************************************************/
140 #define N(name) name,
145 /* abbreviations for flags */
147 #define PEI ICMDTABLE_PEI
148 #define CALLS ICMDTABLE_CALLS
150 /* some machine dependent values */
155 #define IDIV_CALLS ICMDTABLE_CALLS
158 #if (SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
161 #define LDIV_CALLS ICMDTABLE_CALLS
164 /* include the actual table */
166 icmdtable_entry_t icmd_table[256] = {
167 #include <vm/jit/icmdtable.inc>
174 /* XXX hack until the old "PEI" definition is removed */
178 /* jit_init ********************************************************************
180 Initializes the JIT subsystem.
182 *******************************************************************************/
186 TRACESUBSYSTEMINITIALIZATION("jit_init");
188 #if defined(ENABLE_JIT)
189 /* initialize stack analysis subsystem */
194 /* initialize show subsystem */
200 /* initialize codegen subsystem */
204 /* initialize code subsystem */
208 /* Machine dependent initialization. */
210 #if defined(ENABLE_JIT)
211 # if defined(ENABLE_INTRP)
221 #if defined(ENABLE_OPAGENT)
222 if (opt_EnableOpagent)
223 OprofileAgent_initialize();
228 /* jit_close *******************************************************************
230 Close the JIT subsystem.
232 *******************************************************************************/
236 #if defined(ENABLE_OPAGENT)
237 if (opt_EnableOpagent)
238 OprofileAgent_close();
243 /* dummy function, used when there is no JavaVM code available */
245 static u1 *do_nothing_function(void)
251 /* jit_jitdata_new *************************************************************
253 Allocates and initalizes a new jitdata structure.
255 *******************************************************************************/
257 jitdata *jit_jitdata_new(methodinfo *m)
262 /* allocate jitdata structure and fill it */
267 jd->cd = DNEW(codegendata);
268 jd->rd = DNEW(registerdata);
269 #if defined(ENABLE_LOOP)
270 jd->ld = DNEW(loopdata);
273 /* Allocate codeinfo memory from the heap as we need to keep them. */
275 code = code_codeinfo_new(m);
277 /* Set codeinfo flags. */
279 #if defined(ENABLE_THREADS)
280 if (checksync && (m->flags & ACC_SYNCHRONIZED))
281 code_flag_synchronized(code);
283 if (checksync && (m->flags & ACC_SYNCHRONIZED))
284 code_unflag_leafmethod(code);
287 code_flag_leafmethod(code);
289 /* initialize variables */
293 jd->exceptiontable = NULL;
294 jd->exceptiontablelength = 0;
296 jd->branchtoentry = false;
297 jd->branchtoend = false;
299 jd->returnblock = NULL;
300 jd->maxlocals = m->maxlocals;
306 /* jit_compile *****************************************************************
308 Translates one method to machine code.
310 *******************************************************************************/
312 static u1 *jit_compile_intern(jitdata *jd);
314 u1 *jit_compile(methodinfo *m)
320 STATISTICS(count_jit_calls++);
322 /* Initialize the static function's class. */
324 /* ATTENTION: This MUST be done before the method lock is aquired,
325 otherwise we could run into a deadlock with <clinit>'s that
326 call static methods of it's own class. */
328 if ((m->flags & ACC_STATIC) && !(m->clazz->state & CLASS_INITIALIZED)) {
331 log_message_class("Initialize class ", m->clazz);
334 if (!initialize_class(m->clazz))
337 /* check if the method has been compiled during initialization */
339 if ((m->code != NULL) && (m->code->entrypoint != NULL))
340 return m->code->entrypoint;
343 /* enter a monitor on the method */
345 LOCK_MONITOR_ENTER(m);
347 /* if method has been already compiled return immediately */
349 if (m->code != NULL) {
350 LOCK_MONITOR_EXIT(m);
352 assert(m->code->entrypoint);
353 return m->code->entrypoint;
356 TRACECOMPILERCALLS();
358 STATISTICS(count_methods++);
360 #if defined (ENABLE_JITCACHE)
362 if (jitcache_load (m))
364 LOCK_MONITOR_EXIT(m);
366 return m->code->entrypoint;
371 #if defined(ENABLE_STATISTICS)
374 if (opt_getcompilingtime)
375 compilingtime_start();
378 /* mark start of dump memory area */
382 /* create jitdata structure */
384 jd = jit_jitdata_new(m);
386 /* set the flags for the current JIT run */
388 jd->flags = JITDATA_FLAG_PARSE;
390 #if defined(ENABLE_VERIFIER)
392 jd->flags |= JITDATA_FLAG_VERIFY;
395 #if defined(ENABLE_PROFILING)
397 jd->flags |= JITDATA_FLAG_INSTRUMENT;
400 #if defined(ENABLE_IFCONV)
402 jd->flags |= JITDATA_FLAG_IFCONV;
405 #if defined(ENABLE_INLINING) && defined(ENABLE_INLINING_DEBUG)
406 if (opt_Inline && opt_InlineAll)
407 jd->flags |= JITDATA_FLAG_INLINE;
410 if (opt_showintermediate)
411 jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
413 if (opt_showdisassemble)
414 jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
417 jd->flags |= JITDATA_FLAG_VERBOSECALL;
419 #if defined(ENABLE_REPLACEMENT) && defined(ENABLE_INLINING)
420 if (opt_Inline && (jd->m->hitcountdown > 0) && (jd->code->optlevel == 0)) {
421 jd->flags |= JITDATA_FLAG_COUNTDOWN;
425 #if defined(ENABLE_JIT)
426 # if defined(ENABLE_INTRP)
429 /* initialize the register allocator */
435 /* setup the codegendata memory */
439 /* now call internal compile function */
441 r = jit_compile_intern(jd);
444 /* We had an exception! Finish stuff here if necessary. */
446 /* release codeinfo */
448 code_codeinfo_free(jd->code);
450 #if defined(ENABLE_PROFILING)
451 /* Release memory for basic block profiling information. */
453 if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
454 if (jd->code->bbfrequency != NULL)
455 MFREE(jd->code->bbfrequency, u4, jd->code->basicblockcount);
459 DEBUG_JIT_COMPILEVERBOSE("Running: ");
462 #if defined (ENABLE_JITCACHE)
466 /* release dump area */
470 #if defined(ENABLE_STATISTICS)
473 if (opt_getcompilingtime)
474 compilingtime_stop();
477 #if defined(ENABLE_OPAGENT)
478 if (opt_EnableOpagent)
479 OprofileAgent_newmethod(m);
482 /* leave the monitor */
484 LOCK_MONITOR_EXIT(m);
486 /* return pointer to the methods entry point */
492 /* jit_recompile ***************************************************************
494 Recompiles a Java method.
496 *******************************************************************************/
498 u1 *jit_recompile(methodinfo *m)
505 /* check for max. optimization level */
507 optlevel = (m->code) ? m->code->optlevel : 0;
511 /* log_message_method("not recompiling: ", m); */
516 DEBUG_JIT_COMPILEVERBOSE("Recompiling start: ");
518 STATISTICS(count_jit_calls++);
520 #if defined(ENABLE_STATISTICS)
523 if (opt_getcompilingtime)
524 compilingtime_start();
527 /* mark start of dump memory area */
531 /* create jitdata structure */
533 jd = jit_jitdata_new(m);
535 /* set the current optimization level to the previous one plus 1 */
537 jd->code->optlevel = optlevel + 1;
539 /* get the optimization flags for the current JIT run */
541 #if defined(ENABLE_VERIFIER)
542 jd->flags |= JITDATA_FLAG_VERIFY;
545 /* jd->flags |= JITDATA_FLAG_REORDER; */
546 if (opt_showintermediate)
547 jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
548 if (opt_showdisassemble)
549 jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
551 jd->flags |= JITDATA_FLAG_VERBOSECALL;
553 #if defined(ENABLE_INLINING)
555 jd->flags |= JITDATA_FLAG_INLINE;
558 #if defined(ENABLE_JIT)
559 # if defined(ENABLE_INTRP)
562 /* initialize the register allocator */
567 /* setup the codegendata memory */
571 /* now call internal compile function */
573 r = jit_compile_intern(jd);
576 /* We had an exception! Finish stuff here if necessary. */
578 /* release codeinfo */
580 code_codeinfo_free(jd->code);
583 /* release dump area */
587 #if defined(ENABLE_STATISTICS)
590 if (opt_getcompilingtime)
591 compilingtime_stop();
594 #if defined(ENABLE_OPAGENT)
595 if (opt_EnableOpagent)
596 OprofileAgent_newmethod(m);
599 DEBUG_JIT_COMPILEVERBOSE("Recompiling done: ");
601 /* return pointer to the methods entry point */
606 #if defined(ENABLE_PM_HACKS)
607 #include "vm/jit/jit_pm_1.inc"
610 /* jit_compile_intern **********************************************************
612 Static internal function which does the actual compilation.
614 *******************************************************************************/
616 static u1 *jit_compile_intern(jitdata *jd)
622 #if defined(ENABLE_RT_TIMING)
623 struct timespec time_start,time_checks,time_parse,time_stack,
624 time_typecheck,time_loop,time_ifconv,time_alloc,
628 RT_TIMING_GET_TIME(time_start);
630 /* get required compiler data */
632 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
639 #if defined(ENABLE_DEBUG_FILTER)
640 show_filters_apply(jd->m);
643 /* Handle native methods and create a native stub. */
645 if (m->flags & ACC_NATIVE) {
648 f = native_method_resolve(m);
653 code = codegen_generate_stub_native(m, f);
655 /* Native methods are never recompiled. */
661 return code->entrypoint;
664 /* if there is no javacode, print error message and return empty method */
666 if (m->jcode == NULL) {
667 DEBUG_JIT_COMPILEVERBOSE("No code given for: ");
669 code->entrypoint = (u1 *) (ptrint) do_nothing_function;
672 return code->entrypoint; /* return empty method */
675 #if defined(ENABLE_STATISTICS)
677 count_javacodesize += m->jcodelength + 18;
678 count_tryblocks += jd->exceptiontablelength;
679 count_javaexcsize += jd->exceptiontablelength * SIZEOF_VOID_P;
683 RT_TIMING_GET_TIME(time_checks);
685 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
686 /* Code for Sun's OpenJDK (see
687 hotspot/src/share/vm/classfile/verifier.cpp
688 (Verifier::is_eligible_for_verification)): Don't verify
689 dynamically-generated bytecodes. */
691 # if defined(ENABLE_VERIFIER)
692 if (class_issubclass(m->clazz, class_sun_reflect_MagicAccessorImpl))
693 jd->flags &= ~JITDATA_FLAG_VERIFY;
697 /* call the compiler passes ***********************************************/
699 DEBUG_JIT_COMPILEVERBOSE("Parsing: ");
701 /* call parse pass */
704 DEBUG_JIT_COMPILEVERBOSE("Exception while parsing: ");
708 RT_TIMING_GET_TIME(time_parse);
710 DEBUG_JIT_COMPILEVERBOSE("Parsing done: ");
712 #if defined(ENABLE_JIT)
713 # if defined(ENABLE_INTRP)
716 DEBUG_JIT_COMPILEVERBOSE("Analysing: ");
718 /* call stack analysis pass */
720 if (!stack_analyse(jd)) {
721 DEBUG_JIT_COMPILEVERBOSE("Exception while analysing: ");
725 RT_TIMING_GET_TIME(time_stack);
727 DEBUG_JIT_COMPILEVERBOSE("Analysing done: ");
729 #ifdef ENABLE_VERIFIER
730 if (JITDATA_HAS_FLAG_VERIFY(jd)) {
731 DEBUG_JIT_COMPILEVERBOSE("Typechecking: ");
733 /* call typecheck pass */
734 if (!typecheck(jd)) {
735 DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking: ");
740 DEBUG_JIT_COMPILEVERBOSE("Typechecking done: ");
743 RT_TIMING_GET_TIME(time_typecheck);
745 #if defined(ENABLE_LOOP)
750 jit_renumber_basicblocks(jd);
753 RT_TIMING_GET_TIME(time_loop);
755 #if defined(ENABLE_IFCONV)
756 if (JITDATA_HAS_FLAG_IFCONV(jd)) {
757 if (!ifconv_static(jd))
759 jit_renumber_basicblocks(jd);
762 RT_TIMING_GET_TIME(time_ifconv);
766 #if defined(ENABLE_INLINING) && (!defined(ENABLE_ESCAPE) || 1)
767 if (JITDATA_HAS_FLAG_INLINE(jd)) {
768 if (!inline_inline(jd))
773 #if defined(ENABLE_SSA)
775 fix_exception_handlers(jd);
779 /* Build the CFG. This has to be done after stack_analyse, as
780 there happens the JSR elimination. */
785 #if defined(ENABLE_PROFILING)
786 /* Basic block reordering. I think this should be done after
787 if-conversion, as we could lose the ability to do the
790 if (JITDATA_HAS_FLAG_REORDER(jd)) {
793 jit_renumber_basicblocks(jd);
797 #if defined(ENABLE_PM_HACKS)
798 #include "vm/jit/jit_pm_2.inc"
800 DEBUG_JIT_COMPILEVERBOSE("Allocating registers: ");
802 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
803 /* allocate registers */
808 STATISTICS(count_methods_allocated_by_lsra++);
811 # endif /* defined(ENABLE_LSRA) && !defined(ENABLE_SSA) */
812 #if defined(ENABLE_SSA)
813 /* allocate registers */
816 jd->code->optlevel > 0)
817 /* strncmp(jd->m->name->text, "hottie", 6) == 0*/
818 /*&& jd->exceptiontablelength == 0*/
820 /*printf("=== %s ===\n", jd->m->name->text);*/
821 jd->ls = DNEW(lsradata);
824 /*lsra(jd);*/ regalloc(jd);
825 /*eliminate_subbasicblocks(jd);*/
826 STATISTICS(count_methods_allocated_by_lsra++);
829 # endif /* defined(ENABLE_SSA) */
831 STATISTICS(count_locals_conflicts += (jd->maxlocals - 1) * (jd->maxlocals));
836 STATISTICS(simplereg_make_statistics(jd));
838 DEBUG_JIT_COMPILEVERBOSE("Allocating registers done: ");
839 # if defined(ENABLE_INTRP)
842 #endif /* defined(ENABLE_JIT) */
843 RT_TIMING_GET_TIME(time_alloc);
845 #if defined(ENABLE_PROFILING)
846 /* Allocate memory for basic block profiling information. This
847 _must_ be done after loop optimization and register allocation,
848 since they can change the basic block count. */
850 if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
851 code->bbfrequency = MNEW(u4, jd->basicblockcount);
854 DEBUG_JIT_COMPILEVERBOSE("Generating code: ");
856 /* now generate the machine code */
858 #if defined(ENABLE_JIT)
859 # if defined(ENABLE_INTRP)
861 #if defined(ENABLE_VERIFIER)
863 DEBUG_JIT_COMPILEVERBOSE("Typechecking (stackbased): ");
865 if (!typecheck_stackbased(jd)) {
866 DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking (stackbased): ");
871 if (!intrp_codegen(jd)) {
872 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
879 if (!codegen_generate(jd)) {
880 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
886 if (!intrp_codegen(jd)) {
887 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
892 RT_TIMING_GET_TIME(time_codegen);
894 DEBUG_JIT_COMPILEVERBOSE("Generating code done: ");
896 #if !defined(NDEBUG) && defined(ENABLE_REPLACEMENT)
897 /* activate replacement points inside newly created code */
899 if (opt_TestReplacement)
900 replace_activate_replacement_points(code, false);
904 #if defined(ENABLE_DEBUG_FILTER)
905 if (jd->m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
908 /* intermediate and assembly code listings */
910 if (JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)) {
911 show_method(jd, SHOW_CODE);
913 else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
914 # if defined(ENABLE_DISASSEMBLER)
915 DISASSEMBLE(code->entrypoint,
916 code->entrypoint + (code->mcodelength - cd->dseglen));
920 if (opt_showddatasegment)
925 /* switch to the newly generated code */
928 assert(code->entrypoint);
930 /* add the current compile version to the methodinfo */
932 code->prev = m->code;
935 RT_TIMING_TIME_DIFF(time_start,time_checks,RT_TIMING_JIT_CHECKS);
936 RT_TIMING_TIME_DIFF(time_checks,time_parse,RT_TIMING_JIT_PARSE);
937 RT_TIMING_TIME_DIFF(time_parse,time_stack,RT_TIMING_JIT_STACK);
938 RT_TIMING_TIME_DIFF(time_stack,time_typecheck,RT_TIMING_JIT_TYPECHECK);
939 RT_TIMING_TIME_DIFF(time_typecheck,time_loop,RT_TIMING_JIT_LOOP);
940 RT_TIMING_TIME_DIFF(time_loop,time_alloc,RT_TIMING_JIT_ALLOC);
941 RT_TIMING_TIME_DIFF(time_alloc,time_codegen,RT_TIMING_JIT_CODEGEN);
942 RT_TIMING_TIME_DIFF(time_start,time_codegen,RT_TIMING_JIT_TOTAL);
944 /* return pointer to the methods entry point */
946 return code->entrypoint;
950 /* jit_invalidate_code *********************************************************
952 Mark the compiled code of the given method as invalid and take care that
953 it is replaced if necessary.
955 XXX Not fully implemented, yet.
957 *******************************************************************************/
959 void jit_invalidate_code(methodinfo *m)
965 if (code == NULL || code_is_invalid(code))
968 code_flag_invalid(code);
970 /* activate mappable replacement points */
972 #if defined(ENABLE_REPLACEMENT)
973 replace_activate_replacement_points(code, true);
975 vm_abort("invalidating code only works with ENABLE_REPLACEMENT");
980 /* jit_request_optimization ****************************************************
982 Request optimization of the given method. If the code of the method is
983 unoptimized, it will be invalidated, so the next jit_get_current_code(m)
984 triggers an optimized recompilation.
985 If the method is already optimized, this function does nothing.
988 m................the method
990 *******************************************************************************/
992 void jit_request_optimization(methodinfo *m)
998 if (code && code->optlevel == 0)
999 jit_invalidate_code(m);
1003 /* jit_get_current_code ********************************************************
1005 Get the currently valid code for the given method. If there is no valid
1006 code, (re)compile the method.
1009 m................the method
1012 the codeinfo* for the current code, or
1013 NULL if an exception has been thrown during recompilation.
1015 *******************************************************************************/
1017 codeinfo *jit_get_current_code(methodinfo *m)
1021 /* if we have valid code, return it */
1023 if (m->code && !code_is_invalid(m->code))
1026 /* otherwise: recompile */
1028 if (!jit_recompile(m))
1037 /* jit_asm_compile *************************************************************
1039 This method is called from asm_vm_call_method and does:
1041 - create stackframe info for exceptions
1042 - compile the method
1043 - patch the entrypoint of the method into the calculated address in
1045 - flushes the instruction cache.
1047 *******************************************************************************/
1049 #if defined(ENABLE_JIT)
1050 #if !defined(JIT_COMPILER_VIA_SIGNAL)
1051 u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
1053 stackframeinfo_t sfi;
1058 /* create the stackframeinfo (subtract 1 from RA as it points to the */
1059 /* instruction after the call) */
1061 stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra-1);
1063 /* actually compile the method */
1065 entrypoint = jit_compile(m);
1067 /* remove the stackframeinfo */
1069 stacktrace_stackframeinfo_remove(&sfi);
1071 /* there was a problem during compilation */
1073 if (entrypoint == NULL)
1076 /* get the method patch address */
1078 pa = md_jit_method_patch_address(sfi.pv, (void *) ra, mptr);
1080 /* patch the method entry point */
1084 *p = (ptrint) entrypoint;
1086 /* flush the instruction cache */
1088 md_icacheflush(pa, SIZEOF_VOID_P);
1094 /* jit_compile_handle **********************************************************
1096 This method is called from the appropriate signal handler which
1097 handles compiler-traps and does the following:
1099 - compile the method
1100 - patch the entrypoint of the method into the calculated address in
1102 - flush the instruction cache
1104 *******************************************************************************/
1106 void *jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr)
1108 void *newpv; /* new compiled method PV */
1109 void *pa; /* patch address */
1110 uintptr_t *p; /* convenience pointer */
1112 /* Compile the method. */
1114 newpv = jit_compile(m);
1116 /* There was a problem during compilation. */
1121 /* Get the method patch address. */
1123 pa = md_jit_method_patch_address(pv, ra, mptr);
1125 /* Patch the method entry point. */
1127 p = (uintptr_t *) pa;
1129 *p = (uintptr_t) newpv;
1131 /* Flush both caches. */
1133 md_cacheflush(pa, SIZEOF_VOID_P);
1137 #endif /* defined(ENABLE_JIT) */
1140 /* jit_complement_condition ****************************************************
1142 Returns the complement of the passed conditional instruction.
1144 We use the order of the different conditions, e.g.:
1149 If the passed opcode is odd, we simply add 1 to get the complement.
1150 If the opcode is even, we subtract 1.
1157 *******************************************************************************/
1159 s4 jit_complement_condition(s4 opcode)
1163 return ICMD_IFNONNULL;
1165 case ICMD_IFNONNULL:
1169 /* check if opcode is odd */
1179 /* jit_renumber_basicblocks ****************************************************
1181 Set the ->nr of all blocks so it increases when traversing ->next.
1184 jitdata..........the current jitdata
1186 *******************************************************************************/
1188 void jit_renumber_basicblocks(jitdata *jd)
1194 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1198 /* we have one block more than jd->basicblockcount (the end marker) */
1200 assert(nr == jd->basicblockcount + 1);
1204 /* jit_check_basicblock_numbers ************************************************
1206 Assert that the ->nr of the first block is zero and increases by 1 each
1207 time ->next is traversed.
1208 This function should be called before any analysis that relies on
1209 the basicblock numbers.
1212 jitdata..........the current jitdata
1214 NOTE: Aborts with an assertion if the condition is not met!
1216 *******************************************************************************/
1218 #if !defined(NDEBUG)
1219 void jit_check_basicblock_numbers(jitdata *jd)
1225 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1226 assert(bptr->nr == nr);
1230 /* we have one block more than jd->basicblockcount (the end marker) */
1232 assert(nr == jd->basicblockcount + 1);
1234 #endif /* !defined(NDEBUG) */
1236 methoddesc *instruction_call_site(const instruction *iptr) {
1237 if (iptr->opc == ICMD_BUILTIN) {
1238 return iptr->sx.s23.s3.bte->md;
1239 } else if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1240 return iptr->sx.s23.s3.um->methodref->parseddesc.md;
1242 return iptr->sx.s23.s3.fmiref->p.method->parseddesc;
1247 * These are local overrides for various environment variables in Emacs.
1248 * Please do not remove this and leave it at the end of the file, where
1249 * Emacs will automagically detect them.
1250 * ---------------------------------------------------------------------
1253 * indent-tabs-mode: t
1257 * vim:noexpandtab:sw=4:ts=4: