* src/vm/jit/patcher-common.c: Moved to .cpp.
authorChristian Thalinger <twisti@complang.tuwien.ac.at>
Tue, 26 Aug 2008 21:50:23 +0000 (17:50 -0400)
committerChristian Thalinger <twisti@complang.tuwien.ac.at>
Tue, 26 Aug 2008 21:50:23 +0000 (17:50 -0400)
* 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

36 files changed:
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/patcher-common.c [deleted file]
src/vm/jit/patcher-common.cpp [new file with mode: 0644]
src/vm/jit/patcher-common.h [deleted file]
src/vm/jit/patcher-common.hpp [new file with mode: 0644]
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

index 7d70265f3679d1c1062a44e08bb3c007b5271946..c318e6e9731f92feed3a5881d8e63a98a5fd4082 100644 (file)
@@ -61,7 +61,7 @@
 #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"
index c51c8e1754c17f863ab133d03535a806243863bd..e6eab136d39025568eb93d1115d27be14377eb59 100644 (file)
@@ -175,8 +175,8 @@ libjit_la_SOURCES = \
        methodtree.h \
        parse.c \
        parse.h \
-       patcher-common.c \
-       patcher-common.h \
+       patcher-common.cpp \
+       patcher-common.hpp \
        $(RECOMPILE_SOURCES) \
        $(REG_SOURCES) \
        $(REPLACE_SOURCES) \
index 9045721080fdde6ce306a448e44887eac1443dde..72f5dae71ee413a5dabc391f27fddf4891f1c81a 100644 (file)
@@ -58,7 +58,7 @@
 #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"
index cdb00c327c6c4e1a6d77401a3634465dca88aa90..d39158e61b4a06dbdb1a2cb97a51df8cd0cf45eb 100644 (file)
@@ -45,7 +45,7 @@
 #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"
index d57361b6c5527ccfc7dc20951e6947210648dc9e..1f3a9342273fdcdd32c6632f1652a3a7f9ffc6c3 100644 (file)
@@ -44,7 +44,7 @@
 #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"
 
 
index e2fc7f95f163982f9aa901ba490ae86503779b2e..5c30df214d07ac05707a82a95fad12793d694d8c 100644 (file)
@@ -58,7 +58,7 @@
 #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)
index 3fffcdb2ba7a9658c0f96f6fb281172b18ee0e30..26393f68ab8f16ba55431f5d6a83978229f13a29 100644 (file)
@@ -44,7 +44,7 @@
 #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"
index d3c9634102030534ea03ca815b5e996e11fc7e52..051ae1825d8744191005d777218dddbe77012ae7 100644 (file)
@@ -58,7 +58,7 @@ typedef struct ucontext {
 
 #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"
 
 
index d36fe15814f97deb4bd805c88e628e4a07d6f65c..7115d4f5d83bbef486286f76f366c84c114e5992 100644 (file)
@@ -46,7 +46,7 @@
 #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) \
index d9470f0db42b8057e7d85b5b06eff093ec2b9786..e5aac486d5d466b70e14b32758952acaa94fe496 100644 (file)
@@ -37,7 +37,7 @@
 
 #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"
 
 
index 9c16a260d32a4ae3313e61636bd68dd6f22d44e0..0efaad8af10caedc3b57697dd9f21f48fccf86ab 100644 (file)
@@ -87,7 +87,7 @@
 #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"
index 8e2fdef105191fb46ae6562ce488e0d6adf6e8ef..39bb0d23cfb5b0279e4535c84c15782bc768ebd1 100644 (file)
 #ifndef _DISASS_H
 #define _DISASS_H
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #include "config.h"
 
 #if defined(WITH_BINUTILS_DISASSEMBLER)
@@ -98,6 +94,10 @@ extern s4   disass_len;
 
 /* function prototypes *******************************************************/
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #if defined(ENABLE_JIT)
 void disassemble(u1 *start, u1 *end);
 #endif
index 0535e0276470f3c99fc4290a74dc3476454e353a..a5fa481e3b2ef35f89683c8fe21cdc19fb628b6a 100644 (file)
@@ -38,7 +38,7 @@
 
 #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 ****************************************************************
index efb7f8c76b0185bec418ec47b130045f11ede66a..5b0cd8a7f11e000b3c6a7d71179dcd0f91766fd7 100644 (file)
@@ -60,7 +60,7 @@
 #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"
index 5a1f886e3ce4d96504efc1c35b356bdefa26bcd0..68e8a9e114a38db521328867bc1c43792ab6a227 100644 (file)
@@ -45,7 +45,7 @@
 #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"
index 30baa1a2fa6cf9dfcc4584edddd5fc75d730532c..b2146eae5672c4265838c89a9bc45497f8fcf6ea 100644 (file)
@@ -44,7 +44,7 @@
 #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                                                      \
index e020a3b4e09c5662aac7db4152a346b61a7b5574..5d38065b9203da7afb57ed022e0be60bd3943361 100644 (file)
@@ -51,7 +51,7 @@
 
 #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"
index 61e0a18fb3c6bbd01e1535df1189e5450271a856..c9f55dfacf8bb1f3c9e089dc24c262f43e891bb2 100644 (file)
@@ -43,7 +43,7 @@
 #include "vm/resolve.h"
 
 #include "vm/jit/asmpart.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
 
 #include "codegen.h"
 
index bcd85630485e2c051dde10cd8b0314bab334551b..f77101c5f0a4031fe2d21091dd6b2faa239465f1 100644 (file)
@@ -55,7 +55,7 @@
 #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"
index c7eea5e8d5fee42fc5c23f95ce7640301e40d701..e21a41b82d703d9dbdbb947847066ba04630d595 100644 (file)
@@ -45,7 +45,7 @@
 #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"
 
index be0e14d87c1a0b50909b8fe66442c2fecc2b80aa..248635ba99131303d9e582e3f6e8bb67792544ad 100644 (file)
@@ -44,7 +44,7 @@
 #include "vm/resolve.h"
 
 #include "vm/jit/asmpart.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
 
 
 /* patcher_patch_code **********************************************************
diff --git a/src/vm/jit/patcher-common.c b/src/vm/jit/patcher-common.c
deleted file mode 100644 (file)
index b099bbd..0000000
+++ /dev/null
@@ -1,533 +0,0 @@
-/* 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:
- */
-
diff --git a/src/vm/jit/patcher-common.cpp b/src/vm/jit/patcher-common.cpp
new file mode 100644 (file)
index 0000000..a33aba7
--- /dev/null
@@ -0,0 +1,533 @@
+/* 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:
+ */
+
diff --git a/src/vm/jit/patcher-common.h b/src/vm/jit/patcher-common.h
deleted file mode 100644 (file)
index e2cea59..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/* 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:
- */
diff --git a/src/vm/jit/patcher-common.hpp b/src/vm/jit/patcher-common.hpp
new file mode 100644 (file)
index 0000000..5f25ae8
--- /dev/null
@@ -0,0 +1,210 @@
+/* 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:
+ */
index 62742e385caf939bff26e2ba5e89ef917f7c02b5..5d296e8df75b832a6e6979ba3c9ab63d30064aab 100644 (file)
@@ -60,7 +60,7 @@
 #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"
index 282d8e08f7a7f44a3c899d62ba9299477ef09ed5..186131ee4ccaeb5425880050c73ac9523dd08595 100644 (file)
@@ -46,7 +46,7 @@
 
 #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 \
index 6b2fa8cf714277704e2dfc0e947173f9db026ae5..69fe64073e17b5f8e987c7782d9b4a91fa76c47b 100644 (file)
@@ -60,7 +60,7 @@
 #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"
index ce22cf1ad185c8da748f4cec66e510c6cdf7fb14..999ae7aae28b241ed162afbedb7e2c8e3295da4c 100644 (file)
@@ -46,7 +46,7 @@
 
 #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 **********************************************************
index 82612b5c5e58ffc902ac3898c306eb2b96702778..15754e1dbeb7571cac1563b637b6a1d72590411c 100644 (file)
@@ -62,7 +62,7 @@
 #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"
index c3696fd39b6cf1f3022b2ff8f2056d3ca94bf146..2d501b823ea1455affb12ec7ba591e46b57a58cf 100644 (file)
@@ -46,7 +46,7 @@
 #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"
index ba9eea9790f37f9a6c695e74130ae17f1b7a4e4b..c5c0e6a3718f56aa2ccfb54341b1417e2d55d6a0 100644 (file)
@@ -40,7 +40,7 @@
 #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"
 
index b6f96f1851ec9213fc9a4fa14017b76871b27ab6..258530b1ef17f9b700a54593ae5caa2562de8b92 100644 (file)
@@ -46,7 +46,7 @@
 #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"
 
index fec4c97067b511378cb2b8df7121baa0d933e9d2..900780064d5195e64c9dca785e6d992e903f5f44 100644 (file)
@@ -64,7 +64,7 @@
 #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"
index d1076f2db186949b1d7348c79f054628372ea009..c8d929c6574aef54097023297374b44955eb010b 100644 (file)
@@ -45,7 +45,7 @@
 #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"
index 41ed1c08b82194fc86c864ae4cadbc1b4aed7891..49a5d3f6abbd04cd355f7c5a0afe10453bf648fb 100644 (file)
@@ -44,7 +44,7 @@
 #include "vm/references.h"
 #include "vm/resolve.h"
 
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/patcher-common.hpp"
 
 
 /* patcher_patch_code **********************************************************