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.hpp"
39 #include "toolbox/logging.h"
41 #include "threads/mutex.hpp"
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.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.hpp"
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_JITCACHE)
69 # include "vm/jit/jitcache.hpp"
72 #if defined(ENABLE_OPAGENT)
73 #include "vm/jit/oprofile-agent.hpp"
76 #include "vm/jit/allocator/simplereg.h"
77 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
78 # include "vm/jit/allocator/lsra.h"
81 #if defined(ENABLE_SSA)
82 # include "vm/jit/optimizing/lsra.h"
83 # include "vm/jit/optimizing/ssa.h"
86 #if defined(ENABLE_INLINING)
87 # include "vm/jit/inline/inline.h"
90 #include "vm/jit/ir/bytecode.h"
92 #include "vm/jit/loop/analyze.h"
93 #include "vm/jit/loop/graph.h"
94 #include "vm/jit/loop/loop.h"
96 #if defined(ENABLE_IFCONV)
97 # include "vm/jit/optimizing/ifconv.h"
100 #include "vm/jit/optimizing/reorder.h"
102 #if defined(ENABLE_PYTHON)
103 # include "vm/jit/python.h"
106 #include "vm/jit/verify/typecheck.h"
109 /* debug macros ***************************************************************/
112 #define DEBUG_JIT_COMPILEVERBOSE(x) \
114 if (compileverbose) { \
115 log_message_method(x, m); \
119 #define DEBUG_JIT_COMPILEVERBOSE(x) /* nothing */
123 # define TRACECOMPILERCALLS() \
125 if (opt_TraceCompilerCalls) { \
127 log_print("[JIT compiler started: method="); \
134 # define TRACECOMPILERCALLS()
138 /* jit_init ********************************************************************
140 Initializes the JIT subsystem.
142 *******************************************************************************/
146 TRACESUBSYSTEMINITIALIZATION("jit_init");
148 #if defined(ENABLE_JIT)
149 /* initialize stack analysis subsystem */
154 /* initialize show subsystem */
160 /* initialize codegen subsystem */
164 /* initialize code subsystem */
168 /* Machine dependent initialization. */
170 #if defined(ENABLE_JIT)
171 # if defined(ENABLE_INTRP)
181 #if defined(ENABLE_OPAGENT)
182 if (opt_EnableOpagent)
183 OprofileAgent::initialize();
188 /* jit_close *******************************************************************
190 Close the JIT subsystem.
192 *******************************************************************************/
196 #if defined(ENABLE_OPAGENT)
197 if (opt_EnableOpagent)
198 OprofileAgent::close();
203 /* dummy function, used when there is no JavaVM code available */
205 static u1 *do_nothing_function(void)
211 /* jit_jitdata_new *************************************************************
213 Allocates and initalizes a new jitdata structure.
215 *******************************************************************************/
217 jitdata *jit_jitdata_new(methodinfo *m)
222 /* allocate jitdata structure and fill it */
224 jd = (jitdata*) DumpMemory::allocate(sizeof(jitdata));
227 jd->cd = (codegendata*) DumpMemory::allocate(sizeof(codegendata));
228 jd->rd = (registerdata*) DumpMemory::allocate(sizeof(registerdata));
229 #if defined(ENABLE_LOOP)
230 jd->ld = (loopdata*) DumpMemory::allocate(sizeof(loopdata));
233 /* Allocate codeinfo memory from the heap as we need to keep them. */
235 code = code_codeinfo_new(m);
237 /* Set codeinfo flags. */
239 #if defined(ENABLE_THREADS)
240 if (checksync && (m->flags & ACC_SYNCHRONIZED))
241 code_flag_synchronized(code);
243 if (checksync && (m->flags & ACC_SYNCHRONIZED))
244 code_unflag_leafmethod(code);
247 code_flag_leafmethod(code);
249 /* initialize variables */
253 jd->exceptiontable = NULL;
254 jd->exceptiontablelength = 0;
256 jd->branchtoentry = false;
257 jd->branchtoend = false;
259 jd->returnblock = NULL;
260 jd->maxlocals = m->maxlocals;
266 /* jit_compile *****************************************************************
268 Translates one method to machine code.
270 *******************************************************************************/
272 static u1 *jit_compile_intern(jitdata *jd);
274 u1 *jit_compile(methodinfo *m)
279 STATISTICS(count_jit_calls++);
281 /* Initialize the static function's class. */
283 /* ATTENTION: This MUST be done before the method lock is aquired,
284 otherwise we could run into a deadlock with <clinit>'s that
285 call static methods of it's own class. */
287 if ((m->flags & ACC_STATIC) && !(m->clazz->state & CLASS_INITIALIZED)) {
290 log_message_class("Initialize class ", m->clazz);
293 if (!initialize_class(m->clazz))
296 /* check if the method has been compiled during initialization */
298 if ((m->code != NULL) && (m->code->entrypoint != NULL))
299 return m->code->entrypoint;
302 /* enter a monitor on the method */
306 /* if method has been already compiled return immediately */
308 if (m->code != NULL) {
311 assert(m->code->entrypoint);
312 return m->code->entrypoint;
315 TRACECOMPILERCALLS();
317 STATISTICS(count_methods++);
319 #if defined (ENABLE_JITCACHE)
321 if (jitcache_load (m))
325 return m->code->entrypoint;
330 #if defined(ENABLE_STATISTICS)
333 if (opt_getcompilingtime)
334 compilingtime_start();
337 // Create new dump memory area.
340 /* create jitdata structure */
342 jd = jit_jitdata_new(m);
344 /* set the flags for the current JIT run */
346 jd->flags = JITDATA_FLAG_PARSE;
348 #if defined(ENABLE_VERIFIER)
350 jd->flags |= JITDATA_FLAG_VERIFY;
353 #if defined(ENABLE_PROFILING)
355 jd->flags |= JITDATA_FLAG_INSTRUMENT;
358 #if defined(ENABLE_IFCONV)
360 jd->flags |= JITDATA_FLAG_IFCONV;
363 #if defined(ENABLE_INLINING) && defined(ENABLE_INLINING_DEBUG)
364 if (opt_Inline && opt_InlineAll)
365 jd->flags |= JITDATA_FLAG_INLINE;
368 if (opt_showintermediate)
369 jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
371 if (opt_showdisassemble)
372 jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
375 jd->flags |= JITDATA_FLAG_VERBOSECALL;
377 #if defined(ENABLE_REPLACEMENT) && defined(ENABLE_INLINING)
378 if (opt_Inline && (jd->m->hitcountdown > 0) && (jd->code->optlevel == 0)) {
379 jd->flags |= JITDATA_FLAG_COUNTDOWN;
383 #if defined(ENABLE_JIT)
384 # if defined(ENABLE_INTRP)
387 /* initialize the register allocator */
393 /* setup the codegendata memory */
397 /* now call internal compile function */
399 r = jit_compile_intern(jd);
402 /* We had an exception! Finish stuff here if necessary. */
404 /* release codeinfo */
406 code_codeinfo_free(jd->code);
408 #if defined(ENABLE_PROFILING)
409 /* Release memory for basic block profiling information. */
411 if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
412 if (jd->code->bbfrequency != NULL)
413 MFREE(jd->code->bbfrequency, u4, jd->code->basicblockcount);
417 DEBUG_JIT_COMPILEVERBOSE("Running: ");
420 #if defined (ENABLE_JITCACHE)
424 #if defined(ENABLE_STATISTICS)
427 if (opt_getcompilingtime)
428 compilingtime_stop();
431 #if defined(ENABLE_OPAGENT)
432 if (opt_EnableOpagent)
433 OprofileAgent::newmethod(m);
436 /* leave the monitor */
440 /* return pointer to the methods entry point */
446 /* jit_recompile ***************************************************************
448 Recompiles a Java method.
450 *******************************************************************************/
452 u1 *jit_recompile(methodinfo *m)
458 /* check for max. optimization level */
460 optlevel = (m->code) ? m->code->optlevel : 0;
464 /* log_message_method("not recompiling: ", m); */
469 DEBUG_JIT_COMPILEVERBOSE("Recompiling start: ");
471 STATISTICS(count_jit_calls++);
473 #if defined(ENABLE_STATISTICS)
476 if (opt_getcompilingtime)
477 compilingtime_start();
480 // Create new dump memory area.
483 /* create jitdata structure */
485 jd = jit_jitdata_new(m);
487 /* set the current optimization level to the previous one plus 1 */
489 jd->code->optlevel = optlevel + 1;
491 /* get the optimization flags for the current JIT run */
493 #if defined(ENABLE_VERIFIER)
494 jd->flags |= JITDATA_FLAG_VERIFY;
497 /* jd->flags |= JITDATA_FLAG_REORDER; */
498 if (opt_showintermediate)
499 jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
500 if (opt_showdisassemble)
501 jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
503 jd->flags |= JITDATA_FLAG_VERBOSECALL;
505 #if defined(ENABLE_INLINING)
507 jd->flags |= JITDATA_FLAG_INLINE;
510 #if defined(ENABLE_JIT)
511 # if defined(ENABLE_INTRP)
514 /* initialize the register allocator */
519 /* setup the codegendata memory */
523 /* now call internal compile function */
525 r = jit_compile_intern(jd);
528 /* We had an exception! Finish stuff here if necessary. */
530 /* release codeinfo */
532 code_codeinfo_free(jd->code);
535 #if defined(ENABLE_STATISTICS)
538 if (opt_getcompilingtime)
539 compilingtime_stop();
542 #if defined(ENABLE_OPAGENT)
543 if (opt_EnableOpagent)
544 OprofileAgent::newmethod(m);
547 DEBUG_JIT_COMPILEVERBOSE("Recompiling done: ");
549 /* return pointer to the methods entry point */
554 #if defined(ENABLE_PM_HACKS)
555 #include "vm/jit/jit_pm_1.inc"
558 /* jit_compile_intern **********************************************************
560 Static internal function which does the actual compilation.
562 *******************************************************************************/
564 static u1 *jit_compile_intern(jitdata *jd)
570 #if defined(ENABLE_RT_TIMING)
571 struct timespec time_start,time_checks,time_parse,time_stack,
572 time_typecheck,time_loop,time_ifconv,time_alloc,
576 RT_TIMING_GET_TIME(time_start);
578 /* get required compiler data */
580 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
587 #if defined(ENABLE_DEBUG_FILTER)
588 show_filters_apply(jd->m);
591 // Handle native methods and create a native stub.
592 if (m->flags & ACC_NATIVE) {
593 NativeMethods& nm = VM::get_current()->get_nativemethods();
594 void* f = nm.resolve_method(m);
599 code = NativeStub::generate(m, (functionptr) f);
601 /* Native methods are never recompiled. */
607 return code->entrypoint;
610 /* if there is no javacode, print error message and return empty method */
612 if (m->jcode == NULL) {
613 DEBUG_JIT_COMPILEVERBOSE("No code given for: ");
615 code->entrypoint = (u1 *) (ptrint) do_nothing_function;
618 return code->entrypoint; /* return empty method */
621 #if defined(ENABLE_STATISTICS)
623 count_javacodesize += m->jcodelength + 18;
624 count_tryblocks += jd->exceptiontablelength;
625 count_javaexcsize += jd->exceptiontablelength * SIZEOF_VOID_P;
629 RT_TIMING_GET_TIME(time_checks);
631 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
632 /* Code for Sun's OpenJDK (see
633 hotspot/src/share/vm/classfile/verifier.cpp
634 (Verifier::is_eligible_for_verification)): Don't verify
635 dynamically-generated bytecodes. */
637 # if defined(ENABLE_VERIFIER)
638 if (class_issubclass(m->clazz, class_sun_reflect_MagicAccessorImpl))
639 jd->flags &= ~JITDATA_FLAG_VERIFY;
643 /* call the compiler passes ***********************************************/
645 DEBUG_JIT_COMPILEVERBOSE("Parsing: ");
647 /* call parse pass */
650 DEBUG_JIT_COMPILEVERBOSE("Exception while parsing: ");
654 RT_TIMING_GET_TIME(time_parse);
656 DEBUG_JIT_COMPILEVERBOSE("Parsing done: ");
658 #if defined(ENABLE_JIT)
659 # if defined(ENABLE_INTRP)
662 DEBUG_JIT_COMPILEVERBOSE("Analysing: ");
664 /* call stack analysis pass */
666 if (!stack_analyse(jd)) {
667 DEBUG_JIT_COMPILEVERBOSE("Exception while analysing: ");
671 RT_TIMING_GET_TIME(time_stack);
673 DEBUG_JIT_COMPILEVERBOSE("Analysing done: ");
675 #ifdef ENABLE_VERIFIER
676 if (JITDATA_HAS_FLAG_VERIFY(jd)) {
677 DEBUG_JIT_COMPILEVERBOSE("Typechecking: ");
679 /* call typecheck pass */
680 if (!typecheck(jd)) {
681 DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking: ");
686 DEBUG_JIT_COMPILEVERBOSE("Typechecking done: ");
689 RT_TIMING_GET_TIME(time_typecheck);
691 #if defined(ENABLE_LOOP)
696 jit_renumber_basicblocks(jd);
699 RT_TIMING_GET_TIME(time_loop);
701 #if defined(ENABLE_IFCONV)
702 if (JITDATA_HAS_FLAG_IFCONV(jd)) {
703 if (!ifconv_static(jd))
705 jit_renumber_basicblocks(jd);
708 RT_TIMING_GET_TIME(time_ifconv);
712 #if defined(ENABLE_INLINING) && (!defined(ENABLE_ESCAPE) || 1)
713 if (JITDATA_HAS_FLAG_INLINE(jd)) {
714 if (!inline_inline(jd))
719 #if defined(ENABLE_SSA)
721 fix_exception_handlers(jd);
725 /* Build the CFG. This has to be done after stack_analyse, as
726 there happens the JSR elimination. */
731 #if defined(ENABLE_PROFILING)
732 /* Basic block reordering. I think this should be done after
733 if-conversion, as we could lose the ability to do the
736 if (JITDATA_HAS_FLAG_REORDER(jd)) {
739 jit_renumber_basicblocks(jd);
743 #if defined(ENABLE_PM_HACKS)
744 #include "vm/jit/jit_pm_2.inc"
746 DEBUG_JIT_COMPILEVERBOSE("Allocating registers: ");
748 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
749 /* allocate registers */
754 STATISTICS(count_methods_allocated_by_lsra++);
757 # endif /* defined(ENABLE_LSRA) && !defined(ENABLE_SSA) */
758 #if defined(ENABLE_SSA)
759 /* allocate registers */
762 jd->code->optlevel > 0)
763 /* strncmp(jd->m->name->text, "hottie", 6) == 0*/
764 /*&& jd->exceptiontablelength == 0*/
766 /*printf("=== %s ===\n", jd->m->name->text);*/
767 jd->ls = (lsradata*) DumpMemory::allocate(sizeof(lsradata));
770 /*lsra(jd);*/ regalloc(jd);
771 /*eliminate_subbasicblocks(jd);*/
772 STATISTICS(count_methods_allocated_by_lsra++);
775 # endif /* defined(ENABLE_SSA) */
777 STATISTICS(count_locals_conflicts += (jd->maxlocals - 1) * (jd->maxlocals));
782 STATISTICS(simplereg_make_statistics(jd));
784 DEBUG_JIT_COMPILEVERBOSE("Allocating registers done: ");
785 # if defined(ENABLE_INTRP)
788 #endif /* defined(ENABLE_JIT) */
789 RT_TIMING_GET_TIME(time_alloc);
791 #if defined(ENABLE_PROFILING)
792 /* Allocate memory for basic block profiling information. This
793 _must_ be done after loop optimization and register allocation,
794 since they can change the basic block count. */
796 if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
797 code->bbfrequency = MNEW(u4, jd->basicblockcount);
800 DEBUG_JIT_COMPILEVERBOSE("Generating code: ");
802 /* now generate the machine code */
804 #if defined(ENABLE_JIT)
805 # if defined(ENABLE_INTRP)
807 #if defined(ENABLE_VERIFIER)
809 DEBUG_JIT_COMPILEVERBOSE("Typechecking (stackbased): ");
811 if (!typecheck_stackbased(jd)) {
812 DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking (stackbased): ");
817 if (!intrp_codegen(jd)) {
818 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
825 if (!codegen_generate(jd)) {
826 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
832 if (!intrp_codegen(jd)) {
833 DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
838 RT_TIMING_GET_TIME(time_codegen);
840 DEBUG_JIT_COMPILEVERBOSE("Generating code done: ");
842 #if !defined(NDEBUG) && defined(ENABLE_REPLACEMENT)
843 /* activate replacement points inside newly created code */
845 if (opt_TestReplacement)
846 replace_activate_replacement_points(code, false);
850 #if defined(ENABLE_DEBUG_FILTER)
851 if (jd->m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
854 /* intermediate and assembly code listings */
856 if (JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)) {
857 show_method(jd, SHOW_CODE);
859 else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
860 # if defined(ENABLE_DISASSEMBLER)
861 DISASSEMBLE(code->entrypoint,
862 code->entrypoint + (code->mcodelength - cd->dseglen));
866 if (opt_showddatasegment)
871 /* switch to the newly generated code */
874 assert(code->entrypoint);
876 /* add the current compile version to the methodinfo */
878 code->prev = m->code;
881 RT_TIMING_TIME_DIFF(time_start,time_checks,RT_TIMING_JIT_CHECKS);
882 RT_TIMING_TIME_DIFF(time_checks,time_parse,RT_TIMING_JIT_PARSE);
883 RT_TIMING_TIME_DIFF(time_parse,time_stack,RT_TIMING_JIT_STACK);
884 RT_TIMING_TIME_DIFF(time_stack,time_typecheck,RT_TIMING_JIT_TYPECHECK);
885 RT_TIMING_TIME_DIFF(time_typecheck,time_loop,RT_TIMING_JIT_LOOP);
886 RT_TIMING_TIME_DIFF(time_loop,time_alloc,RT_TIMING_JIT_ALLOC);
887 RT_TIMING_TIME_DIFF(time_alloc,time_codegen,RT_TIMING_JIT_CODEGEN);
888 RT_TIMING_TIME_DIFF(time_start,time_codegen,RT_TIMING_JIT_TOTAL);
890 /* return pointer to the methods entry point */
892 return code->entrypoint;
896 /* jit_invalidate_code *********************************************************
898 Mark the compiled code of the given method as invalid and take care that
899 it is replaced if necessary.
901 XXX Not fully implemented, yet.
903 *******************************************************************************/
905 void jit_invalidate_code(methodinfo *m)
911 if (code == NULL || code_is_invalid(code))
914 code_flag_invalid(code);
916 /* activate mappable replacement points */
918 #if defined(ENABLE_REPLACEMENT)
919 replace_activate_replacement_points(code, true);
921 vm_abort("invalidating code only works with ENABLE_REPLACEMENT");
926 /* jit_request_optimization ****************************************************
928 Request optimization of the given method. If the code of the method is
929 unoptimized, it will be invalidated, so the next jit_get_current_code(m)
930 triggers an optimized recompilation.
931 If the method is already optimized, this function does nothing.
934 m................the method
936 *******************************************************************************/
938 void jit_request_optimization(methodinfo *m)
944 if (code && code->optlevel == 0)
945 jit_invalidate_code(m);
949 /* jit_get_current_code ********************************************************
951 Get the currently valid code for the given method. If there is no valid
952 code, (re)compile the method.
955 m................the method
958 the codeinfo* for the current code, or
959 NULL if an exception has been thrown during recompilation.
961 *******************************************************************************/
963 codeinfo *jit_get_current_code(methodinfo *m)
967 /* if we have valid code, return it */
969 if (m->code && !code_is_invalid(m->code))
972 /* otherwise: recompile */
974 if (!jit_recompile(m))
983 /* jit_asm_compile *************************************************************
985 This method is called from asm_vm_call_method and does:
987 - create stackframe info for exceptions
989 - patch the entrypoint of the method into the calculated address in
991 - flushes the instruction cache.
993 *******************************************************************************/
995 #if defined(ENABLE_JIT)
996 #if !defined(JIT_COMPILER_VIA_SIGNAL)
998 void* jit_asm_compile(methodinfo *m, void* mptr, void* sp, void* ra)
1000 stackframeinfo_t sfi;
1005 /* create the stackframeinfo (subtract 1 from RA as it points to the */
1006 /* instruction after the call) */
1008 stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ((uint8_t*) ra) - 1);
1010 /* actually compile the method */
1012 entrypoint = jit_compile(m);
1014 /* remove the stackframeinfo */
1016 stacktrace_stackframeinfo_remove(&sfi);
1018 /* there was a problem during compilation */
1020 if (entrypoint == NULL)
1023 /* get the method patch address */
1025 pa = md_jit_method_patch_address(sfi.pv, (void *) ra, mptr);
1027 /* patch the method entry point */
1029 p = (uintptr_t*) pa;
1031 *p = (uintptr_t) entrypoint;
1033 /* flush the instruction cache */
1035 md_icacheflush(pa, SIZEOF_VOID_P);
1042 /* jit_compile_handle **********************************************************
1044 This method is called from the appropriate signal handler which
1045 handles compiler-traps and does the following:
1047 - compile the method
1048 - patch the entrypoint of the method into the calculated address in
1050 - flush the instruction cache
1052 *******************************************************************************/
1054 void *jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr)
1056 void *newpv; /* new compiled method PV */
1057 void *pa; /* patch address */
1058 uintptr_t *p; /* convenience pointer */
1060 /* Compile the method. */
1062 newpv = jit_compile(m);
1064 /* There was a problem during compilation. */
1069 /* Get the method patch address. */
1071 pa = md_jit_method_patch_address(pv, ra, mptr);
1073 /* Patch the method entry point. */
1075 p = (uintptr_t *) pa;
1077 *p = (uintptr_t) newpv;
1079 /* Flush both caches. */
1081 md_cacheflush(pa, SIZEOF_VOID_P);
1085 #endif /* defined(ENABLE_JIT) */
1088 /* jit_complement_condition ****************************************************
1090 Returns the complement of the passed conditional instruction.
1092 We use the order of the different conditions, e.g.:
1097 If the passed opcode is odd, we simply add 1 to get the complement.
1098 If the opcode is even, we subtract 1.
1105 *******************************************************************************/
1107 s4 jit_complement_condition(s4 opcode)
1111 return ICMD_IFNONNULL;
1113 case ICMD_IFNONNULL:
1117 /* check if opcode is odd */
1127 /* jit_renumber_basicblocks ****************************************************
1129 Set the ->nr of all blocks so it increases when traversing ->next.
1132 jitdata..........the current jitdata
1134 *******************************************************************************/
1136 void jit_renumber_basicblocks(jitdata *jd)
1142 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1146 /* we have one block more than jd->basicblockcount (the end marker) */
1148 assert(nr == jd->basicblockcount + 1);
1152 /* jit_check_basicblock_numbers ************************************************
1154 Assert that the ->nr of the first block is zero and increases by 1 each
1155 time ->next is traversed.
1156 This function should be called before any analysis that relies on
1157 the basicblock numbers.
1160 jitdata..........the current jitdata
1162 NOTE: Aborts with an assertion if the condition is not met!
1164 *******************************************************************************/
1166 #if !defined(NDEBUG)
1167 void jit_check_basicblock_numbers(jitdata *jd)
1173 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1174 assert(bptr->nr == nr);
1178 /* we have one block more than jd->basicblockcount (the end marker) */
1180 assert(nr == jd->basicblockcount + 1);
1182 #endif /* !defined(NDEBUG) */
1186 * These are local overrides for various environment variables in Emacs.
1187 * Please do not remove this and leave it at the end of the file, where
1188 * Emacs will automagically detect them.
1189 * ---------------------------------------------------------------------
1192 * indent-tabs-mode: t
1196 * vim:noexpandtab:sw=4:ts=4: