CACAO
jit.cpp
Go to the documentation of this file.
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
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)
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)
78 #endif
79 
80 #if defined(ENABLE_LOOP)
81 # include "vm/jit/loop/loop.hpp"
82 #endif
83 
84 #if defined(ENABLE_COMPILER2)
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 void jit_init(void)
152 {
153  TRACESUBSYSTEMINITIALIZATION("jit_init");
154 
155 #if defined(ENABLE_JIT)
156  /* initialize stack analysis subsystem */
157 
158  (void) stack_init();
159 #endif
160 
161  /* initialize show subsystem */
162 
163 #if !defined(NDEBUG)
164  (void) show_init();
165 #endif
166 
167  /* initialize codegen subsystem */
168 
169  codegen_init();
170 
171  /* initialize code subsystem */
172 
173  (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  md_init();
184 #else
185  intrp_md_init();
186 #endif
187 }
188 
189 #define DEBUG_NAME "jit"
190 
191 /* jit_close *******************************************************************
192 
193  Close the JIT subsystem.
194 
195 *******************************************************************************/
196 
197 void jit_close(void)
198 {
199  /* nop */
200 }
201 
202 
203 /* dummy function, used when there is no JavaVM code available */
204 
205 static u1 *do_nothing_function(void)
206 {
207  return NULL;
208 }
209 
210 
211 /* jit_jitdata_new *************************************************************
212 
213  Allocates and initalizes a new jitdata structure.
214 
215 *******************************************************************************/
216 
218 {
219  jitdata *jd;
220  codeinfo *code;
221 
222  /* allocate jitdata structure and fill it */
223 
224  jd = (jitdata*) DumpMemory::allocate(sizeof(jitdata));
225 
226  jd->m = m;
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  code = code_codeinfo_new(m);
237 
238  /* Set codeinfo flags. */
239 
240  if (checksync && (m->flags & ACC_SYNCHRONIZED))
242 
243  if (checksync && (m->flags & ACC_SYNCHRONIZED))
245  else
246  code_flag_leafmethod(code);
247 
248  /* initialize variables */
249 
250  jd->code = code;
251  jd->flags = 0;
252  jd->exceptiontable = NULL;
253  jd->exceptiontablelength = 0;
254  jd->returncount = 0;
255  jd->branchtoentry = false;
256  jd->branchtoend = false;
257  jd->returncount = 0;
258  jd->returnblock = NULL;
259  jd->maxlocals = m->maxlocals;
260 
261  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 
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  if ((m->flags & ACC_STATIC) && !(m->clazz->state & CLASS_INITIALIZED)) {
288 #if !defined(NDEBUG)
289  if (initverbose)
290  log_message_class("Initialize class ", m->clazz);
291 #endif
292 
293  if (!initialize_class(m->clazz))
294  return NULL;
295 
296  /* check if the method has been compiled during initialization */
297 
298  if ((m->code != NULL) && (m->code->entrypoint != NULL))
299  return m->code->entrypoint;
300  }
301 
302  /* enter a monitor on the method */
303 
304  m->mutex->lock();
305 
306  /* if method has been already compiled return immediately */
307 
308  if (m->code != NULL) {
309  m->mutex->unlock();
310 
311  assert(m->code->entrypoint);
312  return m->code->entrypoint;
313  }
314 
316 
317  STATISTICS(count_methods++);
318 
319 #if defined(ENABLE_STATISTICS)
320  /* measure time */
321 
322  if (opt_getcompilingtime)
324 #endif
325 
326  // Create new dump memory area.
327  DumpMemoryArea dma;
328 
329  /* create jitdata structure */
330 
331  jd = jit_jitdata_new(m);
332 
333  /* set the flags for the current JIT run */
334 
336 
337 #if defined(ENABLE_VERIFIER)
338  if (opt_verify)
339  jd->flags |= JITDATA_FLAG_VERIFY;
340 #endif
341 
342 #if defined(ENABLE_PROFILING)
343  if (opt_prof)
345 #endif
346 
347 #if defined(ENABLE_IFCONV)
348  if (opt_ifconv)
349  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 
359 
362 
363  if (opt_verbosecall)
365 
366 #if defined(ENABLE_COMPILER2)
367  if (!opt_DisableCountdownTraps && (opt_ReplaceMethod == NULL || method_matches(m, opt_ReplaceMethod)))
369 #endif
370 
371 #if defined(ENABLE_JIT)
372 # if defined(ENABLE_INTRP)
373  if (!opt_intrp)
374 # endif
375  /* initialize the register allocator */
376  {
377  reg_setup(jd);
378  }
379 #endif
380 
381  /* setup the codegendata memory */
382 
383  codegen_setup(jd);
384 
385  /* now call internal compile function */
386 
387  r = jit_compile_intern(jd);
388 #if defined(ENABLE_COMPILER2)
390  using namespace cacao::jit::compiler2;
391  JITData JD(jd);
393  pass.initialize();
394  pass.run(JD);
395  pass.finalize();
396  }
397 #endif
398 
399  if (r == NULL) {
400  /* We had an exception! Finish stuff here if necessary. */
401 
402  /* release codeinfo */
403 
405  }
406  else {
407  DEBUG_JIT_COMPILEVERBOSE("Running: ");
408  }
409 
410 #if defined(ENABLE_STATISTICS)
411  /* measure time */
412 
413  if (opt_getcompilingtime)
415 #endif
416 
417  // Hook point just after code was generated.
418  Hook::jit_generated(m, m->code);
419 
420  /* leave the monitor */
421 
422  m->mutex->unlock();
423 
424 #if defined(ENABLE_STATISTICS)
425  if (m && m->code)
426  compiler_last_codesize = m->code->mcodelength;
427 #endif
428 
429  /* return pointer to the methods entry point */
430 
431  return r;
432 }
433 
434 
435 /* jit_jitdata_init_for_recompilation ******************************************
436 
437  Initalizes a jitdata structure such that it can be used for rompiling a
438  method.
439 
440 *******************************************************************************/
441 
443  /* get the optimization flags for the current JIT run */
444 
445 #if defined(ENABLE_VERIFIER)
446  jd->flags |= JITDATA_FLAG_VERIFY;
447 #endif
448 
453  if (opt_verbosecall)
455 
456 #if defined(ENABLE_JIT)
457 # if defined(ENABLE_INTRP)
458  if (!opt_intrp)
459 # endif
460  /* initialize the register allocator */
461 
462  reg_setup(jd);
463 #endif
464 
465  /* setup the codegendata memory */
466 
467  codegen_setup(jd);
468 }
469 
470 
471 /* jit_recompile ***************************************************************
472 
473  Recompiles a Java method.
474 
475 *******************************************************************************/
476 
478 {
479  DEBUG_JIT_COMPILEVERBOSE("Recompiling start: ");
480 
481 #if defined(ENABLE_STATISTICS)
482  /* measure time */
483 
484  if (opt_getcompilingtime)
486 #endif
487 
488  /* Create new dump memory area. */
489 
490  DumpMemoryArea dma;
491 
492  /* create jitdata structure */
493 
494  jitdata *jd = jit_jitdata_new(m);
496 
497  /* set the current optimization level to the previous one plus 1 */
498 
499  u1 optlevel = (jd->m->code) ? jd->m->code->optlevel : 0;
500  jd->code->optlevel = optlevel + 1;
501 
502  /* now call internal compile function */
503 
504  u1 *entrypoint = jit_compile_intern(jd);
505 
506  if (entrypoint == NULL) {
507  /* We had an exception! Finish stuff here if necessary. */
508 
509  /* release codeinfo */
510 
512  }
513 
514 #if defined(ENABLE_STATISTICS)
515  /* measure time */
516 
517  if (opt_getcompilingtime)
519 #endif
520 
521  // Hook point just after code was generated.
522  Hook::jit_generated(m, m->code);
523 
524  DEBUG_JIT_COMPILEVERBOSE("Recompiling done: ");
525 
526  /* return pointer to the methods entry point */
527 
528  return entrypoint;
529 }
530 
531 
532 /* jit_recompile_for_deoptimization ********************************************
533 
534  Recompiles a Java method generating necessary meta-data for deoptimization.
535 
536 *******************************************************************************/
537 
539 {
540 #if defined(ENABLE_STATISTICS)
541  /* measure time */
542 
543  if (opt_getcompilingtime)
545 #endif
546 
547  /* Create new dump memory area. */
548 
549  DumpMemoryArea dma;
550 
551  /* create jitdata structure */
552 
553  jitdata *jd = jit_jitdata_new(m);
555 
557 
558  /* now call internal compile function */
559 
560  u1 *entrypoint = jit_compile_intern(jd);
561 
562  if (entrypoint == NULL) {
563  /* We had an exception! Finish stuff here if necessary. */
564 
565  /* release codeinfo */
566 
568  }
569 
570 #if defined(ENABLE_STATISTICS)
571  /* measure time */
572 
573  if (opt_getcompilingtime)
575 #endif
576 
577  // Hook point just after code was generated.
578  Hook::jit_generated(m, m->code);
579 
580  /* return pointer to the methods entry point */
581 
582  return entrypoint;
583 }
584 
585 
586 #if defined(ENABLE_PM_HACKS)
587 #include "vm/jit/jit_pm_1.inc"
588 #endif
589 
590 // register compiler real-time group
591 RT_REGISTER_GROUP(compiler_group,"compiler","baseline compiler")
592 
593 // register real-time timers
594 RT_REGISTER_GROUP_TIMER(checks_timer, "compiler","checks at beginning", compiler_group)
595 RT_REGISTER_GROUP_TIMER(parse_timer, "compiler","parse", compiler_group)
596 RT_REGISTER_GROUP_TIMER(stack_timer, "compiler","analyse_stack", compiler_group)
597 RT_REGISTER_GROUP_TIMER(typechecker_timer, "compiler","typecheck", compiler_group)
598 RT_REGISTER_GROUP_TIMER(loop_timer, "compiler","loop", compiler_group)
599 RT_REGISTER_GROUP_TIMER(ifconversion_timer, "compiler","if conversion", compiler_group)
600 RT_REGISTER_GROUP_TIMER(ra_timer, "compiler","register allocation", compiler_group)
601 RT_REGISTER_GROUP_TIMER(codegen_timer, "compiler","codegen", compiler_group)
602 
603 /* jit_compile_intern **********************************************************
604 
605  Static internal function which does the actual compilation.
606 
607 *******************************************************************************/
608 
610 {
611  methodinfo *m;
612  //codegendata *cd;
613  codeinfo *code;
614 
615  RT_TIMER_START(checks_timer);
616 
617  /* get required compiler data */
618 
619 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
620  jd->ls = NULL;
621 #endif
622  m = jd->m;
623  code = jd->code;
624  //cd = jd->cd;
625 
626 #if defined(ENABLE_DEBUG_FILTER)
627  show_filters_apply(jd->m);
628 #endif
629 
630  // Handle native methods and create a native stub.
631  if (m->flags & ACC_NATIVE) {
633  void* f = nm.resolve_method(m);
634 
635  if (f == NULL)
636  return NULL;
637 
638  // XXX reinterpret_cast is used to prevend a compiler warning
639  // The Native* framework requires a rework to make it type safer
640  // and to get rid of this hack
641  code = NativeStub::generate(m, *reinterpret_cast<functionptr*>(&f));
642 
643  /* Native methods are never recompiled. */
644 
645  assert(!m->code);
646 
647  m->code = code;
648 
649  return code->entrypoint;
650  }
651 
652  /* if there is no javacode, print error message and return empty method */
653 
654  if (m->jcode == NULL) {
655  DEBUG_JIT_COMPILEVERBOSE("No code given for: ");
656 
657  code->entrypoint = (u1 *) (ptrint) do_nothing_function;
658  m->code = code;
659 
660  return code->entrypoint; /* return empty method */
661  }
662 
663  STATISTICS(count_javacodesize += m->jcodelength + 18);
664  STATISTICS(count_tryblocks += jd->exceptiontablelength);
665  STATISTICS(count_javaexcsize += jd->exceptiontablelength * SIZEOF_VOID_P);
666 
667  RT_TIMER_STOPSTART(checks_timer,parse_timer);
668 
669 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
670  /* Code for Sun's OpenJDK (see
671  hotspot/src/share/vm/classfile/verifier.cpp
672  (Verifier::is_eligible_for_verification)): Don't verify
673  dynamically-generated bytecodes. */
674 
675 # if defined(ENABLE_VERIFIER)
676  if (class_issubclass(m->clazz, class_sun_reflect_MagicAccessorImpl))
677  jd->flags &= ~JITDATA_FLAG_VERIFY;
678 # endif
679 #endif
680 
681  /* call the compiler passes ***********************************************/
682 
683  DEBUG_JIT_COMPILEVERBOSE("Parsing: ");
684 
685  /* call parse pass */
686 
687  if (!parse(jd)) {
688  DEBUG_JIT_COMPILEVERBOSE("Exception while parsing: ");
689 
690  return NULL;
691  }
692  RT_TIMER_STOP(parse_timer);
693 
694  DEBUG_JIT_COMPILEVERBOSE("Parsing done: ");
695 
696 #if defined(ENABLE_JIT)
697 # if defined(ENABLE_INTRP)
698  if (!opt_intrp) {
699 # endif
700  RT_TIMER_START(stack_timer);
701  DEBUG_JIT_COMPILEVERBOSE("Analysing: ");
702 
703  /* call stack analysis pass */
704 
705  if (!stack_analyse(jd)) {
706  DEBUG_JIT_COMPILEVERBOSE("Exception while analysing: ");
707 
708  return NULL;
709  }
710  RT_TIMER_STOPSTART(stack_timer,typechecker_timer);
711 
712  DEBUG_JIT_COMPILEVERBOSE("Analysing done: ");
713 
714 #ifdef ENABLE_VERIFIER
715  if (JITDATA_HAS_FLAG_VERIFY(jd)) {
716  DEBUG_JIT_COMPILEVERBOSE("Typechecking: ");
717 
718  /* call typecheck pass */
719  if (!typecheck(jd)) {
720  DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking: ");
721 
722  return NULL;
723  }
724 
725  DEBUG_JIT_COMPILEVERBOSE("Typechecking done: ");
726  }
727 #endif
728  RT_TIMER_STOPSTART(typechecker_timer,loop_timer);
729 
730 #if defined(ENABLE_IFCONV)
731  if (JITDATA_HAS_FLAG_IFCONV(jd)) {
732  if (!ifconv_static(jd))
733  return NULL;
735  }
736 #endif
737  RT_TIMER_STOPSTART(ifconversion_timer,ra_timer);
738 
739  /* inlining */
740 
741 #if defined(ENABLE_INLINING) && (!defined(ENABLE_ESCAPE) || 1)
742  if (JITDATA_HAS_FLAG_INLINE(jd)) {
743  if (!inline_inline(jd))
744  return NULL;
745  }
746 #endif
747 
748 #if defined(ENABLE_SSA)
749  if (opt_lsra) {
751  }
752 #endif
753 
754  /* Build the CFG. This has to be done after stack_analyse, as
755  there happens the JSR elimination. */
756 
757  if (!cfg_build(jd))
758  return NULL;
759 
760 #if defined(ENABLE_LOOP)
761  if (opt_loops)
762  {
765 
766  cfg_clear(jd);
767  if (!cfg_build(jd))
768  return NULL;
769  }
770 #endif
771  RT_TIMER_STOPSTART(ra_timer,loop_timer);
772 
773 #if defined(ENABLE_PROFILING)
774  /* Basic block reordering. I think this should be done after
775  if-conversion, as we could lose the ability to do the
776  if-conversion. */
777 
778  if (JITDATA_HAS_FLAG_REORDER(jd)) {
779  if (!reorder(jd))
780  return NULL;
782  }
783 #endif
784 
785 #if defined(ENABLE_PM_HACKS)
786 #include "vm/jit/jit_pm_2.inc"
787 #endif
788  DEBUG_JIT_COMPILEVERBOSE("Allocating registers: ");
789 
790 #if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
791  /* allocate registers */
792  if (opt_lsra) {
793  if (!lsra(jd))
794  return NULL;
795 
796  STATISTICS(count_methods_allocated_by_lsra++);
797 
798  } else
799 # endif /* defined(ENABLE_LSRA) && !defined(ENABLE_SSA) */
800 #if defined(ENABLE_SSA)
801  /* allocate registers */
802  if (
803  (opt_lsra &&
804  jd->code->optlevel > 0)
805  /* strncmp(UTF_TEXT(jd->m->name), "hottie", 6) == 0*/
806  /*&& jd->exceptiontablelength == 0*/
807  ) {
808  /*printf("=== %s ===\n", UTF_TEXT(jd->m->name));*/
809  jd->ls = (lsradata*) DumpMemory::allocate(sizeof(lsradata));
810  jd->ls = NULL;
811  ssa(jd);
812  /*lsra(jd);*/ regalloc(jd);
813  /*eliminate_subbasicblocks(jd);*/
814  STATISTICS(count_methods_allocated_by_lsra++);
815 
816  } else
817 # endif /* defined(ENABLE_SSA) */
818  {
819  STATISTICS(count_locals_conflicts += (jd->maxlocals - 1) * (jd->maxlocals));
820 
821  regalloc(jd);
822  }
823 
824  STATISTICS(simplereg_make_statistics(jd));
825 
826  RT_TIMER_STOP(ra_timer);
827  DEBUG_JIT_COMPILEVERBOSE("Allocating registers done: ");
828 # if defined(ENABLE_INTRP)
829  }
830 # endif
831 #endif /* defined(ENABLE_JIT) */
832  RT_TIMER_START(codegen_timer);
833 
834 #if defined(ENABLE_PROFILING)
835  /* Allocate memory for basic block profiling information. This
836  _must_ be done after loop optimization and register allocation,
837  since they can change the basic block count. */
838 
839  if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
840  code->basicblockcount = jd->basicblockcount;
841  code->bbfrequency = MNEW(u4, jd->basicblockcount);
842  }
843 #endif
844 
845  DEBUG_JIT_COMPILEVERBOSE("Generating code: ");
846 
847  /* now generate the machine code */
848 
849 #if defined(ENABLE_JIT)
850 # if defined(ENABLE_INTRP)
851  if (opt_intrp) {
852 #if defined(ENABLE_VERIFIER)
853  if (opt_verify) {
854  DEBUG_JIT_COMPILEVERBOSE("Typechecking (stackbased): ");
855 
856  if (!typecheck_stackbased(jd)) {
857  DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking (stackbased): ");
858  return NULL;
859  }
860  }
861 #endif
862  if (!intrp_codegen(jd)) {
863  DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
864 
865  return NULL;
866  }
867  } else
868 # endif
869  {
870  if (!codegen_generate(jd)) {
871  DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
872 
873  return NULL;
874  }
875  }
876 #else
877  if (!intrp_codegen(jd)) {
878  DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
879 
880  return NULL;
881  }
882 #endif
883  RT_TIMER_STOP(codegen_timer);
884 
885  DEBUG_JIT_COMPILEVERBOSE("Generating code done: ");
886 
887 #if !defined(NDEBUG)
888 #if defined(ENABLE_DEBUG_FILTER)
889  if (jd->m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
890 #endif
891  {
892  /* intermediate and assembly code listings */
893 
895  show_method(jd, SHOW_CODE);
896  }
897  else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
898 # if defined(ENABLE_DISASSEMBLER)
899  DISASSEMBLE(code->entrypoint,
900  code->entrypoint + (code->mcodelength - jd->cd->dseglen));
901 # endif
902  }
903 
905  dseg_display(jd);
906  }
907 #endif
908 
909  /* switch to the newly generated code */
910 
911  assert(code);
912  assert(code->entrypoint);
913 
914  /* add the current compile version to the methodinfo */
915 
916  code->prev = m->code;
917  m->code = code;
918 
919  /* return pointer to the methods entry point */
920 
921  return code->entrypoint;
922 }
923 
924 
925 /* jit_invalidate_code *********************************************************
926 
927  Mark the compiled code of the given method as invalid and take care that
928  it is replaced if necessary.
929 
930  XXX Not fully implemented, yet.
931 
932 *******************************************************************************/
933 
935 {
936  codeinfo *code;
937 
938  code = m->code;
939 
940  if (code == NULL || code_is_invalid(code))
941  return;
942 
943  code_flag_invalid(code);
944 
945  /* activate mappable replacement points */
946 
947 #if defined(ENABLE_COMPILER2)
949 #else
950  vm_abort("invalidating code only works with ENABLE_COMPILER2");
951 #endif
952 }
953 
954 
955 /* jit_request_optimization ****************************************************
956 
957  Request optimization of the given method. If the code of the method is
958  unoptimized, it will be invalidated, so the next jit_get_current_code(m)
959  triggers an optimized recompilation.
960  If the method is already optimized, this function does nothing.
961 
962  IN:
963  m................the method
964 
965 *******************************************************************************/
966 
968 {
969  codeinfo *code;
970 
971  code = m->code;
972 
973  if (code && code->optlevel == 0)
975 }
976 
977 
978 /* jit_get_current_code ********************************************************
979 
980  Get the currently valid code for the given method. If there is no valid
981  code, (re)compile the method.
982 
983  IN:
984  m................the method
985 
986  RETURN VALUE:
987  the codeinfo* for the current code, or
988  NULL if an exception has been thrown during recompilation.
989 
990 *******************************************************************************/
991 
993 {
994  assert(m);
995 
996  /* if we have valid code, return it */
997 
998  if (m->code && !code_is_invalid(m->code))
999  return m->code;
1000 
1001  /* otherwise: recompile */
1002 
1003 #if defined(ENABLE_COMPILER2)
1005  return NULL;
1006 #else
1007  if (!jit_recompile(m))
1008  return NULL;
1009 #endif
1010 
1011  assert(m->code);
1012 
1013  return m->code;
1014 }
1015 
1016 
1017 /* jit_asm_compile *************************************************************
1018 
1019  This method is called from asm_vm_call_method and does:
1020 
1021  - create stackframe info for exceptions
1022  - compile the method
1023  - patch the entrypoint of the method into the calculated address in
1024  the JIT code
1025  - flushes the instruction cache.
1026 
1027 *******************************************************************************/
1028 
1029 #if defined(ENABLE_JIT)
1030 #if !defined(JIT_COMPILER_VIA_SIGNAL)
1031 extern "C" {
1032 void* jit_asm_compile(methodinfo *m, void* mptr, void* sp, void* ra)
1033 {
1034  stackframeinfo_t sfi;
1035  void *entrypoint;
1036  void *pa;
1037  uintptr_t *p;
1038 
1039  /* create the stackframeinfo (subtract 1 from RA as it points to the */
1040  /* instruction after the call) */
1041 
1042  stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ((uint8_t*) ra) - 1);
1043 
1044  /* actually compile the method */
1045 
1046  entrypoint = jit_compile(m);
1047 
1048  /* remove the stackframeinfo */
1049 
1051 
1052  /* there was a problem during compilation */
1053 
1054  if (entrypoint == NULL)
1055  return NULL;
1056 
1057  /* get the method patch address */
1058 
1059  pa = md_jit_method_patch_address(sfi.pv, (void *) ra, mptr);
1060 
1061  /* patch the method entry point */
1062 
1063  p = (uintptr_t*) pa;
1064 
1065  *p = (uintptr_t) entrypoint;
1066 
1067  /* flush the instruction cache */
1068 
1069  md_icacheflush(pa, SIZEOF_VOID_P);
1070 
1071  return entrypoint;
1072 }
1073 }
1074 #endif
1075 
1076 /* jit_compile_handle **********************************************************
1077 
1078  This method is called from the appropriate signal handler which
1079  handles compiler-traps and does the following:
1080 
1081  - compile the method
1082  - patch the entrypoint of the method into the calculated address in
1083  the JIT code
1084  - flush the instruction cache
1085 
1086 *******************************************************************************/
1087 
1088 void *jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr)
1089 {
1090  void *newpv; /* new compiled method PV */
1091  void *pa; /* patch address */
1092  uintptr_t *p; /* convenience pointer */
1093 
1094  /* Compile the method. */
1095 
1096  bool compile_optimized = false;
1097 #if defined(ENABLE_COMPILER2)
1098  compile_optimized = method_matches(m,opt_OptimizeMethod);
1099 #endif
1100 
1101  if (compile_optimized) {
1102 #if defined(ENABLE_COMPILER2)
1103  newpv = cacao::jit::compiler2::compile(m);
1104 #endif
1105  } else {
1106  newpv = jit_compile(m);
1107  }
1108 
1109  /* There was a problem during compilation. */
1110 
1111  if (newpv == NULL)
1112  return NULL;
1113 
1114  /* Get the method patch address. */
1115 
1116  pa = md_jit_method_patch_address(pv, ra, mptr);
1117 
1118  /* Patch the method entry point. */
1119 
1120  p = (uintptr_t *) pa;
1121 
1122  *p = (uintptr_t) newpv;
1123 
1124  /* Flush both caches. */
1125 
1126  md_cacheflush(pa, SIZEOF_VOID_P);
1127 
1128  return newpv;
1129 }
1130 #endif /* defined(ENABLE_JIT) */
1131 
1132 
1133 /* jit_complement_condition ****************************************************
1134 
1135  Returns the complement of the passed conditional instruction.
1136 
1137  We use the order of the different conditions, e.g.:
1138 
1139  ICMD_IFEQ 153
1140  ICMD_IFNE 154
1141 
1142  If the passed opcode is odd, we simply add 1 to get the complement.
1143  If the opcode is even, we subtract 1.
1144 
1145  Exception:
1146 
1147  ICMD_IFNULL 198
1148  ICMD_IFNONNULL 199
1149 
1150 *******************************************************************************/
1151 
1153 {
1154  switch (opcode) {
1155  case ICMD_IFNULL:
1156  return ICMD_IFNONNULL;
1157 
1158  case ICMD_IFNONNULL:
1159  return ICMD_IFNULL;
1160 
1161  default:
1162  /* check if opcode is odd */
1163 
1164  if (opcode & 0x1)
1165  return ICMD(opcode + 1);
1166  else
1167  return ICMD(opcode - 1);
1168  }
1169 }
1170 
1171 
1172 /* jit_renumber_basicblocks ****************************************************
1173 
1174  Set the ->nr of all blocks so it increases when traversing ->next.
1175 
1176  IN:
1177  jitdata..........the current jitdata
1178 
1179 *******************************************************************************/
1180 
1182 {
1183  s4 nr;
1184  basicblock *bptr;
1185 
1186  nr = 0;
1187  for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1188  bptr->nr = nr++;
1189  }
1190 
1191  /* we have one block more than jd->basicblockcount (the end marker) */
1192 
1193  assert(nr == jd->basicblockcount + 1);
1194 }
1195 
1196 
1197 /* jit_check_basicblock_numbers ************************************************
1198 
1199  Assert that the ->nr of the first block is zero and increases by 1 each
1200  time ->next is traversed.
1201  This function should be called before any analysis that relies on
1202  the basicblock numbers.
1203 
1204  IN:
1205  jitdata..........the current jitdata
1206 
1207  NOTE: Aborts with an assertion if the condition is not met!
1208 
1209 *******************************************************************************/
1210 
1211 #if !defined(NDEBUG)
1213 {
1214  s4 nr;
1215  basicblock *bptr;
1216 
1217  nr = 0;
1218  for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
1219  assert(bptr->nr == nr);
1220  nr++;
1221  }
1222 
1223  /* we have one block more than jd->basicblockcount (the end marker) */
1224 
1225  assert(nr == jd->basicblockcount + 1);
1226 }
1227 #endif /* !defined(NDEBUG) */
1228 
1229 
1230 /*
1231  * These are local overrides for various environment variables in Emacs.
1232  * Please do not remove this and leave it at the end of the file, where
1233  * Emacs will automagically detect them.
1234  * ---------------------------------------------------------------------
1235  * Local variables:
1236  * mode: c++
1237  * indent-tabs-mode: t
1238  * c-basic-offset: 4
1239  * tab-width: 4
1240  * End:
1241  * vim:noexpandtab:sw=4:ts=4:
1242  */
#define SHOW_CODE
Definition: show.hpp:44
#define JITDATA_FLAG_IFCONV
Definition: jit.hpp:189
#define JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)
Definition: jit.hpp:231
bool cfg_build(jitdata *jd)
Definition: cfg.cpp:124
#define JITDATA_HAS_FLAG_INLINE(jd)
Definition: jit.hpp:219
#define pv
Definition: md-asm.hpp:65
bool opt_showdisassemble
Definition: options.cpp:85
#define mptr
Definition: md-asm.hpp:66
s4 exceptiontablelength
Definition: jit.hpp:167
codeinfo * jit_get_current_code(methodinfo *m)
Definition: jit.cpp:992
#define STATISTICS(x)
Wrapper for statistics only code.
Definition: statistics.hpp:975
void code_codeinfo_free(codeinfo *code)
Definition: code.cpp:213
basicblock * basicblocks
Definition: jit.hpp:141
Definition: jit.hpp:126
#define ra
Definition: md-asm.hpp:62
Table containing all native methods registered with the VM.
Definition: native.hpp:132
NativeMethods & get_nativemethods()
Definition: vm.hpp:128
#define JITDATA_HAS_FLAG_REORDER(jd)
Definition: jit.hpp:216
s4 jcodelength
Definition: method.hpp:85
#define RT_TIMER_STOP(var)
Stop the timer var.
Definition: rt-timing.hpp:695
basicblock * returnblock
Definition: jit.hpp:170
void replace_activate_replacement_points(codeinfo *code, bool mappable)
Definition: replace.cpp:132
exception_entry * exceptiontable
Definition: jit.hpp:168
void * jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr)
Definition: jit.cpp:1088
void cfg_clear(jitdata *jd)
Definition: cfg.cpp:515
void code_init(void)
Definition: code.cpp:46
argument_type from
#define JITDATA_FLAG_DEOPTIMIZE
Definition: jit.hpp:197
bool inline_inline(jitdata *jd)
Definition: inline.cpp:3198
s4 maxlocals
Definition: jit.hpp:162
static int code_is_invalid(codeinfo *code)
Definition: code.hpp:128
basicblock * next
Definition: jit.hpp:344
void jit_jitdata_init_for_recompilation(jitdata *jd)
Definition: jit.cpp:442
#define JITDATA_FLAG_VERBOSECALL
Definition: jit.hpp:201
bool stack_init(void)
Definition: stack.cpp:666
codeinfo * code
Definition: jit.hpp:128
u1 optlevel
Definition: code.hpp:79
bool reorder(jitdata *jd)
Definition: reorder.cpp:84
MachineLoop * loop
bool typecheck(jitdata *jd)
Definition: typecheck.cpp:684
bool typecheck_stackbased(jitdata *jd)
#define show_method(...)
Definition: ssa2.cpp:41
bool opt_intrp
Definition: options.cpp:55
#define JITDATA_FLAG_INSTRUMENT
Definition: jit.hpp:187
codegendata * cd
Definition: jit.hpp:129
#define JITDATA_HAS_FLAG_INSTRUMENT(jd)
Definition: jit.hpp:210
u4 flags
Definition: jit.hpp:138
typedef void(JNICALL *jvmtiEventSingleStep)(jvmtiEnv *jvmti_env
_Jv_JavaVM JavaVM
Definition: jni.hpp:114
#define JITDATA_FLAG_VERIFY
Definition: jit.hpp:185
bool initverbose
Definition: options.cpp:71
static void code_flag_invalid(codeinfo *code)
Definition: code.hpp:133
u1 * jit_compile(methodinfo *m)
Definition: jit.cpp:274
bool show_init(void)
Definition: show.cpp:90
#define RT_TIMER_START(var)
Start the timer var.
Definition: rt-timing.hpp:694
MachineCode * compile(methodinfo *m)
Definition: Compiler.cpp:123
static void code_flag_synchronized(codeinfo *code)
Definition: code.hpp:177
void codegen_init(void)
#define DEBUG_JIT_COMPILEVERBOSE(x)
Definition: jit.cpp:93
uint8_t u1
Definition: types.hpp:40
static void code_unflag_leafmethod(codeinfo *code)
Definition: code.hpp:160
s4 mcodelength
Definition: code.hpp:84
bool opt_verbosecall
Definition: options.cpp:76
char * opt_CompileMethod
Definition: options.cpp:166
Second stage compiler class.
static u1 * do_nothing_function(void)
Definition: jit.cpp:205
JNIEnv jthread jobject jclass jlong size
Definition: jvmti.h:387
void dseg_display(jitdata *jd)
Definition: dseg.cpp:633
void jit_request_optimization(methodinfo *m)
Definition: jit.cpp:967
#define TRACESUBSYSTEMINITIALIZATION(text)
Definition: options.hpp:257
bool opt_ifconv
Definition: options.cpp:118
void md_cacheflush(u1 *addr, s4 nbytes)
Definition: md.c:49
#define JITDATA_FLAG_PARSE
Definition: jit.hpp:184
void vm_abort(const char *text,...)
Definition: vm.cpp:2586
#define RT_REGISTER_GROUP(var, name, description)
Register a new (toplevel) group.
Definition: rt-timing.hpp:683
void intrp_md_init(void)
Definition: md.c:58
codeinfo * code_codeinfo_new(methodinfo *m)
Definition: code.cpp:72
#define JITDATA_FLAG_SHOWINTERMEDIATE
Definition: jit.hpp:199
void jit_renumber_basicblocks(jitdata *jd)
Definition: jit.cpp:1181
void jit_invalidate_code(methodinfo *m)
Definition: jit.cpp:934
static u1 * jit_compile_intern(jitdata *jd)
Definition: jit.cpp:609
#define RT_REGISTER_GROUP_TIMER(var, name, description, group)
Register a new timer.
Definition: rt-timing.hpp:682
bool opt_showddatasegment
Definition: options.cpp:86
ObjectFileWriterPass TODO: more info.
struct MethodLoopData MethodLoopData
Definition: loop.hpp:29
Dump memory area.
Definition: dumpmemory.hpp:90
jitdata * jit_jitdata_new(methodinfo *m)
Definition: jit.cpp:217
bool stack_analyse(jitdata *jd)
Definition: stack.cpp:2156
classinfo * clazz
Definition: method.hpp:80
static JNINativeMethod methods[]
alloc::list< PassInfo::IDTy >::type & stack
This file contains the statistics framework.
#define SHOW_FILTER_FLAG_SHOW_METHOD
Definition: show.hpp:70
bool checksync
Definition: options.cpp:90
s4 returncount
Definition: jit.hpp:172
#define JITDATA_HAS_FLAG_VERIFY(jd)
Definition: jit.hpp:207
void reg_setup(jitdata *jd)
Definition: reg.cpp:42
bool lsra(jitdata *jd)
Definition: lsra.cpp:101
#define STAT_REGISTER_SUM_GROUP(var, name, description)
Register a statistics summary group.
Definition: statistics.hpp:972
bool method_matches(methodinfo *m, const char *name)
Definition: method.cpp:1271
u1 * jit_recompile(methodinfo *m)
Definition: jit.cpp:477
static void Exception(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread, jmethodID method, jlocation location, jobject exception, jmethodID catch_method, jlocation catch_location)
Definition: VMjdwp.cpp:127
#define JITDATA_HAS_FLAG_IFCONV(jd)
Definition: jit.hpp:213
#define JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)
Definition: jit.hpp:228
void jit_init(void)
Definition: jit.cpp:151
u1 * jcode
Definition: method.hpp:86
void jit_close(void)
Definition: jit.cpp:197
MIIterator i
void jit_generated(methodinfo *m, codeinfo *code)
Hook point just after code was generated.
Definition: hook.hpp:102
bool branchtoentry
Definition: jit.hpp:173
static void code_flag_leafmethod(codeinfo *code)
Definition: code.hpp:155
int32_t s4
Definition: types.hpp:45
void stacktrace_stackframeinfo_add(stackframeinfo_t *sfi, void *pv, void *sp, void *ra, void *xpc)
Definition: stacktrace.cpp:84
ICMD
Definition: icmd.hpp:37
registerdata * rd
Definition: jit.hpp:130
s4 maxlocals
Definition: method.hpp:84
bool initialize_class(classinfo *c)
Definition: initialize.cpp:110
codeinfo * code
Definition: method.hpp:103
bool class_issubclass(classinfo *sub, classinfo *super)
Definition: class.cpp:1404
codeinfo * prev
Definition: code.hpp:75
bool opt_verify
Definition: options.cpp:103
This file contains the real-time timing utilities.
#define MNEW(type, num)
Definition: memory.hpp:96
void * resolve_method(methodinfo *m)
Resolves a native method, maybe from a dynamic library.
Definition: native.cpp:271
void compilingtime_start(void)
Definition: statistics.cpp:81
void * md_jit_method_patch_address(void *pv, void *ra, void *mptr)
Definition: md.cpp:83
bool regalloc(jitdata *jd)
Definition: simplereg.cpp:262
uint32_t u4
Definition: types.hpp:46
void codegen_setup(jitdata *jd)
This is a generic accessor class for Java arrays (of unspecified type), which can be used to safely o...
Definition: array.hpp:87
#define sp
Definition: md-asm.hpp:81
STAT_REGISTER_GROUP_VAR_EXTERN(int, size_classinfo, 0,"size classinfo","classinfo", info_struct_stat) STAT_REGISTER_GROUP_VAR(int
bool opt_showintermediate
Definition: options.cpp:87
void removeArrayBoundChecks(jitdata *jd)
Definition: loop.cpp:404
#define JITDATA_FLAG_INLINE
Definition: jit.hpp:191
methodinfo * m
Definition: jit.hpp:127
void stacktrace_stackframeinfo_remove(stackframeinfo_t *sfi)
Definition: stacktrace.cpp:204
void show_filters_apply(methodinfo *m)
Definition: show.cpp:1516
bool parse(jitdata *jd)
Definition: parse.cpp:604
static void * allocate(size_t size)
Definition: dumpmemory.hpp:251
s4 nr
Definition: jit.hpp:319
s4 basicblockcount
Definition: jit.hpp:144
#define JITDATA_FLAG_COUNTDOWN
Definition: jit.hpp:194
bool branchtoend
Definition: jit.hpp:174
#define RT_TIMER_STOPSTART(var1, var2)
Stop the timer var1 and start the timer var2.
Definition: rt-timing.hpp:696
#define TRACECOMPILERCALLS()
Definition: jit.cpp:104
void ssa(jitdata *jd)
Definition: ssa.cpp:105
void jit_check_basicblock_numbers(jitdata *jd)
Definition: jit.cpp:1212
void fix_exception_handlers(jitdata *jd)
Definition: ssa3.cpp:989
#define JITDATA_FLAG_SHOWDISASSEMBLE
Definition: jit.hpp:200
#define jit_asm_compile
Definition: md-asm.hpp:103
ICMD jit_complement_condition(ICMD opcode)
Definition: jit.cpp:1152
bool codegen_generate(jitdata *jd)
bool intrp_codegen(jitdata *jd)
Definition: codegen.c:281
s4 flags
Definition: method.hpp:70
block_count * blocks[HASH_SIZE]
Definition: profile.c:48
void md_init(void)
Definition: md.cpp:48
uintptr_t ptrint
Definition: types.hpp:54
static void md_icacheflush(void *addr, int nbytes)
Definition: md.hpp:155
static codeinfo * generate(methodinfo *m, functionptr f)
Wrapper for codegen_emit_stub_native.
Definition: stubs.cpp:282
#define STAT_REGISTER_VAR_EXTERN(type, var, init, name, description)
Register an external statistics variable.
Definition: statistics.hpp:964
#define STAT_REGISTER_VAR(type, var, init, name, description)
Register an external statistics variable.
Definition: statistics.hpp:966
bool ifconv_static(jitdata *jd)
Definition: ifconv.cpp:123
u1 * jit_recompile_for_deoptimization(methodinfo *m)
Definition: jit.cpp:538
virtual void initialize()
Initialize the Pass.
Definition: Pass.hpp:118
void log_message_class(const char *msg, classinfo *c)
Definition: logging.cpp:237
void compilingtime_stop(void)
Definition: statistics.cpp:96
static VM * get_current()
Definition: vm.hpp:99
u1 * entrypoint
Definition: code.hpp:83