LCOV - code coverage report
Current view: top level - vm/jit - jit.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 125 204 61.3 %
Date: 2017-07-14 10:03:36 Functions: 6 14 42.9 %

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

Generated by: LCOV version 1.11