* src/vm/jit/patcher-common.h: Likewise.
* src/vm/jit/patcher-common.cpp: New file.
* src/vm/jit/patcher-common.hpp: Likewise.
* src/vm/exceptions.cpp,
src/vm/jit/Makefile.am,
src/vm/jit/alpha/codegen.c,
src/vm/jit/alpha/emit.c,
src/vm/jit/alpha/patcher.c,
src/vm/jit/arm/codegen.c,
src/vm/jit/arm/emit.c,
src/vm/jit/arm/linux/md-os.c,
src/vm/jit/arm/patcher.c,
src/vm/jit/code.cpp,
src/vm/jit/codegen-common.cpp,
src/vm/jit/disass.h,
src/vm/jit/emit-common.cpp,
src/vm/jit/i386/codegen.c,
src/vm/jit/i386/emit.c,
src/vm/jit/i386/patcher.c,
src/vm/jit/m68k/codegen.c,
src/vm/jit/m68k/patcher.c,
src/vm/jit/mips/codegen.c,
src/vm/jit/mips/emit.c,
src/vm/jit/mips/patcher.c,
src/vm/jit/powerpc/codegen.c,
src/vm/jit/powerpc/patcher.c,
src/vm/jit/powerpc64/codegen.c,
src/vm/jit/powerpc64/patcher.c,
src/vm/jit/s390/codegen.c,
src/vm/jit/s390/emit.c,
src/vm/jit/s390/patcher.c,
src/vm/jit/trap.c,
src/vm/jit/x86_64/codegen.c,
src/vm/jit/x86_64/emit.c,
src/vm/jit/x86_64/patcher.c: Related changes.
--HG--
rename : src/vm/jit/patcher-common.c => src/vm/jit/patcher-common.cpp
rename : src/vm/jit/patcher-common.h => src/vm/jit/patcher-common.hpp
#include "vm/jit/asmpart.h"
#include "vm/jit/jit.hpp"
#include "vm/jit/methodheader.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/show.h"
#include "vm/jit/stacktrace.hpp"
#include "vm/jit/trace.hpp"
methodtree.h \
parse.c \
parse.h \
- patcher-common.c \
- patcher-common.h \
+ patcher-common.cpp \
+ patcher-common.hpp \
$(RECOMPILE_SOURCES) \
$(REG_SOURCES) \
$(REPLACE_SOURCES) \
#include "vm/jit/jit.hpp"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/parse.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/reg.h"
#include "vm/jit/replace.hpp"
#include "vm/jit/stacktrace.hpp"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.hpp"
#include "vm/jit/jit.hpp"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/replace.hpp"
#include "vm/jit/trace.hpp"
#include "vm/jit/trap.h"
#include "vm/resolve.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/methodheader.h"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/parse.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/reg.h"
#if defined(ENABLE_LSRA)
#include "vm/jit/asmpart.h"
#include "vm/jit/emit-common.hpp"
#include "vm/jit/jit.hpp"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/replace.hpp"
#include "vm/jit/trace.hpp"
#include "vm/jit/trap.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/executionstate.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/trap.h"
#include "vm/resolve.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#define gen_resolveload(inst,offset) \
#include "vm/jit/code.hpp"
#include "vm/jit/codegen-common.hpp"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/methodtree.h"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/methodtree.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/replace.hpp"
#if defined(ENABLE_SSA)
# include "vm/jit/optimizing/lsra.h"
#ifndef _DISASS_H
#define _DISASS_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
#include "config.h"
#if defined(WITH_BINUTILS_DISASSEMBLER)
/* function prototypes *******************************************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#if defined(ENABLE_JIT)
void disassemble(u1 *start, u1 *end);
#endif
#include "vm/jit/emit-common.hpp"
#include "vm/jit/jit.hpp"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
/* emit_load_s1 ****************************************************************
#include "vm/jit/jit.hpp"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/parse.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/reg.h"
#include "vm/jit/replace.hpp"
#include "vm/jit/stacktrace.hpp"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.hpp"
#include "vm/jit/jit.hpp"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/replace.hpp"
#include "vm/jit/trace.hpp"
#include "vm/jit/trap.h"
#include "vm/references.h"
#include "vm/resolve.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#define PATCH_BACK_ORIGINAL_MCODE \
#include "vm/jit/asmpart.h"
#include "vm/jit/codegen-common.hpp"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/dseg.h"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/emit-common.hpp"
#include "vm/resolve.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "codegen.h"
#include "vm/jit/emit-common.hpp"
#include "vm/jit/jit.hpp"
#include "vm/jit/linenumbertable.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/reg.h"
#include "vm/jit/replace.hpp"
#include "vm/jit/trap.h"
#include "vm/jit/dseg.h"
#include "vm/jit/emit-common.hpp"
#include "vm/jit/jit.hpp"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/replace.hpp"
#include "vm/jit/trap.h"
#include "vm/resolve.h"
#include "vm/jit/asmpart.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
/* patcher_patch_code **********************************************************
+++ /dev/null
-/* src/vm/jit/patcher-common.c - architecture independent code patching stuff
-
- Copyright (C) 2007, 2008
- CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
- Copyright (C) 2008 Theobroma Systems Ltd.
-
- 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 "codegen.h" /* for PATCHER_NOPS */
-#include "md.h"
-
-#include "mm/memory.h"
-
-#include "native/native.h"
-
-#include "toolbox/list.h"
-#include "toolbox/logging.h" /* XXX remove me! */
-
-#include "vm/exceptions.hpp"
-#include "vm/initialize.h"
-#include "vm/options.h"
-#include "vm/resolve.h"
-#include "vm/vm.hpp" /* for vm_abort */
-
-#include "vm/jit/code.hpp"
-#include "vm/jit/disass.h"
-#include "vm/jit/jit.hpp"
-#include "vm/jit/patcher-common.h"
-
-
-/* patcher_function_list *******************************************************
-
- This is a list which maps patcher function pointers to the according
- names of the patcher functions. It is only usefull for debugging
- purposes.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-typedef struct patcher_function_list_t {
- functionptr patcher;
- char *name;
-} patcher_function_list_t;
-
-static patcher_function_list_t patcher_function_list[] = {
- { PATCHER_initialize_class, "initialize_class" },
- { PATCHER_resolve_class, "resolve_class" },
- { PATCHER_resolve_native_function, "resolve_native_function" },
- { PATCHER_invokestatic_special, "invokestatic_special" },
- { PATCHER_invokevirtual, "invokevirtual" },
- { PATCHER_invokeinterface, "invokeinterface" },
- { NULL, "-UNKNOWN PATCHER FUNCTION-" }
-};
-#endif
-
-
-/* patcher_list_create *********************************************************
-
- Creates an empty patcher list for the given codeinfo.
-
-*******************************************************************************/
-
-void patcher_list_create(codeinfo *code)
-{
- code->patchers = list_create(OFFSET(patchref_t, linkage));
-}
-
-
-/* patcher_list_reset **********************************************************
-
- Resets the patcher list inside a codeinfo. This is usefull when
- resetting a codeinfo for recompiling.
-
-*******************************************************************************/
-
-void patcher_list_reset(codeinfo *code)
-{
- patchref_t *pr;
-
- /* free all elements of the list */
-
- while((pr = list_first(code->patchers)) != NULL) {
- list_remove(code->patchers, pr);
-
- FREE(pr, patchref_t);
-
-#if defined(ENABLE_STATISTICS)
- if (opt_stat)
- size_patchref -= sizeof(patchref_t);
-#endif
- }
-}
-
-/* patcher_list_free ***********************************************************
-
- Frees the patcher list and all its entries for the given codeinfo.
-
-*******************************************************************************/
-
-void patcher_list_free(codeinfo *code)
-{
- /* free all elements of the list */
-
- patcher_list_reset(code);
-
- /* free the list itself */
-
- list_free(code->patchers);
-}
-
-
-/* patcher_list_find ***********************************************************
-
- Find an entry inside the patcher list for the given codeinfo
- by specifying the program counter of the patcher position.
-
- NOTE: Caller should hold the patcher list lock or maintain
- exclusive access otherwise.
-
-*******************************************************************************/
-
-static patchref_t *patcher_list_find(codeinfo *code, u1 *pc)
-{
- patchref_t *pr;
-
- /* walk through all patcher references for the given codeinfo */
-
- pr = list_first(code->patchers);
-
- while (pr) {
-
-/*#define TRACE_PATCHER_FIND*/
-#ifdef TRACE_PATCHER_FIND
- log_println("patcher_list_find: %p == %p", pr->mpc, pc);
-#endif
-
- if (pr->mpc == (ptrint) pc)
- return pr;
-
- pr = list_next(code->patchers, pr);
- }
-
- return NULL;
-}
-
-
-/* patcher_add_patch_ref *******************************************************
-
- Appends a new patcher reference to the list of patching positions.
-
-*******************************************************************************/
-
-void patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp)
-{
- codegendata *cd;
- codeinfo *code;
- patchref_t *pr;
- s4 patchmpc;
-
- cd = jd->cd;
- code = jd->code;
- patchmpc = cd->mcodeptr - cd->mcodebase;
-
-#if !defined(NDEBUG)
- if (patcher_list_find(code, (u1 *) (intptr_t) patchmpc) != NULL)
- vm_abort("patcher_add_patch_ref: different patchers at same position.");
-#endif
-
- /* allocate patchref on heap (at least freed together with codeinfo) */
-
- pr = NEW(patchref_t);
- list_add_first(code->patchers, pr);
-
-#if defined(ENABLE_STATISTICS)
- if (opt_stat)
- size_patchref += sizeof(patchref_t);
-#endif
-
- /* set patcher information (mpc is resolved later) */
-
- pr->mpc = patchmpc;
- pr->disp = disp;
- pr->patcher = patcher;
- pr->ref = ref;
- pr->mcode = 0;
- pr->done = false;
-
-#if defined(ENABLE_JIT) && (defined(__I386__) || defined(__M68K__) || defined(__SPARC_64__) || defined(__X86_64__))
-
- /* XXX We can remove that when we don't use UD2 anymore on i386
- and x86_64. */
-
- /* On some architectures the patcher stub call instruction might
- be longer than the actual instruction generated. On this
- architectures we store the last patcher call position and after
- the basic block code generation is completed, we check the
- range and maybe generate some nop's. */
- /* The nops are generated in codegen_emit in each codegen */
-
- cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
-#endif
-}
-
-
-/**
- * Resolve all patchers in the current JIT run.
- *
- * @param jd JIT data-structure
- */
-void patcher_resolve(jitdata* jd)
-{
- codeinfo* code;
- patchref_t* pr;
-
- /* Get required compiler data. */
-
- code = jd->code;
-
- for (pr = list_first(code->patchers); pr != NULL; pr = list_next(code->patchers, pr)) {
- pr->mpc += (intptr_t) code->entrypoint;
- pr->datap = (intptr_t) (pr->disp + code->entrypoint);
- }
-}
-
-
-/**
- * Check if the patcher is already patched. This is done by comparing
- * the machine instruction.
- *
- * @param pr Patcher structure.
- *
- * @return true if patched, false otherwise.
- */
-bool patcher_is_patched(patchref_t* pr)
-{
- // Validate the instruction at the patching position is the same
- // instruction as the patcher structure contains.
- uint32_t mcode = *((uint32_t*) pr->mpc);
-
- if (mcode != pr->mcode) {
- // The code differs.
- return false;
- }
-
- return true;
-}
-
-
-/**
- *
- */
-bool patcher_is_patched_at(void* pc)
-{
- codeinfo* code = code_find_codeinfo_for_pc(pc);
-
- // Get the patcher for the given PC.
- patchref_t* pr = patcher_list_find(code, pc);
-
- if (pr == NULL) {
- // The given PC is not a patcher position.
- return false;
- }
-
- // Validate the instruction.
- return patcher_is_patched(pr);
-}
-
-
-/* patcher_handler *************************************************************
-
- Handles the request to patch JIT code at the given patching
- position. This function is normally called by the signal
- handler.
-
- NOTE: The patcher list lock is used to maintain exclusive
- access of the patched position (in fact of the whole code).
- After patching has suceeded, the patcher reference should be
- removed from the patcher list to avoid double patching.
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-/* XXX this indent is not thread safe! */
-/* XXX if you want it thread safe, place patcher_depth in threadobject! */
-static int patcher_depth = 0;
-#define TRACE_PATCHER_INDENT for (i=0; i<patcher_depth; i++) printf("\t")
-#endif /* !defined(NDEBUG) */
-
-java_handle_t *patcher_handler(u1 *pc)
-{
- codeinfo *code;
- patchref_t *pr;
- bool result;
- java_handle_t *e;
-#if !defined(NDEBUG)
- patcher_function_list_t *l;
- int i;
-#endif
-
- /* define the patcher function */
-
- bool (*patcher_function)(patchref_t *);
-
- /* search the codeinfo for the given PC */
-
- code = code_find_codeinfo_for_pc(pc);
- assert(code);
-
- /* enter a monitor on the patcher list */
-
- list_lock(code->patchers);
-
- /* search the patcher information for the given PC */
-
- pr = patcher_list_find(code, pc);
-
- if (pr == NULL)
- vm_abort("patcher_handler: Unable to find patcher reference.");
-
- if (pr->done) {
-#if !defined(NDEBUG)
- if (opt_DebugPatcher) {
- log_println("patcher_handler: double-patching detected!");
- }
-#endif
- list_unlock(code->patchers);
- return NULL;
- }
-
-#if !defined(NDEBUG)
- if (opt_DebugPatcher) {
- for (l = patcher_function_list; l->patcher != NULL; l++)
- if (l->patcher == pr->patcher)
- break;
-
- TRACE_PATCHER_INDENT; printf("patching in "); method_print(code->m); printf(" at %p\n", (void *) pr->mpc);
- TRACE_PATCHER_INDENT; printf("\tpatcher function = %s <%p>\n", l->name, (void *) (intptr_t) pr->patcher);
-
- TRACE_PATCHER_INDENT;
- printf("\tmachine code before = ");
-
-# if defined(ENABLE_DISASSEMBLER)
- disassinstr((void *) pr->mpc);
-# else
- printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
-# endif
-
- patcher_depth++;
- assert(patcher_depth > 0);
- }
-#endif
-
- /* cast the passed function to a patcher function */
-
- patcher_function = (bool (*)(patchref_t *)) (ptrint) pr->patcher;
-
- /* call the proper patcher function */
-
- result = (patcher_function)(pr);
-
-#if !defined(NDEBUG)
- if (opt_DebugPatcher) {
- assert(patcher_depth > 0);
- patcher_depth--;
-
- TRACE_PATCHER_INDENT;
- printf("\tmachine code after = ");
-
-# if defined(ENABLE_DISASSEMBLER)
- disassinstr((void *) pr->mpc);
-# else
- printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
-# endif
-
- if (result == false) {
- TRACE_PATCHER_INDENT; printf("\tPATCHER EXCEPTION!\n");
- }
- }
-#endif
-
- /* check for return value and exit accordingly */
-
- if (result == false) {
- e = exceptions_get_and_clear_exception();
-
- list_unlock(code->patchers);
-
- return e;
- }
-
- pr->done = true; /* XXX this is only preliminary to prevent double-patching */
-
- list_unlock(code->patchers);
-
- return NULL;
-}
-
-
-/* patcher_initialize_class ****************************************************
-
- Initalizes a given classinfo pointer.
- This function does not patch any data.
-
-*******************************************************************************/
-
-bool patcher_initialize_class(patchref_t *pr)
-{
- classinfo *c;
-
- /* get stuff from the patcher reference */
-
- c = (classinfo *) pr->ref;
-
- /* check if the class is initialized */
-
- if (!(c->state & CLASS_INITIALIZED))
- if (!initialize_class(c))
- return false;
-
- /* patch back original code */
-
- patcher_patch_code(pr);
-
- return true;
-}
-
-
-/* patcher_resolve_class *******************************************************
-
- Resolves a given unresolved class reference.
- This function does not patch any data.
-
-*******************************************************************************/
-
-#ifdef ENABLE_VERIFIER
-bool patcher_resolve_class(patchref_t *pr)
-{
- unresolved_class *uc;
-
- /* get stuff from the patcher reference */
-
- uc = (unresolved_class *) pr->ref;
-
- /* resolve the class and check subtype constraints */
-
- if (!resolve_class_eager_no_access_check(uc))
- return false;
-
- /* patch back original code */
-
- patcher_patch_code(pr);
-
- return true;
-}
-#endif /* ENABLE_VERIFIER */
-
-
-/* patcher_resolve_native_function *********************************************
-
- Resolves the native function for a given methodinfo.
- This function patches one data segment word.
-
-*******************************************************************************/
-
-bool patcher_resolve_native_function(patchref_t *pr)
-{
- methodinfo *m;
- uint8_t *datap;
- functionptr f;
-
- /* get stuff from the patcher reference */
-
- m = (methodinfo *) pr->ref;
- datap = (uint8_t *) pr->datap;
-
- /* resolve native function */
-
- if (!(f = native_method_resolve(m)))
- return false;
-
- /* patch native function pointer */
-
- *((intptr_t *) datap) = (intptr_t) f;
-
- /* synchronize data cache */
-
- md_dcacheflush(datap, SIZEOF_VOID_P);
-
- /* patch back original code */
-
- patcher_patch_code(pr);
-
- return true;
-}
-
-
-/*
- * 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/patcher-common.cpp - architecture independent code patching stuff
+
+ Copyright (C) 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+ Copyright (C) 2008 Theobroma Systems Ltd.
+
+ 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 "codegen.h" /* for PATCHER_NOPS */
+#include "md.h"
+
+#include "mm/memory.h"
+
+#include "native/native.h"
+
+#include "toolbox/list.h"
+#include "toolbox/logging.h" /* XXX remove me! */
+
+#include "vm/exceptions.hpp"
+#include "vm/initialize.h"
+#include "vm/options.h"
+#include "vm/resolve.h"
+#include "vm/vm.hpp" /* for vm_abort */
+
+#include "vm/jit/code.hpp"
+#include "vm/jit/disass.h"
+#include "vm/jit/jit.hpp"
+#include "vm/jit/patcher-common.hpp"
+
+
+/* patcher_function_list *******************************************************
+
+ This is a list which maps patcher function pointers to the according
+ names of the patcher functions. It is only usefull for debugging
+ purposes.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+typedef struct patcher_function_list_t {
+ functionptr patcher;
+ const char* name;
+} patcher_function_list_t;
+
+static patcher_function_list_t patcher_function_list[] = {
+ { PATCHER_initialize_class, "initialize_class" },
+ { PATCHER_resolve_class, "resolve_class" },
+ { PATCHER_resolve_native_function, "resolve_native_function" },
+ { PATCHER_invokestatic_special, "invokestatic_special" },
+ { PATCHER_invokevirtual, "invokevirtual" },
+ { PATCHER_invokeinterface, "invokeinterface" },
+ { NULL, "-UNKNOWN PATCHER FUNCTION-" }
+};
+#endif
+
+
+/* patcher_list_create *********************************************************
+
+ Creates an empty patcher list for the given codeinfo.
+
+*******************************************************************************/
+
+void patcher_list_create(codeinfo *code)
+{
+ code->patchers = list_create(OFFSET(patchref_t, linkage));
+}
+
+
+/* patcher_list_reset **********************************************************
+
+ Resets the patcher list inside a codeinfo. This is usefull when
+ resetting a codeinfo for recompiling.
+
+*******************************************************************************/
+
+void patcher_list_reset(codeinfo *code)
+{
+ patchref_t *pr;
+
+ /* free all elements of the list */
+
+ while((pr = (patchref_t*) list_first(code->patchers)) != NULL) {
+ list_remove(code->patchers, pr);
+
+ FREE(pr, patchref_t);
+
+#if defined(ENABLE_STATISTICS)
+ if (opt_stat)
+ size_patchref -= sizeof(patchref_t);
+#endif
+ }
+}
+
+/* patcher_list_free ***********************************************************
+
+ Frees the patcher list and all its entries for the given codeinfo.
+
+*******************************************************************************/
+
+void patcher_list_free(codeinfo *code)
+{
+ /* free all elements of the list */
+
+ patcher_list_reset(code);
+
+ /* free the list itself */
+
+ list_free(code->patchers);
+}
+
+
+/* patcher_list_find ***********************************************************
+
+ Find an entry inside the patcher list for the given codeinfo
+ by specifying the program counter of the patcher position.
+
+ NOTE: Caller should hold the patcher list lock or maintain
+ exclusive access otherwise.
+
+*******************************************************************************/
+
+static patchref_t *patcher_list_find(codeinfo *code, void *pc)
+{
+ patchref_t *pr;
+
+ /* walk through all patcher references for the given codeinfo */
+
+ pr = (patchref_t*) list_first(code->patchers);
+
+ while (pr) {
+
+/*#define TRACE_PATCHER_FIND*/
+#ifdef TRACE_PATCHER_FIND
+ log_println("patcher_list_find: %p == %p", pr->mpc, pc);
+#endif
+
+ if (pr->mpc == (ptrint) pc)
+ return pr;
+
+ pr = (patchref_t*) list_next(code->patchers, pr);
+ }
+
+ return NULL;
+}
+
+
+/* patcher_add_patch_ref *******************************************************
+
+ Appends a new patcher reference to the list of patching positions.
+
+*******************************************************************************/
+
+void patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp)
+{
+ codegendata *cd;
+ codeinfo *code;
+ patchref_t *pr;
+ s4 patchmpc;
+
+ cd = jd->cd;
+ code = jd->code;
+ patchmpc = cd->mcodeptr - cd->mcodebase;
+
+#if !defined(NDEBUG)
+ if (patcher_list_find(code, (void*) (intptr_t) patchmpc) != NULL)
+ vm_abort("patcher_add_patch_ref: different patchers at same position.");
+#endif
+
+ /* allocate patchref on heap (at least freed together with codeinfo) */
+
+ pr = NEW(patchref_t);
+ list_add_first(code->patchers, pr);
+
+#if defined(ENABLE_STATISTICS)
+ if (opt_stat)
+ size_patchref += sizeof(patchref_t);
+#endif
+
+ /* set patcher information (mpc is resolved later) */
+
+ pr->mpc = patchmpc;
+ pr->disp = disp;
+ pr->patcher = patcher;
+ pr->ref = ref;
+ pr->mcode = 0;
+ pr->done = false;
+
+#if defined(ENABLE_JIT) && (defined(__I386__) || defined(__M68K__) || defined(__SPARC_64__) || defined(__X86_64__))
+
+ /* XXX We can remove that when we don't use UD2 anymore on i386
+ and x86_64. */
+
+ /* On some architectures the patcher stub call instruction might
+ be longer than the actual instruction generated. On this
+ architectures we store the last patcher call position and after
+ the basic block code generation is completed, we check the
+ range and maybe generate some nop's. */
+ /* The nops are generated in codegen_emit in each codegen */
+
+ cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
+#endif
+}
+
+
+/**
+ * Resolve all patchers in the current JIT run.
+ *
+ * @param jd JIT data-structure
+ */
+void patcher_resolve(jitdata* jd)
+{
+ codeinfo* code;
+ patchref_t* pr;
+
+ /* Get required compiler data. */
+
+ code = jd->code;
+
+ for (pr = (patchref_t*) list_first(code->patchers); pr != NULL; pr = (patchref_t*) list_next(code->patchers, pr)) {
+ pr->mpc += (intptr_t) code->entrypoint;
+ pr->datap = (intptr_t) (pr->disp + code->entrypoint);
+ }
+}
+
+
+/**
+ * Check if the patcher is already patched. This is done by comparing
+ * the machine instruction.
+ *
+ * @param pr Patcher structure.
+ *
+ * @return true if patched, false otherwise.
+ */
+bool patcher_is_patched(patchref_t* pr)
+{
+ // Validate the instruction at the patching position is the same
+ // instruction as the patcher structure contains.
+ uint32_t mcode = *((uint32_t*) pr->mpc);
+
+ if (mcode != pr->mcode) {
+ // The code differs.
+ return false;
+ }
+
+ return true;
+}
+
+
+/**
+ *
+ */
+bool patcher_is_patched_at(void* pc)
+{
+ codeinfo* code = code_find_codeinfo_for_pc(pc);
+
+ // Get the patcher for the given PC.
+ patchref_t* pr = patcher_list_find(code, pc);
+
+ if (pr == NULL) {
+ // The given PC is not a patcher position.
+ return false;
+ }
+
+ // Validate the instruction.
+ return patcher_is_patched(pr);
+}
+
+
+/* patcher_handler *************************************************************
+
+ Handles the request to patch JIT code at the given patching
+ position. This function is normally called by the signal
+ handler.
+
+ NOTE: The patcher list lock is used to maintain exclusive
+ access of the patched position (in fact of the whole code).
+ After patching has suceeded, the patcher reference should be
+ removed from the patcher list to avoid double patching.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+/* XXX this indent is not thread safe! */
+/* XXX if you want it thread safe, place patcher_depth in threadobject! */
+static int patcher_depth = 0;
+#define TRACE_PATCHER_INDENT for (i=0; i<patcher_depth; i++) printf("\t")
+#endif /* !defined(NDEBUG) */
+
+java_handle_t *patcher_handler(u1 *pc)
+{
+ codeinfo *code;
+ patchref_t *pr;
+ bool result;
+ java_handle_t *e;
+#if !defined(NDEBUG)
+ patcher_function_list_t *l;
+ int i;
+#endif
+
+ /* define the patcher function */
+
+ bool (*patcher_function)(patchref_t *);
+
+ /* search the codeinfo for the given PC */
+
+ code = code_find_codeinfo_for_pc(pc);
+ assert(code);
+
+ /* enter a monitor on the patcher list */
+
+ list_lock(code->patchers);
+
+ /* search the patcher information for the given PC */
+
+ pr = patcher_list_find(code, pc);
+
+ if (pr == NULL)
+ vm_abort("patcher_handler: Unable to find patcher reference.");
+
+ if (pr->done) {
+#if !defined(NDEBUG)
+ if (opt_DebugPatcher) {
+ log_println("patcher_handler: double-patching detected!");
+ }
+#endif
+ list_unlock(code->patchers);
+ return NULL;
+ }
+
+#if !defined(NDEBUG)
+ if (opt_DebugPatcher) {
+ for (l = patcher_function_list; l->patcher != NULL; l++)
+ if (l->patcher == pr->patcher)
+ break;
+
+ TRACE_PATCHER_INDENT; printf("patching in "); method_print(code->m); printf(" at %p\n", (void *) pr->mpc);
+ TRACE_PATCHER_INDENT; printf("\tpatcher function = %s <%p>\n", l->name, (void *) (intptr_t) pr->patcher);
+
+ TRACE_PATCHER_INDENT;
+ printf("\tmachine code before = ");
+
+# if defined(ENABLE_DISASSEMBLER)
+ disassinstr((u1*) (void*) pr->mpc);
+# else
+ printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
+# endif
+
+ patcher_depth++;
+ assert(patcher_depth > 0);
+ }
+#endif
+
+ /* cast the passed function to a patcher function */
+
+ patcher_function = (bool (*)(patchref_t *)) (ptrint) pr->patcher;
+
+ /* call the proper patcher function */
+
+ result = (patcher_function)(pr);
+
+#if !defined(NDEBUG)
+ if (opt_DebugPatcher) {
+ assert(patcher_depth > 0);
+ patcher_depth--;
+
+ TRACE_PATCHER_INDENT;
+ printf("\tmachine code after = ");
+
+# if defined(ENABLE_DISASSEMBLER)
+ disassinstr((u1*) (void*) pr->mpc);
+# else
+ printf("%x at %p (disassembler disabled)\n", *((uint32_t*) pr->mpc), (void*) pr->mpc);
+# endif
+
+ if (result == false) {
+ TRACE_PATCHER_INDENT; printf("\tPATCHER EXCEPTION!\n");
+ }
+ }
+#endif
+
+ /* check for return value and exit accordingly */
+
+ if (result == false) {
+ e = exceptions_get_and_clear_exception();
+
+ list_unlock(code->patchers);
+
+ return e;
+ }
+
+ pr->done = true; /* XXX this is only preliminary to prevent double-patching */
+
+ list_unlock(code->patchers);
+
+ return NULL;
+}
+
+
+/* patcher_initialize_class ****************************************************
+
+ Initalizes a given classinfo pointer.
+ This function does not patch any data.
+
+*******************************************************************************/
+
+bool patcher_initialize_class(patchref_t *pr)
+{
+ classinfo *c;
+
+ /* get stuff from the patcher reference */
+
+ c = (classinfo *) pr->ref;
+
+ /* check if the class is initialized */
+
+ if (!(c->state & CLASS_INITIALIZED))
+ if (!initialize_class(c))
+ return false;
+
+ /* patch back original code */
+
+ patcher_patch_code(pr);
+
+ return true;
+}
+
+
+/* patcher_resolve_class *******************************************************
+
+ Resolves a given unresolved class reference.
+ This function does not patch any data.
+
+*******************************************************************************/
+
+#ifdef ENABLE_VERIFIER
+bool patcher_resolve_class(patchref_t *pr)
+{
+ unresolved_class *uc;
+
+ /* get stuff from the patcher reference */
+
+ uc = (unresolved_class *) pr->ref;
+
+ /* resolve the class and check subtype constraints */
+
+ if (!resolve_class_eager_no_access_check(uc))
+ return false;
+
+ /* patch back original code */
+
+ patcher_patch_code(pr);
+
+ return true;
+}
+#endif /* ENABLE_VERIFIER */
+
+
+/* patcher_resolve_native_function *********************************************
+
+ Resolves the native function for a given methodinfo.
+ This function patches one data segment word.
+
+*******************************************************************************/
+
+bool patcher_resolve_native_function(patchref_t *pr)
+{
+ methodinfo *m;
+ uint8_t *datap;
+ functionptr f;
+
+ /* get stuff from the patcher reference */
+
+ m = (methodinfo *) pr->ref;
+ datap = (uint8_t *) pr->datap;
+
+ /* resolve native function */
+
+ if (!(f = native_method_resolve(m)))
+ return false;
+
+ /* patch native function pointer */
+
+ *((intptr_t *) datap) = (intptr_t) f;
+
+ /* synchronize data cache */
+
+ md_dcacheflush(datap, SIZEOF_VOID_P);
+
+ /* patch back original code */
+
+ patcher_patch_code(pr);
+
+ return true;
+}
+
+
+/*
+ * 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/patcher-common.h - architecture independent code patching stuff
-
- Copyright (C) 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 _PATCHER_COMMON_H
-#define _PATCHER_COMMON_H
-
-/* forward typedefs ***********************************************************/
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "toolbox/list.h"
-
-#include "vm/global.h"
-
-#include "vm/jit/jit.hpp"
-
-
-/* patchref_t ******************************************************************
-
- A patcher reference contains information about a code position
- which needs additional code patching during runtime.
-
-*******************************************************************************/
-
-typedef struct patchref_t {
- ptrint mpc; /* absolute position in code segment */
- ptrint datap; /* absolute position in data segment */
- s4 disp; /* displacement of ref in the data segment */
- functionptr patcher; /* patcher function to call */
- void* ref; /* reference passed */
- uint32_t mcode; /* machine code to be patched back in */
- bool done; /* XXX preliminary: patch already applied? */
- listnode_t linkage;
-} patchref_t;
-
-
-/* macros *********************************************************************/
-
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void patcher_list_create(codeinfo *code);
-void patcher_list_reset(codeinfo *code);
-void patcher_list_free(codeinfo *code);
-
-void patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp);
-
-void patcher_resolve(jitdata* jd);
-
-bool patcher_is_patched(patchref_t* pr);
-bool patcher_is_patched_at(void* pc);
-
-// MD function.
-bool patcher_is_valid_trap_instruction_at(void* pc);
-
-java_handle_t *patcher_handler(u1 *pc);
-
-
-/* empty patcher (just patches back original mcode) ***************************/
-
-void patcher_patch_code(patchref_t *pr);
-
-
-/* patcher prototypes and macros **********************************************/
-
-/* new patcher functions */
-
-bool patcher_resolve_class(patchref_t *pr);
-#define PATCHER_resolve_class (functionptr) patcher_resolve_class
-
-bool patcher_initialize_class(patchref_t *pr);
-#define PATCHER_initialize_class (functionptr) patcher_initialize_class
-
-bool patcher_resolve_classref_to_classinfo(patchref_t *pr);
-#define PATCHER_resolve_classref_to_classinfo (functionptr) patcher_resolve_classref_to_classinfo
-
-bool patcher_resolve_classref_to_vftbl(patchref_t *pr);
-#define PATCHER_resolve_classref_to_vftbl (functionptr) patcher_resolve_classref_to_vftbl
-
-bool patcher_resolve_classref_to_index(patchref_t *pr);
-#define PATCHER_resolve_classref_to_index (functionptr) patcher_resolve_classref_to_index
-
-bool patcher_resolve_classref_to_flags(patchref_t *pr);
-#define PATCHER_resolve_classref_to_flags (functionptr) patcher_resolve_classref_to_flags
-
-bool patcher_resolve_native_function(patchref_t *pr);
-#define PATCHER_resolve_native_function (functionptr) patcher_resolve_native_function
-
-/* old patcher functions */
-
-bool patcher_get_putstatic(patchref_t *pr);
-#define PATCHER_get_putstatic (functionptr) patcher_get_putstatic
-
-#if defined(__I386__)
-
-bool patcher_getfield(patchref_t *pr);
-#define PATCHER_getfield (functionptr) patcher_getfield
-
-bool patcher_putfield(patchref_t *pr);
-#define PATCHER_putfield (functionptr) patcher_putfield
-
-#else
-
-bool patcher_get_putfield(patchref_t *pr);
-#define PATCHER_get_putfield (functionptr) patcher_get_putfield
-
-#endif /* defined(__I386__) */
-
-#if defined(__I386__) || defined(__X86_64__)
-
-bool patcher_putfieldconst(patchref_t *pr);
-#define PATCHER_putfieldconst (functionptr) patcher_putfieldconst
-
-#endif /* defined(__I386__) || defined(__X86_64__) */
-
-bool patcher_invokestatic_special(patchref_t *pr);
-#define PATCHER_invokestatic_special (functionptr) patcher_invokestatic_special
-
-bool patcher_invokevirtual(patchref_t *pr);
-#define PATCHER_invokevirtual (functionptr) patcher_invokevirtual
-
-bool patcher_invokeinterface(patchref_t *pr);
-#define PATCHER_invokeinterface (functionptr) patcher_invokeinterface
-
-#if defined(__ALPHA__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__) || defined(__M68K__)
-
-bool patcher_checkcast_interface(patchref_t *pr);
-#define PATCHER_checkcast_interface (functionptr) patcher_checkcast_interface
-
-bool patcher_instanceof_interface(patchref_t *pr);
-#define PATCHER_instanceof_interface (functionptr) patcher_instanceof_interface
-
-#endif /* defined(__ALPHA__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__) || defined(__M68K__) */
-
-#if defined(__S390__)
-
-bool patcher_checkcast_instanceof_interface(patchref_t *pr);
-#define PATCHER_checkcast_instanceof_interface (functionptr) patcher_checkcast_instanceof_interface
-
-#endif /* defined(__S390__) */
-
-#if defined(__I386__)
-
-bool patcher_aconst(patchref_t *pr);
-#define PATCHER_aconst (functionptr) patcher_aconst
-
-bool patcher_builtin_multianewarray(patchref_t *pr);
-#define PATCHER_builtin_multianewarray (functionptr) patcher_builtin_multianewarray
-
-bool patcher_builtin_arraycheckcast(patchref_t *pr);
-#define PATCHER_builtin_arraycheckcast (functionptr) patcher_builtin_arraycheckcast
-
-bool patcher_checkcast_instanceof_flags(patchref_t *pr);
-#define PATCHER_checkcast_instanceof_flags (functionptr) patcher_checkcast_instanceof_flags
-
-bool patcher_checkcast_class(patchref_t *pr);
-#define PATCHER_checkcast_class (functionptr) patcher_checkcast_class
-
-bool patcher_instanceof_class(patchref_t *pr);
-#define PATCHER_instanceof_class (functionptr) patcher_instanceof_class
-
-#endif /* defined(__I386__) */
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif /* _PATCHER_COMMON_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/patcher-common.hpp - architecture independent code patching stuff
+
+ Copyright (C) 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 _PATCHER_COMMON_HPP
+#define _PATCHER_COMMON_HPP
+
+/* forward typedefs ***********************************************************/
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "toolbox/list.h"
+
+#include "vm/global.h"
+
+#include "vm/jit/jit.hpp"
+
+
+/* patchref_t ******************************************************************
+
+ A patcher reference contains information about a code position
+ which needs additional code patching during runtime.
+
+*******************************************************************************/
+
+typedef struct patchref_t {
+ ptrint mpc; /* absolute position in code segment */
+ ptrint datap; /* absolute position in data segment */
+ s4 disp; /* displacement of ref in the data segment */
+ functionptr patcher; /* patcher function to call */
+ void* ref; /* reference passed */
+ uint32_t mcode; /* machine code to be patched back in */
+ bool done; /* XXX preliminary: patch already applied? */
+ listnode_t linkage;
+} patchref_t;
+
+
+/* macros *********************************************************************/
+
+
+/* function prototypes ********************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void patcher_list_create(codeinfo *code);
+void patcher_list_reset(codeinfo *code);
+void patcher_list_free(codeinfo *code);
+
+void patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp);
+
+void patcher_resolve(jitdata* jd);
+
+bool patcher_is_patched(patchref_t* pr);
+bool patcher_is_patched_at(void* pc);
+
+// MD function.
+bool patcher_is_valid_trap_instruction_at(void* pc);
+
+java_handle_t *patcher_handler(u1 *pc);
+
+
+/* empty patcher (just patches back original mcode) ***************************/
+
+void patcher_patch_code(patchref_t *pr);
+
+
+/* patcher prototypes and macros **********************************************/
+
+/* new patcher functions */
+
+bool patcher_resolve_class(patchref_t *pr);
+#define PATCHER_resolve_class (functionptr) patcher_resolve_class
+
+bool patcher_initialize_class(patchref_t *pr);
+#define PATCHER_initialize_class (functionptr) patcher_initialize_class
+
+bool patcher_resolve_classref_to_classinfo(patchref_t *pr);
+#define PATCHER_resolve_classref_to_classinfo (functionptr) patcher_resolve_classref_to_classinfo
+
+bool patcher_resolve_classref_to_vftbl(patchref_t *pr);
+#define PATCHER_resolve_classref_to_vftbl (functionptr) patcher_resolve_classref_to_vftbl
+
+bool patcher_resolve_classref_to_index(patchref_t *pr);
+#define PATCHER_resolve_classref_to_index (functionptr) patcher_resolve_classref_to_index
+
+bool patcher_resolve_classref_to_flags(patchref_t *pr);
+#define PATCHER_resolve_classref_to_flags (functionptr) patcher_resolve_classref_to_flags
+
+bool patcher_resolve_native_function(patchref_t *pr);
+#define PATCHER_resolve_native_function (functionptr) patcher_resolve_native_function
+
+/* old patcher functions */
+
+bool patcher_get_putstatic(patchref_t *pr);
+#define PATCHER_get_putstatic (functionptr) patcher_get_putstatic
+
+#if defined(__I386__)
+
+bool patcher_getfield(patchref_t *pr);
+#define PATCHER_getfield (functionptr) patcher_getfield
+
+bool patcher_putfield(patchref_t *pr);
+#define PATCHER_putfield (functionptr) patcher_putfield
+
+#else
+
+bool patcher_get_putfield(patchref_t *pr);
+#define PATCHER_get_putfield (functionptr) patcher_get_putfield
+
+#endif /* defined(__I386__) */
+
+#if defined(__I386__) || defined(__X86_64__)
+
+bool patcher_putfieldconst(patchref_t *pr);
+#define PATCHER_putfieldconst (functionptr) patcher_putfieldconst
+
+#endif /* defined(__I386__) || defined(__X86_64__) */
+
+bool patcher_invokestatic_special(patchref_t *pr);
+#define PATCHER_invokestatic_special (functionptr) patcher_invokestatic_special
+
+bool patcher_invokevirtual(patchref_t *pr);
+#define PATCHER_invokevirtual (functionptr) patcher_invokevirtual
+
+bool patcher_invokeinterface(patchref_t *pr);
+#define PATCHER_invokeinterface (functionptr) patcher_invokeinterface
+
+#if defined(__ALPHA__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__) || defined(__M68K__)
+
+bool patcher_checkcast_interface(patchref_t *pr);
+#define PATCHER_checkcast_interface (functionptr) patcher_checkcast_interface
+
+bool patcher_instanceof_interface(patchref_t *pr);
+#define PATCHER_instanceof_interface (functionptr) patcher_instanceof_interface
+
+#endif /* defined(__ALPHA__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__) || defined(__M68K__) */
+
+#if defined(__S390__)
+
+bool patcher_checkcast_instanceof_interface(patchref_t *pr);
+#define PATCHER_checkcast_instanceof_interface (functionptr) patcher_checkcast_instanceof_interface
+
+#endif /* defined(__S390__) */
+
+#if defined(__I386__)
+
+bool patcher_aconst(patchref_t *pr);
+#define PATCHER_aconst (functionptr) patcher_aconst
+
+bool patcher_builtin_multianewarray(patchref_t *pr);
+#define PATCHER_builtin_multianewarray (functionptr) patcher_builtin_multianewarray
+
+bool patcher_builtin_arraycheckcast(patchref_t *pr);
+#define PATCHER_builtin_arraycheckcast (functionptr) patcher_builtin_arraycheckcast
+
+bool patcher_checkcast_instanceof_flags(patchref_t *pr);
+#define PATCHER_checkcast_instanceof_flags (functionptr) patcher_checkcast_instanceof_flags
+
+bool patcher_checkcast_class(patchref_t *pr);
+#define PATCHER_checkcast_class (functionptr) patcher_checkcast_class
+
+bool patcher_instanceof_class(patchref_t *pr);
+#define PATCHER_instanceof_class (functionptr) patcher_instanceof_class
+
+#endif /* defined(__I386__) */
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PATCHER_COMMON_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/jit/linenumbertable.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/parse.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/reg.h"
#include "vm/jit/replace.hpp"
#include "vm/jit/stacktrace.hpp"
#include "vm/jit/asmpart.h"
#include "vm/jit/methodheader.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#define PATCH_BACK_ORIGINAL_MCODE \
#include "vm/jit/jit.hpp"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/parse.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/reg.h"
#include "vm/jit/replace.hpp"
#include "vm/jit/stacktrace.hpp"
#include "vm/jit/asmpart.h"
#include "vm/jit/methodheader.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
/* patcher_patch_code **********************************************************
#include "vm/jit/linenumbertable.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/parse.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/reg.h"
#include "vm/jit/replace.hpp"
#include "vm/jit/stacktrace.hpp"
#include "vm/jit/codegen-common.hpp"
#include "vm/jit/emit-common.hpp"
#include "vm/jit/jit.hpp"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/replace.hpp"
#include "vm/jit/trace.hpp"
#include "vm/jit/trap.h"
#include "vm/resolve.h"
#include "vm/types.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/s390/codegen.h"
#include "vm/jit/s390/md-abi.h"
#include "vm/jit/disass.h"
#include "vm/jit/jit.hpp"
#include "vm/jit/methodtree.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/replace.hpp"
#include "vm/jit/stacktrace.hpp"
#include "vm/jit/linenumbertable.h"
#include "vm/jit/methodheader.h"
#include "vm/jit/parse.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/reg.h"
#include "vm/jit/replace.hpp"
#include "vm/jit/stacktrace.hpp"
#include "vm/jit/codegen-common.hpp"
#include "vm/jit/emit-common.hpp"
#include "vm/jit/jit.hpp"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
#include "vm/jit/replace.hpp"
#include "vm/jit/trace.hpp"
#include "vm/jit/trap.h"
#include "vm/references.h"
#include "vm/resolve.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
/* patcher_patch_code **********************************************************