1 /* src/vm/jit/jit.cpp - Just-In-Time compiler
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/mutex.hpp"
44 #include "vm/global.h"
45 #include "vm/globals.hpp"
46 #include "vm/initialize.h"
47 #include "vm/loader.hpp"
48 #include "vm/method.h"
49 #include "vm/options.h"
50 #include "vm/rt-timing.h"
51 #include "vm/statistics.h"
53 #include "vm/jit/asmpart.h"
55 #include "vm/jit/cfg.h"
57 #include "vm/jit/codegen-common.hpp"
58 #include "vm/jit/disass.h"
59 #include "vm/jit/dseg.h"
60 #include "vm/jit/jit.hpp"
61 #include "vm/jit/parse.h"
62 #include "vm/jit/reg.h"
64 #include "vm/jit/show.hpp"
65 #include "vm/jit/stack.h"
66 #include "vm/jit/stubs.hpp"
68 #if defined(ENABLE_OPAGENT)
69 #include "vm/jit/oprofile-agent.hpp"
72 #include "vm/jit/allocator/simplereg.h"
73 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
74 # include "vm/jit/allocator/lsra.h"
77 #if defined(ENABLE_SSA)
78 # include "vm/jit/optimizing/lsra.h"
79 # include "vm/jit/optimizing/ssa.h"
82 #if defined(ENABLE_INLINING)
83 # include "vm/jit/inline/inline.h"
86 #include "vm/jit/ir/bytecode.h"
88 #include "vm/jit/loop/analyze.h"
89 #include "vm/jit/loop/graph.h"
90 #include "vm/jit/loop/loop.h"
92 #if defined(ENABLE_IFCONV)
93 # include "vm/jit/optimizing/ifconv.h"
96 #include "vm/jit/optimizing/reorder.h"
98 #if defined(ENABLE_PYTHON)
99 # include "vm/jit/python.h"
102 #include "vm/jit/verify/typecheck.h"
105 /* debug macros ***************************************************************/
108 #define DEBUG_JIT_COMPILEVERBOSE(x) \
110 if (compileverbose) { \
111 log_message_method(x, m); \
115 #define DEBUG_JIT_COMPILEVERBOSE(x) /* nothing */
119 # define TRACECOMPILERCALLS() \
121 if (opt_TraceCompilerCalls) { \
123 log_print("[JIT compiler started: method="); \
130 # define TRACECOMPILERCALLS()
134 /* jit_init ********************************************************************
136 Initializes the JIT subsystem.
138 *******************************************************************************/
142 TRACESUBSYSTEMINITIALIZATION("jit_init");
144 #if defined(ENABLE_JIT)
145 /* initialize stack analysis subsystem */
150 /* initialize show subsystem */
156 /* initialize codegen subsystem */
160 /* initialize code subsystem */
164 /* Machine dependent initialization. */
166 #if defined(ENABLE_JIT)
167 # if defined(ENABLE_INTRP)
177 #if defined(ENABLE_OPAGENT)
178 if (opt_EnableOpagent)
179 OprofileAgent_initialize();
184 /* jit_close *******************************************************************
186 Close the JIT subsystem.
188 *******************************************************************************/
192 #if defined(ENABLE_OPAGENT)
193 if (opt_EnableOpagent)
194 OprofileAgent_close();
199 /* dummy function, used when there is no JavaVM code available */
201 static u1 *do_nothing_function(void)
207 /* jit_jitdata_new *************************************************************
209 Allocates and initalizes a new jitdata structure.
211 *******************************************************************************/
213 jitdata *jit_jitdata_new(methodinfo *m)
218 /* allocate jitdata structure and fill it */
220 jd = (jitdata*) DumpMemory::allocate(sizeof(jitdata));
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));
229 /* Allocate codeinfo memory from the heap as we need to keep them. */
231 code = code_codeinfo_new(m);
233 /* Set codeinfo flags. */
235 #if defined(ENABLE_THREADS)
236 if (checksync && (m->flags & ACC_SYNCHRONIZED))
237 code_flag_synchronized(code);
239 if (checksync && (m->flags & ACC_SYNCHRONIZED))
240 code_unflag_leafmethod(code);
243 code_flag_leafmethod(code);
245 /* initialize variables */
249 jd->exceptiontable = NULL;
250 jd->exceptiontablelength = 0;
252 jd->branchtoentry = false;
253 jd->branchtoend = false;
255 jd->returnblock = NULL;
256 jd->maxlocals = m->maxlocals;
262 /* jit_compile *****************************************************************
264 Translates one method to machine code.
266 *******************************************************************************/
268 static u1 *jit_compile_intern(jitdata *jd);
270 u1 *jit_compile(methodinfo *m)
275 STATISTICS(count_jit_calls++);
277 /* Initialize the static function's class. */
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. */
283 if ((m->flags & ACC_STATIC) && !(m->clazz->state & CLASS_INITIALIZED)) {
286 log_message_class("Initialize class ", m->clazz);
289 if (!initialize_class(m->clazz))
292 /* check if the method has been compiled during initialization */
294 if ((m->code != NULL) && (m->code->entrypoint != NULL))
295 return m->code->entrypoint;
298 /* enter a monitor on the method */
302 /* if method has been already compiled return immediately */
304 if (m->code != NULL) {
307 assert(m->code->entrypoint);
308 return m->code->entrypoint;
311 TRACECOMPILERCALLS();
313 STATISTICS(count_methods++);
315 #if defined(ENABLE_STATISTICS)
318 if (opt_getcompilingtime)
319 compilingtime_start();
322 // Create new dump memory area.
325 /* create jitdata structure */
327 jd = jit_jitdata_new(m);
329 /* set the flags for the current JIT run */
331 jd->flags = JITDATA_FLAG_PARSE;
333 #if defined(ENABLE_VERIFIER)
335 jd->flags |= JITDATA_FLAG_VERIFY;
338 #if defined(ENABLE_PROFILING)
340 jd->flags |= JITDATA_FLAG_INSTRUMENT;
343 #if defined(ENABLE_IFCONV)
345 jd->flags |= JITDATA_FLAG_IFCONV;
348 #if defined(ENABLE_INLINING) && defined(ENABLE_INLINING_DEBUG)
349 if (opt_Inline && opt_InlineAll)
350 jd->flags |= JITDATA_FLAG_INLINE;
353 if (opt_showintermediate)
354 jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
356 if (opt_showdisassemble)
357 jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
360 jd->flags |= JITDATA_FLAG_VERBOSECALL;
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;
368 #if defined(ENABLE_JIT)
369 # if defined(ENABLE_INTRP)
372 /* initialize the register allocator */
378 /* setup the codegendata memory */
382 /* now call internal compile function */
384 r = jit_compile_intern(jd);
387 /* We had an exception! Finish stuff here if necessary. */
389 /* release codeinfo */
391 code_codeinfo_free(jd->code);
393 #if defined(ENABLE_PROFILING)
394 /* Release memory for basic block profiling information. */
396 if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
397 if (jd->code->bbfrequency != NULL)
398 MFREE(jd->code->bbfrequency, u4, jd->code->basicblockcount);
402 DEBUG_JIT_COMPILEVERBOSE("Running: ");
405 #if defined(ENABLE_STATISTICS)
408 if (opt_getcompilingtime)
409 compilingtime_stop();
412 #if defined(ENABLE_OPAGENT)
413 if (opt_EnableOpagent)
414 OprofileAgent_newmethod(m);
417 /* leave the monitor */
421 /* return pointer to the methods entry point */
427 /* jit_recompile ***************************************************************
429 Recompiles a Java method.
431 *******************************************************************************/
433 u1 *jit_recompile(methodinfo *m)
439 /* check for max. optimization level */
441 optlevel = (m->code) ? m->code->optlevel : 0;
445 /* log_message_method("not recompiling: ", m); */
450 DEBUG_JIT_COMPILEVERBOSE("Recompiling start: ");
452 STATISTICS(count_jit_calls++);
454 #if defined(ENABLE_STATISTICS)
457 if (opt_getcompilingtime)
458 compilingtime_start();
461 // Create new dump memory area.
464 /* create jitdata structure */
466 jd = jit_jitdata_new(m);
468 /* set the current optimization level to the previous one plus 1 */
470 jd->code->optlevel = optlevel + 1;
472 /* get the optimization flags for the current JIT run */
474 #if defined(ENABLE_VERIFIER)
475 jd->flags |= JITDATA_FLAG_VERIFY;
478 /* jd->flags |= JITDATA_FLAG_REORDER; */
479 if (opt_showintermediate)
480 jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
481 if (opt_showdisassemble)
482 jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
484 jd->flags |= JITDATA_FLAG_VERBOSECALL;
486 #if defined(ENABLE_INLINING)
488 jd->flags |= JITDATA_FLAG_INLINE;
491 #if defined(ENABLE_JIT)
492 # if defined(ENABLE_INTRP)
495 /* initialize the register allocator */
500 /* setup the codegendata memory */
504 /* now call internal compile function */
506 r = jit_compile_intern(jd);
509 /* We had an exception! Finish stuff here if necessary. */
511 /* release codeinfo */
513 code_codeinfo_free(jd->code);
516 #if defined(ENABLE_STATISTICS)
519 if (opt_getcompilingtime)
520 compilingtime_stop();
523 #if defined(ENABLE_OPAGENT)
524 if (opt_EnableOpagent)
525 OprofileAgent_newmethod(m);
528 DEBUG_JIT_COMPILEVERBOSE("Recompiling done: ");
530 /* return pointer to the methods entry point */
535 #if defined(ENABLE_PM_HACKS)
536 #include "vm/jit/jit_pm_1.inc"
539 /* jit_compile_intern **********************************************************
541 Static internal function which does the actual compilation.
543 *******************************************************************************/
545 static u1 *jit_compile_intern(jitdata *jd)
551 #if defined(ENABLE_RT_TIMING)
552 struct timespec time_start,time_checks,time_parse,time_stack,
553 time_typecheck,time_loop,time_ifconv,time_alloc,
557 RT_TIMING_GET_TIME(time_start);
559 /* get required compiler data */
561 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
568 #if defined(ENABLE_DEBUG_FILTER)
569 show_filters_apply(jd->m);
572 /* Handle native methods and create a native stub. */
574 if (m->flags & ACC_NATIVE) {
577 f = native_method_resolve(m);
582 code = NativeStub::generate(m, f);
584 /* Native methods are never recompiled. */
590 return code->entrypoint;
593 /* if there is no javacode, print error message and return empty method */
595 if (m->jcode == NULL) {
596 DEBUG_JIT_COMPILEVERBOSE("No code given for: ");
598 code->entrypoint = (u1 *) (ptrint) do_nothing_function;
601 return code->entrypoint; /* return empty method */
604 #if defined(ENABLE_STATISTICS)
606 count_javacodesize += m->jcodelength + 18;
607 count_tryblocks += jd->exceptiontablelength;
608 count_javaexcsize += jd->exceptiontablelength * SIZEOF_VOID_P;
612 RT_TIMING_GET_TIME(time_checks);
614 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
615 /* Code for Sun's OpenJDK (see
616 hotspot/src/share/vm/classfile/verifier.cpp
617 (Verifier::is_eligible_for_verification)): Don't verify
618 dynamically-generated bytecodes. */
620 # if defined(ENABLE_VERIFIER)
621 if (class_issubclass(m->clazz, class_sun_reflect_MagicAccessorImpl))
622 jd->flags &= ~JITDATA_FLAG_VERIFY;
626 /* call the compiler passes ***********************************************/
628 DEBUG_JIT_COMPILEVERBOSE("Parsing: ");
630 /* call parse pass */
633 DEBUG_JIT_COMPILEVERBOSE("Exception while parsing: ");
637 RT_TIMING_GET_TIME(time_parse);
639 DEBUG_JIT_COMPILEVERBOSE("Parsing done: ");
641 #if defined(ENABLE_JIT)
642 # if defined(ENABLE_INTRP)
645 DEBUG_JIT_COMPILEVERBOSE("Analysing: ");
647 /* call stack analysis pass */
649 if (!stack_analyse(jd)) {
650 DEBUG_JIT_COMPILEVERBOSE("Exception while analysing: ");
654 RT_TIMING_GET_TIME(time_stack);
656 DEBUG_JIT_COMPILEVERBOSE("Analysing done: ");
658 #ifdef ENABLE_VERIFIER
659 if (JITDATA_HAS_FLAG_VERIFY(jd)) {
660 DEBUG_JIT_COMPILEVERBOSE("Typechecking: ");
662 /* call typecheck pass */
663 if (!typecheck(jd)) {
664 DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking: ");
669 DEBUG_JIT_COMPILEVERBOSE("Typechecking done: ");
672 RT_TIMING_GET_TIME(time_typecheck);
674 #if defined(ENABLE_LOOP)
679 jit_renumber_basicblocks(jd);
682 RT_TIMING_GET_TIME(time_loop);
684 #if defined(ENABLE_IFCONV)
685 if (JITDATA_HAS_FLAG_IFCONV(jd)) {
686 if (!ifconv_static(jd))
688 jit_renumber_basicblocks(jd);
691 RT_TIMING_GET_TIME(time_ifconv);
695 #if defined(ENABLE_INLINING) && (!defined(ENABLE_ESCAPE) || 1)
696 if (JITDATA_HAS_FLAG_INLINE(jd)) {
697 if (!inline_inline(jd))
702 #if defined(ENABLE_SSA)
704 fix_exception_handlers(jd);
708 /* Build the CFG. This has to be done after stack_analyse, as
709 there happens the JSR elimination. */
714 #if defined(ENABLE_PROFILING)
715 /* Basic block reordering. I think this should be done after
716 if-conversion, as we could lose the ability to do the
719 if (JITDATA_HAS_FLAG_REORDER(jd)) {
722 jit_renumber_basicblocks(jd);
726 #if defined(ENABLE_PM_HACKS)
727 #include "vm/jit/jit_pm_2.inc"
729 DEBUG_JIT_COMPILEVERBOSE("Allocating registers: ");
731 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
732 /* allocate registers */
737 STATISTICS(count_methods_allocated_by_lsra++);
740 # endif /* defined(ENABLE_LSRA) && !defined(ENABLE_SSA) */
741 #if defined(ENABLE_SSA)
742 /* allocate registers */
745 jd->code->optlevel > 0)
746 /* strncmp(jd->m->name->text, "hottie", 6) == 0*/
747 /*&& jd->exceptiontablelength == 0*/
749 /*printf("=== %s ===\n", jd->m->name->text);*/
750 jd->ls = (lsradata*) DumpMemory::allocate(sizeof(lsradata));
753 /*lsra(jd);*/ regalloc(jd);
754 /*eliminate_subbasicblocks(jd);*/
755 STATISTICS(count_methods_allocated_by_lsra++);
758 # endif /* defined(ENABLE_SSA) */
760 STATISTICS(count_locals_conflicts += (jd->maxlocals - 1) * (jd->maxlocals));
765 STATISTICS(simplereg_make_statistics(jd));
767 DEBUG_JIT_COMPILEVERBOSE("Allocating registers done: ");
768 # if defined(ENABLE_INTRP)
771 #endif /* defined(ENABLE_JIT) */
772 RT_TIMING_GET_TIME(time_alloc);
774 #if defined(ENABLE_PROFILING)
775 /* Allocate memory for basic block profiling information. This
776 _must_ be done after loop optimization and register allocation,
777 since they can change the basic block count. */
779 if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
780 code->bbfrequency = MNEW(u4, jd->basicblockcount);
783 DEBUG_JIT_COMPILEVERBOSE("Generating code: ");
785 /* now generate the machine code */
787 #if defined(ENABLE_JIT)
788 # if defined(ENABLE_INTRP)
790 #if defined(ENABLE_VERIFIER)
792 DEBUG_JIT_COMPILEVERBOSE("Typechecking (stackbased): ");
794 if (!typecheck_stackbased(jd)) {
795 DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking (stackbased): ");
800 if (!intrp_codegen(jd)) {
801 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
808 if (!codegen_generate(jd)) {
809 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
815 if (!intrp_codegen(jd)) {
816 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
821 RT_TIMING_GET_TIME(time_codegen);
823 DEBUG_JIT_COMPILEVERBOSE("Generating code done: ");
825 #if !defined(NDEBUG) && defined(ENABLE_REPLACEMENT)
826 /* activate replacement points inside newly created code */
828 if (opt_TestReplacement)
829 replace_activate_replacement_points(code, false);
833 #if defined(ENABLE_DEBUG_FILTER)
834 if (jd->m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
837 /* intermediate and assembly code listings */
839 if (JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)) {
840 show_method(jd, SHOW_CODE);
842 else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
843 # if defined(ENABLE_DISASSEMBLER)
844 DISASSEMBLE(code->entrypoint,
845 code->entrypoint + (code->mcodelength - cd->dseglen));
849 if (opt_showddatasegment)
854 /* switch to the newly generated code */
857 assert(code->entrypoint);
859 /* add the current compile version to the methodinfo */
861 code->prev = m->code;
864 RT_TIMING_TIME_DIFF(time_start,time_checks,RT_TIMING_JIT_CHECKS);
865 RT_TIMING_TIME_DIFF(time_checks,time_parse,RT_TIMING_JIT_PARSE);
866 RT_TIMING_TIME_DIFF(time_parse,time_stack,RT_TIMING_JIT_STACK);
867 RT_TIMING_TIME_DIFF(time_stack,time_typecheck,RT_TIMING_JIT_TYPECHECK);
868 RT_TIMING_TIME_DIFF(time_typecheck,time_loop,RT_TIMING_JIT_LOOP);
869 RT_TIMING_TIME_DIFF(time_loop,time_alloc,RT_TIMING_JIT_ALLOC);
870 RT_TIMING_TIME_DIFF(time_alloc,time_codegen,RT_TIMING_JIT_CODEGEN);
871 RT_TIMING_TIME_DIFF(time_start,time_codegen,RT_TIMING_JIT_TOTAL);
873 /* return pointer to the methods entry point */
875 return code->entrypoint;
879 /* jit_invalidate_code *********************************************************
881 Mark the compiled code of the given method as invalid and take care that
882 it is replaced if necessary.
884 XXX Not fully implemented, yet.
886 *******************************************************************************/
888 void jit_invalidate_code(methodinfo *m)
894 if (code == NULL || code_is_invalid(code))
897 code_flag_invalid(code);
899 /* activate mappable replacement points */
901 #if defined(ENABLE_REPLACEMENT)
902 replace_activate_replacement_points(code, true);
904 vm_abort("invalidating code only works with ENABLE_REPLACEMENT");
909 /* jit_request_optimization ****************************************************
911 Request optimization of the given method. If the code of the method is
912 unoptimized, it will be invalidated, so the next jit_get_current_code(m)
913 triggers an optimized recompilation.
914 If the method is already optimized, this function does nothing.
917 m................the method
919 *******************************************************************************/
921 void jit_request_optimization(methodinfo *m)
927 if (code && code->optlevel == 0)
928 jit_invalidate_code(m);
932 /* jit_get_current_code ********************************************************
934 Get the currently valid code for the given method. If there is no valid
935 code, (re)compile the method.
938 m................the method
941 the codeinfo* for the current code, or
942 NULL if an exception has been thrown during recompilation.
944 *******************************************************************************/
946 codeinfo *jit_get_current_code(methodinfo *m)
950 /* if we have valid code, return it */
952 if (m->code && !code_is_invalid(m->code))
955 /* otherwise: recompile */
957 if (!jit_recompile(m))
966 /* jit_asm_compile *************************************************************
968 This method is called from asm_vm_call_method and does:
970 - create stackframe info for exceptions
972 - patch the entrypoint of the method into the calculated address in
974 - flushes the instruction cache.
976 *******************************************************************************/
978 #if defined(ENABLE_JIT)
979 #if !defined(JIT_COMPILER_VIA_SIGNAL)
981 void* jit_asm_compile(methodinfo *m, void* mptr, void* sp, void* ra)
983 stackframeinfo_t sfi;
988 /* create the stackframeinfo (subtract 1 from RA as it points to the */
989 /* instruction after the call) */
991 stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ((uint8_t*) ra) - 1);
993 /* actually compile the method */
995 entrypoint = jit_compile(m);
997 /* remove the stackframeinfo */
999 stacktrace_stackframeinfo_remove(&sfi);
1001 /* there was a problem during compilation */
1003 if (entrypoint == NULL)
1006 /* get the method patch address */
1008 pa = md_jit_method_patch_address(sfi.pv, (void *) ra, mptr);
1010 /* patch the method entry point */
1012 p = (uintptr_t*) pa;
1014 *p = (uintptr_t) entrypoint;
1016 /* flush the instruction cache */
1018 md_icacheflush(pa, SIZEOF_VOID_P);
1025 /* jit_compile_handle **********************************************************
1027 This method is called from the appropriate signal handler which
1028 handles compiler-traps and does the following:
1030 - compile the method
1031 - patch the entrypoint of the method into the calculated address in
1033 - flush the instruction cache
1035 *******************************************************************************/
1037 void *jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr)
1039 void *newpv; /* new compiled method PV */
1040 void *pa; /* patch address */
1041 uintptr_t *p; /* convenience pointer */
1043 /* Compile the method. */
1045 newpv = jit_compile(m);
1047 /* There was a problem during compilation. */
1052 /* Get the method patch address. */
1054 pa = md_jit_method_patch_address(pv, ra, mptr);
1056 /* Patch the method entry point. */
1058 p = (uintptr_t *) pa;
1060 *p = (uintptr_t) newpv;
1062 /* Flush both caches. */
1064 md_cacheflush(pa, SIZEOF_VOID_P);
1068 #endif /* defined(ENABLE_JIT) */
1071 /* jit_complement_condition ****************************************************
1073 Returns the complement of the passed conditional instruction.
1075 We use the order of the different conditions, e.g.:
1080 If the passed opcode is odd, we simply add 1 to get the complement.
1081 If the opcode is even, we subtract 1.
1088 *******************************************************************************/
1090 s4 jit_complement_condition(s4 opcode)
1094 return ICMD_IFNONNULL;
1096 case ICMD_IFNONNULL:
1100 /* check if opcode is odd */
1110 /* jit_renumber_basicblocks ****************************************************
1112 Set the ->nr of all blocks so it increases when traversing ->next.
1115 jitdata..........the current jitdata
1117 *******************************************************************************/
1119 void jit_renumber_basicblocks(jitdata *jd)
1125 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1129 /* we have one block more than jd->basicblockcount (the end marker) */
1131 assert(nr == jd->basicblockcount + 1);
1135 /* jit_check_basicblock_numbers ************************************************
1137 Assert that the ->nr of the first block is zero and increases by 1 each
1138 time ->next is traversed.
1139 This function should be called before any analysis that relies on
1140 the basicblock numbers.
1143 jitdata..........the current jitdata
1145 NOTE: Aborts with an assertion if the condition is not met!
1147 *******************************************************************************/
1149 #if !defined(NDEBUG)
1150 void jit_check_basicblock_numbers(jitdata *jd)
1156 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1157 assert(bptr->nr == nr);
1161 /* we have one block more than jd->basicblockcount (the end marker) */
1163 assert(nr == jd->basicblockcount + 1);
1165 #endif /* !defined(NDEBUG) */
1169 * These are local overrides for various environment variables in Emacs.
1170 * Please do not remove this and leave it at the end of the file, where
1171 * Emacs will automagically detect them.
1172 * ---------------------------------------------------------------------
1175 * indent-tabs-mode: t
1179 * vim:noexpandtab:sw=4:ts=4: