* src/vm/jit/jit.h: Likewise.
* src/vm/jit/jit.cpp: New file.
* src/vm/jit/jit.hpp: Likewise.
* src/native/jni.cpp,
src/native/native.c,
src/vm/builtintable.inc,
src/vm/exceptions.cpp,
src/vm/jit/Makefile.am,
src/vm/jit/abi.h,
src/vm/jit/allocator/liveness.c,
src/vm/jit/allocator/simplereg.h,
src/vm/jit/alpha/codegen.c,
src/vm/jit/alpha/codegen.h,
src/vm/jit/alpha/emit.c,
src/vm/jit/alpha/md.c,
src/vm/jit/arm/codegen.c,
src/vm/jit/arm/emit.c,
src/vm/jit/cfg.c,
src/vm/jit/cfg.h,
src/vm/jit/codegen-common.c,
src/vm/jit/codegen-common.h,
src/vm/jit/dseg.h,
src/vm/jit/emit-common.c,
src/vm/jit/emit-common.h,
src/vm/jit/exceptiontable.c,
src/vm/jit/exceptiontable.h,
src/vm/jit/i386/codegen.c,
src/vm/jit/i386/codegen.h,
src/vm/jit/i386/emit.c,
src/vm/jit/i386/md.c,
src/vm/jit/inline/inline.c,
src/vm/jit/inline/inline.h,
src/vm/jit/intrp/codegen.c,
src/vm/jit/ir/instruction.hpp,
src/vm/jit/linenumbertable.h,
src/vm/jit/loop/analyze.c,
src/vm/jit/loop/analyze.h,
src/vm/jit/loop/graph.c,
src/vm/jit/loop/loop.c,
src/vm/jit/loop/loop.h,
src/vm/jit/loop/tracing.h,
src/vm/jit/m68k/codegen.c,
src/vm/jit/mips/codegen.c,
src/vm/jit/mips/codegen.h,
src/vm/jit/mips/emit.c,
src/vm/jit/mips/md.c,
src/vm/jit/optimizing/dominators.c,
src/vm/jit/optimizing/escape.c,
src/vm/jit/optimizing/escape.h,
src/vm/jit/optimizing/graph.c,
src/vm/jit/optimizing/ifconv.c,
src/vm/jit/optimizing/ifconv.h,
src/vm/jit/optimizing/lifetimes.c,
src/vm/jit/optimizing/lsra.c,
src/vm/jit/optimizing/profile.c,
src/vm/jit/optimizing/recompile.c,
src/vm/jit/optimizing/reorder.c,
src/vm/jit/optimizing/reorder.h,
src/vm/jit/optimizing/ssa.c,
src/vm/jit/optimizing/ssa2.c,
src/vm/jit/optimizing/ssa3.c,
src/vm/jit/optimizing/ssa_phi.c,
src/vm/jit/optimizing/ssa_rename.c,
src/vm/jit/parse.c,
src/vm/jit/parse.h,
src/vm/jit/patcher-common.c,
src/vm/jit/patcher-common.h,
src/vm/jit/powerpc/codegen.c,
src/vm/jit/powerpc/codegen.h,
src/vm/jit/powerpc/emit.c,
src/vm/jit/powerpc/md.c,
src/vm/jit/powerpc64/codegen.c,
src/vm/jit/powerpc64/codegen.h,
src/vm/jit/powerpc64/emit.c,
src/vm/jit/powerpc64/md.c,
src/vm/jit/powerpc64/md.h,
src/vm/jit/python.h,
src/vm/jit/reg.h,
src/vm/jit/replace.c,
src/vm/jit/replace.h,
src/vm/jit/s390/codegen.c,
src/vm/jit/s390/codegen.h,
src/vm/jit/s390/emit.c,
src/vm/jit/s390/md-abi.c,
src/vm/jit/show.c,
src/vm/jit/show.h,
src/vm/jit/sparc64/codegen.c,
src/vm/jit/sparc64/codegen.h,
src/vm/jit/sparc64/emit.c,
src/vm/jit/sparc64/md.c,
src/vm/jit/stack.c,
src/vm/jit/stack.h,
src/vm/jit/stubs.cpp,
src/vm/jit/trap.c,
src/vm/jit/verify/typecheck-common.h,
src/vm/jit/verify/typecheck-typeinferer.c,
src/vm/jit/verify/typecheck-typeinferer.h,
src/vm/jit/verify/typecheck.c,
src/vm/jit/verify/typecheck.h,
src/vm/jit/verify/typeinfo.c,
src/vm/jit/x86_64/codegen.c,
src/vm/jit/x86_64/codegen.h,
src/vm/jit/x86_64/emit.c,
src/vm/jit/x86_64/emit.h,
src/vm/jit/x86_64/md-abi.c,
src/vm/jit/x86_64/md.c,
src/vm/loader.c,
src/vm/resolve.c,
src/vm/resolve.h,
src/vm/statistics.h,
src/vm/vm.cpp: Include changes or extern "C".
--HG--
rename : src/vm/jit/jit.c => src/vm/jit/jit.cpp
rename : src/vm/jit/jit.h => src/vm/jit/jit.hpp
#include "vm/jit/argument.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/stacktrace.hpp"
#include "vm/vm.hpp"
#include "vm/jit/asmpart.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#if defined(ENABLE_JVMTI)
#include "native/jvmti/cacaodbg.h"
#include "vm/builtin.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* internal and not automatically replaced functions **************************/
#include "vm/vm.hpp"
#include "vm/jit/asmpart.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/methodheader.h"
#include "vm/jit/patcher-common.h"
#include "vm/jit/show.h"
exceptiontable.h \
executionstate.c \
executionstate.h \
- jit.c \
- jit.h \
+ jit.cpp \
+ jit.hpp \
linenumbertable.c \
linenumbertable.h \
methodtree.c \
#include "arch.h"
#include "vm/jit/abi-asm.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/stack.h"
#include "vm/method.h"
#include "vm/resolve.h"
#include "vm/jit/codegen-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/allocator/lsra.h"
#include "vm/jit/allocator/liveness.h"
/* src/vm/jit/allocator/simplereg.h - register allocator header
- Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Contact: cacao@cacaojvm.org
-
- Authors: Christian Thalinger
-
- Changes: Christian Ullrich
-
*/
#include "arch.h"
#include "vm/jit/codegen-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/inline/inline.h"
/* function prototypes ********************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
bool regalloc(jitdata *jd);
#if defined(ENABLE_STATISTICS)
void simplereg_make_statistics(jitdata *jd);
#endif
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _SIMPLE_REG_H */
#include "vm/jit/codegen-common.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/parse.h"
#include "vm/jit/patcher-common.h"
#include "config.h"
#include "vm/types.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* additional functions and macros to generate code ***************************/
#include "vm/jit/asmpart.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/patcher-common.h"
#include "vm/jit/replace.h"
#include "vm/jit/trace.hpp"
#include "vm/jit/alpha/md.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/trap.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/parse.h"
#include "vm/jit/abi.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/patcher-common.h"
#include "vm/jit/replace.h"
#include "vm/jit/trace.hpp"
#include "vm/global.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/stack.h"
/* src/vm/jit/cfg.h - build a control-flow graph
- Copyright (C) 2006, 2007 R. Grafl, A. Krall, C. Kruegel, C. Oates,
- R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
- C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
#include "vm/global.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* defines ********************************************************************/
/* function prototypes ********************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
bool cfg_build(jitdata *jd);
void cfg_add_root(jitdata *jd);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _CFG_H */
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/methodtree.h"
#include "vm/references.h"
#include "vm/jit/dseg.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/reg.h"
#include "vm/jit/code.h"
#include "vm/jit/replace.h"
#include "vm/references.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/codegen-common.h"
#include "vm/statistics.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/patcher-common.h"
#include "arch.h"
#include "vm/jit/codegen-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* branch labels **************************************************************/
#include "vm/jit/code.h"
#include "vm/jit/exceptiontable.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* exceptiontable_create *******************************************************
#include <stdint.h>
#include "vm/jit/code.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* exceptiontable_t ***********************************************************/
#include "vm/jit/codegen-common.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/parse.h"
#include "vm/jit/patcher-common.h"
#include "vm/jit/i386/emit.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#if defined(ENABLE_LSRA)
#include "vm/jit/asmpart.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/patcher-common.h"
#include "vm/jit/replace.h"
#include "vm/jit/trace.hpp"
#include "vm/vm.hpp"
#include "vm/jit/asmpart.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* md_init *********************************************************************
#include "vm/options.h"
#include "vm/statistics.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/parse.h"
#include "vm/jit/reg.h"
#include "vm/jit/show.h"
/* src/vm/jit/inline/inline.h - code inliner
- Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
#include "config.h"
-#include "vm/global.h"
+#include <stdbool.h>
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* function prototypes ********************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
bool inline_inline(jitdata *jd);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _INLINE_H */
/*
#include "vm/jit/asmpart.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/dseg.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/parse.h"
#include "vm/jit/patcher.h"
#include "vm/jit/stack.h"
#include "vm/descriptor.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/replace.h"
#include "vm/jit/ir/icmd.hpp"
+++ /dev/null
-/* src/vm/jit/jit.c - calls the code generation functions
-
- Copyright (C) 1996-2005, 2006, 2007, 2008
- CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
- This file is part of CACAO.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdint.h>
-
-#include "vm/types.h"
-
-#include "md.h"
-
-#include "mm/memory.h"
-
-#include "native/native.h"
-
-#include "toolbox/logging.h"
-
-#include "threads/lock-common.h"
-
-#include "vm/class.h"
-#include "vm/global.h"
-#include "vm/globals.hpp"
-#include "vm/initialize.h"
-#include "vm/loader.h"
-#include "vm/method.h"
-#include "vm/options.h"
-#include "vm/rt-timing.h"
-#include "vm/statistics.h"
-
-#include "vm/jit/asmpart.h"
-
-#include "vm/jit/cfg.h"
-
-#include "vm/jit/codegen-common.h"
-#include "vm/jit/disass.h"
-#include "vm/jit/dseg.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/parse.h"
-#include "vm/jit/reg.h"
-
-#include "vm/jit/show.h"
-#include "vm/jit/stack.h"
-#include "vm/jit/stubs.hpp"
-
-#if defined(ENABLE_OPAGENT)
-#include "vm/jit/oprofile-agent.hpp"
-#endif
-
-#include "vm/jit/allocator/simplereg.h"
-#if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
-# include "vm/jit/allocator/lsra.h"
-#endif
-
-#if defined(ENABLE_SSA)
-# include "vm/jit/optimizing/lsra.h"
-# include "vm/jit/optimizing/ssa.h"
-#endif
-
-#if defined(ENABLE_INLINING)
-# include "vm/jit/inline/inline.h"
-#endif
-
-#include "vm/jit/ir/bytecode.h"
-
-#include "vm/jit/loop/analyze.h"
-#include "vm/jit/loop/graph.h"
-#include "vm/jit/loop/loop.h"
-
-#if defined(ENABLE_IFCONV)
-# include "vm/jit/optimizing/ifconv.h"
-#endif
-
-#include "vm/jit/optimizing/reorder.h"
-
-#if defined(ENABLE_PYTHON)
-# include "vm/jit/python.h"
-#endif
-
-#include "vm/jit/verify/typecheck.h"
-
-
-/* debug macros ***************************************************************/
-
-#if !defined(NDEBUG)
-#define DEBUG_JIT_COMPILEVERBOSE(x) \
- do { \
- if (compileverbose) { \
- log_message_method(x, m); \
- } \
- } while (0)
-#else
-#define DEBUG_JIT_COMPILEVERBOSE(x) /* nothing */
-#endif
-
-#if !defined(NDEBUG)
-# define TRACECOMPILERCALLS() \
- do { \
- if (opt_TraceCompilerCalls) { \
- log_start(); \
- log_print("[JIT compiler started: method="); \
- method_print(m); \
- log_print("]"); \
- log_finish(); \
- } \
- } while (0)
-#else
-# define TRACECOMPILERCALLS()
-#endif
-
-
-/* jit_init ********************************************************************
-
- Initializes the JIT subsystem.
-
-*******************************************************************************/
-
-void jit_init(void)
-{
- TRACESUBSYSTEMINITIALIZATION("jit_init");
-
-#if defined(ENABLE_JIT)
- /* initialize stack analysis subsystem */
-
- (void) stack_init();
-#endif
-
- /* initialize show subsystem */
-
-#if !defined(NDEBUG)
- (void) show_init();
-#endif
-
- /* initialize codegen subsystem */
-
- codegen_init();
-
- /* initialize code subsystem */
-
- (void) code_init();
-
- /* Machine dependent initialization. */
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
- if (opt_intrp)
- intrp_md_init();
- else
-# endif
- md_init();
-#else
- intrp_md_init();
-#endif
-
-#if defined(ENABLE_OPAGENT)
- if (opt_EnableOpagent)
- OprofileAgent_initialize();
-#endif
-}
-
-
-/* jit_close *******************************************************************
-
- Close the JIT subsystem.
-
-*******************************************************************************/
-
-void jit_close(void)
-{
-#if defined(ENABLE_OPAGENT)
- if (opt_EnableOpagent)
- OprofileAgent_close();
-#endif
-}
-
-
-/* dummy function, used when there is no JavaVM code available */
-
-static u1 *do_nothing_function(void)
-{
- return NULL;
-}
-
-
-/* jit_jitdata_new *************************************************************
-
- Allocates and initalizes a new jitdata structure.
-
-*******************************************************************************/
-
-jitdata *jit_jitdata_new(methodinfo *m)
-{
- jitdata *jd;
- codeinfo *code;
-
- /* allocate jitdata structure and fill it */
-
- jd = DNEW(jitdata);
-
- jd->m = m;
- jd->cd = DNEW(codegendata);
- jd->rd = DNEW(registerdata);
-#if defined(ENABLE_LOOP)
- jd->ld = DNEW(loopdata);
-#endif
-
- /* Allocate codeinfo memory from the heap as we need to keep them. */
-
- code = code_codeinfo_new(m);
-
- /* Set codeinfo flags. */
-
-#if defined(ENABLE_THREADS)
- if (checksync && (m->flags & ACC_SYNCHRONIZED))
- code_flag_synchronized(code);
-
- if (checksync && (m->flags & ACC_SYNCHRONIZED))
- code_unflag_leafmethod(code);
- else
-#endif
- code_flag_leafmethod(code);
-
- /* initialize variables */
-
- jd->code = code;
- jd->flags = 0;
- jd->exceptiontable = NULL;
- jd->exceptiontablelength = 0;
- jd->returncount = 0;
- jd->branchtoentry = false;
- jd->branchtoend = false;
- jd->returncount = 0;
- jd->returnblock = NULL;
- jd->maxlocals = m->maxlocals;
-
- return jd;
-}
-
-
-/* jit_compile *****************************************************************
-
- Translates one method to machine code.
-
-*******************************************************************************/
-
-static u1 *jit_compile_intern(jitdata *jd);
-
-u1 *jit_compile(methodinfo *m)
-{
- u1 *r;
- jitdata *jd;
- int32_t dumpmarker;
-
- STATISTICS(count_jit_calls++);
-
- /* Initialize the static function's class. */
-
- /* ATTENTION: This MUST be done before the method lock is aquired,
- otherwise we could run into a deadlock with <clinit>'s that
- call static methods of it's own class. */
-
- if ((m->flags & ACC_STATIC) && !(m->clazz->state & CLASS_INITIALIZED)) {
-#if !defined(NDEBUG)
- if (initverbose)
- log_message_class("Initialize class ", m->clazz);
-#endif
-
- if (!initialize_class(m->clazz))
- return NULL;
-
- /* check if the method has been compiled during initialization */
-
- if ((m->code != NULL) && (m->code->entrypoint != NULL))
- return m->code->entrypoint;
- }
-
- /* enter a monitor on the method */
-
- LOCK_MONITOR_ENTER(m);
-
- /* if method has been already compiled return immediately */
-
- if (m->code != NULL) {
- LOCK_MONITOR_EXIT(m);
-
- assert(m->code->entrypoint);
- return m->code->entrypoint;
- }
-
- TRACECOMPILERCALLS();
-
- STATISTICS(count_methods++);
-
-#if defined(ENABLE_STATISTICS)
- /* measure time */
-
- if (opt_getcompilingtime)
- compilingtime_start();
-#endif
-
- /* mark start of dump memory area */
-
- DMARKER;
-
- /* create jitdata structure */
-
- jd = jit_jitdata_new(m);
-
- /* set the flags for the current JIT run */
-
- jd->flags = JITDATA_FLAG_PARSE;
-
-#if defined(ENABLE_VERIFIER)
- if (opt_verify)
- jd->flags |= JITDATA_FLAG_VERIFY;
-#endif
-
-#if defined(ENABLE_PROFILING)
- if (opt_prof)
- jd->flags |= JITDATA_FLAG_INSTRUMENT;
-#endif
-
-#if defined(ENABLE_IFCONV)
- if (opt_ifconv)
- jd->flags |= JITDATA_FLAG_IFCONV;
-#endif
-
-#if defined(ENABLE_INLINING) && defined(ENABLE_INLINING_DEBUG)
- if (opt_Inline && opt_InlineAll)
- jd->flags |= JITDATA_FLAG_INLINE;
-#endif
-
- if (opt_showintermediate)
- jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
-
- if (opt_showdisassemble)
- jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
-
- if (opt_verbosecall)
- jd->flags |= JITDATA_FLAG_VERBOSECALL;
-
-#if defined(ENABLE_REPLACEMENT) && defined(ENABLE_INLINING)
- if (opt_Inline && (jd->m->hitcountdown > 0) && (jd->code->optlevel == 0)) {
- jd->flags |= JITDATA_FLAG_COUNTDOWN;
- }
-#endif
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
- if (!opt_intrp)
-# endif
- /* initialize the register allocator */
- {
- reg_setup(jd);
- }
-#endif
-
- /* setup the codegendata memory */
-
- codegen_setup(jd);
-
- /* now call internal compile function */
-
- r = jit_compile_intern(jd);
-
- if (r == NULL) {
- /* We had an exception! Finish stuff here if necessary. */
-
- /* release codeinfo */
-
- code_codeinfo_free(jd->code);
-
-#if defined(ENABLE_PROFILING)
- /* Release memory for basic block profiling information. */
-
- if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
- if (jd->code->bbfrequency != NULL)
- MFREE(jd->code->bbfrequency, u4, jd->code->basicblockcount);
-#endif
- }
- else {
- DEBUG_JIT_COMPILEVERBOSE("Running: ");
- }
-
- /* release dump area */
-
- DRELEASE;
-
-#if defined(ENABLE_STATISTICS)
- /* measure time */
-
- if (opt_getcompilingtime)
- compilingtime_stop();
-#endif
-
-#if defined(ENABLE_OPAGENT)
- if (opt_EnableOpagent)
- OprofileAgent_newmethod(m);
-#endif
-
- /* leave the monitor */
-
- LOCK_MONITOR_EXIT(m);
-
- /* return pointer to the methods entry point */
-
- return r;
-}
-
-
-/* jit_recompile ***************************************************************
-
- Recompiles a Java method.
-
-*******************************************************************************/
-
-u1 *jit_recompile(methodinfo *m)
-{
- u1 *r;
- jitdata *jd;
- u1 optlevel;
- int32_t dumpmarker;
-
- /* check for max. optimization level */
-
- optlevel = (m->code) ? m->code->optlevel : 0;
-
-#if 0
- if (optlevel == 1) {
-/* log_message_method("not recompiling: ", m); */
- return NULL;
- }
-#endif
-
- DEBUG_JIT_COMPILEVERBOSE("Recompiling start: ");
-
- STATISTICS(count_jit_calls++);
-
-#if defined(ENABLE_STATISTICS)
- /* measure time */
-
- if (opt_getcompilingtime)
- compilingtime_start();
-#endif
-
- /* mark start of dump memory area */
-
- DMARKER;
-
- /* create jitdata structure */
-
- jd = jit_jitdata_new(m);
-
- /* set the current optimization level to the previous one plus 1 */
-
- jd->code->optlevel = optlevel + 1;
-
- /* get the optimization flags for the current JIT run */
-
-#if defined(ENABLE_VERIFIER)
- jd->flags |= JITDATA_FLAG_VERIFY;
-#endif
-
- /* jd->flags |= JITDATA_FLAG_REORDER; */
- if (opt_showintermediate)
- jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
- if (opt_showdisassemble)
- jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
- if (opt_verbosecall)
- jd->flags |= JITDATA_FLAG_VERBOSECALL;
-
-#if defined(ENABLE_INLINING)
- if (opt_Inline)
- jd->flags |= JITDATA_FLAG_INLINE;
-#endif
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
- if (!opt_intrp)
-# endif
- /* initialize the register allocator */
-
- reg_setup(jd);
-#endif
-
- /* setup the codegendata memory */
-
- codegen_setup(jd);
-
- /* now call internal compile function */
-
- r = jit_compile_intern(jd);
-
- if (r == NULL) {
- /* We had an exception! Finish stuff here if necessary. */
-
- /* release codeinfo */
-
- code_codeinfo_free(jd->code);
- }
-
- /* release dump area */
-
- DRELEASE;
-
-#if defined(ENABLE_STATISTICS)
- /* measure time */
-
- if (opt_getcompilingtime)
- compilingtime_stop();
-#endif
-
-#if defined(ENABLE_OPAGENT)
- if (opt_EnableOpagent)
- OprofileAgent_newmethod(m);
-#endif
-
- DEBUG_JIT_COMPILEVERBOSE("Recompiling done: ");
-
- /* return pointer to the methods entry point */
-
- return r;
-}
-
-#if defined(ENABLE_PM_HACKS)
-#include "vm/jit/jit_pm_1.inc"
-#endif
-
-/* jit_compile_intern **********************************************************
-
- Static internal function which does the actual compilation.
-
-*******************************************************************************/
-
-static u1 *jit_compile_intern(jitdata *jd)
-{
- methodinfo *m;
- codegendata *cd;
- codeinfo *code;
-
-#if defined(ENABLE_RT_TIMING)
- struct timespec time_start,time_checks,time_parse,time_stack,
- time_typecheck,time_loop,time_ifconv,time_alloc,
- time_codegen;
-#endif
-
- RT_TIMING_GET_TIME(time_start);
-
- /* get required compiler data */
-
-#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
- jd->ls = NULL;
-#endif
- m = jd->m;
- code = jd->code;
- cd = jd->cd;
-
-#if defined(ENABLE_DEBUG_FILTER)
- show_filters_apply(jd->m);
-#endif
-
- /* Handle native methods and create a native stub. */
-
- if (m->flags & ACC_NATIVE) {
- functionptr f;
-
- f = native_method_resolve(m);
-
- if (f == NULL)
- return NULL;
-
- code = NativeStub_generate(m, f);
-
- /* Native methods are never recompiled. */
-
- assert(!m->code);
-
- m->code = code;
-
- return code->entrypoint;
- }
-
- /* if there is no javacode, print error message and return empty method */
-
- if (m->jcode == NULL) {
- DEBUG_JIT_COMPILEVERBOSE("No code given for: ");
-
- code->entrypoint = (u1 *) (ptrint) do_nothing_function;
- m->code = code;
-
- return code->entrypoint; /* return empty method */
- }
-
-#if defined(ENABLE_STATISTICS)
- if (opt_stat) {
- count_javacodesize += m->jcodelength + 18;
- count_tryblocks += jd->exceptiontablelength;
- count_javaexcsize += jd->exceptiontablelength * SIZEOF_VOID_P;
- }
-#endif
-
- RT_TIMING_GET_TIME(time_checks);
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
- /* Code for Sun's OpenJDK (see
- hotspot/src/share/vm/classfile/verifier.cpp
- (Verifier::is_eligible_for_verification)): Don't verify
- dynamically-generated bytecodes. */
-
-# if defined(ENABLE_VERIFIER)
- if (class_issubclass(m->clazz, class_sun_reflect_MagicAccessorImpl))
- jd->flags &= ~JITDATA_FLAG_VERIFY;
-# endif
-#endif
-
- /* call the compiler passes ***********************************************/
-
- DEBUG_JIT_COMPILEVERBOSE("Parsing: ");
-
- /* call parse pass */
-
- if (!parse(jd)) {
- DEBUG_JIT_COMPILEVERBOSE("Exception while parsing: ");
-
- return NULL;
- }
- RT_TIMING_GET_TIME(time_parse);
-
- DEBUG_JIT_COMPILEVERBOSE("Parsing done: ");
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
- if (!opt_intrp) {
-# endif
- DEBUG_JIT_COMPILEVERBOSE("Analysing: ");
-
- /* call stack analysis pass */
-
- if (!stack_analyse(jd)) {
- DEBUG_JIT_COMPILEVERBOSE("Exception while analysing: ");
-
- return NULL;
- }
- RT_TIMING_GET_TIME(time_stack);
-
- DEBUG_JIT_COMPILEVERBOSE("Analysing done: ");
-
-#ifdef ENABLE_VERIFIER
- if (JITDATA_HAS_FLAG_VERIFY(jd)) {
- DEBUG_JIT_COMPILEVERBOSE("Typechecking: ");
-
- /* call typecheck pass */
- if (!typecheck(jd)) {
- DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking: ");
-
- return NULL;
- }
-
- DEBUG_JIT_COMPILEVERBOSE("Typechecking done: ");
- }
-#endif
- RT_TIMING_GET_TIME(time_typecheck);
-
-#if defined(ENABLE_LOOP)
- if (opt_loops) {
- depthFirst(jd);
- analyseGraph(jd);
- optimize_loops(jd);
- jit_renumber_basicblocks(jd);
- }
-#endif
- RT_TIMING_GET_TIME(time_loop);
-
-#if defined(ENABLE_IFCONV)
- if (JITDATA_HAS_FLAG_IFCONV(jd)) {
- if (!ifconv_static(jd))
- return NULL;
- jit_renumber_basicblocks(jd);
- }
-#endif
- RT_TIMING_GET_TIME(time_ifconv);
-
- /* inlining */
-
-#if defined(ENABLE_INLINING) && (!defined(ENABLE_ESCAPE) || 1)
- if (JITDATA_HAS_FLAG_INLINE(jd)) {
- if (!inline_inline(jd))
- return NULL;
- }
-#endif
-
-#if defined(ENABLE_SSA)
- if (opt_lsra) {
- fix_exception_handlers(jd);
- }
-#endif
-
- /* Build the CFG. This has to be done after stack_analyse, as
- there happens the JSR elimination. */
-
- if (!cfg_build(jd))
- return NULL;
-
-#if defined(ENABLE_PROFILING)
- /* Basic block reordering. I think this should be done after
- if-conversion, as we could lose the ability to do the
- if-conversion. */
-
- if (JITDATA_HAS_FLAG_REORDER(jd)) {
- if (!reorder(jd))
- return NULL;
- jit_renumber_basicblocks(jd);
- }
-#endif
-
-#if defined(ENABLE_PM_HACKS)
-#include "vm/jit/jit_pm_2.inc"
-#endif
- DEBUG_JIT_COMPILEVERBOSE("Allocating registers: ");
-
-#if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
- /* allocate registers */
- if (opt_lsra) {
- if (!lsra(jd))
- return NULL;
-
- STATISTICS(count_methods_allocated_by_lsra++);
-
- } else
-# endif /* defined(ENABLE_LSRA) && !defined(ENABLE_SSA) */
-#if defined(ENABLE_SSA)
- /* allocate registers */
- if (
- (opt_lsra &&
- jd->code->optlevel > 0)
- /* strncmp(jd->m->name->text, "hottie", 6) == 0*/
- /*&& jd->exceptiontablelength == 0*/
- ) {
- /*printf("=== %s ===\n", jd->m->name->text);*/
- jd->ls = DNEW(lsradata);
- jd->ls = NULL;
- ssa(jd);
- /*lsra(jd);*/ regalloc(jd);
- /*eliminate_subbasicblocks(jd);*/
- STATISTICS(count_methods_allocated_by_lsra++);
-
- } else
-# endif /* defined(ENABLE_SSA) */
- {
- STATISTICS(count_locals_conflicts += (jd->maxlocals - 1) * (jd->maxlocals));
-
- regalloc(jd);
- }
-
- STATISTICS(simplereg_make_statistics(jd));
-
- DEBUG_JIT_COMPILEVERBOSE("Allocating registers done: ");
-# if defined(ENABLE_INTRP)
- }
-# endif
-#endif /* defined(ENABLE_JIT) */
- RT_TIMING_GET_TIME(time_alloc);
-
-#if defined(ENABLE_PROFILING)
- /* Allocate memory for basic block profiling information. This
- _must_ be done after loop optimization and register allocation,
- since they can change the basic block count. */
-
- if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
- code->bbfrequency = MNEW(u4, jd->basicblockcount);
-#endif
-
- DEBUG_JIT_COMPILEVERBOSE("Generating code: ");
-
- /* now generate the machine code */
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
- if (opt_intrp) {
-#if defined(ENABLE_VERIFIER)
- if (opt_verify) {
- DEBUG_JIT_COMPILEVERBOSE("Typechecking (stackbased): ");
-
- if (!typecheck_stackbased(jd)) {
- DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking (stackbased): ");
- return NULL;
- }
- }
-#endif
- if (!intrp_codegen(jd)) {
- DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
-
- return NULL;
- }
- } else
-# endif
- {
- if (!codegen_generate(jd)) {
- DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
-
- return NULL;
- }
- }
-#else
- if (!intrp_codegen(jd)) {
- DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
-
- return NULL;
- }
-#endif
- RT_TIMING_GET_TIME(time_codegen);
-
- DEBUG_JIT_COMPILEVERBOSE("Generating code done: ");
-
-#if !defined(NDEBUG) && defined(ENABLE_REPLACEMENT)
- /* activate replacement points inside newly created code */
-
- if (opt_TestReplacement)
- replace_activate_replacement_points(code, false);
-#endif
-
-#if !defined(NDEBUG)
-#if defined(ENABLE_DEBUG_FILTER)
- if (jd->m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
-#endif
- {
- /* intermediate and assembly code listings */
-
- if (JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)) {
- show_method(jd, SHOW_CODE);
- }
- else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
-# if defined(ENABLE_DISASSEMBLER)
- DISASSEMBLE(code->entrypoint,
- code->entrypoint + (code->mcodelength - cd->dseglen));
-# endif
- }
-
- if (opt_showddatasegment)
- dseg_display(jd);
- }
-#endif
-
- /* switch to the newly generated code */
-
- assert(code);
- assert(code->entrypoint);
-
- /* add the current compile version to the methodinfo */
-
- code->prev = m->code;
- m->code = code;
-
- RT_TIMING_TIME_DIFF(time_start,time_checks,RT_TIMING_JIT_CHECKS);
- RT_TIMING_TIME_DIFF(time_checks,time_parse,RT_TIMING_JIT_PARSE);
- RT_TIMING_TIME_DIFF(time_parse,time_stack,RT_TIMING_JIT_STACK);
- RT_TIMING_TIME_DIFF(time_stack,time_typecheck,RT_TIMING_JIT_TYPECHECK);
- RT_TIMING_TIME_DIFF(time_typecheck,time_loop,RT_TIMING_JIT_LOOP);
- RT_TIMING_TIME_DIFF(time_loop,time_alloc,RT_TIMING_JIT_ALLOC);
- RT_TIMING_TIME_DIFF(time_alloc,time_codegen,RT_TIMING_JIT_CODEGEN);
- RT_TIMING_TIME_DIFF(time_start,time_codegen,RT_TIMING_JIT_TOTAL);
-
- /* return pointer to the methods entry point */
-
- return code->entrypoint;
-}
-
-
-/* jit_invalidate_code *********************************************************
-
- Mark the compiled code of the given method as invalid and take care that
- it is replaced if necessary.
-
- XXX Not fully implemented, yet.
-
-*******************************************************************************/
-
-void jit_invalidate_code(methodinfo *m)
-{
- codeinfo *code;
-
- code = m->code;
-
- if (code == NULL || code_is_invalid(code))
- return;
-
- code_flag_invalid(code);
-
- /* activate mappable replacement points */
-
-#if defined(ENABLE_REPLACEMENT)
- replace_activate_replacement_points(code, true);
-#else
- vm_abort("invalidating code only works with ENABLE_REPLACEMENT");
-#endif
-}
-
-
-/* jit_request_optimization ****************************************************
-
- Request optimization of the given method. If the code of the method is
- unoptimized, it will be invalidated, so the next jit_get_current_code(m)
- triggers an optimized recompilation.
- If the method is already optimized, this function does nothing.
-
- IN:
- m................the method
-
-*******************************************************************************/
-
-void jit_request_optimization(methodinfo *m)
-{
- codeinfo *code;
-
- code = m->code;
-
- if (code && code->optlevel == 0)
- jit_invalidate_code(m);
-}
-
-
-/* jit_get_current_code ********************************************************
-
- Get the currently valid code for the given method. If there is no valid
- code, (re)compile the method.
-
- IN:
- m................the method
-
- RETURN VALUE:
- the codeinfo* for the current code, or
- NULL if an exception has been thrown during recompilation.
-
-*******************************************************************************/
-
-codeinfo *jit_get_current_code(methodinfo *m)
-{
- assert(m);
-
- /* if we have valid code, return it */
-
- if (m->code && !code_is_invalid(m->code))
- return m->code;
-
- /* otherwise: recompile */
-
- if (!jit_recompile(m))
- return NULL;
-
- assert(m->code);
-
- return m->code;
-}
-
-
-/* jit_asm_compile *************************************************************
-
- This method is called from asm_vm_call_method and does:
-
- - create stackframe info for exceptions
- - compile the method
- - patch the entrypoint of the method into the calculated address in
- the JIT code
- - flushes the instruction cache.
-
-*******************************************************************************/
-
-#if defined(ENABLE_JIT)
-#if !defined(JIT_COMPILER_VIA_SIGNAL)
-u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
-{
- stackframeinfo_t sfi;
- u1 *entrypoint;
- u1 *pa;
- ptrint *p;
-
- /* create the stackframeinfo (subtract 1 from RA as it points to the */
- /* instruction after the call) */
-
- stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra-1);
-
- /* actually compile the method */
-
- entrypoint = jit_compile(m);
-
- /* remove the stackframeinfo */
-
- stacktrace_stackframeinfo_remove(&sfi);
-
- /* there was a problem during compilation */
-
- if (entrypoint == NULL)
- return NULL;
-
- /* get the method patch address */
-
- pa = md_jit_method_patch_address(sfi.pv, (void *) ra, mptr);
-
- /* patch the method entry point */
-
- p = (ptrint *) pa;
-
- *p = (ptrint) entrypoint;
-
- /* flush the instruction cache */
-
- md_icacheflush(pa, SIZEOF_VOID_P);
-
- return entrypoint;
-}
-#endif
-
-/* jit_compile_handle **********************************************************
-
- This method is called from the appropriate signal handler which
- handles compiler-traps and does the following:
-
- - compile the method
- - patch the entrypoint of the method into the calculated address in
- the JIT code
- - flush the instruction cache
-
-*******************************************************************************/
-
-void *jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr)
-{
- void *newpv; /* new compiled method PV */
- void *pa; /* patch address */
- uintptr_t *p; /* convenience pointer */
-
- /* Compile the method. */
-
- newpv = jit_compile(m);
-
- /* There was a problem during compilation. */
-
- if (newpv == NULL)
- return NULL;
-
- /* Get the method patch address. */
-
- pa = md_jit_method_patch_address(pv, ra, mptr);
-
- /* Patch the method entry point. */
-
- p = (uintptr_t *) pa;
-
- *p = (uintptr_t) newpv;
-
- /* Flush both caches. */
-
- md_cacheflush(pa, SIZEOF_VOID_P);
-
- return newpv;
-}
-#endif /* defined(ENABLE_JIT) */
-
-
-/* jit_complement_condition ****************************************************
-
- Returns the complement of the passed conditional instruction.
-
- We use the order of the different conditions, e.g.:
-
- ICMD_IFEQ 153
- ICMD_IFNE 154
-
- If the passed opcode is odd, we simply add 1 to get the complement.
- If the opcode is even, we subtract 1.
-
- Exception:
-
- ICMD_IFNULL 198
- ICMD_IFNONNULL 199
-
-*******************************************************************************/
-
-s4 jit_complement_condition(s4 opcode)
-{
- switch (opcode) {
- case ICMD_IFNULL:
- return ICMD_IFNONNULL;
-
- case ICMD_IFNONNULL:
- return ICMD_IFNULL;
-
- default:
- /* check if opcode is odd */
-
- if (opcode & 0x1)
- return opcode + 1;
- else
- return opcode - 1;
- }
-}
-
-
-/* jit_renumber_basicblocks ****************************************************
-
- Set the ->nr of all blocks so it increases when traversing ->next.
-
- IN:
- jitdata..........the current jitdata
-
-*******************************************************************************/
-
-void jit_renumber_basicblocks(jitdata *jd)
-{
- s4 nr;
- basicblock *bptr;
-
- nr = 0;
- for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
- bptr->nr = nr++;
- }
-
- /* we have one block more than jd->basicblockcount (the end marker) */
-
- assert(nr == jd->basicblockcount + 1);
-}
-
-
-/* jit_check_basicblock_numbers ************************************************
-
- Assert that the ->nr of the first block is zero and increases by 1 each
- time ->next is traversed.
- This function should be called before any analysis that relies on
- the basicblock numbers.
-
- IN:
- jitdata..........the current jitdata
-
- NOTE: Aborts with an assertion if the condition is not met!
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void jit_check_basicblock_numbers(jitdata *jd)
-{
- s4 nr;
- basicblock *bptr;
-
- nr = 0;
- for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
- assert(bptr->nr == nr);
- nr++;
- }
-
- /* we have one block more than jd->basicblockcount (the end marker) */
-
- assert(nr == jd->basicblockcount + 1);
-}
-#endif /* !defined(NDEBUG) */
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- * vim:noexpandtab:sw=4:ts=4:
- */
--- /dev/null
+/* src/vm/jit/jit.cpp - Just-In-Time compiler
+
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "vm/types.h"
+
+#include "md.h"
+
+#include "mm/memory.h"
+
+#include "native/native.h"
+
+#include "toolbox/logging.h"
+
+#include "threads/lock-common.h"
+
+#include "vm/class.h"
+#include "vm/global.h"
+#include "vm/globals.hpp"
+#include "vm/initialize.h"
+#include "vm/loader.h"
+#include "vm/method.h"
+#include "vm/options.h"
+#include "vm/rt-timing.h"
+#include "vm/statistics.h"
+
+#include "vm/jit/asmpart.h"
+
+#include "vm/jit/cfg.h"
+
+#include "vm/jit/codegen-common.h"
+#include "vm/jit/disass.h"
+#include "vm/jit/dseg.h"
+#include "vm/jit/jit.hpp"
+#include "vm/jit/parse.h"
+#include "vm/jit/reg.h"
+
+#include "vm/jit/show.h"
+#include "vm/jit/stack.h"
+#include "vm/jit/stubs.hpp"
+
+#if defined(ENABLE_OPAGENT)
+#include "vm/jit/oprofile-agent.hpp"
+#endif
+
+#include "vm/jit/allocator/simplereg.h"
+#if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
+# include "vm/jit/allocator/lsra.h"
+#endif
+
+#if defined(ENABLE_SSA)
+# include "vm/jit/optimizing/lsra.h"
+# include "vm/jit/optimizing/ssa.h"
+#endif
+
+#if defined(ENABLE_INLINING)
+# include "vm/jit/inline/inline.h"
+#endif
+
+#include "vm/jit/ir/bytecode.h"
+
+#include "vm/jit/loop/analyze.h"
+#include "vm/jit/loop/graph.h"
+#include "vm/jit/loop/loop.h"
+
+#if defined(ENABLE_IFCONV)
+# include "vm/jit/optimizing/ifconv.h"
+#endif
+
+#include "vm/jit/optimizing/reorder.h"
+
+#if defined(ENABLE_PYTHON)
+# include "vm/jit/python.h"
+#endif
+
+#include "vm/jit/verify/typecheck.h"
+
+
+/* debug macros ***************************************************************/
+
+#if !defined(NDEBUG)
+#define DEBUG_JIT_COMPILEVERBOSE(x) \
+ do { \
+ if (compileverbose) { \
+ log_message_method(x, m); \
+ } \
+ } while (0)
+#else
+#define DEBUG_JIT_COMPILEVERBOSE(x) /* nothing */
+#endif
+
+#if !defined(NDEBUG)
+# define TRACECOMPILERCALLS() \
+ do { \
+ if (opt_TraceCompilerCalls) { \
+ log_start(); \
+ log_print("[JIT compiler started: method="); \
+ method_print(m); \
+ log_print("]"); \
+ log_finish(); \
+ } \
+ } while (0)
+#else
+# define TRACECOMPILERCALLS()
+#endif
+
+
+/* jit_init ********************************************************************
+
+ Initializes the JIT subsystem.
+
+*******************************************************************************/
+
+void jit_init(void)
+{
+ TRACESUBSYSTEMINITIALIZATION("jit_init");
+
+#if defined(ENABLE_JIT)
+ /* initialize stack analysis subsystem */
+
+ (void) stack_init();
+#endif
+
+ /* initialize show subsystem */
+
+#if !defined(NDEBUG)
+ (void) show_init();
+#endif
+
+ /* initialize codegen subsystem */
+
+ codegen_init();
+
+ /* initialize code subsystem */
+
+ (void) code_init();
+
+ /* Machine dependent initialization. */
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (opt_intrp)
+ intrp_md_init();
+ else
+# endif
+ md_init();
+#else
+ intrp_md_init();
+#endif
+
+#if defined(ENABLE_OPAGENT)
+ if (opt_EnableOpagent)
+ OprofileAgent_initialize();
+#endif
+}
+
+
+/* jit_close *******************************************************************
+
+ Close the JIT subsystem.
+
+*******************************************************************************/
+
+void jit_close(void)
+{
+#if defined(ENABLE_OPAGENT)
+ if (opt_EnableOpagent)
+ OprofileAgent_close();
+#endif
+}
+
+
+/* dummy function, used when there is no JavaVM code available */
+
+static u1 *do_nothing_function(void)
+{
+ return NULL;
+}
+
+
+/* jit_jitdata_new *************************************************************
+
+ Allocates and initalizes a new jitdata structure.
+
+*******************************************************************************/
+
+jitdata *jit_jitdata_new(methodinfo *m)
+{
+ jitdata *jd;
+ codeinfo *code;
+
+ /* allocate jitdata structure and fill it */
+
+ jd = DNEW(jitdata);
+
+ jd->m = m;
+ jd->cd = DNEW(codegendata);
+ jd->rd = DNEW(registerdata);
+#if defined(ENABLE_LOOP)
+ jd->ld = DNEW(loopdata);
+#endif
+
+ /* Allocate codeinfo memory from the heap as we need to keep them. */
+
+ code = code_codeinfo_new(m);
+
+ /* Set codeinfo flags. */
+
+#if defined(ENABLE_THREADS)
+ if (checksync && (m->flags & ACC_SYNCHRONIZED))
+ code_flag_synchronized(code);
+
+ if (checksync && (m->flags & ACC_SYNCHRONIZED))
+ code_unflag_leafmethod(code);
+ else
+#endif
+ code_flag_leafmethod(code);
+
+ /* initialize variables */
+
+ jd->code = code;
+ jd->flags = 0;
+ jd->exceptiontable = NULL;
+ jd->exceptiontablelength = 0;
+ jd->returncount = 0;
+ jd->branchtoentry = false;
+ jd->branchtoend = false;
+ jd->returncount = 0;
+ jd->returnblock = NULL;
+ jd->maxlocals = m->maxlocals;
+
+ return jd;
+}
+
+
+/* jit_compile *****************************************************************
+
+ Translates one method to machine code.
+
+*******************************************************************************/
+
+static u1 *jit_compile_intern(jitdata *jd);
+
+u1 *jit_compile(methodinfo *m)
+{
+ u1 *r;
+ jitdata *jd;
+ int32_t dumpmarker;
+
+ STATISTICS(count_jit_calls++);
+
+ /* Initialize the static function's class. */
+
+ /* ATTENTION: This MUST be done before the method lock is aquired,
+ otherwise we could run into a deadlock with <clinit>'s that
+ call static methods of it's own class. */
+
+ if ((m->flags & ACC_STATIC) && !(m->clazz->state & CLASS_INITIALIZED)) {
+#if !defined(NDEBUG)
+ if (initverbose)
+ log_message_class("Initialize class ", m->clazz);
+#endif
+
+ if (!initialize_class(m->clazz))
+ return NULL;
+
+ /* check if the method has been compiled during initialization */
+
+ if ((m->code != NULL) && (m->code->entrypoint != NULL))
+ return m->code->entrypoint;
+ }
+
+ /* enter a monitor on the method */
+
+ LOCK_MONITOR_ENTER(m);
+
+ /* if method has been already compiled return immediately */
+
+ if (m->code != NULL) {
+ LOCK_MONITOR_EXIT(m);
+
+ assert(m->code->entrypoint);
+ return m->code->entrypoint;
+ }
+
+ TRACECOMPILERCALLS();
+
+ STATISTICS(count_methods++);
+
+#if defined(ENABLE_STATISTICS)
+ /* measure time */
+
+ if (opt_getcompilingtime)
+ compilingtime_start();
+#endif
+
+ /* mark start of dump memory area */
+
+ DMARKER;
+
+ /* create jitdata structure */
+
+ jd = jit_jitdata_new(m);
+
+ /* set the flags for the current JIT run */
+
+ jd->flags = JITDATA_FLAG_PARSE;
+
+#if defined(ENABLE_VERIFIER)
+ if (opt_verify)
+ jd->flags |= JITDATA_FLAG_VERIFY;
+#endif
+
+#if defined(ENABLE_PROFILING)
+ if (opt_prof)
+ jd->flags |= JITDATA_FLAG_INSTRUMENT;
+#endif
+
+#if defined(ENABLE_IFCONV)
+ if (opt_ifconv)
+ jd->flags |= JITDATA_FLAG_IFCONV;
+#endif
+
+#if defined(ENABLE_INLINING) && defined(ENABLE_INLINING_DEBUG)
+ if (opt_Inline && opt_InlineAll)
+ jd->flags |= JITDATA_FLAG_INLINE;
+#endif
+
+ if (opt_showintermediate)
+ jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
+
+ if (opt_showdisassemble)
+ jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
+
+ if (opt_verbosecall)
+ jd->flags |= JITDATA_FLAG_VERBOSECALL;
+
+#if defined(ENABLE_REPLACEMENT) && defined(ENABLE_INLINING)
+ if (opt_Inline && (jd->m->hitcountdown > 0) && (jd->code->optlevel == 0)) {
+ jd->flags |= JITDATA_FLAG_COUNTDOWN;
+ }
+#endif
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (!opt_intrp)
+# endif
+ /* initialize the register allocator */
+ {
+ reg_setup(jd);
+ }
+#endif
+
+ /* setup the codegendata memory */
+
+ codegen_setup(jd);
+
+ /* now call internal compile function */
+
+ r = jit_compile_intern(jd);
+
+ if (r == NULL) {
+ /* We had an exception! Finish stuff here if necessary. */
+
+ /* release codeinfo */
+
+ code_codeinfo_free(jd->code);
+
+#if defined(ENABLE_PROFILING)
+ /* Release memory for basic block profiling information. */
+
+ if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
+ if (jd->code->bbfrequency != NULL)
+ MFREE(jd->code->bbfrequency, u4, jd->code->basicblockcount);
+#endif
+ }
+ else {
+ DEBUG_JIT_COMPILEVERBOSE("Running: ");
+ }
+
+ /* release dump area */
+
+ DRELEASE;
+
+#if defined(ENABLE_STATISTICS)
+ /* measure time */
+
+ if (opt_getcompilingtime)
+ compilingtime_stop();
+#endif
+
+#if defined(ENABLE_OPAGENT)
+ if (opt_EnableOpagent)
+ OprofileAgent_newmethod(m);
+#endif
+
+ /* leave the monitor */
+
+ LOCK_MONITOR_EXIT(m);
+
+ /* return pointer to the methods entry point */
+
+ return r;
+}
+
+
+/* jit_recompile ***************************************************************
+
+ Recompiles a Java method.
+
+*******************************************************************************/
+
+u1 *jit_recompile(methodinfo *m)
+{
+ u1 *r;
+ jitdata *jd;
+ u1 optlevel;
+ int32_t dumpmarker;
+
+ /* check for max. optimization level */
+
+ optlevel = (m->code) ? m->code->optlevel : 0;
+
+#if 0
+ if (optlevel == 1) {
+/* log_message_method("not recompiling: ", m); */
+ return NULL;
+ }
+#endif
+
+ DEBUG_JIT_COMPILEVERBOSE("Recompiling start: ");
+
+ STATISTICS(count_jit_calls++);
+
+#if defined(ENABLE_STATISTICS)
+ /* measure time */
+
+ if (opt_getcompilingtime)
+ compilingtime_start();
+#endif
+
+ /* mark start of dump memory area */
+
+ DMARKER;
+
+ /* create jitdata structure */
+
+ jd = jit_jitdata_new(m);
+
+ /* set the current optimization level to the previous one plus 1 */
+
+ jd->code->optlevel = optlevel + 1;
+
+ /* get the optimization flags for the current JIT run */
+
+#if defined(ENABLE_VERIFIER)
+ jd->flags |= JITDATA_FLAG_VERIFY;
+#endif
+
+ /* jd->flags |= JITDATA_FLAG_REORDER; */
+ if (opt_showintermediate)
+ jd->flags |= JITDATA_FLAG_SHOWINTERMEDIATE;
+ if (opt_showdisassemble)
+ jd->flags |= JITDATA_FLAG_SHOWDISASSEMBLE;
+ if (opt_verbosecall)
+ jd->flags |= JITDATA_FLAG_VERBOSECALL;
+
+#if defined(ENABLE_INLINING)
+ if (opt_Inline)
+ jd->flags |= JITDATA_FLAG_INLINE;
+#endif
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (!opt_intrp)
+# endif
+ /* initialize the register allocator */
+
+ reg_setup(jd);
+#endif
+
+ /* setup the codegendata memory */
+
+ codegen_setup(jd);
+
+ /* now call internal compile function */
+
+ r = jit_compile_intern(jd);
+
+ if (r == NULL) {
+ /* We had an exception! Finish stuff here if necessary. */
+
+ /* release codeinfo */
+
+ code_codeinfo_free(jd->code);
+ }
+
+ /* release dump area */
+
+ DRELEASE;
+
+#if defined(ENABLE_STATISTICS)
+ /* measure time */
+
+ if (opt_getcompilingtime)
+ compilingtime_stop();
+#endif
+
+#if defined(ENABLE_OPAGENT)
+ if (opt_EnableOpagent)
+ OprofileAgent_newmethod(m);
+#endif
+
+ DEBUG_JIT_COMPILEVERBOSE("Recompiling done: ");
+
+ /* return pointer to the methods entry point */
+
+ return r;
+}
+
+#if defined(ENABLE_PM_HACKS)
+#include "vm/jit/jit_pm_1.inc"
+#endif
+
+/* jit_compile_intern **********************************************************
+
+ Static internal function which does the actual compilation.
+
+*******************************************************************************/
+
+static u1 *jit_compile_intern(jitdata *jd)
+{
+ methodinfo *m;
+ codegendata *cd;
+ codeinfo *code;
+
+#if defined(ENABLE_RT_TIMING)
+ struct timespec time_start,time_checks,time_parse,time_stack,
+ time_typecheck,time_loop,time_ifconv,time_alloc,
+ time_codegen;
+#endif
+
+ RT_TIMING_GET_TIME(time_start);
+
+ /* get required compiler data */
+
+#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
+ jd->ls = NULL;
+#endif
+ m = jd->m;
+ code = jd->code;
+ cd = jd->cd;
+
+#if defined(ENABLE_DEBUG_FILTER)
+ show_filters_apply(jd->m);
+#endif
+
+ /* Handle native methods and create a native stub. */
+
+ if (m->flags & ACC_NATIVE) {
+ functionptr f;
+
+ f = native_method_resolve(m);
+
+ if (f == NULL)
+ return NULL;
+
+ code = NativeStub::generate(m, f);
+
+ /* Native methods are never recompiled. */
+
+ assert(!m->code);
+
+ m->code = code;
+
+ return code->entrypoint;
+ }
+
+ /* if there is no javacode, print error message and return empty method */
+
+ if (m->jcode == NULL) {
+ DEBUG_JIT_COMPILEVERBOSE("No code given for: ");
+
+ code->entrypoint = (u1 *) (ptrint) do_nothing_function;
+ m->code = code;
+
+ return code->entrypoint; /* return empty method */
+ }
+
+#if defined(ENABLE_STATISTICS)
+ if (opt_stat) {
+ count_javacodesize += m->jcodelength + 18;
+ count_tryblocks += jd->exceptiontablelength;
+ count_javaexcsize += jd->exceptiontablelength * SIZEOF_VOID_P;
+ }
+#endif
+
+ RT_TIMING_GET_TIME(time_checks);
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+ /* Code for Sun's OpenJDK (see
+ hotspot/src/share/vm/classfile/verifier.cpp
+ (Verifier::is_eligible_for_verification)): Don't verify
+ dynamically-generated bytecodes. */
+
+# if defined(ENABLE_VERIFIER)
+ if (class_issubclass(m->clazz, class_sun_reflect_MagicAccessorImpl))
+ jd->flags &= ~JITDATA_FLAG_VERIFY;
+# endif
+#endif
+
+ /* call the compiler passes ***********************************************/
+
+ DEBUG_JIT_COMPILEVERBOSE("Parsing: ");
+
+ /* call parse pass */
+
+ if (!parse(jd)) {
+ DEBUG_JIT_COMPILEVERBOSE("Exception while parsing: ");
+
+ return NULL;
+ }
+ RT_TIMING_GET_TIME(time_parse);
+
+ DEBUG_JIT_COMPILEVERBOSE("Parsing done: ");
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (!opt_intrp) {
+# endif
+ DEBUG_JIT_COMPILEVERBOSE("Analysing: ");
+
+ /* call stack analysis pass */
+
+ if (!stack_analyse(jd)) {
+ DEBUG_JIT_COMPILEVERBOSE("Exception while analysing: ");
+
+ return NULL;
+ }
+ RT_TIMING_GET_TIME(time_stack);
+
+ DEBUG_JIT_COMPILEVERBOSE("Analysing done: ");
+
+#ifdef ENABLE_VERIFIER
+ if (JITDATA_HAS_FLAG_VERIFY(jd)) {
+ DEBUG_JIT_COMPILEVERBOSE("Typechecking: ");
+
+ /* call typecheck pass */
+ if (!typecheck(jd)) {
+ DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking: ");
+
+ return NULL;
+ }
+
+ DEBUG_JIT_COMPILEVERBOSE("Typechecking done: ");
+ }
+#endif
+ RT_TIMING_GET_TIME(time_typecheck);
+
+#if defined(ENABLE_LOOP)
+ if (opt_loops) {
+ depthFirst(jd);
+ analyseGraph(jd);
+ optimize_loops(jd);
+ jit_renumber_basicblocks(jd);
+ }
+#endif
+ RT_TIMING_GET_TIME(time_loop);
+
+#if defined(ENABLE_IFCONV)
+ if (JITDATA_HAS_FLAG_IFCONV(jd)) {
+ if (!ifconv_static(jd))
+ return NULL;
+ jit_renumber_basicblocks(jd);
+ }
+#endif
+ RT_TIMING_GET_TIME(time_ifconv);
+
+ /* inlining */
+
+#if defined(ENABLE_INLINING) && (!defined(ENABLE_ESCAPE) || 1)
+ if (JITDATA_HAS_FLAG_INLINE(jd)) {
+ if (!inline_inline(jd))
+ return NULL;
+ }
+#endif
+
+#if defined(ENABLE_SSA)
+ if (opt_lsra) {
+ fix_exception_handlers(jd);
+ }
+#endif
+
+ /* Build the CFG. This has to be done after stack_analyse, as
+ there happens the JSR elimination. */
+
+ if (!cfg_build(jd))
+ return NULL;
+
+#if defined(ENABLE_PROFILING)
+ /* Basic block reordering. I think this should be done after
+ if-conversion, as we could lose the ability to do the
+ if-conversion. */
+
+ if (JITDATA_HAS_FLAG_REORDER(jd)) {
+ if (!reorder(jd))
+ return NULL;
+ jit_renumber_basicblocks(jd);
+ }
+#endif
+
+#if defined(ENABLE_PM_HACKS)
+#include "vm/jit/jit_pm_2.inc"
+#endif
+ DEBUG_JIT_COMPILEVERBOSE("Allocating registers: ");
+
+#if defined(ENABLE_LSRA) && !defined(ENABLE_SSA)
+ /* allocate registers */
+ if (opt_lsra) {
+ if (!lsra(jd))
+ return NULL;
+
+ STATISTICS(count_methods_allocated_by_lsra++);
+
+ } else
+# endif /* defined(ENABLE_LSRA) && !defined(ENABLE_SSA) */
+#if defined(ENABLE_SSA)
+ /* allocate registers */
+ if (
+ (opt_lsra &&
+ jd->code->optlevel > 0)
+ /* strncmp(jd->m->name->text, "hottie", 6) == 0*/
+ /*&& jd->exceptiontablelength == 0*/
+ ) {
+ /*printf("=== %s ===\n", jd->m->name->text);*/
+ jd->ls = DNEW(lsradata);
+ jd->ls = NULL;
+ ssa(jd);
+ /*lsra(jd);*/ regalloc(jd);
+ /*eliminate_subbasicblocks(jd);*/
+ STATISTICS(count_methods_allocated_by_lsra++);
+
+ } else
+# endif /* defined(ENABLE_SSA) */
+ {
+ STATISTICS(count_locals_conflicts += (jd->maxlocals - 1) * (jd->maxlocals));
+
+ regalloc(jd);
+ }
+
+ STATISTICS(simplereg_make_statistics(jd));
+
+ DEBUG_JIT_COMPILEVERBOSE("Allocating registers done: ");
+# if defined(ENABLE_INTRP)
+ }
+# endif
+#endif /* defined(ENABLE_JIT) */
+ RT_TIMING_GET_TIME(time_alloc);
+
+#if defined(ENABLE_PROFILING)
+ /* Allocate memory for basic block profiling information. This
+ _must_ be done after loop optimization and register allocation,
+ since they can change the basic block count. */
+
+ if (JITDATA_HAS_FLAG_INSTRUMENT(jd))
+ code->bbfrequency = MNEW(u4, jd->basicblockcount);
+#endif
+
+ DEBUG_JIT_COMPILEVERBOSE("Generating code: ");
+
+ /* now generate the machine code */
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (opt_intrp) {
+#if defined(ENABLE_VERIFIER)
+ if (opt_verify) {
+ DEBUG_JIT_COMPILEVERBOSE("Typechecking (stackbased): ");
+
+ if (!typecheck_stackbased(jd)) {
+ DEBUG_JIT_COMPILEVERBOSE("Exception while typechecking (stackbased): ");
+ return NULL;
+ }
+ }
+#endif
+ if (!intrp_codegen(jd)) {
+ DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
+
+ return NULL;
+ }
+ } else
+# endif
+ {
+ if (!codegen_generate(jd)) {
+ DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
+
+ return NULL;
+ }
+ }
+#else
+ if (!intrp_codegen(jd)) {
+ DEBUG_JIT_COMPILEVERBOSE("Exception while generating code: ");
+
+ return NULL;
+ }
+#endif
+ RT_TIMING_GET_TIME(time_codegen);
+
+ DEBUG_JIT_COMPILEVERBOSE("Generating code done: ");
+
+#if !defined(NDEBUG) && defined(ENABLE_REPLACEMENT)
+ /* activate replacement points inside newly created code */
+
+ if (opt_TestReplacement)
+ replace_activate_replacement_points(code, false);
+#endif
+
+#if !defined(NDEBUG)
+#if defined(ENABLE_DEBUG_FILTER)
+ if (jd->m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD)
+#endif
+ {
+ /* intermediate and assembly code listings */
+
+ if (JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd)) {
+ show_method(jd, SHOW_CODE);
+ }
+ else if (JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd)) {
+# if defined(ENABLE_DISASSEMBLER)
+ DISASSEMBLE(code->entrypoint,
+ code->entrypoint + (code->mcodelength - cd->dseglen));
+# endif
+ }
+
+ if (opt_showddatasegment)
+ dseg_display(jd);
+ }
+#endif
+
+ /* switch to the newly generated code */
+
+ assert(code);
+ assert(code->entrypoint);
+
+ /* add the current compile version to the methodinfo */
+
+ code->prev = m->code;
+ m->code = code;
+
+ RT_TIMING_TIME_DIFF(time_start,time_checks,RT_TIMING_JIT_CHECKS);
+ RT_TIMING_TIME_DIFF(time_checks,time_parse,RT_TIMING_JIT_PARSE);
+ RT_TIMING_TIME_DIFF(time_parse,time_stack,RT_TIMING_JIT_STACK);
+ RT_TIMING_TIME_DIFF(time_stack,time_typecheck,RT_TIMING_JIT_TYPECHECK);
+ RT_TIMING_TIME_DIFF(time_typecheck,time_loop,RT_TIMING_JIT_LOOP);
+ RT_TIMING_TIME_DIFF(time_loop,time_alloc,RT_TIMING_JIT_ALLOC);
+ RT_TIMING_TIME_DIFF(time_alloc,time_codegen,RT_TIMING_JIT_CODEGEN);
+ RT_TIMING_TIME_DIFF(time_start,time_codegen,RT_TIMING_JIT_TOTAL);
+
+ /* return pointer to the methods entry point */
+
+ return code->entrypoint;
+}
+
+
+/* jit_invalidate_code *********************************************************
+
+ Mark the compiled code of the given method as invalid and take care that
+ it is replaced if necessary.
+
+ XXX Not fully implemented, yet.
+
+*******************************************************************************/
+
+void jit_invalidate_code(methodinfo *m)
+{
+ codeinfo *code;
+
+ code = m->code;
+
+ if (code == NULL || code_is_invalid(code))
+ return;
+
+ code_flag_invalid(code);
+
+ /* activate mappable replacement points */
+
+#if defined(ENABLE_REPLACEMENT)
+ replace_activate_replacement_points(code, true);
+#else
+ vm_abort("invalidating code only works with ENABLE_REPLACEMENT");
+#endif
+}
+
+
+/* jit_request_optimization ****************************************************
+
+ Request optimization of the given method. If the code of the method is
+ unoptimized, it will be invalidated, so the next jit_get_current_code(m)
+ triggers an optimized recompilation.
+ If the method is already optimized, this function does nothing.
+
+ IN:
+ m................the method
+
+*******************************************************************************/
+
+void jit_request_optimization(methodinfo *m)
+{
+ codeinfo *code;
+
+ code = m->code;
+
+ if (code && code->optlevel == 0)
+ jit_invalidate_code(m);
+}
+
+
+/* jit_get_current_code ********************************************************
+
+ Get the currently valid code for the given method. If there is no valid
+ code, (re)compile the method.
+
+ IN:
+ m................the method
+
+ RETURN VALUE:
+ the codeinfo* for the current code, or
+ NULL if an exception has been thrown during recompilation.
+
+*******************************************************************************/
+
+codeinfo *jit_get_current_code(methodinfo *m)
+{
+ assert(m);
+
+ /* if we have valid code, return it */
+
+ if (m->code && !code_is_invalid(m->code))
+ return m->code;
+
+ /* otherwise: recompile */
+
+ if (!jit_recompile(m))
+ return NULL;
+
+ assert(m->code);
+
+ return m->code;
+}
+
+
+/* jit_asm_compile *************************************************************
+
+ This method is called from asm_vm_call_method and does:
+
+ - create stackframe info for exceptions
+ - compile the method
+ - patch the entrypoint of the method into the calculated address in
+ the JIT code
+ - flushes the instruction cache.
+
+*******************************************************************************/
+
+#if defined(ENABLE_JIT)
+#if !defined(JIT_COMPILER_VIA_SIGNAL)
+u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra)
+{
+ stackframeinfo_t sfi;
+ u1 *entrypoint;
+ u1 *pa;
+ ptrint *p;
+
+ /* create the stackframeinfo (subtract 1 from RA as it points to the */
+ /* instruction after the call) */
+
+ stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra-1);
+
+ /* actually compile the method */
+
+ entrypoint = jit_compile(m);
+
+ /* remove the stackframeinfo */
+
+ stacktrace_stackframeinfo_remove(&sfi);
+
+ /* there was a problem during compilation */
+
+ if (entrypoint == NULL)
+ return NULL;
+
+ /* get the method patch address */
+
+ pa = md_jit_method_patch_address(sfi.pv, (void *) ra, mptr);
+
+ /* patch the method entry point */
+
+ p = (ptrint *) pa;
+
+ *p = (ptrint) entrypoint;
+
+ /* flush the instruction cache */
+
+ md_icacheflush(pa, SIZEOF_VOID_P);
+
+ return entrypoint;
+}
+#endif
+
+/* jit_compile_handle **********************************************************
+
+ This method is called from the appropriate signal handler which
+ handles compiler-traps and does the following:
+
+ - compile the method
+ - patch the entrypoint of the method into the calculated address in
+ the JIT code
+ - flush the instruction cache
+
+*******************************************************************************/
+
+void *jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr)
+{
+ void *newpv; /* new compiled method PV */
+ void *pa; /* patch address */
+ uintptr_t *p; /* convenience pointer */
+
+ /* Compile the method. */
+
+ newpv = jit_compile(m);
+
+ /* There was a problem during compilation. */
+
+ if (newpv == NULL)
+ return NULL;
+
+ /* Get the method patch address. */
+
+ pa = md_jit_method_patch_address(pv, ra, mptr);
+
+ /* Patch the method entry point. */
+
+ p = (uintptr_t *) pa;
+
+ *p = (uintptr_t) newpv;
+
+ /* Flush both caches. */
+
+ md_cacheflush(pa, SIZEOF_VOID_P);
+
+ return newpv;
+}
+#endif /* defined(ENABLE_JIT) */
+
+
+/* jit_complement_condition ****************************************************
+
+ Returns the complement of the passed conditional instruction.
+
+ We use the order of the different conditions, e.g.:
+
+ ICMD_IFEQ 153
+ ICMD_IFNE 154
+
+ If the passed opcode is odd, we simply add 1 to get the complement.
+ If the opcode is even, we subtract 1.
+
+ Exception:
+
+ ICMD_IFNULL 198
+ ICMD_IFNONNULL 199
+
+*******************************************************************************/
+
+s4 jit_complement_condition(s4 opcode)
+{
+ switch (opcode) {
+ case ICMD_IFNULL:
+ return ICMD_IFNONNULL;
+
+ case ICMD_IFNONNULL:
+ return ICMD_IFNULL;
+
+ default:
+ /* check if opcode is odd */
+
+ if (opcode & 0x1)
+ return opcode + 1;
+ else
+ return opcode - 1;
+ }
+}
+
+
+/* jit_renumber_basicblocks ****************************************************
+
+ Set the ->nr of all blocks so it increases when traversing ->next.
+
+ IN:
+ jitdata..........the current jitdata
+
+*******************************************************************************/
+
+void jit_renumber_basicblocks(jitdata *jd)
+{
+ s4 nr;
+ basicblock *bptr;
+
+ nr = 0;
+ for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
+ bptr->nr = nr++;
+ }
+
+ /* we have one block more than jd->basicblockcount (the end marker) */
+
+ assert(nr == jd->basicblockcount + 1);
+}
+
+
+/* jit_check_basicblock_numbers ************************************************
+
+ Assert that the ->nr of the first block is zero and increases by 1 each
+ time ->next is traversed.
+ This function should be called before any analysis that relies on
+ the basicblock numbers.
+
+ IN:
+ jitdata..........the current jitdata
+
+ NOTE: Aborts with an assertion if the condition is not met!
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void jit_check_basicblock_numbers(jitdata *jd)
+{
+ s4 nr;
+ basicblock *bptr;
+
+ nr = 0;
+ for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
+ assert(bptr->nr == nr);
+ nr++;
+ }
+
+ /* we have one block more than jd->basicblockcount (the end marker) */
+
+ assert(nr == jd->basicblockcount + 1);
+}
+#endif /* !defined(NDEBUG) */
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c++
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
+++ /dev/null
-/* src/vm/jit/jit.h - code generation header
-
- Copyright (C) 1996-2005, 2006, 2007, 2008
- CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
- This file is part of CACAO.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2, or (at
- your option) any later version.
-
- This program is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301, USA.
-
-*/
-
-
-#ifndef _JIT_H
-#define _JIT_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct jitdata jitdata;
-typedef struct basicblock basicblock;
-typedef struct exception_entry exception_entry;
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "vm/global.h"
-#include "vm/method.h"
-#include "vm/references.h"
-#include "vm/resolve.h"
-
-#if defined(ENABLE_STATISTICS)
-# include "vm/statistics.h"
-#endif
-
-#include "vm/jit/codegen-common.h"
-#include "vm/jit/reg.h"
-#include "vm/jit/replace.h"
-#include "vm/jit/stack.h"
-#include "vm/jit/stacktrace.hpp"
-
-#if defined(ENABLE_INLINING)
-# include "vm/jit/inline/inline.h"
-#endif
-
-#include "vm/jit/ir/bytecode.h"
-#include "vm/jit/ir/instruction.hpp"
-
-#if defined(ENABLE_LOOP)
-# include "vm/jit/loop/loop.h"
-#endif
-#if defined(ENABLE_SSA)
-# include "vm/jit/optimizing/lsra.h"
-#endif
-#if defined(ENABLE_LSRA)
-# include "vm/jit/allocator/lsra.h"
-#endif
-
-#include "vm/jit/verify/typeinfo.h"
-
-
-/* common jit/codegen macros **************************************************/
-
-#if defined(ENABLE_STATISTICS)
-# define COUNT(x) (x)++
-# define COUNT_SPILLS /* use COUNT_(READ|WRITE)_SPILLS instead */
-# define COUNT_READ_SPILLS(var) \
- switch(var->type) { \
- case TYPE_FLT: count_spills_read_flt++; break; \
- case TYPE_DBL: count_spills_read_dbl++; break; \
- default: count_spills_read_ila++; break; \
- }
-
-# define COUNT_WRITE_SPILLS(var) \
- switch(var->type) { \
- case TYPE_FLT: count_spills_write_flt++; break; \
- case TYPE_DBL: count_spills_write_dbl++; break; \
- default: count_spills_write_ila++; break; \
- }
-
-#else
-# define COUNT(x) /* nothing */
-# define COUNT_SPILLS /* nothing */
-# define COUNT_READ_SPILLS(x) /* nothing */
-# define COUNT_WRITE_SPILLS(x) /* nothing */
-#endif
-
-typedef struct interface_info interface_info;
-
-struct interface_info {
- s4 flags;
- s4 regoff;
-};
-
-
-/* jitdata ********************************************************************/
-
-struct jitdata {
- methodinfo *m; /* methodinfo of the method compiled */
- codeinfo *code;
- codegendata *cd;
- registerdata *rd;
-#if defined(ENABLE_LOOP)
- loopdata *ld;
-#endif
-#if defined(ENABLE_SSA) || defined(ENABLE_LSRA)
- lsradata *ls;
-#endif
-
- u4 flags; /* contains JIT compiler flags */
-
- instruction *instructions; /* ICMDs, valid between parse and stack */
- basicblock *basicblocks; /* start of basic block list */
- stackelement_t *stack; /* XXX should become stack.c internal */
- s4 instructioncount;/* XXX remove this? */
- s4 basicblockcount; /* number of basic blocks */
- s4 stackcount; /* number of stackelements to allocate */
- /* (passed from parse to stack) */
-
- varinfo *var; /* array of variables */
- s4 vartop; /* next free index in var array */
-
- s4 varcount; /* number of variables in var array */
- s4 localcount; /* number of locals at start of var ar. */
- s4 *local_map; /* map for renaming (de-coallescing) */
- /* locals and keeping the coalescing info for simplereg. */
- /* local_map[javaindex * 5 + type] = */
- /* >= 0......index into jd->var, or */
- /* UNUSED....this (javaindex,type) pair is not used */
-
- s4 *reverselocalmap; /* map from CACAO varindex to javaindex */
- /* (varindex must be < localcount) */
-
- s4 maxlocals; /* max. number of javalocals */
-
- interface_info *interface_map; /* interface variables (for simplereg) */
- s4 maxinterfaces; /* max. number of interface variables */
-
- s4 exceptiontablelength; /* exceptiontable length */
- exception_entry *exceptiontable; /* the exceptiontable */
-
- basicblock *returnblock; /* block containing the *RETURN */
- /* (only use if returncount==1) */
- s4 returncount; /* number of return instructions */
- bool branchtoentry; /* true if first block is a target */
- bool branchtoend; /* true if end dummy is a target */
-};
-
-#define FOR_EACH_BASICBLOCK(jd, it) \
- for ((it) = (jd)->basicblocks; (it) != NULL; (it) = (it)->next)
-
-#define UNUSED -1
-
-#define JITDATA_FLAG_PARSE 0x00000001
-#define JITDATA_FLAG_VERIFY 0x00000002
-
-#define JITDATA_FLAG_INSTRUMENT 0x00000004
-
-#define JITDATA_FLAG_IFCONV 0x00000008
-#define JITDATA_FLAG_REORDER 0x00000010
-#define JITDATA_FLAG_INLINE 0x00000020
-
-#define JITDATA_FLAG_COUNTDOWN 0x00000100
-
-#define JITDATA_FLAG_SHOWINTERMEDIATE 0x20000000
-#define JITDATA_FLAG_SHOWDISASSEMBLE 0x40000000
-#define JITDATA_FLAG_VERBOSECALL 0x80000000
-
-
-#define JITDATA_HAS_FLAG_PARSE(jd) \
- ((jd)->flags & JITDATA_FLAG_PARSE)
-
-#define JITDATA_HAS_FLAG_VERIFY(jd) \
- ((jd)->flags & JITDATA_FLAG_VERIFY)
-
-#define JITDATA_HAS_FLAG_INSTRUMENT(jd) \
- ((jd)->flags & JITDATA_FLAG_INSTRUMENT)
-
-#define JITDATA_HAS_FLAG_IFCONV(jd) \
- ((jd)->flags & JITDATA_FLAG_IFCONV)
-
-#define JITDATA_HAS_FLAG_REORDER(jd) \
- ((jd)->flags & JITDATA_FLAG_REORDER)
-
-#define JITDATA_HAS_FLAG_INLINE(jd) \
- ((jd)->flags & JITDATA_FLAG_INLINE)
-
-#define JITDATA_HAS_FLAG_COUNTDOWN(jd) \
- ((jd)->flags & JITDATA_FLAG_COUNTDOWN)
-
-#define JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd) \
- ((jd)->flags & JITDATA_FLAG_SHOWINTERMEDIATE)
-
-#define JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd) \
- ((jd)->flags & JITDATA_FLAG_SHOWDISASSEMBLE)
-
-#define JITDATA_HAS_FLAG_VERBOSECALL(jd) \
- ((jd)->flags & JITDATA_FLAG_VERBOSECALL)
-
-
-/* exception_entry ************************************************************/
-
-struct exception_entry {
- basicblock *start;
- basicblock *end;
- basicblock *handler;
- classref_or_classinfo catchtype; /* catchtype of exc. (NULL == catchall) */
- exception_entry *next; /* next in list of exceptions when */
- /* loops are copied */
- exception_entry *down; /* next exception_entry */
-};
-
-
-/* macros for accessing variables *********************************************
-
- Use VAROP for s1, s2, s3 and dst operands (eg. VAROP(iptr->s1)),
- use VAR if you have the variable index (eg. VAR(iptr->sx.s23.s2.args[0])).
-
-******************************************************************************/
-
-#define VAROP(v) (jd->var + (v).varindex)
-#define VAR(i) (jd->var + (i))
-
-static inline bool var_is_local(const jitdata *jd, s4 i) {
- return (i < jd->localcount);
-}
-
-static inline bool var_is_prealloc(const jitdata *jd, s4 i) {
- return ((i >= jd->localcount) && (jd->var[i].flags & PREALLOC));
-}
-
-static inline bool var_is_inout(const jitdata *jd, s4 i) {
- const varinfo *v = jd->var + i;
- return (
- (i >= jd->localcount) && (
- (!(v->flags & PREALLOC) && (v->flags & INOUT)) ||
- /* special case of TYPE_RET, used with JSR */
- ((v->flags & PREALLOC) && (v->flags & INOUT) && (v->type == TYPE_RET))
- )
- );
-}
-
-static inline bool var_is_temp(const jitdata *jd, s4 i) {
- const varinfo *v = jd->var + i;
- return ((i >= jd->localcount) && !(v->flags & PREALLOC) && !(v->flags & INOUT));
-}
-
-static inline bool var_is_saved(const jitdata *jd, s4 i) {
- return (jd->var[i].flags & SAVEDVAR);
-}
-
-
-/* basicblock *****************************************************************/
-
-/* flags */
-
-#define BBDELETED -2
-#define BBUNDEF -1
-#define BBREACHED 0
-#define BBFINISHED 1
-
-#define BBTYPECHECK_UNDEF 2
-#define BBTYPECHECK_REACHED 3
-
-#define BBTYPE_STD 0 /* standard basic block type */
-#define BBTYPE_EXH 1 /* exception handler basic block type */
-#define BBTYPE_SBR 2 /* subroutine basic block type */
-
-#define BBFLAG_REPLACEMENT 0x01 /* put a replacement point at the start */
-
-/* XXX basicblock wastes quite a lot of memory by having four flag fields */
-/* (flags, bitflags, type and lflags). Probably the last three could be */
-/* combined without loss of efficiency. The first one could be combined with */
-/* the others by using bitfields. */
-
-/* XXX "flags" should probably be called "state", as it is an integer state */
-
-struct basicblock {
- s4 nr; /* basic block number */
- s4 flags; /* used during stack analysis, init with -1 */
- s4 bitflags; /* OR of BBFLAG_... constants, init with 0 */
- s4 type; /* basic block type (std, xhandler, subroutine*/
- s4 lflags; /* used during loop copying, init with 0 */
-
- s4 icount; /* number of intermediate code instructions */
- instruction *iinstr; /* pointer to intermediate code instructions */
-
- varinfo *inlocals; /* copy of locals on block entry */
- s4 *javalocals; /* map from java locals to cacao variables[+] */
- s4 *invars; /* array of in-variables at begin of block */
- s4 *outvars; /* array of out-variables at end of block */
- s4 indepth; /* stack depth at begin of basic block */
- s4 outdepth; /* stack depth end of basic block */
- s4 varstart; /* index of first non-invar block variable */
- s4 varcount; /* number of non-invar block variables */
-
- s4 predecessorcount;
- s4 successorcount;
- basicblock **predecessors; /* array of predecessor basic blocks */
- basicblock **successors; /* array of successor basic blocks */
-
- branchref *branchrefs; /* list of branches to be patched */
-
- basicblock *next; /* used to build a BB list (instead of array) */
- basicblock *copied_to; /* points to the copy of this basic block */
- /* when loop nodes are copied */
- basicblock *original; /* block of which this block is a clone */
- /* NULL for the original block itself */
- methodinfo *method; /* method this block belongs to */
- insinfo_inline *inlineinfo; /* inlineinfo for the start of this block */
-
- s4 mpc; /* machine code pc at start of block */
-
- /* TODO: those fields are probably usefull for other passes as well. */
-
-#if defined(ENABLE_SSA)
- basicblock *idom; /* Immediate dominator, parent in dominator tree */
- basicblock **domsuccessors;/* Children in dominator tree */
- s4 domsuccessorcount;
-
- basicblock **domfrontier; /* Dominance frontier */
- s4 domfrontiercount;
-
- basicblock **exhandlers; /* Exception handlers for this block */
- s4 exhandlercount;
- basicblock **expredecessors; /* Blocks this block is exception handler for */
- s4 expredecessorcount;
- s4 exouts; /* Number of exceptional exits */
-
- instruction *phis; /* Phi functions */
- s4 phicount; /* Number of phi functions */
-
- void *vp; /* Freely used by different passes */
-#endif
-};
-
-#define FOR_EACH_SUCCESSOR(bptr, it) \
- for ((it) = (bptr)->successors; (it) != (bptr)->successors + (bptr)->successorcount; ++(it))
-
-#define FOR_EACH_PREDECESSOR(bptr, it) \
- for ( \
- (it) = (bptr)->predecessors; \
- (it) != (bptr)->predecessors + ((bptr)->predecessorcount < 0 ? 0 : (bptr)->predecessorcount); \
- ++(it) \
- )
-
-#define FOR_EACH_INSTRUCTION(bptr, it) \
- for ((it) = (bptr)->iinstr; (it) != (bptr)->iinstr + (bptr)->icount; ++(it))
-
-#define FOR_EACH_INSTRUCTION_REV(bptr, it) \
- for ((it) = (bptr)->iinstr + (bptr)->icount - 1; (it) != (bptr)->iinstr - 1; --(it))
-
-#if defined(ENABLE_SSA)
-
-#define FOR_EACH_EXHANDLER(bptr, it) \
- for ((it) = (bptr)->exhandlers; (it) != (bptr)->exhandlers + (bptr)->exhandlercount; ++(it))
-
-#define FOR_EACH_EXPREDECESSOR(bptr, it) \
- for ((it) = (bptr)->expredecessors; (it) != (bptr)->expredecessors + (bptr)->expredecessorcount; ++(it))
-
-#endif
-
-/* [+]...the javalocals array: This array is indexed by the javaindex (the */
-/* local variable index ocurring in the original bytecode). An element */
-/* javalocals[javaindex] encodes where to find the contents of the */
-/* original variable at this point in the program. */
-/* There are three cases for javalocals[javaindex]: */
-/* >= 0.......it's an index into the jd->var array, where the */
-/* CACAO variable corresponding to the original local */
-/* can be found. */
-/* UNUSED.....the original variable is not live at this point */
-/* < UNUSED...the original variable contains a returnAddress at */
-/* this point. The number of the block to return to can */
-/* be calculated using RETADDR_FROM_JAVALOCAL: */
-/* */
-/* javalocals[javaindex] == JAVALOCAL_FROM_RETADDR(nr) */
-/* RETADDR_FROM_JAVALOCAL(javalocals[javaindex]) == nr */
-
-#define JAVALOCAL_FROM_RETADDR(nr) (UNUSED - (1 + (nr)))
-#define RETADDR_FROM_JAVALOCAL(jl) (UNUSED - (1 + (jl)))
-
-
-/* Macro for initializing newly allocated basic block's. It does not
- need to zero fields, as we zero out the whole basic block array. */
-
-#define BASICBLOCK_INIT(bptr,m) \
- do { \
- bptr->mpc = -1; \
- bptr->flags = -1; \
- bptr->type = BBTYPE_STD; \
- bptr->method = (m); \
- } while (0)
-
-static inline bool basicblock_reached(const basicblock *bptr) {
- return (bptr->flags >= BBREACHED);
-}
-
-
-
-/***************************** register types *********************************/
-
-#define REG_RES 0 /* reserved register for OS or code generator */
-#define REG_RET 1 /* return value register */
-#define REG_EXC 2 /* exception value register */
-#define REG_SAV 3 /* (callee) saved register */
-#define REG_TMP 4 /* scratch temporary register (caller saved) */
-#define REG_ARG 5 /* argument register (caller saved) */
-
-#define REG_END -1 /* last entry in tables */
-
-#define PARAMMODE_NUMBERED 0
-#define PARAMMODE_STUFFED 1
-
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* compiler initialisation */
-void jit_init(void);
-
-/* compiler finalisation */
-void jit_close(void);
-
-/* create a new jitdata */
-jitdata *jit_jitdata_new(methodinfo *m);
-
-/* compile a method with jit compiler */
-u1 *jit_compile(methodinfo *m);
-u1 *jit_recompile(methodinfo *m);
-
-void jit_invalidate_code(methodinfo *m);
-codeinfo *jit_get_current_code(methodinfo *m);
-void jit_request_optimization(methodinfo *m);
-
-/* patch the method entrypoint */
-#if !defined(JIT_COMPILER_VIA_SIGNAL)
-u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra);
-#endif
-void *jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr);
-
-s4 jit_complement_condition(s4 opcode);
-
-void jit_renumber_basicblocks(jitdata *jd);
-#if !defined(NDEBUG)
-void jit_check_basicblock_numbers(jitdata *jd);
-#endif
-
-
-/* machine dependent functions ************************************************/
-
-#if defined(ENABLE_JIT)
-void md_init(void);
-#endif
-
-#if defined(ENABLE_INTRP)
-void intrp_md_init(void);
-#endif
-
-void *md_jit_method_patch_address(void *pv, void *ra, void *mptr);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _JIT_H */
-
-
-/*
- * These are local overrides for various environment variables in Emacs.
- * Please do not remove this and leave it at the end of the file, where
- * Emacs will automagically detect them.
- * ---------------------------------------------------------------------
- * Local variables:
- * mode: c
- * indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
- * End:
- * vim:noexpandtab:sw=4:ts=4:
- */
--- /dev/null
+/* src/vm/jit/jit.hpp - Just-In-Time compiler
+
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+
+*/
+
+
+#ifndef _JIT_HPP
+#define _JIT_HPP
+
+/* forward typedefs ***********************************************************/
+
+typedef struct jitdata jitdata;
+typedef struct basicblock basicblock;
+typedef struct exception_entry exception_entry;
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "vm/global.h"
+#include "vm/method.h"
+#include "vm/references.h"
+#include "vm/resolve.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
+#include "vm/jit/codegen-common.h"
+#include "vm/jit/reg.h"
+#include "vm/jit/replace.h"
+#include "vm/jit/stack.h"
+#include "vm/jit/stacktrace.hpp"
+
+#if defined(ENABLE_INLINING)
+# include "vm/jit/inline/inline.h"
+#endif
+
+#include "vm/jit/ir/bytecode.h"
+#include "vm/jit/ir/instruction.hpp"
+
+#if defined(ENABLE_LOOP)
+# include "vm/jit/loop/loop.h"
+#endif
+#if defined(ENABLE_SSA)
+# include "vm/jit/optimizing/lsra.h"
+#endif
+#if defined(ENABLE_LSRA)
+# include "vm/jit/allocator/lsra.h"
+#endif
+
+#include "vm/jit/verify/typeinfo.h"
+
+
+/* common jit/codegen macros **************************************************/
+
+#if defined(ENABLE_STATISTICS)
+# define COUNT(x) (x)++
+# define COUNT_SPILLS /* use COUNT_(READ|WRITE)_SPILLS instead */
+# define COUNT_READ_SPILLS(var) \
+ switch(var->type) { \
+ case TYPE_FLT: count_spills_read_flt++; break; \
+ case TYPE_DBL: count_spills_read_dbl++; break; \
+ default: count_spills_read_ila++; break; \
+ }
+
+# define COUNT_WRITE_SPILLS(var) \
+ switch(var->type) { \
+ case TYPE_FLT: count_spills_write_flt++; break; \
+ case TYPE_DBL: count_spills_write_dbl++; break; \
+ default: count_spills_write_ila++; break; \
+ }
+
+#else
+# define COUNT(x) /* nothing */
+# define COUNT_SPILLS /* nothing */
+# define COUNT_READ_SPILLS(x) /* nothing */
+# define COUNT_WRITE_SPILLS(x) /* nothing */
+#endif
+
+typedef struct interface_info interface_info;
+
+struct interface_info {
+ s4 flags;
+ s4 regoff;
+};
+
+
+/* jitdata ********************************************************************/
+
+struct jitdata {
+ methodinfo *m; /* methodinfo of the method compiled */
+ codeinfo *code;
+ codegendata *cd;
+ registerdata *rd;
+#if defined(ENABLE_LOOP)
+ loopdata *ld;
+#endif
+#if defined(ENABLE_SSA) || defined(ENABLE_LSRA)
+ lsradata *ls;
+#endif
+
+ u4 flags; /* contains JIT compiler flags */
+
+ instruction *instructions; /* ICMDs, valid between parse and stack */
+ basicblock *basicblocks; /* start of basic block list */
+ stackelement_t *stack; /* XXX should become stack.c internal */
+ s4 instructioncount;/* XXX remove this? */
+ s4 basicblockcount; /* number of basic blocks */
+ s4 stackcount; /* number of stackelements to allocate */
+ /* (passed from parse to stack) */
+
+ varinfo *var; /* array of variables */
+ s4 vartop; /* next free index in var array */
+
+ s4 varcount; /* number of variables in var array */
+ s4 localcount; /* number of locals at start of var ar. */
+ s4 *local_map; /* map for renaming (de-coallescing) */
+ /* locals and keeping the coalescing info for simplereg. */
+ /* local_map[javaindex * 5 + type] = */
+ /* >= 0......index into jd->var, or */
+ /* UNUSED....this (javaindex,type) pair is not used */
+
+ s4 *reverselocalmap; /* map from CACAO varindex to javaindex */
+ /* (varindex must be < localcount) */
+
+ s4 maxlocals; /* max. number of javalocals */
+
+ interface_info *interface_map; /* interface variables (for simplereg) */
+ s4 maxinterfaces; /* max. number of interface variables */
+
+ s4 exceptiontablelength; /* exceptiontable length */
+ exception_entry *exceptiontable; /* the exceptiontable */
+
+ basicblock *returnblock; /* block containing the *RETURN */
+ /* (only use if returncount==1) */
+ s4 returncount; /* number of return instructions */
+ bool branchtoentry; /* true if first block is a target */
+ bool branchtoend; /* true if end dummy is a target */
+};
+
+#define FOR_EACH_BASICBLOCK(jd, it) \
+ for ((it) = (jd)->basicblocks; (it) != NULL; (it) = (it)->next)
+
+#define UNUSED -1
+
+#define JITDATA_FLAG_PARSE 0x00000001
+#define JITDATA_FLAG_VERIFY 0x00000002
+
+#define JITDATA_FLAG_INSTRUMENT 0x00000004
+
+#define JITDATA_FLAG_IFCONV 0x00000008
+#define JITDATA_FLAG_REORDER 0x00000010
+#define JITDATA_FLAG_INLINE 0x00000020
+
+#define JITDATA_FLAG_COUNTDOWN 0x00000100
+
+#define JITDATA_FLAG_SHOWINTERMEDIATE 0x20000000
+#define JITDATA_FLAG_SHOWDISASSEMBLE 0x40000000
+#define JITDATA_FLAG_VERBOSECALL 0x80000000
+
+
+#define JITDATA_HAS_FLAG_PARSE(jd) \
+ ((jd)->flags & JITDATA_FLAG_PARSE)
+
+#define JITDATA_HAS_FLAG_VERIFY(jd) \
+ ((jd)->flags & JITDATA_FLAG_VERIFY)
+
+#define JITDATA_HAS_FLAG_INSTRUMENT(jd) \
+ ((jd)->flags & JITDATA_FLAG_INSTRUMENT)
+
+#define JITDATA_HAS_FLAG_IFCONV(jd) \
+ ((jd)->flags & JITDATA_FLAG_IFCONV)
+
+#define JITDATA_HAS_FLAG_REORDER(jd) \
+ ((jd)->flags & JITDATA_FLAG_REORDER)
+
+#define JITDATA_HAS_FLAG_INLINE(jd) \
+ ((jd)->flags & JITDATA_FLAG_INLINE)
+
+#define JITDATA_HAS_FLAG_COUNTDOWN(jd) \
+ ((jd)->flags & JITDATA_FLAG_COUNTDOWN)
+
+#define JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd) \
+ ((jd)->flags & JITDATA_FLAG_SHOWINTERMEDIATE)
+
+#define JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd) \
+ ((jd)->flags & JITDATA_FLAG_SHOWDISASSEMBLE)
+
+#define JITDATA_HAS_FLAG_VERBOSECALL(jd) \
+ ((jd)->flags & JITDATA_FLAG_VERBOSECALL)
+
+
+/* exception_entry ************************************************************/
+
+struct exception_entry {
+ basicblock *start;
+ basicblock *end;
+ basicblock *handler;
+ classref_or_classinfo catchtype; /* catchtype of exc. (NULL == catchall) */
+ exception_entry *next; /* next in list of exceptions when */
+ /* loops are copied */
+ exception_entry *down; /* next exception_entry */
+};
+
+
+/* macros for accessing variables *********************************************
+
+ Use VAROP for s1, s2, s3 and dst operands (eg. VAROP(iptr->s1)),
+ use VAR if you have the variable index (eg. VAR(iptr->sx.s23.s2.args[0])).
+
+******************************************************************************/
+
+#define VAROP(v) (jd->var + (v).varindex)
+#define VAR(i) (jd->var + (i))
+
+static inline bool var_is_local(const jitdata *jd, s4 i) {
+ return (i < jd->localcount);
+}
+
+static inline bool var_is_prealloc(const jitdata *jd, s4 i) {
+ return ((i >= jd->localcount) && (jd->var[i].flags & PREALLOC));
+}
+
+static inline bool var_is_inout(const jitdata *jd, s4 i) {
+ const varinfo *v = jd->var + i;
+ return (
+ (i >= jd->localcount) && (
+ (!(v->flags & PREALLOC) && (v->flags & INOUT)) ||
+ /* special case of TYPE_RET, used with JSR */
+ ((v->flags & PREALLOC) && (v->flags & INOUT) && (v->type == TYPE_RET))
+ )
+ );
+}
+
+static inline bool var_is_temp(const jitdata *jd, s4 i) {
+ const varinfo *v = jd->var + i;
+ return ((i >= jd->localcount) && !(v->flags & PREALLOC) && !(v->flags & INOUT));
+}
+
+static inline bool var_is_saved(const jitdata *jd, s4 i) {
+ return (jd->var[i].flags & SAVEDVAR);
+}
+
+
+/* basicblock *****************************************************************/
+
+/* flags */
+
+#define BBDELETED -2
+#define BBUNDEF -1
+#define BBREACHED 0
+#define BBFINISHED 1
+
+#define BBTYPECHECK_UNDEF 2
+#define BBTYPECHECK_REACHED 3
+
+#define BBTYPE_STD 0 /* standard basic block type */
+#define BBTYPE_EXH 1 /* exception handler basic block type */
+#define BBTYPE_SBR 2 /* subroutine basic block type */
+
+#define BBFLAG_REPLACEMENT 0x01 /* put a replacement point at the start */
+
+/* XXX basicblock wastes quite a lot of memory by having four flag fields */
+/* (flags, bitflags, type and lflags). Probably the last three could be */
+/* combined without loss of efficiency. The first one could be combined with */
+/* the others by using bitfields. */
+
+/* XXX "flags" should probably be called "state", as it is an integer state */
+
+struct basicblock {
+ s4 nr; /* basic block number */
+ s4 flags; /* used during stack analysis, init with -1 */
+ s4 bitflags; /* OR of BBFLAG_... constants, init with 0 */
+ s4 type; /* basic block type (std, xhandler, subroutine*/
+ s4 lflags; /* used during loop copying, init with 0 */
+
+ s4 icount; /* number of intermediate code instructions */
+ instruction *iinstr; /* pointer to intermediate code instructions */
+
+ varinfo *inlocals; /* copy of locals on block entry */
+ s4 *javalocals; /* map from java locals to cacao variables[+] */
+ s4 *invars; /* array of in-variables at begin of block */
+ s4 *outvars; /* array of out-variables at end of block */
+ s4 indepth; /* stack depth at begin of basic block */
+ s4 outdepth; /* stack depth end of basic block */
+ s4 varstart; /* index of first non-invar block variable */
+ s4 varcount; /* number of non-invar block variables */
+
+ s4 predecessorcount;
+ s4 successorcount;
+ basicblock **predecessors; /* array of predecessor basic blocks */
+ basicblock **successors; /* array of successor basic blocks */
+
+ branchref *branchrefs; /* list of branches to be patched */
+
+ basicblock *next; /* used to build a BB list (instead of array) */
+ basicblock *copied_to; /* points to the copy of this basic block */
+ /* when loop nodes are copied */
+ basicblock *original; /* block of which this block is a clone */
+ /* NULL for the original block itself */
+ methodinfo *method; /* method this block belongs to */
+ insinfo_inline *inlineinfo; /* inlineinfo for the start of this block */
+
+ s4 mpc; /* machine code pc at start of block */
+
+ /* TODO: those fields are probably usefull for other passes as well. */
+
+#if defined(ENABLE_SSA)
+ basicblock *idom; /* Immediate dominator, parent in dominator tree */
+ basicblock **domsuccessors;/* Children in dominator tree */
+ s4 domsuccessorcount;
+
+ basicblock **domfrontier; /* Dominance frontier */
+ s4 domfrontiercount;
+
+ basicblock **exhandlers; /* Exception handlers for this block */
+ s4 exhandlercount;
+ basicblock **expredecessors; /* Blocks this block is exception handler for */
+ s4 expredecessorcount;
+ s4 exouts; /* Number of exceptional exits */
+
+ instruction *phis; /* Phi functions */
+ s4 phicount; /* Number of phi functions */
+
+ void *vp; /* Freely used by different passes */
+#endif
+};
+
+#define FOR_EACH_SUCCESSOR(bptr, it) \
+ for ((it) = (bptr)->successors; (it) != (bptr)->successors + (bptr)->successorcount; ++(it))
+
+#define FOR_EACH_PREDECESSOR(bptr, it) \
+ for ( \
+ (it) = (bptr)->predecessors; \
+ (it) != (bptr)->predecessors + ((bptr)->predecessorcount < 0 ? 0 : (bptr)->predecessorcount); \
+ ++(it) \
+ )
+
+#define FOR_EACH_INSTRUCTION(bptr, it) \
+ for ((it) = (bptr)->iinstr; (it) != (bptr)->iinstr + (bptr)->icount; ++(it))
+
+#define FOR_EACH_INSTRUCTION_REV(bptr, it) \
+ for ((it) = (bptr)->iinstr + (bptr)->icount - 1; (it) != (bptr)->iinstr - 1; --(it))
+
+#if defined(ENABLE_SSA)
+
+#define FOR_EACH_EXHANDLER(bptr, it) \
+ for ((it) = (bptr)->exhandlers; (it) != (bptr)->exhandlers + (bptr)->exhandlercount; ++(it))
+
+#define FOR_EACH_EXPREDECESSOR(bptr, it) \
+ for ((it) = (bptr)->expredecessors; (it) != (bptr)->expredecessors + (bptr)->expredecessorcount; ++(it))
+
+#endif
+
+/* [+]...the javalocals array: This array is indexed by the javaindex (the */
+/* local variable index ocurring in the original bytecode). An element */
+/* javalocals[javaindex] encodes where to find the contents of the */
+/* original variable at this point in the program. */
+/* There are three cases for javalocals[javaindex]: */
+/* >= 0.......it's an index into the jd->var array, where the */
+/* CACAO variable corresponding to the original local */
+/* can be found. */
+/* UNUSED.....the original variable is not live at this point */
+/* < UNUSED...the original variable contains a returnAddress at */
+/* this point. The number of the block to return to can */
+/* be calculated using RETADDR_FROM_JAVALOCAL: */
+/* */
+/* javalocals[javaindex] == JAVALOCAL_FROM_RETADDR(nr) */
+/* RETADDR_FROM_JAVALOCAL(javalocals[javaindex]) == nr */
+
+#define JAVALOCAL_FROM_RETADDR(nr) (UNUSED - (1 + (nr)))
+#define RETADDR_FROM_JAVALOCAL(jl) (UNUSED - (1 + (jl)))
+
+
+/* Macro for initializing newly allocated basic block's. It does not
+ need to zero fields, as we zero out the whole basic block array. */
+
+#define BASICBLOCK_INIT(bptr,m) \
+ do { \
+ bptr->mpc = -1; \
+ bptr->flags = -1; \
+ bptr->type = BBTYPE_STD; \
+ bptr->method = (m); \
+ } while (0)
+
+static inline bool basicblock_reached(const basicblock *bptr) {
+ return (bptr->flags >= BBREACHED);
+}
+
+
+
+/***************************** register types *********************************/
+
+#define REG_RES 0 /* reserved register for OS or code generator */
+#define REG_RET 1 /* return value register */
+#define REG_EXC 2 /* exception value register */
+#define REG_SAV 3 /* (callee) saved register */
+#define REG_TMP 4 /* scratch temporary register (caller saved) */
+#define REG_ARG 5 /* argument register (caller saved) */
+
+#define REG_END -1 /* last entry in tables */
+
+#define PARAMMODE_NUMBERED 0
+#define PARAMMODE_STUFFED 1
+
+
+/* function prototypes ********************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* compiler initialisation */
+void jit_init(void);
+
+/* compiler finalisation */
+void jit_close(void);
+
+/* create a new jitdata */
+jitdata *jit_jitdata_new(methodinfo *m);
+
+/* compile a method with jit compiler */
+u1 *jit_compile(methodinfo *m);
+u1 *jit_recompile(methodinfo *m);
+
+void jit_invalidate_code(methodinfo *m);
+codeinfo *jit_get_current_code(methodinfo *m);
+void jit_request_optimization(methodinfo *m);
+
+/* patch the method entrypoint */
+#if !defined(JIT_COMPILER_VIA_SIGNAL)
+u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra);
+#endif
+void *jit_compile_handle(methodinfo *m, void *pv, void *ra, void *mptr);
+
+s4 jit_complement_condition(s4 opcode);
+
+void jit_renumber_basicblocks(jitdata *jd);
+#if !defined(NDEBUG)
+void jit_check_basicblock_numbers(jitdata *jd);
+#endif
+
+
+/* machine dependent functions ************************************************/
+
+#if defined(ENABLE_JIT)
+void md_init(void);
+#endif
+
+#if defined(ENABLE_INTRP)
+void intrp_md_init(void);
+#endif
+
+void *md_jit_method_patch_address(void *pv, void *ra, void *mptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _JIT_HPP
+
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c++
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */
#include "vm/method.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/code.h"
#include "vm/jit/codegen-common.h"
#include "mm/memory.h"
#include "toolbox/logging.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/stack.h"
#include "vm/jit/loop/analyze.h"
#include "config.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* function prototypes ********************************************************/
#include "mm/memory.h"
#include "toolbox/logging.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/loop/graph.h"
#include "vm/jit/loop/loop.h"
#include "mm/memory.h"
#include "toolbox/logging.h"
#include "vm/global.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/loop/loop.h"
#include "vm/jit/loop/graph.h"
#include "vm/jit/loop/tracing.h"
#include "vm/global.h"
#include "vm/method.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* Different types for struct Trace */
#ifndef _TRACING_H
#define _TRACING_H
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
typedef struct Trace Trace;
#include "vm/jit/dseg.h"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/abi.h"
#include "vm/jit/parse.h"
#include "vm/jit/reg.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/patcher-common.h"
#include "vm/jit/reg.h"
#include "config.h"
#include "vm/types.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* additional functions and macros to generate code ***************************/
#include "vm/jit/asmpart.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/patcher-common.h"
#include "vm/jit/replace.h"
#include "vm/jit/trap.h"
#include "vm/global.h"
#include "vm/vm.hpp"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* md_jit_method_patch_address *************************************************
#include "toolbox/bitvector.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/optimizing/graph.h"
#include "vm/jit/optimizing/dominators.h"
#include "vm/class.h"
#include "vm/classcache.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/optimizing/escape.h"
#include <stdarg.h>
#ifndef _VM_JIT_OPTIMIZING_ESCAPE_H
#define _VM_JIT_OPTIMIZING_ESCAPE_H
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/method.h"
typedef enum {
#include "toolbox/bitvector.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/optimizing/lsra.h"
#include "vm/jit/optimizing/ssa.h"
#include "vm/vm.hpp"
#include "vm/jit/codegen-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/reg.h"
#include "vm/jit/show.h"
#define _IFCONV_H
#include "config.h"
-#include "vm/types.h"
-#include "vm/jit/codegen-common.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/reg.h"
+#include <stdbool.h>
+
+#include "vm/jit/jit.hpp"
/* function prototypes ********************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
bool ifconv_static(jitdata *jd);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _IFCONV_H */
#include "vm/exceptions.hpp"
#include "vm/string.hpp"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/optimizing/graph.h"
#include "vm/jit/optimizing/lsra.h"
#include "vm/jit/abi.h"
#include "vm/jit/reg.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/optimizing/graph.h"
#include "vm/jit/optimizing/lifetimes.h"
#include "vm/options.h"
#include "vm/string.hpp"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/methodheader.h"
#include "vm/jit/methodtree.h"
#include "vm/string.hpp"
#include "vm/jit/code.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/optimizing/recompile.h"
#include "vm/types.h"
#include "mm/memory.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* reorder_place_next_unplaced_block *******************************************
-/* src/vm/reorder.h - basic block reordering
+/* src/vm/optimizing/reorder.h - basic block reordering
- Copyright (C) 2006 R. Grafl, A. Krall, C. Kruegel, C. Oates,
- R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
- C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 2006, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Contact: cacao@cacaojvm.org
-
- Authors: Christian Thalinger
-
- Changes:
-
*/
#define _REORDER_H
#include "config.h"
-#include "vm/types.h"
-#include "vm/jit/jit.h"
+#include <stdbool.h>
+
+#include "vm/jit/jit.hpp"
/* function prototypes ********************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
bool reorder(jitdata *jd);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _REORDER_H */
#include "vm/builtin.h"
-#include "vm/jit/jit.h" /* icmd_table */
+#include "vm/jit/jit.hpp" /* icmd_table */
#include "vm/jit/ir/bytecode.h"
#include "toolbox/worklist.h"
#include "vm/global.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#if 1
#define printf(...) do { if (getenv("VERB")) printf(__VA_ARGS__); } while (0)
* Unify access to phi args.
*/
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/global.h"
#include "mm/memory.h"
#include "mm/dumpmemory.h"
#include "vm/builtin.h"
-#include "vm/jit/jit.h" /* icmd_table */
+#include "vm/jit/jit.hpp" /* icmd_table */
#include "vm/jit/optimizing/dominators.h"
#include "vm/jit/optimizing/graph.h"
#include "vm/builtin.h"
-#include "vm/jit/jit.h" /* icmd_table */
+#include "vm/jit/jit.hpp" /* icmd_table */
#include "vm/jit/optimizing/dominators.h"
#include "vm/jit/optimizing/graph.h"
#include "vm/suck.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/parse.h"
#include "vm/jit/loop/loop.h"
/* src/vm/jit/parse.h - parser header
- Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Contact: cacao@cacaojvm.org
-
- Author: Christian Thalinger
- Edwin Steiner
-
*/
/* function prototypes ********************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
bool parse(jitdata *jd);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _PARSE_H */
#include "vm/jit/code.h"
#include "vm/jit/disass.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/patcher-common.h"
#include "vm/global.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* patchref_t ******************************************************************
#include "vm/jit/codegen-common.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/parse.h"
#include "md-abi.h"
#include "vm/global.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/reg.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/replace.h"
#include "vm/jit/trace.hpp"
#include "vm/jit/trap.h"
#include "vm/global.h"
#include "vm/vm.hpp"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* md_init *********************************************************************
#include "vm/jit/codegen-common.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/parse.h"
#include "vm/jit/patcher-common.h"
#include "md-abi.h"
#include "vm/global.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/reg.h"
#include "vm/jit/abi.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/trace.hpp"
#include "vm/jit/trap.h"
#include "vm/global.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/trap.h"
#include "vm/vm.hpp"
#include "vm/jit/asmpart.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* md_stacktrace_get_returnaddress *********************************************
#define _VM_JIT_PYTHON_H
#if defined(ENABLE_PYTHON)
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
void pythonpass_init();
void pythonpass_cleanup();
#include "arch.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/verify/typeinfo.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/disass.h"
#include "vm/jit/executionstate.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/methodheader.h"
#include "vm/jit/replace.h"
#include "vm/jit/show.h"
/*** prototypes ********************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
bool replace_create_replacement_points(jitdata *jd);
void replace_free_replacement_points(codeinfo *code);
#endif /* defined(ENABLE_REPLACEMENT) */
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _REPLACE_H */
#include "vm/jit/codegen-common.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/parse.h"
#include "vm/types.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* MCODECHECK(icnt) */
#include "vm/jit/asmpart.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/patcher-common.h"
#include "vm/jit/replace.h"
#include "vm/jit/trace.hpp"
#include "vm/global.h"
#include "vm/types.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/stack.h"
#include "vm/jit/s390/md-abi.h"
#include "vm/vm.hpp"
#include "vm/jit/abi.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/show.h"
#include "vm/jit/disass.h"
#include "vm/jit/stack.h"
#include "config.h"
#include "vm/types.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* compiler stage defines *****************************************************/
#include "vm/jit/codegen-common.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/parse.h"
#include "vm/jit/patcher.h"
#include "config.h"
#include "vm/types.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "md-abi.h" /* for INT_NATARG_CNT */
#include "vm/jit/asmpart.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/replace.h"
#include "vm/jit/sparc64/solaris/macro_rename.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/codegen-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* assembler function prototypes **********************************************/
# include "vm/jit/disass.h"
#endif
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/stack.h"
#if 0
#include "vm/global.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/reg.h"
/* function prototypes ********************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
bool stack_init(void);
bool stack_analyse(jitdata *jd);
void stack_javalocals_store(instruction *iptr, s4 *javalocals);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _STACK_H */
#include "vm/jit/codegen-common.h"
#include "vm/jit/disass.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/show.h"
#include "vm/jit/stubs.hpp"
#include "vm/jit/code.h"
#include "vm/jit/disass.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/methodtree.h"
#include "vm/jit/patcher-common.h"
#include "vm/jit/replace.h"
#include <assert.h>
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/****************************************************************************/
#include "vm/resolve.h"
#include "vm/vm.hpp"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/show.h"
#include "vm/jit/parse.h"
#include "config.h"
#include "vm/global.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* function prototypes ********************************************************/
#include "vm/primitive.hpp"
#include "vm/resolve.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/parse.h"
#include "vm/jit/show.h"
/* src/vm/jit/verify/typecheck.h - type checking header
- Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Contact: cacao@cacaojvm.org
-
- Authors: Christian Thalinger
-
-
*/
#include "config.h"
#include "vm/global.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* function prototypes ********************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#if defined(ENABLE_VERIFIER)
bool typecheck(jitdata *jd);
bool typecheck_stackbased(jitdata *jd);
#endif
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _TYPECHECK_H */
#include "vm/primitive.hpp"
#include "vm/resolve.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/verify/typeinfo.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/parse.h"
#include "vm/jit/x86_64/emit.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* additional functions and macros to generate code ***************************/
#include "vm/jit/asmpart.h"
#include "vm/jit/codegen-common.h"
#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/patcher-common.h"
#include "vm/jit/replace.h"
#include "vm/jit/trace.hpp"
#include "vm/types.h"
#include "vm/jit/codegen-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* macros to create code ******************************************************/
#include "vm/global.h"
#include "vm/jit/abi.h"
-#include "vm/jit/jit.h" /* for REG_* (maybe can be removed) */
+#include "vm/jit/jit.hpp" /* for REG_* (maybe can be removed) */
#include "vm/jit/stack.h"
#include "vm/vm.hpp"
#include "vm/jit/codegen-common.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
/* md_init *********************************************************************
# include "vm/zip.h"
#endif
+#include "vm/jit/stubs.hpp"
+
#if defined(ENABLE_JVMTI)
# include "native/jvmti/cacaodbg.h"
#endif
#include "vm/primitive.hpp"
#include "vm/resolve.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/verify/typeinfo.h"
#include "vm/method.h"
#include "vm/references.h"
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/reg.h"
#include "vm/jit/ir/instruction.hpp"
/* function prototypes ********************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
s8 getcputime(void);
void loadingtime_start(void);
void jnicallXmethodnvokation(void);
void jniinvokation(void);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _STATISTICS_H */
# include "vm/jit/disass.h"
#endif
-#include "vm/jit/jit.h"
+#include "vm/jit/jit.hpp"
#include "vm/jit/methodtree.h"
#if defined(ENABLE_PROFILING)