* src/vm/jit/replace.c: Moved to .cpp.
authorChristian Thalinger <twisti@complang.tuwien.ac.at>
Thu, 21 Aug 2008 15:42:40 +0000 (17:42 +0200)
committerChristian Thalinger <twisti@complang.tuwien.ac.at>
Thu, 21 Aug 2008 15:42:40 +0000 (17:42 +0200)
* src/vm/jit/replace.h: Likewise.
* src/vm/jit/replace.cpp: New file.
* src/vm/jit/replace.hpp: Likewise.
* src/mm/cacao-gc/gc.h,
src/mm/cacao-gc/rootset.c,
src/mm/cacao-gc/rootset.h,
src/threads/posix/thread-posix.hpp,
src/vm/jit/Makefile.am,
src/vm/jit/alpha/codegen.c,
src/vm/jit/alpha/emit.c,
src/vm/jit/arm/emit.c,
src/vm/jit/code.h,
src/vm/jit/codegen-common.c,
src/vm/jit/codegen-common.h,
src/vm/jit/executionstate.h,
src/vm/jit/i386/codegen.c,
src/vm/jit/i386/emit.c,
src/vm/jit/ir/instruction.hpp,
src/vm/jit/jit.hpp,
src/vm/jit/m68k/codegen.c,
src/vm/jit/mips/codegen.c,
src/vm/jit/mips/emit.c,
src/vm/jit/powerpc/codegen.c,
src/vm/jit/powerpc/emit.c,
src/vm/jit/powerpc64/codegen.c,
src/vm/jit/s390/codegen.c,
src/vm/jit/s390/emit.c,
src/vm/jit/sparc64/codegen.c,
src/vm/jit/sparc64/emit.c,
src/vm/jit/stacktrace.hpp,
src/vm/jit/trap.c,
src/vm/jit/x86_64/codegen.c,
src/vm/jit/x86_64/emit.c: Changed include and other related fixes.

--HG--
rename : src/vm/jit/replace.c => src/vm/jit/replace.cpp
rename : src/vm/jit/replace.h => src/vm/jit/replace.hpp

34 files changed:
src/mm/cacao-gc/gc.h
src/mm/cacao-gc/rootset.c
src/mm/cacao-gc/rootset.h
src/threads/posix/thread-posix.hpp
src/vm/jit/Makefile.am
src/vm/jit/alpha/codegen.c
src/vm/jit/alpha/emit.c
src/vm/jit/arm/emit.c
src/vm/jit/code.h
src/vm/jit/codegen-common.c
src/vm/jit/codegen-common.h
src/vm/jit/executionstate.h
src/vm/jit/i386/codegen.c
src/vm/jit/i386/emit.c
src/vm/jit/ir/instruction.hpp
src/vm/jit/jit.hpp
src/vm/jit/m68k/codegen.c
src/vm/jit/mips/codegen.c
src/vm/jit/mips/emit.c
src/vm/jit/powerpc/codegen.c
src/vm/jit/powerpc/emit.c
src/vm/jit/powerpc64/codegen.c
src/vm/jit/replace.c [deleted file]
src/vm/jit/replace.cpp [new file with mode: 0644]
src/vm/jit/replace.h [deleted file]
src/vm/jit/replace.hpp [new file with mode: 0644]
src/vm/jit/s390/codegen.c
src/vm/jit/s390/emit.c
src/vm/jit/sparc64/codegen.c
src/vm/jit/sparc64/emit.c
src/vm/jit/stacktrace.hpp
src/vm/jit/trap.c
src/vm/jit/x86_64/codegen.c
src/vm/jit/x86_64/emit.c

index fd42e44a40f34d409f6d25ded778a32b217996fc..d4a300946426216c45ece6a44d39f1883daa30b7 100644 (file)
@@ -38,7 +38,7 @@
 #include "threads/thread.hpp"
 
 #include "toolbox/list.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 
 
 /* Configuration Switches *****************************************************/
index fe3253579640d3797d90d0761ed45946c3d9c869..7761fa8089b0050309df666fa9c841c577b7058a 100644 (file)
@@ -38,7 +38,7 @@
 #include "toolbox/logging.h"
 
 #include "vm/global.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/stacktrace.hpp"
 
 
index 5b0dc52b824d30ffbf50a8fa4d82096609a9040f..9267d7fdb791f9975b1c946e54e6bf58a27c9f81 100644 (file)
@@ -35,7 +35,7 @@ typedef struct rootset_t rootset_t;
 
 #include "vm/method.h"
 
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 
 
 /* Structures *****************************************************************/
index e1e412ecb8402ac1eb945ea55d0ab61bb3250954..a084bd9244004257046cad10b674778407237141 100644 (file)
@@ -56,7 +56,7 @@ typedef struct threadobject threadobject;
 
 #if defined(ENABLE_GC_CACAO)
 # include "vm/jit/executionstate.h"
-# include "vm/jit/replace.h"
+# include "vm/jit/replace.hpp"
 #endif
 
 #include "vm/jit/stacktrace.hpp"
index 02535f30b3030784a471cc186a6704f97090e4df..50ed6d5051e81daf45f4e19c252c3a699721bdf0 100644 (file)
@@ -103,7 +103,7 @@ REG_SOURCES = \
        reg.h
 
 REPLACE_SOURCES += \
-       replace.h
+       replace.hpp
 
 STACK_SOURCES = \
        stack.c \
@@ -116,7 +116,7 @@ endif
 
 if ENABLE_REPLACEMENT
 REPLACE_SOURCES += \
-       replace.c
+       replace.cpp
 endif
 
 if ENABLE_VERIFIER
index 341bf901c350a1ec1fc9941f31aaaaaa68732827..f176d8bba03802e8d1435e4964db4c60812a1d01 100644 (file)
@@ -60,7 +60,7 @@
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/reg.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
index eae793e6ba02ea3d05aa7456e292a5d0acbecc36..0fc5314db299e38c0761620a8cb75d4897214d79 100644 (file)
@@ -46,7 +46,7 @@
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.hpp"
 #include "vm/jit/patcher-common.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/trace.hpp"
 #include "vm/jit/trap.h"
 
index 847e9c38809c75eaa3f4e2a0d414314833b01fff..b3efb40d288e15c6d6f6a7e4879df61c8f69a96a 100644 (file)
@@ -45,7 +45,7 @@
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.hpp"
 #include "vm/jit/patcher-common.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/trace.hpp"
 #include "vm/jit/trap.h"
 
index 9185575944fe405ababdedae71e30ea7e1270b14..c859984caf2aa029a4d35f4060c2b0d526aca121 100644 (file)
@@ -41,7 +41,7 @@
 #include "vm/jit/exceptiontable.h"
 #include "vm/jit/linenumbertable.h"
 #include "vm/jit/methodheader.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 
 
 /* constants ******************************************************************/
index 240bf1a78def9a7e69c4684bc237254222cf1123..0f2dd7419ab1699d011b223d5f9ad0711b354ef0 100644 (file)
@@ -88,7 +88,7 @@
 #include "vm/jit/methodheader.h"
 #include "vm/jit/methodtree.h"
 #include "vm/jit/patcher-common.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #if defined(ENABLE_SSA)
 # include "vm/jit/optimizing/lsra.h"
 # include "vm/jit/optimizing/ssa.h"
index 3b27daa3b1aa866de58a5743e685d770dca2ad16..5235d149a359fd07254bd5b68f420a23a2770dfd 100644 (file)
@@ -50,7 +50,7 @@ typedef struct linenumberref          linenumberref;
 #include "vm/jit/jit.hpp"
 #include "vm/jit/reg.h"
 #include "vm/jit/code.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 
 
 #define MCODEINITSIZE (1<<15)       /* 32 Kbyte code area initialization size */
index 46211e722eecceb90767ddf30597a3bc174aea6b..4ae8ab6c2ba1dad7729ddbf0cb39d760ca7fe6c5 100644 (file)
@@ -68,6 +68,10 @@ struct executionstate_t {
 
 /* prototypes *****************************************************************/
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #if !defined(NDEBUG)
 void executionstate_sanity_check(void *context);
 void executionstate_println(executionstate_t *es);
@@ -78,6 +82,10 @@ void executionstate_println(executionstate_t *es);
 void md_executionstate_read(executionstate_t *es, void *ucontext);
 void md_executionstate_write(executionstate_t *es, void *ucontext);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* _EXECUTIONSTATE_H */
 
 
index 4f70c2a8605c8553ca5e87a023ed1e423cab342c..48a7758bbb5a254e669abcfbeac851fa25921a39 100644 (file)
@@ -62,7 +62,7 @@
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/reg.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
index 8d8940a3430648d2764829dee8ffe42fe507185d..2d63231c68fa0ac7a2fc0a3fd22d9bb7ae0237a5 100644 (file)
@@ -46,7 +46,7 @@
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.hpp"
 #include "vm/jit/patcher-common.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/trace.hpp"
 #include "vm/jit/trap.h"
 
index 7beb2e2d22c72707774b40a96cf9d6b3bac89a41..c9f3e30753d9d6c2478a30467e95ca3f7fe30608 100644 (file)
@@ -38,7 +38,7 @@ typedef struct insinfo_inline insinfo_inline;
 #include "vm/descriptor.h"
 
 #include "vm/jit/jit.hpp"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 
 #include "vm/jit/ir/icmd.hpp"
 
index fb1c7dab4257200616c26fb74a2cea9e74f78ba3..2ee4248bcbef82427b38bbbc67be28ee6f72740d 100644 (file)
@@ -47,7 +47,7 @@ typedef struct exception_entry exception_entry;
 
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/reg.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/stack.h"
 #include "vm/jit/stacktrace.hpp"
 
index 62b9a178201c4cf243efe3f16ccee0a71b5deb2e..960d33fec6fc6e5ac2ab0c84011bd062e72e44c4 100644 (file)
@@ -59,7 +59,7 @@
 #include "vm/jit/abi.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/reg.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
index 8ef9892d15079ada4b9aa7851c819633a0871825..04aa489949dfce6487605658ccc51fc299a567d3 100644 (file)
@@ -57,7 +57,7 @@
 #include "vm/jit/linenumbertable.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/reg.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/trap.h"
 
 #if defined(ENABLE_LSRA)
index a5d0ffd03e0b78c6b8d35598c6853ce7be21e706..e1f2c2652ea0d341d95454dc340352e60eaa4071 100644 (file)
@@ -46,7 +46,7 @@
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.hpp"
 #include "vm/jit/patcher-common.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/trap.h"
 
 
index 8b22847c676c947551a2e08ec61866b010718207..c22682d8081395fa0ce3cc3d4b9211045df91a53 100644 (file)
@@ -62,7 +62,7 @@
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/reg.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
index 21f03e35a90d3de28743ae77128684a86c96eb1c..2ef0d7d1c6133cb654eb395c9e8f1cc5aa415786 100644 (file)
@@ -46,7 +46,7 @@
 #include "vm/jit/dseg.h"
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.hpp"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/trace.hpp"
 #include "vm/jit/trap.h"
 
index 211082c893ccd62db28cbc5eabb162e2c00ed053..97606fb885b674453009dba772fce929db72c0de 100644 (file)
@@ -62,7 +62,7 @@
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/reg.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
diff --git a/src/vm/jit/replace.c b/src/vm/jit/replace.c
deleted file mode 100644 (file)
index 8708e32..0000000
+++ /dev/null
@@ -1,3609 +0,0 @@
-/* src/vm/jit/replace.c - on-stack replacement of methods
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-#include "config.h"
-#include "vm/types.h"
-
-#include <assert.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "arch.h"
-#include "md.h"
-
-#if defined(ENABLE_GC_CACAO)
-# include "mm/cacao-gc/gc.h"
-#endif
-
-#include "mm/memory.h"
-
-#include "threads/thread.hpp"
-
-#include "toolbox/logging.h"
-
-#include "vm/classcache.h"
-#include "vm/globals.hpp"
-#include "vm/options.h"
-#include "vm/string.hpp"
-
-#if defined(ENABLE_RT_TIMING)
-# include "vm/rt-timing.h"
-#endif
-
-#include "vm/jit/abi.h"
-#include "vm/jit/asmpart.h"
-#include "vm/jit/disass.h"
-#include "vm/jit/executionstate.h"
-#include "vm/jit/jit.hpp"
-#include "vm/jit/methodheader.h"
-#include "vm/jit/replace.h"
-#include "vm/jit/show.h"
-#include "vm/jit/stack.h"
-
-
-#define REPLACE_PATCH_DYNAMIC_CALL
-/*#define REPLACE_PATCH_ALL*/
-
-#if defined(ENABLE_VMLOG)
-#include <vmlog_cacao.h>
-#endif
-
-/*** architecture-dependent configuration *************************************/
-
-/* first unset the macros (default) */
-#undef REPLACE_RA_BETWEEN_FRAMES
-#undef REPLACE_RA_TOP_OF_FRAME
-#undef REPLACE_RA_LINKAGE_AREA
-#undef REPLACE_LEAFMETHODS_RA_REGISTER
-
-/* i386, x86_64 and m68k */
-#if defined(__I386__) || defined(__X86_64__) || defined(__M68K__)
-#define REPLACE_RA_BETWEEN_FRAMES
-/* alpha */
-#elif defined(__ALPHA__)
-#define REPLACE_RA_TOP_OF_FRAME
-#define REPLACE_LEAFMETHODS_RA_REGISTER
-/* powerpc */
-#elif defined(__POWERPC__)
-#define REPLACE_RA_LINKAGE_AREA
-#define REPLACE_LEAFMETHODS_RA_REGISTER
-/* s390 */
-#elif defined(__S390__)
-#define REPLACE_RA_TOP_OF_FRAME
-#endif
-
-
-/*** configuration of native stack slot size **********************************/
-
-/* XXX this should be in md-abi.h files, probably */
-
-#if defined(HAS_4BYTE_STACKSLOT)
-#define SIZE_OF_STACKSLOT      4
-#define STACK_SLOTS_PER_FLOAT  2
-typedef u4 stackslot_t;
-#else
-#define SIZE_OF_STACKSLOT      8
-#define STACK_SLOTS_PER_FLOAT  1
-typedef u8 stackslot_t;
-#endif
-
-
-/*** debugging ****************************************************************/
-
-#if !defined(NDEBUG)
-static void java_value_print(s4 type, replace_val_t value);
-static void replace_stackframeinfo_println(stackframeinfo_t *sfi);
-#endif
-
-#if !defined(NDEBUG)
-#define DOLOG(code)        do{ if (opt_TraceReplacement > 1) { code; } } while(0)
-#define DOLOG_SHORT(code)  do{ if (opt_TraceReplacement > 0) { code; } } while(0)
-#else
-#define DOLOG(code)
-#define DOLOG_SHORT(code)
-#endif
-
-
-/*** statistics ***************************************************************/
-
-#define REPLACE_STATISTICS
-
-#if defined(REPLACE_STATISTICS)
-
-static int stat_replacements = 0;
-static int stat_frames = 0;
-static int stat_recompile = 0;
-static int stat_staticpatch = 0;
-static int stat_unroll_inline = 0;
-static int stat_unroll_call = 0;
-static int stat_dist_frames[20] = { 0 };
-static int stat_dist_locals[20] = { 0 };
-static int stat_dist_locals_adr[10] = { 0 };
-static int stat_dist_locals_prim[10] = { 0 };
-static int stat_dist_locals_ret[10] = { 0 };
-static int stat_dist_locals_void[10] = { 0 };
-static int stat_dist_stack[10] = { 0 };
-static int stat_dist_stack_adr[10] = { 0 };
-static int stat_dist_stack_prim[10] = { 0 };
-static int stat_dist_stack_ret[10] = { 0 };
-static int stat_methods = 0;
-static int stat_rploints = 0;
-static int stat_regallocs = 0;
-static int stat_dist_method_rplpoints[20] = { 0 };
-
-#define REPLACE_COUNT(cnt)  (cnt)++
-#define REPLACE_COUNT_IF(cnt, cond)  do{ if(cond) (cnt)++; } while(0)
-#define REPLACE_COUNT_INC(cnt, inc)  ((cnt) += (inc))
-
-#define REPLACE_COUNT_DIST(array, val)                               \
-    do {                                                             \
-        int limit = (sizeof(array) / sizeof(int)) - 1;               \
-        if ((val) < (limit)) (array)[val]++;                         \
-        else (array)[limit]++;                                       \
-    } while (0)
-
-static void replace_statistics_source_frame(sourceframe_t *frame);
-
-#else
-
-#define REPLACE_COUNT(cnt)
-#define REPLACE_COUNT_IF(cnt, cond)
-#define REPLACE_COUNT_INC(cnt, inc)
-#define REPLACE_COUNT_DIST(array, val)
-
-#endif /* defined(REPLACE_STATISTICS) */
-
-
-/*** constants used internally ************************************************/
-
-#define TOP_IS_NORMAL    0
-#define TOP_IS_ON_STACK  1
-#define TOP_IS_IN_ITMP1  2
-#define TOP_IS_VOID      3
-
-
-/******************************************************************************/
-/* PART I: Creating / freeing replacement points                              */
-/******************************************************************************/
-
-
-/* replace_create_replacement_point ********************************************
-   Create a replacement point.
-  
-   IN:
-       jd...............current jitdata
-          iinfo............inlining info for the current position
-          rp...............pre-allocated (uninitialized) rplpoint
-          type.............RPLPOINT_TYPE constant
-          iptr.............current instruction
-          *pra.............current rplalloc pointer
-          javalocals.......the javalocals at the current point
-          stackvars........the stack variables at the current point
-          stackdepth.......the stack depth at the current point
-          paramcount.......number of parameters at the start of stackvars
-  
-   OUT:
-       *rpa.............points to the next free rplalloc
-  
-*******************************************************************************/
-
-static void replace_create_replacement_point(jitdata *jd,
-                                                                                        insinfo_inline *iinfo,
-                                                                                        rplpoint *rp,
-                                                                                        s4 type,
-                                                                                        instruction *iptr,
-                                                                                        rplalloc **pra,
-                                                                                        s4 *javalocals,
-                                                                                        s4 *stackvars,
-                                                                                        s4 stackdepth,
-                                                                                        s4 paramcount)
-{
-       rplalloc *ra;
-       s4        i;
-       varinfo  *v;
-       s4        index;
-
-       ra = *pra;
-
-       REPLACE_COUNT(stat_rploints);
-
-       rp->method = (iinfo) ? iinfo->method : jd->m;
-       rp->pc = NULL;        /* set by codegen */
-       rp->callsize = 0;     /* set by codegen */
-       rp->regalloc = ra;
-       rp->flags = 0;
-       rp->type = type;
-       rp->id = iptr->flags.bits >> INS_FLAG_ID_SHIFT;
-
-       /* XXX unify these two fields */
-       rp->parent = (iinfo) ? iinfo->rp : NULL;
-
-       /* store local allocation info of javalocals */
-
-       if (javalocals) {
-               for (i = 0; i < rp->method->maxlocals; ++i) {
-                       index = javalocals[i];
-                       if (index == UNUSED)
-                               continue;
-
-                       ra->index = i;
-                       if (index >= 0) {
-                               v = VAR(index);
-                               ra->flags = v->flags & (INMEMORY);
-                               ra->regoff = v->vv.regoff;
-                               ra->type = v->type;
-                       }
-                       else {
-                               ra->regoff = RETADDR_FROM_JAVALOCAL(index);
-                               ra->type = TYPE_RET;
-                               ra->flags = 0;
-                       }
-                       ra++;
-               }
-       }
-
-       /* store allocation info of java stack vars */
-
-       for (i = 0; i < stackdepth; ++i) {
-               v = VAR(stackvars[i]);
-               ra->flags = v->flags & (INMEMORY);
-               ra->index = (i < paramcount) ? RPLALLOC_PARAM : RPLALLOC_STACK;
-               ra->type  = v->type;
-               /* XXX how to handle locals on the stack containing returnAddresses? */
-               if (v->type == TYPE_RET) {
-                       assert(stackvars[i] >= jd->localcount);
-                       ra->regoff = v->vv.retaddr->nr;
-               }
-               else
-                       ra->regoff = v->vv.regoff;
-               ra++;
-       }
-
-       /* total number of allocations */
-
-       rp->regalloccount = ra - rp->regalloc;
-
-       *pra = ra;
-}
-
-
-/* replace_create_inline_start_replacement_point *******************************
-
-   Create an INLINE_START replacement point.
-
-   IN:
-       jd...............current jitdata
-          rp...............pre-allocated (uninitialized) rplpoint
-          iptr.............current instruction
-          *pra.............current rplalloc pointer
-          javalocals.......the javalocals at the current point
-
-   OUT:
-       *rpa.............points to the next free rplalloc
-
-   RETURN VALUE:
-       the insinfo_inline * for the following inlined body
-
-*******************************************************************************/
-
-static insinfo_inline * replace_create_inline_start_replacement_point(
-                                                                                        jitdata *jd,
-                                                                                        rplpoint *rp,
-                                                                                        instruction *iptr,
-                                                                                        rplalloc **pra,
-                                                                                        s4 *javalocals)
-{
-       insinfo_inline *calleeinfo;
-       rplalloc       *ra;
-
-       calleeinfo = iptr->sx.s23.s3.inlineinfo;
-
-       calleeinfo->rp = rp;
-
-       replace_create_replacement_point(jd, calleeinfo->parent, rp,
-                       RPLPOINT_TYPE_INLINE, iptr, pra,
-                       javalocals,
-                       calleeinfo->stackvars, calleeinfo->stackvarscount,
-                       calleeinfo->paramcount);
-
-       if (calleeinfo->synclocal != UNUSED) {
-               ra = (*pra)++;
-               ra->index  = RPLALLOC_SYNC;
-               ra->regoff = jd->var[calleeinfo->synclocal].vv.regoff;
-               ra->flags  = jd->var[calleeinfo->synclocal].flags & INMEMORY;
-               ra->type   = TYPE_ADR;
-
-               rp->regalloccount++;
-       }
-
-       return calleeinfo;
-}
-
-
-/* replace_create_replacement_points *******************************************
-   Create the replacement points for the given code.
-  
-   IN:
-       jd...............current jitdata, must not have any replacement points
-  
-   OUT:
-       code->rplpoints.......set to the list of replacement points
-          code->rplpointcount...number of replacement points
-          code->regalloc........list of allocation info
-          code->regalloccount...total length of allocation info list
-          code->globalcount.....number of global allocations at the
-                                start of code->regalloc
-  
-   RETURN VALUE:
-       true.............everything ok 
-       false............an exception has been thrown
-   
-*******************************************************************************/
-
-#define CLEAR_javalocals(array, method)                              \
-    do {                                                             \
-        for (i=0; i<(method)->maxlocals; ++i)                        \
-            (array)[i] = UNUSED;                                     \
-    } while (0)
-
-#define COPY_OR_CLEAR_javalocals(dest, array, method)                \
-    do {                                                             \
-        if ((array) != NULL)                                         \
-            MCOPY((dest), (array), s4, (method)->maxlocals);         \
-        else                                                         \
-            CLEAR_javalocals((dest), (method));                      \
-    } while (0)
-
-#define COUNT_javalocals(array, method, counter)                     \
-    do {                                                             \
-        for (i=0; i<(method)->maxlocals; ++i)                        \
-            if ((array)[i] != UNUSED)                                \
-                               (counter)++;                                         \
-    } while (0)
-
-bool replace_create_replacement_points(jitdata *jd)
-{
-       codeinfo        *code;
-       registerdata    *rd;
-       basicblock      *bptr;
-       int              count;
-       methodinfo      *m;
-       rplpoint        *rplpoints;
-       rplpoint        *rp;
-       int              alloccount;
-       rplalloc        *regalloc;
-       rplalloc        *ra;
-       int              i;
-       instruction     *iptr;
-       instruction     *iend;
-       s4              *javalocals;
-       s4              *jl;
-       methoddesc      *md;
-       insinfo_inline  *iinfo;
-       s4               startcount;
-       s4               firstcount;
-#if defined(REPLACE_PATCH_DYNAMIC_CALL)
-       bool             needentry;
-#endif
-
-       REPLACE_COUNT(stat_methods);
-
-       /* get required compiler data */
-
-       code = jd->code;
-       rd   = jd->rd;
-
-       /* assert that we wont overwrite already allocated data */
-
-       assert(code);
-       assert(code->m);
-       assert(code->rplpoints == NULL);
-       assert(code->rplpointcount == 0);
-       assert(code->regalloc == NULL);
-       assert(code->regalloccount == 0);
-       assert(code->globalcount == 0);
-
-       m = code->m;
-
-       /* in instance methods, we may need a rplpoint at the method entry */
-
-#if defined(REPLACE_PATCH_DYNAMIC_CALL)
-       if (!(m->flags & ACC_STATIC)) {
-               jd->basicblocks[0].bitflags |= BBFLAG_REPLACEMENT;
-               needentry = true;
-       }
-       else {
-               needentry = false;
-       }
-#endif /* defined(REPLACE_PATCH_DYNAMIC_CALL) */
-
-       /* iterate over the basic block list to find replacement points */
-
-       count = 0;
-       alloccount = 0;
-
-       javalocals = DMNEW(s4, jd->maxlocals);
-
-       for (bptr = jd->basicblocks; bptr; bptr = bptr->next) {
-
-               /* skip dead code */
-
-               if (bptr->flags < BBFINISHED)
-                       continue;
-
-               /* get info about this block */
-
-               m = bptr->method;
-               iinfo = bptr->inlineinfo;
-
-               /* initialize javalocals at the start of this block */
-
-               COPY_OR_CLEAR_javalocals(javalocals, bptr->javalocals, m);
-
-               /* iterate over the instructions */
-
-               iptr = bptr->iinstr;
-               iend = iptr + bptr->icount;
-               startcount = count;
-               firstcount = count;
-
-               for (; iptr != iend; ++iptr) {
-                       switch (iptr->opc) {
-#if defined(ENABLE_GC_CACAO)
-                               case ICMD_BUILTIN:
-                                       md = iptr->sx.s23.s3.bte->md;
-                                       count++;
-                                       COUNT_javalocals(javalocals, m, alloccount);
-                                       alloccount += iptr->s1.argcount;
-                                       if (iinfo)
-                                               alloccount -= iinfo->throughcount;
-                                       break;
-#endif
-
-                               case ICMD_INVOKESTATIC:
-                               case ICMD_INVOKESPECIAL:
-                               case ICMD_INVOKEVIRTUAL:
-                               case ICMD_INVOKEINTERFACE:
-                                       INSTRUCTION_GET_METHODDESC(iptr, md);
-                                       count++;
-                                       COUNT_javalocals(javalocals, m, alloccount);
-                                       alloccount += iptr->s1.argcount;
-                                       if (iinfo)
-                                               alloccount -= iinfo->throughcount;
-                                       break;
-
-                               case ICMD_ISTORE:
-                               case ICMD_LSTORE:
-                               case ICMD_FSTORE:
-                               case ICMD_DSTORE:
-                               case ICMD_ASTORE:
-                                       stack_javalocals_store(iptr, javalocals);
-                                       break;
-
-                               case ICMD_IRETURN:
-                               case ICMD_LRETURN:
-                               case ICMD_FRETURN:
-                               case ICMD_DRETURN:
-                               case ICMD_ARETURN:
-                                       alloccount += 1;
-                                       /* FALLTHROUGH! */
-                               case ICMD_RETURN:
-                                       count++;
-                                       break;
-
-                               case ICMD_INLINE_START:
-                                       iinfo = iptr->sx.s23.s3.inlineinfo;
-
-                                       count++;
-                                       COUNT_javalocals(javalocals, m, alloccount);
-                                       alloccount += iinfo->stackvarscount;
-                                       if (iinfo->synclocal != UNUSED)
-                                               alloccount++;
-
-                                       m = iinfo->method;
-                                       /* javalocals may be set at next block start, or now */
-                                       COPY_OR_CLEAR_javalocals(javalocals, iinfo->javalocals_start, m);
-                                       break;
-
-                               case ICMD_INLINE_BODY:
-                                       assert(iinfo == iptr->sx.s23.s3.inlineinfo);
-
-                                       jl = iinfo->javalocals_start;
-                                       if (jl == NULL) {
-                                               /* get the javalocals from the following block start */
-                                               assert(bptr->next);
-                                               jl = bptr->next->javalocals;
-                                       }
-                                       count++;
-                                       COUNT_javalocals(jl, m, alloccount);
-                                       break;
-
-                               case ICMD_INLINE_END:
-                                       assert(iinfo == iptr->sx.s23.s3.inlineinfo ||
-                                                  iinfo == iptr->sx.s23.s3.inlineinfo->parent);
-                                       iinfo = iptr->sx.s23.s3.inlineinfo;
-                                       m = iinfo->outer;
-                                       if (iinfo->javalocals_end)
-                                               MCOPY(javalocals, iinfo->javalocals_end, s4, m->maxlocals);
-                                       iinfo = iinfo->parent;
-                                       break;
-                       }
-
-                       if (iptr == bptr->iinstr)
-                               firstcount = count;
-               } /* end instruction loop */
-
-               /* create replacement points at targets of backward branches */
-               /* We only need the replacement point there, if there is no  */
-               /* replacement point inside the block.                       */
-
-               if (bptr->bitflags & BBFLAG_REPLACEMENT) {
-#if defined(REPLACE_PATCH_DYNAMIC_CALL)
-                       int test = (needentry && bptr == jd->basicblocks) ? firstcount : count;
-#else
-                       int test = count;
-#endif
-                       if (test > startcount) {
-                               /* we don't need an extra rplpoint */
-                               bptr->bitflags &= ~BBFLAG_REPLACEMENT;
-                       }
-                       else {
-                               count++;
-                               alloccount += bptr->indepth;
-                               if (bptr->inlineinfo)
-                                       alloccount -= bptr->inlineinfo->throughcount;
-
-                               COUNT_javalocals(bptr->javalocals, bptr->method, alloccount);
-                       }
-               }
-
-       } /* end basicblock loop */
-
-       /* if no points were found, there's nothing to do */
-
-       if (!count)
-               return true;
-
-       /* allocate replacement point array and allocation array */
-
-       rplpoints = MNEW(rplpoint, count);
-       regalloc = MNEW(rplalloc, alloccount);
-       ra = regalloc;
-
-       /* initialize replacement point structs */
-
-       rp = rplpoints;
-
-       /* XXX try to share code with the counting loop! */
-
-       for (bptr = jd->basicblocks; bptr; bptr = bptr->next) {
-               /* skip dead code */
-
-               if (bptr->flags < BBFINISHED)
-                       continue;
-
-               /* get info about this block */
-
-               m = bptr->method;
-               iinfo = bptr->inlineinfo;
-
-               /* initialize javalocals at the start of this block */
-
-               COPY_OR_CLEAR_javalocals(javalocals, bptr->javalocals, m);
-
-               /* create replacement points at targets of backward branches */
-
-               if (bptr->bitflags & BBFLAG_REPLACEMENT) {
-
-                       i = (iinfo) ? iinfo->throughcount : 0;
-                       replace_create_replacement_point(jd, iinfo, rp++,
-                                       bptr->type, bptr->iinstr, &ra,
-                                       bptr->javalocals, bptr->invars + i, bptr->indepth - i, 0);
-
-                       if (JITDATA_HAS_FLAG_COUNTDOWN(jd))
-                               rp[-1].flags |= RPLPOINT_FLAG_COUNTDOWN;
-               }
-
-               /* iterate over the instructions */
-
-               iptr = bptr->iinstr;
-               iend = iptr + bptr->icount;
-
-               for (; iptr != iend; ++iptr) {
-                       switch (iptr->opc) {
-#if defined(ENABLE_GC_CACAO)
-                               case ICMD_BUILTIN:
-                                       md = iptr->sx.s23.s3.bte->md;
-
-                                       i = (iinfo) ? iinfo->throughcount : 0;
-                                       replace_create_replacement_point(jd, iinfo, rp++,
-                                                       RPLPOINT_TYPE_CALL, iptr, &ra,
-                                                       javalocals, iptr->sx.s23.s2.args,
-                                                       iptr->s1.argcount - i,
-                                                       md->paramcount);
-                                       break;
-#endif
-
-                               case ICMD_INVOKESTATIC:
-                               case ICMD_INVOKESPECIAL:
-                               case ICMD_INVOKEVIRTUAL:
-                               case ICMD_INVOKEINTERFACE:
-                                       INSTRUCTION_GET_METHODDESC(iptr, md);
-
-                                       i = (iinfo) ? iinfo->throughcount : 0;
-                                       replace_create_replacement_point(jd, iinfo, rp++,
-                                                       RPLPOINT_TYPE_CALL, iptr, &ra,
-                                                       javalocals, iptr->sx.s23.s2.args,
-                                                       iptr->s1.argcount - i,
-                                                       md->paramcount);
-                                       break;
-
-                               case ICMD_ISTORE:
-                               case ICMD_LSTORE:
-                               case ICMD_FSTORE:
-                               case ICMD_DSTORE:
-                               case ICMD_ASTORE:
-                                       stack_javalocals_store(iptr, javalocals);
-                                       break;
-
-                               case ICMD_IRETURN:
-                               case ICMD_LRETURN:
-                               case ICMD_FRETURN:
-                               case ICMD_DRETURN:
-                               case ICMD_ARETURN:
-                                       replace_create_replacement_point(jd, iinfo, rp++,
-                                                       RPLPOINT_TYPE_RETURN, iptr, &ra,
-                                                       NULL, &(iptr->s1.varindex), 1, 0);
-                                       break;
-
-                               case ICMD_RETURN:
-                                       replace_create_replacement_point(jd, iinfo, rp++,
-                                                       RPLPOINT_TYPE_RETURN, iptr, &ra,
-                                                       NULL, NULL, 0, 0);
-                                       break;
-
-                               case ICMD_INLINE_START:
-                                       iinfo = replace_create_inline_start_replacement_point(
-                                                               jd, rp++, iptr, &ra, javalocals);
-                                       m = iinfo->method;
-                                       /* javalocals may be set at next block start, or now */
-                                       COPY_OR_CLEAR_javalocals(javalocals, iinfo->javalocals_start, m);
-                                       break;
-
-                               case ICMD_INLINE_BODY:
-                                       assert(iinfo == iptr->sx.s23.s3.inlineinfo);
-
-                                       jl = iinfo->javalocals_start;
-                                       if (jl == NULL) {
-                                               /* get the javalocals from the following block start */
-                                               assert(bptr->next);
-                                               jl = bptr->next->javalocals;
-                                       }
-                                       /* create a non-trappable rplpoint */
-                                       replace_create_replacement_point(jd, iinfo, rp++,
-                                                       RPLPOINT_TYPE_BODY, iptr, &ra,
-                                                       jl, NULL, 0, 0);
-                                       rp[-1].flags |= RPLPOINT_FLAG_NOTRAP;
-                                       break;
-
-                               case ICMD_INLINE_END:
-                                       assert(iinfo == iptr->sx.s23.s3.inlineinfo ||
-                                                  iinfo == iptr->sx.s23.s3.inlineinfo->parent);
-                                       iinfo = iptr->sx.s23.s3.inlineinfo;
-                                       m = iinfo->outer;
-                                       if (iinfo->javalocals_end)
-                                               MCOPY(javalocals, iinfo->javalocals_end, s4, m->maxlocals);
-                                       iinfo = iinfo->parent;
-                                       break;
-                       }
-               } /* end instruction loop */
-       } /* end basicblock loop */
-
-       assert((rp - rplpoints) == count);
-       assert((ra - regalloc) == alloccount);
-
-       /* store the data in the codeinfo */
-
-       code->rplpoints     = rplpoints;
-       code->rplpointcount = count;
-       code->regalloc      = regalloc;
-       code->regalloccount = alloccount;
-       code->globalcount   = 0;
-       code->savedintcount = INT_SAV_CNT - rd->savintreguse;
-       code->savedfltcount = FLT_SAV_CNT - rd->savfltreguse;
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-       code->savedadrcount = ADR_SAV_CNT - rd->savadrreguse;
-#endif
-       code->memuse        = rd->memuse;
-       code->stackframesize = jd->cd->stackframesize;
-
-       REPLACE_COUNT_DIST(stat_dist_method_rplpoints, count);
-       REPLACE_COUNT_INC(stat_regallocs, alloccount);
-
-       /* everything alright */
-
-       return true;
-}
-
-
-/* replace_free_replacement_points *********************************************
-   Free memory used by replacement points.
-  
-   IN:
-       code.............codeinfo whose replacement points should be freed.
-  
-*******************************************************************************/
-
-void replace_free_replacement_points(codeinfo *code)
-{
-       assert(code);
-
-       if (code->rplpoints)
-               MFREE(code->rplpoints,rplpoint,code->rplpointcount);
-
-       if (code->regalloc)
-               MFREE(code->regalloc,rplalloc,code->regalloccount);
-
-       code->rplpoints = NULL;
-       code->rplpointcount = 0;
-       code->regalloc = NULL;
-       code->regalloccount = 0;
-       code->globalcount = 0;
-}
-
-
-/******************************************************************************/
-/* PART II: Activating / deactivating replacement points                      */
-/******************************************************************************/
-
-
-/* replace_activate_replacement_points *****************************************
-   Activate the replacement points of the given compilation unit. When this
-   function returns, the replacement points are "armed", so each thread
-   reaching one of the points will enter the replacement mechanism.
-   
-   IN:
-       code.............codeinfo of which replacement points should be
-                                               activated
-          mappable.........if true, only mappable replacement points are
-                                               activated
-  
-*******************************************************************************/
-
-void replace_activate_replacement_points(codeinfo *code, bool mappable)
-{
-       rplpoint *rp;
-       s4        i;
-       s4        count;
-       u1       *savedmcode;
-
-       assert(code->savedmcode == NULL);
-
-       /* count trappable replacement points */
-
-       count = 0;
-       i = code->rplpointcount;
-       rp = code->rplpoints;
-       for (; i--; rp++) {
-               if (rp->flags & RPLPOINT_FLAG_NOTRAP)
-                       continue;
-
-               if (mappable && (rp->type == RPLPOINT_TYPE_RETURN))
-                       continue;
-
-               count++;
-       }
-
-       /* allocate buffer for saved machine code */
-
-       savedmcode = MNEW(u1, count * REPLACEMENT_PATCH_SIZE);
-       code->savedmcode = savedmcode;
-       savedmcode += count * REPLACEMENT_PATCH_SIZE;
-
-       /* activate trappable replacement points */
-       /* (in reverse order to handle overlapping points within basic blocks) */
-
-       i = code->rplpointcount;
-       rp = code->rplpoints + i;
-       while (rp--, i--) {
-               assert(!(rp->flags & RPLPOINT_FLAG_ACTIVE));
-
-               if (rp->flags & RPLPOINT_FLAG_NOTRAP)
-                       continue;
-
-               if (mappable && (rp->type == RPLPOINT_TYPE_RETURN))
-                       continue;
-
-               DOLOG( printf("activate replacement point:\n");
-                          replace_replacement_point_println(rp, 1); fflush(stdout); );
-
-               savedmcode -= REPLACEMENT_PATCH_SIZE;
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_DISASSEMBLER)
-               DOLOG( printf("\tinstruction before: ");
-                          disassinstr(rp->pc); fflush(stdout); );
-# endif
-
-               md_patch_replacement_point(rp->pc, savedmcode, false);
-
-# if defined(ENABLE_DISASSEMBLER)
-               DOLOG( printf("\tinstruction after : ");
-                          disassinstr(rp->pc); fflush(stdout); );
-# endif
-#endif
-
-               rp->flags |= RPLPOINT_FLAG_ACTIVE;
-       }
-
-       assert(savedmcode == code->savedmcode);
-}
-
-
-/* replace_deactivate_replacement_points ***************************************
-   Deactivate a replacement points in the given compilation unit.
-   When this function returns, the replacement points will be "un-armed",
-   that is a each thread reaching a point will just continue normally.
-   
-   IN:
-       code.............the compilation unit
-  
-*******************************************************************************/
-
-void replace_deactivate_replacement_points(codeinfo *code)
-{
-       rplpoint *rp;
-       s4        i;
-       s4        count;
-       u1       *savedmcode;
-
-       if (code->savedmcode == NULL) {
-               /* disarm countdown points by patching the branches */
-
-               i = code->rplpointcount;
-               rp = code->rplpoints;
-               for (; i--; rp++) {
-                       if ((rp->flags & (RPLPOINT_FLAG_ACTIVE | RPLPOINT_FLAG_COUNTDOWN))
-                                       == RPLPOINT_FLAG_COUNTDOWN)
-                       {
-#if 0
-                               *(s4*) (rp->pc + 9) = 0; /* XXX machine dependent! */
-#endif
-                       }
-               }
-               return;
-       }
-
-       assert(code->savedmcode != NULL);
-       savedmcode = code->savedmcode;
-
-       /* de-activate each trappable replacement point */
-
-       i = code->rplpointcount;
-       rp = code->rplpoints;
-       count = 0;
-       for (; i--; rp++) {
-               if (!(rp->flags & RPLPOINT_FLAG_ACTIVE))
-                       continue;
-
-               count++;
-
-               DOLOG( printf("deactivate replacement point:\n");
-                          replace_replacement_point_println(rp, 1); fflush(stdout); );
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_DISASSEMBLER)
-               DOLOG( printf("\tinstruction before: ");
-                          disassinstr(rp->pc); fflush(stdout); );
-# endif
-
-               md_patch_replacement_point(rp->pc, savedmcode, true);
-
-# if defined(ENABLE_DISASSEMBLER)
-               DOLOG( printf("\tinstruction before: ");
-                          disassinstr(rp->pc); fflush(stdout); );
-# endif
-#endif
-
-               rp->flags &= ~RPLPOINT_FLAG_ACTIVE;
-
-               savedmcode += REPLACEMENT_PATCH_SIZE;
-       }
-
-       assert(savedmcode == code->savedmcode + count * REPLACEMENT_PATCH_SIZE);
-
-       /* free saved machine code */
-
-       MFREE(code->savedmcode, u1, count * REPLACEMENT_PATCH_SIZE);
-       code->savedmcode = NULL;
-}
-
-
-/******************************************************************************/
-/* PART III: The replacement mechanism                                        */
-/******************************************************************************/
-
-
-/* replace_read_value **********************************************************
-
-   Read a value with the given allocation from the execution state.
-   
-   IN:
-          es...............execution state
-          ra...............allocation
-          javaval..........where to put the value
-
-   OUT:
-       *javaval.........the value
-  
-*******************************************************************************/
-
-static void replace_read_value(executionstate_t *es,
-                                                          rplalloc *ra,
-                                                          replace_val_t *javaval)
-{
-       if (ra->flags & INMEMORY) {
-               /* XXX HAS_4BYTE_STACKSLOT may not be the right discriminant here */
-#ifdef HAS_4BYTE_STACKSLOT
-               if (IS_2_WORD_TYPE(ra->type)) {
-                       javaval->l = *(u8*)(es->sp + ra->regoff);
-               }
-               else {
-#endif
-                       javaval->p = *(ptrint*)(es->sp + ra->regoff);
-#ifdef HAS_4BYTE_STACKSLOT
-               }
-#endif
-       }
-       else {
-               /* allocated register */
-               if (IS_FLT_DBL_TYPE(ra->type)) {
-                       javaval->d = es->fltregs[ra->regoff];
-
-                       if (ra->type == TYPE_FLT)
-                               javaval->f = javaval->d;
-               }
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-               else if (IS_ADR_TYPE(ra->type)) {
-                       javaval->p = es->adrregs[ra->regoff];
-               }
-#endif
-               else {
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                       if (ra->type == TYPE_LNG) {
-                               javaval->words.lo = es->intregs[GET_LOW_REG(ra->regoff)];
-                               javaval->words.hi = es->intregs[GET_HIGH_REG(ra->regoff)];
-                       }
-                       else
-#endif /* defined(SUPPORT_COMBINE_INTEGER_REGISTERS) */
-                               javaval->p = es->intregs[ra->regoff];
-               }
-       }
-}
-
-
-/* replace_write_value *********************************************************
-
-   Write a value to the given allocation in the execution state.
-   
-   IN:
-          es...............execution state
-          ra...............allocation
-          *javaval.........the value
-
-*******************************************************************************/
-
-static void replace_write_value(executionstate_t *es,
-                                                           rplalloc *ra,
-                                                           replace_val_t *javaval)
-{
-       if (ra->flags & INMEMORY) {
-               /* XXX HAS_4BYTE_STACKSLOT may not be the right discriminant here */
-#ifdef HAS_4BYTE_STACKSLOT
-               if (IS_2_WORD_TYPE(ra->type)) {
-                       *(u8*)(es->sp + ra->regoff) = javaval->l;
-               }
-               else {
-#endif
-                       *(ptrint*)(es->sp + ra->regoff) = javaval->p;
-#ifdef HAS_4BYTE_STACKSLOT
-               }
-#endif
-       }
-       else {
-               /* allocated register */
-               switch (ra->type) {
-                       case TYPE_FLT:
-                               es->fltregs[ra->regoff] = (double) javaval->f;
-                               break;
-                       case TYPE_DBL:
-                               es->fltregs[ra->regoff] = javaval->d;
-                               break;
-#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
-                       case TYPE_LNG:
-                               es->intregs[GET_LOW_REG(ra->regoff)] = javaval->words.lo;
-                               es->intregs[GET_HIGH_REG(ra->regoff)] = javaval->words.hi;
-                               break;
-#endif
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-                       case TYPE_ADR:
-                               es->adrregs[ra->regoff] = javaval->p;
-#endif
-                       default:
-                               es->intregs[ra->regoff] = javaval->p;
-               }
-       }
-}
-
-
-/* replace_new_sourceframe *****************************************************
-
-   Allocate a new source frame and insert it at the front of the frame list.
-   
-   IN:
-          ss...............the source state
-
-   OUT:
-          ss->frames.......set to new frame (the new head of the frame list).
-
-   RETURN VALUE:
-       returns the new frame
-
-*******************************************************************************/
-
-static sourceframe_t *replace_new_sourceframe(sourcestate_t *ss)
-{
-       sourceframe_t *frame;
-
-       frame = DNEW(sourceframe_t);
-       MZERO(frame, sourceframe_t, 1);
-
-       frame->down = ss->frames;
-       ss->frames = frame;
-
-       return frame;
-}
-
-
-/* replace_read_executionstate *************************************************
-
-   Read a source frame from the given executions state.
-   The new source frame is pushed to the front of the frame list of the
-   source state.
-
-   IN:
-       rp...............replacement point at which `es` was taken
-          es...............execution state
-          ss...............the source state to add the source frame to
-          topframe.........true, if the first (top-most) source frame on the
-                           stack is to be read
-
-   OUT:
-       *ss..............the source state with the newly created source frame
-                           added
-  
-*******************************************************************************/
-
-static s4 replace_normalize_type_map[] = {
-/* RPLPOINT_TYPE_STD    |--> */ RPLPOINT_TYPE_STD,
-/* RPLPOINT_TYPE_EXH    |--> */ RPLPOINT_TYPE_STD,
-/* RPLPOINT_TYPE_SBR    |--> */ RPLPOINT_TYPE_STD,
-/* RPLPOINT_TYPE_CALL   |--> */ RPLPOINT_TYPE_CALL,
-/* RPLPOINT_TYPE_INLINE |--> */ RPLPOINT_TYPE_CALL,
-/* RPLPOINT_TYPE_RETURN |--> */ RPLPOINT_TYPE_RETURN,
-/* RPLPOINT_TYPE_BODY   |--> */ RPLPOINT_TYPE_STD
-};
-
-
-static void replace_read_executionstate(rplpoint *rp,
-                                                                               executionstate_t *es,
-                                                                               sourcestate_t *ss,
-                                                                               bool topframe)
-{
-       methodinfo    *m;
-       codeinfo      *code;
-       int            count;
-       int            i;
-       rplalloc      *ra;
-       sourceframe_t *frame;
-       int            topslot;
-       stackslot_t   *sp;
-       stackslot_t   *basesp;
-
-       code = code_find_codeinfo_for_pc(rp->pc);
-       m = rp->method;
-       topslot = TOP_IS_NORMAL;
-
-       /* stack pointer */
-
-       sp = (stackslot_t *) es->sp;
-
-       /* in some cases the top stack slot is passed in REG_ITMP1 */
-
-       if (rp->type == BBTYPE_EXH) {
-               topslot = TOP_IS_IN_ITMP1;
-       }
-
-       /* calculate base stack pointer */
-
-       basesp = sp + code->stackframesize;
-
-       /* create the source frame */
-
-       frame = replace_new_sourceframe(ss);
-       frame->method = rp->method;
-       frame->id = rp->id;
-       assert(rp->type >= 0 && rp->type < sizeof(replace_normalize_type_map)/sizeof(s4));
-       frame->type = replace_normalize_type_map[rp->type];
-       frame->fromrp = rp;
-       frame->fromcode = code;
-
-       /* read local variables */
-
-       count = m->maxlocals;
-       frame->javalocalcount = count;
-       frame->javalocals = DMNEW(replace_val_t, count);
-       frame->javalocaltype = DMNEW(u1, count);
-
-       /* mark values as undefined */
-       for (i=0; i<count; ++i) {
-#if !defined(NDEBUG)
-               frame->javalocals[i].l = (u8) 0x00dead0000dead00ULL;
-#endif
-               frame->javalocaltype[i] = TYPE_VOID;
-       }
-
-       /* some entries in the intregs array are not meaningful */
-       /*es->intregs[REG_ITMP3] = (u8) 0x11dead1111dead11ULL;*/
-#if !defined(NDEBUG)
-       es->intregs[REG_SP   ] = (ptrint) 0x11dead1111dead11ULL;
-#ifdef REG_PV
-       es->intregs[REG_PV   ] = (ptrint) 0x11dead1111dead11ULL;
-#endif
-#endif /* !defined(NDEBUG) */
-
-       /* read javalocals */
-
-       count = rp->regalloccount;
-       ra = rp->regalloc;
-
-       while (count && (i = ra->index) >= 0) {
-               assert(i < m->maxlocals);
-               frame->javalocaltype[i] = ra->type;
-               if (ra->type == TYPE_RET)
-                       frame->javalocals[i].i = ra->regoff;
-               else
-                       replace_read_value(es, ra, frame->javalocals + i);
-               ra++;
-               count--;
-       }
-
-       /* read instance, if this is the first rplpoint */
-
-#if defined(REPLACE_PATCH_DYNAMIC_CALL)
-       if (topframe && !(rp->method->flags & ACC_STATIC) && rp == code->rplpoints) {
-#if 1
-               /* we are at the start of the method body, so if local 0 is set, */
-               /* it is the instance.                                           */
-               if (frame->javalocaltype[0] == TYPE_ADR)
-                       frame->instance = frame->javalocals[0];
-#else
-               rplalloc instra;
-               methoddesc *md;
-
-               md = rp->method->parseddesc;
-               assert(md->params);
-               assert(md->paramcount >= 1);
-               instra.type = TYPE_ADR;
-               instra.regoff = md->params[0].regoff;
-               if (md->params[0].inmemory) {
-                       instra.flags = INMEMORY;
-                       instra.regoff += (1 + code->stackframesize) * SIZE_OF_STACKSLOT;
-               }
-               else {
-                       instra.flags = 0;
-               }
-               replace_read_value(es, &instra, &(frame->instance));
-#endif
-       }
-#if defined(__I386__)
-       else if (!(rp->method->flags & ACC_STATIC)) {
-               /* On i386 we always pass the first argument on stack. */
-               frame->instance.a = *(java_object_t **)(basesp + 1);
-       } 
-#endif
-#endif /* defined(REPLACE_PATCH_DYNAMIC_CALL) */
-
-       /* read stack slots */
-
-       frame->javastackdepth = count;
-       frame->javastack = DMNEW(replace_val_t, count);
-       frame->javastacktype = DMNEW(u1, count);
-
-#if !defined(NDEBUG)
-       /* mark values as undefined */
-       for (i=0; i<count; ++i) {
-               frame->javastack[i].l = (u8) 0x00dead0000dead00ULL;
-               frame->javastacktype[i] = TYPE_VOID;
-       }
-#endif /* !defined(NDEBUG) */
-
-       i = 0;
-
-       /* the first stack slot is special in SBR and EXH blocks */
-
-       if (topslot == TOP_IS_ON_STACK) {
-               assert(count);
-
-               assert(ra->index == RPLALLOC_STACK);
-               assert(ra->type == TYPE_ADR);
-               frame->javastack[i].p = sp[-1];
-               frame->javastacktype[i] = TYPE_ADR; /* XXX RET */
-               count--;
-               i++;
-               ra++;
-       }
-       else if (topslot == TOP_IS_IN_ITMP1) {
-               assert(count);
-
-               assert(ra->index == RPLALLOC_STACK);
-               assert(ra->type == TYPE_ADR);
-               frame->javastack[i].p = es->intregs[REG_ITMP1];
-               frame->javastacktype[i] = TYPE_ADR; /* XXX RET */
-               count--;
-               i++;
-               ra++;
-       }
-       else if (topslot == TOP_IS_VOID) {
-               assert(count);
-
-               assert(ra->index == RPLALLOC_STACK);
-               frame->javastack[i].l = 0;
-               frame->javastacktype[i] = TYPE_VOID;
-               count--;
-               i++;
-               ra++;
-       }
-
-       /* read remaining stack slots */
-
-       for (; count--; ra++) {
-               if (ra->index == RPLALLOC_SYNC) {
-                       assert(rp->type == RPLPOINT_TYPE_INLINE);
-
-                       /* only read synchronization slots when traversing an inline point */
-
-                       if (!topframe) {
-                               sourceframe_t *calleeframe = frame->down;
-                               assert(calleeframe);
-                               assert(calleeframe->syncslotcount == 0);
-                               assert(calleeframe->syncslots == NULL);
-
-                               calleeframe->syncslotcount = 1;
-                               calleeframe->syncslots = DMNEW(replace_val_t, 1);
-                               replace_read_value(es,ra,calleeframe->syncslots);
-                       }
-
-                       frame->javastackdepth--;
-                       continue;
-               }
-
-               assert(ra->index == RPLALLOC_STACK || ra->index == RPLALLOC_PARAM);
-
-               /* do not read parameters of calls down the call chain */
-
-               if (!topframe && ra->index == RPLALLOC_PARAM) {
-                       frame->javastackdepth--;
-               }
-               else {
-                       if (ra->type == TYPE_RET)
-                               frame->javastack[i].i = ra->regoff;
-                       else
-                               replace_read_value(es,ra,frame->javastack + i);
-                       frame->javastacktype[i] = ra->type;
-                       i++;
-               }
-       }
-}
-
-
-/* replace_write_executionstate ************************************************
-
-   Pop a source frame from the front of the frame list of the given source state
-   and write its values into the execution state.
-
-   IN:
-       rp...............replacement point for which execution state should be
-                           created
-          es...............the execution state to modify
-          ss...............the given source state
-          topframe.........true, if this is the last (top-most) source frame to be
-                           translated
-
-   OUT:
-       *es..............the execution state derived from the source state
-  
-*******************************************************************************/
-
-static void replace_write_executionstate(rplpoint *rp,
-                                                                                executionstate_t *es,
-                                                                                sourcestate_t *ss,
-                                                                                bool topframe)
-{
-       methodinfo     *m;
-       codeinfo       *code;
-       int             count;
-       int             i;
-       rplalloc       *ra;
-       sourceframe_t  *frame;
-       int             topslot;
-       stackslot_t    *sp;
-       stackslot_t    *basesp;
-
-       code = code_find_codeinfo_for_pc(rp->pc);
-       m = rp->method;
-       topslot = TOP_IS_NORMAL;
-
-       /* pop a source frame */
-
-       frame = ss->frames;
-       assert(frame);
-       ss->frames = frame->down;
-
-       /* calculate stack pointer */
-
-       sp = (stackslot_t *) es->sp;
-
-       basesp = sp + code->stackframesize;
-
-       /* in some cases the top stack slot is passed in REG_ITMP1 */
-
-       if (rp->type == BBTYPE_EXH) {
-               topslot = TOP_IS_IN_ITMP1;
-       }
-
-       /* write javalocals */
-
-       ra = rp->regalloc;
-       count = rp->regalloccount;
-
-       while (count && (i = ra->index) >= 0) {
-               assert(i < m->maxlocals);
-               assert(i < frame->javalocalcount);
-               assert(ra->type == frame->javalocaltype[i]);
-               if (ra->type == TYPE_RET) {
-                       /* XXX assert that it matches this rplpoint */
-               }
-               else
-                       replace_write_value(es, ra, frame->javalocals + i);
-               count--;
-               ra++;
-       }
-
-       /* write stack slots */
-
-       i = 0;
-
-       /* the first stack slot is special in SBR and EXH blocks */
-
-       if (topslot == TOP_IS_ON_STACK) {
-               assert(count);
-
-               assert(ra->index == RPLALLOC_STACK);
-               assert(i < frame->javastackdepth);
-               assert(frame->javastacktype[i] == TYPE_ADR);
-               sp[-1] = frame->javastack[i].p;
-               count--;
-               i++;
-               ra++;
-       }
-       else if (topslot == TOP_IS_IN_ITMP1) {
-               assert(count);
-
-               assert(ra->index == RPLALLOC_STACK);
-               assert(i < frame->javastackdepth);
-               assert(frame->javastacktype[i] == TYPE_ADR);
-               es->intregs[REG_ITMP1] = frame->javastack[i].p;
-               count--;
-               i++;
-               ra++;
-       }
-       else if (topslot == TOP_IS_VOID) {
-               assert(count);
-
-               assert(ra->index == RPLALLOC_STACK);
-               assert(i < frame->javastackdepth);
-               assert(frame->javastacktype[i] == TYPE_VOID);
-               count--;
-               i++;
-               ra++;
-       }
-
-       /* write remaining stack slots */
-
-       for (; count--; ra++) {
-               if (ra->index == RPLALLOC_SYNC) {
-                       assert(rp->type == RPLPOINT_TYPE_INLINE);
-
-                       /* only write synchronization slots when traversing an inline point */
-
-                       if (!topframe) {
-                               assert(frame->down);
-                               assert(frame->down->syncslotcount == 1); /* XXX need to understand more cases */
-                               assert(frame->down->syncslots != NULL);
-
-                               replace_write_value(es,ra,frame->down->syncslots);
-                       }
-                       continue;
-               }
-
-               assert(ra->index == RPLALLOC_STACK || ra->index == RPLALLOC_PARAM);
-
-               /* do not write parameters of calls down the call chain */
-
-               if (!topframe && ra->index == RPLALLOC_PARAM) {
-                       /* skip it */
-                       /*
-                       ra->index = RPLALLOC_PARAM;
-                       replace_val_t v;
-                       v.l = 0;
-                       replace_write_value(es,ra,&v);
-                       */
-               }
-               else {
-                       assert(i < frame->javastackdepth);
-                       assert(ra->type == frame->javastacktype[i]);
-                       if (ra->type == TYPE_RET) {
-                               /* XXX assert that it matches this rplpoint */
-                       }
-                       else {
-                               replace_write_value(es,ra,frame->javastack + i);
-                       }
-                       i++;
-               }
-       }
-
-       /* set new pc */
-
-       es->pc = rp->pc;
-}
-
-
-/* md_pop_stackframe ***********************************************************
-
-   Restore callee-saved registers (including the RA register),
-   set the stack pointer to the next stackframe,
-   set the PC to the return address of the popped frame.
-
-   *** This function imitates the effects of the method epilog ***
-   *** and returning from the method call.                     ***
-
-   IN:
-       es...............execution state
-
-   OUT:
-       *es..............the execution state after popping the stack frame
-                        NOTE: es->code and es->pv are NOT updated.
-
-*******************************************************************************/
-
-void md_pop_stackframe(executionstate_t *es)
-{
-       u1 *ra;
-       s4 ra_align_off;
-       s4 reg;
-       s4 i;
-       stackslot_t *basesp;
-       stackslot_t *sp;
-
-       assert(es->code);
-
-       /* alignment offset of RA */
-
-       ra_align_off = 0;
-#if defined(REPLACE_RA_BETWEEN_FRAMES)
-    if (es->code->stackframesize)
-               ra_align_off = SIZE_OF_STACKSLOT - SIZEOF_VOID_P;
-#endif
-
-       /* read the return address */
-
-#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
-       if (code_is_leafmethod(es->code))
-               ra = es->ra;
-       else
-#endif
-               ra = md_stacktrace_get_returnaddress(es->sp,
-                          SIZE_OF_STACKSLOT * es->code->stackframesize + ra_align_off);
-
-       /* calculate the base of the stack frame */
-
-       sp = (stackslot_t *) es->sp;
-       basesp = sp + es->code->stackframesize;
-
-       /* restore return address, if part of frame */
-
-#if defined(REPLACE_RA_TOP_OF_FRAME)
-#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
-       if (!code_is_leafmethod(es->code))
-#endif
-               es->ra = (u1*) (ptrint) *--basesp;
-#endif /* REPLACE_RA_TOP_OF_FRAME */
-
-#if defined(REPLACE_RA_LINKAGE_AREA)
-#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
-       if (!code_is_leafmethod(es->code))
-#endif
-               es->ra = (u1*) (ptrint) basesp[LA_LR_OFFSET / sizeof(stackslot_t)];
-#endif /* REPLACE_RA_LINKAGE_AREA */
-
-       /* restore saved int registers */
-
-       reg = INT_REG_CNT;
-       for (i=0; i<es->code->savedintcount; ++i) {
-               while (nregdescint[--reg] != REG_SAV)
-                       ;
-               es->intregs[reg] = *--basesp;
-       }
-
-       /* restore saved flt registers */
-
-       /* XXX align? */
-       reg = FLT_REG_CNT;
-       for (i=0; i<es->code->savedfltcount; ++i) {
-               while (nregdescfloat[--reg] != REG_SAV)
-                       ;
-               basesp -= STACK_SLOTS_PER_FLOAT;
-               es->fltregs[reg] = *(double*)basesp;
-       }
-
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-       /* restore saved adr registers */
-
-       reg = ADR_REG_CNT;
-       for (i=0; i<es->code->savedadrcount; ++i) {
-               while (nregdescadr[--reg] != REG_SAV)
-                       ;
-               es->adrregs[reg] = *--basesp;
-       }
-#endif
-
-       /* adjust the stackpointer */
-
-       es->sp += SIZE_OF_STACKSLOT * es->code->stackframesize;
-
-#if defined(REPLACE_RA_BETWEEN_FRAMES)
-       es->sp += ra_align_off + SIZEOF_VOID_P; /* skip return address */
-#endif
-
-       /* set the program counter to the return address */
-
-       es->pc = ra;
-
-       /* in debugging mode clobber non-saved registers */
-
-#if !defined(NDEBUG)
-       /* for debugging */
-       for (i=0; i<INT_REG_CNT; ++i)
-               if (nregdescint[i] != REG_SAV)
-                       es->intregs[i] = (ptrint) 0x33dead3333dead33ULL;
-       for (i=0; i<FLT_REG_CNT; ++i)
-               if (nregdescfloat[i] != REG_SAV)
-                       *(u8*)&(es->fltregs[i]) = 0x33dead3333dead33ULL;
-# if defined(HAS_ADDRESS_REGISTER_FILE)
-       for (i=0; i<ADR_REG_CNT; ++i)
-               if (nregdescadr[i] != REG_SAV)
-                       es->adrregs[i] = (ptrint) 0x33dead3333dead33ULL;
-# endif
-#endif /* !defined(NDEBUG) */
-}
-
-
-/* md_push_stackframe **********************************************************
-
-   Save the given return address, build the new stackframe,
-   and store callee-saved registers.
-
-   *** This function imitates the effects of a call and the ***
-   *** method prolog of the callee.                         ***
-
-   IN:
-       es...............execution state
-       calleecode.......the code we are "calling"
-       ra...............the return address to save
-
-   OUT:
-       *es..............the execution state after pushing the stack frame
-                        NOTE: es->pc, es->code, and es->pv are NOT updated.
-
-*******************************************************************************/
-
-void md_push_stackframe(executionstate_t *es, codeinfo *calleecode, u1 *ra)
-{
-       s4           reg;
-       s4           i;
-       stackslot_t *basesp;
-       stackslot_t *sp;
-
-       assert(es);
-       assert(calleecode);
-
-       /* write the return address */
-
-#if defined(REPLACE_RA_BETWEEN_FRAMES)
-       es->sp -= SIZEOF_VOID_P;
-       *((void **)es->sp) = (void *) ra;
-       if (calleecode->stackframesize)
-               es->sp -= (SIZE_OF_STACKSLOT - SIZEOF_VOID_P);
-#endif /* REPLACE_RA_BETWEEN_FRAMES */
-
-       es->ra = (u1*) (ptrint) ra;
-
-       /* build the stackframe */
-
-       DOLOG( printf("building stackframe of %d words at %p\n",
-                                 calleecode->stackframesize, (void*)es->sp); );
-
-       sp = (stackslot_t *) es->sp;
-       basesp = sp;
-
-       sp -= calleecode->stackframesize;
-       es->sp = (u1*) sp;
-
-       /* in debug mode, invalidate stack frame first */
-
-       /* XXX may not invalidate linkage area used by native code! */
-
-#if !defined(NDEBUG) && 0
-       for (i=0; i< (basesp - sp) && i < 1; ++i) {
-               sp[i] = 0xdeaddeadU;
-       }
-#endif
-
-#if defined(__I386__)
-       /* Stackslot 0 may contain the object instance for vftbl patching.
-          Destroy it, so there's no undefined value used. */
-       if ((basesp - sp) > 0) {
-               sp[0] = 0;
-       }
-#endif
-
-       /* save the return address register */
-
-#if defined(REPLACE_RA_TOP_OF_FRAME)
-#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
-       if (!code_is_leafmethod(calleecode))
-#endif
-               *--basesp = (ptrint) ra;
-#endif /* REPLACE_RA_TOP_OF_FRAME */
-
-#if defined(REPLACE_RA_LINKAGE_AREA)
-#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
-       if (!code_is_leafmethod(calleecode))
-#endif
-               basesp[LA_LR_OFFSET / sizeof(stackslot_t)] = (ptrint) ra;
-#endif /* REPLACE_RA_LINKAGE_AREA */
-
-       /* save int registers */
-
-       reg = INT_REG_CNT;
-       for (i=0; i<calleecode->savedintcount; ++i) {
-               while (nregdescint[--reg] != REG_SAV)
-                       ;
-               *--basesp = es->intregs[reg];
-
-               /* XXX may not clobber saved regs used by native code! */
-#if !defined(NDEBUG) && 0
-               es->intregs[reg] = (ptrint) 0x44dead4444dead44ULL;
-#endif
-       }
-
-       /* save flt registers */
-
-       /* XXX align? */
-       reg = FLT_REG_CNT;
-       for (i=0; i<calleecode->savedfltcount; ++i) {
-               while (nregdescfloat[--reg] != REG_SAV)
-                       ;
-               basesp -= STACK_SLOTS_PER_FLOAT;
-               *(double*)basesp = es->fltregs[reg];
-
-               /* XXX may not clobber saved regs used by native code! */
-#if !defined(NDEBUG) && 0
-               *(u8*)&(es->fltregs[reg]) = 0x44dead4444dead44ULL;
-#endif
-       }
-
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-       /* save adr registers */
-
-       reg = ADR_REG_CNT;
-       for (i=0; i<calleecode->savedadrcount; ++i) {
-               while (nregdescadr[--reg] != REG_SAV)
-                       ;
-               *--basesp = es->adrregs[reg];
-
-               /* XXX may not clobber saved regs used by native code! */
-#if !defined(NDEBUG) && 0
-               es->adrregs[reg] = (ptrint) 0x44dead4444dead44ULL;
-#endif
-       }
-#endif
-}
-
-
-/* replace_pop_activation_record ***********************************************
-
-   Peel a stack frame from the execution state.
-
-   *** This function imitates the effects of the method epilog ***
-   *** and returning from the method call.                     ***
-
-   IN:
-       es...............execution state
-       frame............source frame, receives synchronization slots
-
-   OUT:
-       *es..............the execution state after popping the stack frame
-
-   RETURN VALUE:
-       the return address of the poped activation record
-
-*******************************************************************************/
-
-u1* replace_pop_activation_record(executionstate_t *es,
-                                                                 sourceframe_t *frame)
-{
-       u1 *ra;
-       u1 *pv;
-       s4 i;
-       s4 count;
-       codeinfo *code;
-       stackslot_t *sp;
-
-       assert(es->code);
-       assert(frame);
-
-       /* calculate the base of the stack frame */
-
-       sp = (stackslot_t *) es->sp;
-       assert(frame->syncslotcount == 0);
-       assert(frame->syncslots == NULL);
-       count = code_get_sync_slot_count(es->code);
-       frame->syncslotcount = count;
-       frame->syncslots = DMNEW(replace_val_t, count);
-       for (i=0; i<count; ++i) {
-               frame->syncslots[i].p = sp[es->code->memuse + i]; /* XXX md_ function */
-       }
-
-       /* pop the stackframe */
-
-       md_pop_stackframe(es);
-
-       ra = es->pc;
-
-       DOLOG( printf("RA = %p\n", (void*)ra); );
-
-       /* Subtract one from the PC so we do not hit the replacement point */
-       /* of the instruction following the call, if there is one.         */
-
-       es->pc--;
-
-       /* find the new codeinfo */
-
-       pv = md_codegen_get_pv_from_pc(ra);
-       DOLOG( printf("PV = %p\n", (void*) pv); );
-
-       code = code_get_codeinfo_for_pv(pv);
-       DOLOG( printf("CODE = %p\n", (void*) code); );
-
-       /* return NULL if we reached native code */
-
-       es->pv = pv;
-       es->code = code;
-
-       return (code) ? ra : NULL;
-}
-
-
-/* replace_patch_method_pointer ************************************************
-
-   Patch a method pointer (may be in code, data segment, vftbl, or interface
-   table).
-
-   IN:
-          mpp..............address of the method pointer to patch
-          entrypoint.......the new entrypoint of the method
-          kind.............kind of call to patch, used only for debugging
-
-*******************************************************************************/
-
-static void replace_patch_method_pointer(methodptr *mpp,
-                                                                                methodptr entrypoint,
-                                                                                const char *kind)
-{
-#if !defined(NDEBUG)
-       codeinfo       *oldcode;
-       codeinfo       *newcode;
-#endif
-
-       DOLOG( printf("patch method pointer from: %p to %p\n",
-                                 (void*) *mpp, (void*)entrypoint); );
-
-#if !defined(NDEBUG)
-       oldcode = code_get_codeinfo_for_pv(*mpp);
-       newcode = code_get_codeinfo_for_pv(entrypoint);
-
-       DOLOG_SHORT( printf("\tpatch %s %p ", kind, (void*) oldcode);
-                                method_println(oldcode->m);
-                                printf("\t      with      %p ", (void*) newcode);
-                                method_println(newcode->m); );
-
-       assert(oldcode->m == newcode->m);
-#endif
-
-       /* write the new entrypoint */
-
-       *mpp = (methodptr) entrypoint;
-}
-
-
-/* replace_patch_class *********************************************************
-
-   Patch a method in the given class.
-
-   IN:
-          vftbl............vftbl of the class
-          m................the method to patch
-          oldentrypoint....the old entrypoint to replace
-          entrypoint.......the new entrypoint
-
-*******************************************************************************/
-
-void replace_patch_class(vftbl_t *vftbl,
-                                                methodinfo *m,
-                                                u1 *oldentrypoint,
-                                                u1 *entrypoint)
-{
-       s4                 i;
-       methodptr         *mpp;
-       methodptr         *mppend;
-
-       /* patch the vftbl of the class */
-
-       replace_patch_method_pointer(vftbl->table + m->vftblindex,
-                                                                entrypoint,
-                                                                "virtual  ");
-
-       /* patch the interface tables */
-
-       assert(oldentrypoint);
-
-       for (i=0; i < vftbl->interfacetablelength; ++i) {
-               mpp = vftbl->interfacetable[-i];
-               mppend = mpp + vftbl->interfacevftbllength[i];
-               for (; mpp != mppend; ++mpp)
-                       if (*mpp == oldentrypoint) {
-                               replace_patch_method_pointer(mpp, entrypoint, "interface");
-                       }
-       }
-}
-
-
-/* replace_patch_class_hierarchy ***********************************************
-
-   Patch a method in all loaded classes.
-
-   IN:
-          m................the method to patch
-          oldentrypoint....the old entrypoint to replace
-          entrypoint.......the new entrypoint
-
-*******************************************************************************/
-
-struct replace_patch_data_t {
-       methodinfo *m;
-       u1         *oldentrypoint;
-       u1         *entrypoint;
-};
-
-void replace_patch_callback(classinfo *c, struct replace_patch_data_t *pd)
-{
-       vftbl_t *vftbl = c->vftbl;
-
-       if (vftbl != NULL
-               && vftbl->vftbllength > pd->m->vftblindex
-               && vftbl->table[pd->m->vftblindex] != &asm_abstractmethoderror
-               && code_get_methodinfo_for_pv(vftbl->table[pd->m->vftblindex]) == pd->m)
-       {
-               replace_patch_class(c->vftbl, pd->m, pd->oldentrypoint, pd->entrypoint);
-       }
-}
-
-void replace_patch_class_hierarchy(methodinfo *m,
-                                                                  u1 *oldentrypoint,
-                                                                  u1 *entrypoint)
-{
-       struct replace_patch_data_t pd;
-
-       pd.m = m;
-       pd.oldentrypoint = oldentrypoint;
-       pd.entrypoint = entrypoint;
-
-       DOLOG_SHORT( printf("patching class hierarchy: ");
-                            method_println(m); );
-
-       classcache_foreach_loaded_class(
-                       (classcache_foreach_functionptr_t) &replace_patch_callback,
-                       (void*) &pd);
-}
-
-
-/* replace_patch_future_calls **************************************************
-
-   Analyse a call site and depending on the kind of call patch the call, the
-   virtual function table, or the interface table.
-
-   IN:
-          ra...............return address pointing after the call site
-          callerframe......source frame of the caller
-          calleeframe......source frame of the callee, must have been mapped
-
-*******************************************************************************/
-
-void replace_patch_future_calls(u1 *ra,
-                                                               sourceframe_t *callerframe,
-                                                               sourceframe_t *calleeframe)
-{
-       u1            *patchpos;
-       methodptr      entrypoint;
-       methodptr      oldentrypoint;
-       bool           atentry;
-       void          *pv;
-       codeinfo      *calleecode;
-       methodinfo    *calleem;
-       java_object_t *obj;
-       vftbl_t       *vftbl;
-
-       assert(ra);
-       assert(callerframe->down == calleeframe);
-
-       /* get the new codeinfo and the method that shall be entered */
-
-       calleecode = calleeframe->tocode;
-       assert(calleecode);
-
-       calleem = calleeframe->method;
-       assert(calleem == calleecode->m);
-
-       entrypoint = (methodptr) calleecode->entrypoint;
-
-       /* check if we are at an method entry rplpoint at the innermost frame */
-
-       atentry = (calleeframe->down == NULL)
-                       && !(calleem->flags & ACC_STATIC)
-                       && (calleeframe->fromrp->id == 0); /* XXX */
-
-       /* get the position to patch, in case it was a statically bound call   */
-
-       pv = callerframe->fromcode->entrypoint;
-       patchpos = md_jit_method_patch_address(pv, ra, NULL);
-
-       if (patchpos == NULL) {
-               /* the call was dispatched dynamically */
-
-               /* we can only patch such calls if we are at the entry point */
-
-#if !defined(__I386__)
-               /* On i386 we always know the instance argument. */
-               if (!atentry)
-                       return;
-#endif
-
-               assert((calleem->flags & ACC_STATIC) == 0);
-
-               oldentrypoint = calleeframe->fromcode->entrypoint;
-
-               /* we need to know the instance */
-
-               if (!calleeframe->instance.a) {
-                       DOLOG_SHORT( printf("WARNING: object instance unknown!\n"); );
-                       replace_patch_class_hierarchy(calleem, oldentrypoint, entrypoint);
-                       return;
-               }
-
-               /* get the vftbl */
-
-               obj = calleeframe->instance.a;
-               vftbl = obj->vftbl;
-
-               assert(vftbl->clazz->vftbl == vftbl);
-
-               DOLOG_SHORT( printf("\tclass: "); class_println(vftbl->clazz); );
-
-               replace_patch_class(vftbl, calleem, oldentrypoint, entrypoint);
-       }
-       else {
-               /* the call was statically bound */
-
-#if defined(__I386__)
-               /* It happens that there is a patcher trap. (pm) */
-               if (*(u2 *)(patchpos - 1) == 0x0b0f) {
-               } else
-#endif
-               replace_patch_method_pointer((methodptr *) patchpos, entrypoint, "static   ");
-       }
-}
-
-
-/* replace_push_activation_record **********************************************
-
-   Push a stack frame onto the execution state.
-   
-   *** This function imitates the effects of a call and the ***
-   *** method prolog of the callee.                         ***
-
-   IN:
-          es...............execution state
-          rpcall...........the replacement point at the call site
-          callerframe......source frame of the caller, or NULL for creating the
-                           first frame
-          calleeframe......source frame of the callee, must have been mapped
-
-   OUT:
-       *es..............the execution state after pushing the stack frame
-  
-*******************************************************************************/
-
-void replace_push_activation_record(executionstate_t *es,
-                                                                       rplpoint *rpcall,
-                                                                       sourceframe_t *callerframe,
-                                                                       sourceframe_t *calleeframe)
-{
-       s4           i;
-       s4           count;
-       stackslot_t *sp;
-       u1          *ra;
-       codeinfo    *calleecode;
-
-       assert(es);
-       assert(!rpcall || callerframe);
-    assert(!rpcall || rpcall->type == RPLPOINT_TYPE_CALL);
-       assert(!rpcall || rpcall == callerframe->torp);
-       assert(calleeframe);
-       assert(!callerframe || calleeframe == callerframe->down);
-
-       /* the compilation unit we are entering */
-
-       calleecode = calleeframe->tocode;
-       assert(calleecode);
-
-       /* calculate the return address */
-
-       if (rpcall)
-               ra = rpcall->pc + rpcall->callsize;
-       else
-               ra = es->pc + 1 /* XXX this is ugly */;
-
-       /* push the stackframe */
-
-       md_push_stackframe(es, calleecode, ra);
-
-       /* we move into a new code unit, set code, PC, PV */
-
-       es->code = calleecode;
-       es->pc = calleecode->entrypoint; /* XXX not needed? */
-       es->pv = calleecode->entrypoint;
-
-       /* write slots used for synchronization */
-
-       sp = (stackslot_t *) es->sp;
-       count = code_get_sync_slot_count(calleecode);
-       assert(count == calleeframe->syncslotcount);
-       for (i=0; i<count; ++i) {
-               sp[calleecode->memuse + i] = calleeframe->syncslots[i].p;
-       }
-
-       /* redirect future invocations */
-
-       if (callerframe && rpcall) {
-#if defined(REPLACE_PATCH_ALL)
-               if (rpcall->type == callerframe->fromrp->type)
-#else
-               if (rpcall == callerframe->fromrp)
-#endif
-                       replace_patch_future_calls(ra, callerframe, calleeframe);
-       }
-}
-
-
-/* replace_find_replacement_point **********************************************
-
-   Find the replacement point in the given code corresponding to the
-   position given in the source frame.
-   
-   IN:
-          code.............the codeinfo in which to search the rplpoint
-          frame............the source frame defining the position to look for
-          parent...........parent replacement point to match
-
-   RETURN VALUE:
-       the replacement point
-  
-*******************************************************************************/
-
-rplpoint * replace_find_replacement_point(codeinfo *code,
-                                                                                 sourceframe_t *frame,
-                                                                                 rplpoint *parent)
-{
-       methodinfo *m;
-       rplpoint *rp;
-       s4        i;
-       s4        j;
-       s4        stacki;
-       rplalloc *ra;
-
-       assert(code);
-       assert(frame);
-
-       DOLOG( printf("searching replacement point for:\n");
-                  replace_source_frame_println(frame); );
-
-       m = frame->method;
-
-       DOLOG( printf("code = %p\n", (void*)code); );
-
-       rp = code->rplpoints;
-       i = code->rplpointcount;
-       while (i--) {
-               if (rp->id == frame->id && rp->method == frame->method
-                               && rp->parent == parent
-                               && replace_normalize_type_map[rp->type] == frame->type)
-               {
-                       /* check if returnAddresses match */
-                       /* XXX optimize: only do this if JSRs in method */
-                       DOLOG( printf("checking match for:");
-                                  replace_replacement_point_println(rp, 1); fflush(stdout); );
-                       ra = rp->regalloc;
-                       stacki = 0;
-                       for (j = rp->regalloccount; j--; ++ra) {
-                               if (ra->type == TYPE_RET) {
-                                       if (ra->index == RPLALLOC_STACK) {
-                                               assert(stacki < frame->javastackdepth);
-                                               if (frame->javastack[stacki].i != ra->regoff)
-                                                       goto no_match;
-                                               stacki++;
-                                       }
-                                       else {
-                                               assert(ra->index >= 0 && ra->index < frame->javalocalcount);
-                                               if (frame->javalocals[ra->index].i != ra->regoff)
-                                                       goto no_match;
-                                       }
-                               }
-                       }
-
-                       /* found */
-                       return rp;
-               }
-no_match:
-               rp++;
-       }
-
-#if !defined(NDEBUG)
-       printf("candidate replacement points were:\n");
-       rp = code->rplpoints;
-       i = code->rplpointcount;
-       for (; i--; ++rp) {
-               replace_replacement_point_println(rp, 1);
-       }
-#endif
-
-       vm_abort("no matching replacement point found");
-       return NULL; /* NOT REACHED */
-}
-
-
-/* replace_find_replacement_point_for_pc ***************************************
-
-   Find the nearest replacement point at or before the given PC. The
-   given PC has to be between (rp->pc) and (rp->pc+rp->callsize) for
-   the replacement point to be found.
-
-   IN:
-       code.............compilation unit the PC is in
-          pc...............the machine code PC
-
-   RETURN VALUE:
-       the replacement point found, or
-          NULL if no replacement point was found
-
-*******************************************************************************/
-
-rplpoint *replace_find_replacement_point_for_pc(codeinfo *code, u1 *pc, unsigned desired_flags)
-{
-       rplpoint *found;
-       rplpoint *rp;
-       s4        i;
-
-       DOLOG( printf("searching for rp at pc:%p in %p ", (void*)pc, (void*)code);
-                  method_println(code->m); );
-
-       found = NULL;
-
-       rp = code->rplpoints;
-       for (i=0; i<code->rplpointcount; ++i, ++rp) {
-               DOLOG( replace_replacement_point_println(rp, 2); );
-               if (rp->pc <= pc && rp->pc + rp->callsize >= pc) {
-                       if (desired_flags) {
-                               if (rp->flags & desired_flags) {
-                                       found = rp;
-                               }
-                       } else {
-                               found = rp;
-                       }
-               }
-       }
-
-       return found;
-}
-
-/* replace_pop_native_frame ****************************************************
-
-   Unroll a native frame in the execution state and create a source frame
-   for it.
-
-   IN:
-          es...............current execution state
-          ss...............the current source state
-          sfi..............stackframeinfo for the native frame
-
-   OUT:
-       es...............execution state after unrolling the native frame
-          ss...............gets the added native source frame
-
-*******************************************************************************/
-
-static void replace_pop_native_frame(executionstate_t *es,
-                                                                        sourcestate_t *ss,
-                                                                        stackframeinfo_t *sfi)
-{
-       sourceframe_t *frame;
-       codeinfo      *code;
-       s4             i,j;
-
-       assert(sfi);
-
-       frame = replace_new_sourceframe(ss);
-
-       frame->sfi = sfi;
-
-       /* remember pc and size of native frame */
-
-       frame->nativepc = es->pc;
-       frame->nativeframesize = (es->sp != 0) ? (((uintptr_t) sfi->sp) - ((uintptr_t) es->sp)) : 0;
-       assert(frame->nativeframesize >= 0);
-
-       /* remember values of saved registers */
-
-       j = 0;
-       for (i=0; i<INT_REG_CNT; ++i) {
-               if (nregdescint[i] == REG_SAV)
-                       frame->nativesavint[j++] = es->intregs[i];
-       }
-
-       j = 0;
-       for (i=0; i<FLT_REG_CNT; ++i) {
-               if (nregdescfloat[i] == REG_SAV)
-                       frame->nativesavflt[j++] = es->fltregs[i];
-       }
-
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-       j = 0;
-       for (i=0; i<ADR_REG_CNT; ++i) {
-               if (nregdescadr[i] == REG_SAV)
-                       frame->nativesavadr[j++] = es->adrregs[i];
-       }
-#endif
-
-       /* restore saved registers */
-
-#if defined(ENABLE_GC_CACAO) && !defined(HAS_ADDRESS_REGISTER_FILE)
-       j = 0;
-       for (i=0; i<INT_REG_CNT; ++i) {
-               if (nregdescint[i] == REG_SAV)
-                       es->intregs[i] = sfi->intregs[j++];
-       }
-#else
-       /* XXX we don't have them, yet, in the sfi, so clear them */
-
-       for (i=0; i<INT_REG_CNT; ++i) {
-               if (nregdescint[i] == REG_SAV)
-                       es->intregs[i] = 0;
-       }
-#endif
-
-       /* XXX we don't have float registers in the sfi, so clear them */
-
-       for (i=0; i<FLT_REG_CNT; ++i) {
-               if (nregdescfloat[i] == REG_SAV)
-                       es->fltregs[i] = 0.0;
-       }
-
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-# if defined(ENABLE_GC_CACAO)
-       j = 0;
-       for (i=0; i<ADR_REG_CNT; ++i) {
-               if (nregdescadr[i] == REG_SAV)
-                       es->adrregs[i] = sfi->adrregs[j++];
-       }
-# else
-       for (i=0; i<ADR_REG_CNT; ++i) {
-               if (nregdescadr[i] == REG_SAV)
-                       es->adrregs[i] = 0;
-       }
-# endif
-#endif
-
-       /* restore codeinfo of the native stub */
-
-       code = code_get_codeinfo_for_pv(sfi->pv);
-
-       /* restore sp, pv, pc and codeinfo of the parent method */
-
-       /* XXX michi: use this instead:
-       es->sp = sfi->sp + code->stackframesize; */
-       es->sp   = (void*) (((uintptr_t) sfi->sp) + (*(s4 *) (((uintptr_t) sfi->pv) + FrameSize)));
-#if defined(REPLACE_RA_BETWEEN_FRAMES)
-       es->sp  += SIZE_OF_STACKSLOT; /* skip return address */
-#endif
-       es->pv   = md_codegen_get_pv_from_pc(sfi->ra);
-       es->pc   = (void*) (((uintptr_t) ((sfi->xpc) ? sfi->xpc : sfi->ra)) - 1);
-       es->code = code_get_codeinfo_for_pv(es->pv);
-}
-
-
-/* replace_push_native_frame ***************************************************
-
-   Rebuild a native frame onto the execution state and remove its source frame.
-
-   Note: The native frame is "rebuild" by setting fields like PC and stack
-         pointer in the execution state accordingly. Values in the
-                stackframeinfo may be modified, but the actual stack frame of the
-                native code is not touched.
-
-   IN:
-          es...............current execution state
-          ss...............the current source state
-
-   OUT:
-       es...............execution state after re-rolling the native frame
-          ss...............the native source frame is removed
-
-*******************************************************************************/
-
-static void replace_push_native_frame(executionstate_t *es, sourcestate_t *ss)
-{
-       sourceframe_t *frame;
-       s4             i,j;
-
-       assert(es);
-       assert(ss);
-
-       DOLOG( printf("pushing native frame\n"); );
-
-       /* remove the frame from the source state */
-
-       frame = ss->frames;
-       assert(frame);
-       assert(REPLACE_IS_NATIVE_FRAME(frame));
-
-       ss->frames = frame->down;
-
-       /* skip sp for the native stub */
-
-       es->sp -= (*(s4 *) (((uintptr_t) frame->sfi->pv) + FrameSize));
-#if defined(REPLACE_RA_BETWEEN_FRAMES)
-       es->sp -= SIZE_OF_STACKSLOT; /* skip return address */
-#endif
-
-       /* assert that the native frame has not moved */
-
-       assert(es->sp == frame->sfi->sp);
-
-       /* update saved registers in the stackframeinfo */
-
-#if defined(ENABLE_GC_CACAO)
-       j = 0;
-# if !defined(HAS_ADDRESS_REGISTER_FILE)
-       for (i=0; i<INT_REG_CNT; ++i) {
-               if (nregdescint[i] == REG_SAV)
-                       frame->sfi->intregs[j++] = es->intregs[i];
-       }
-# else
-       for (i=0; i<ADR_REG_CNT; ++i) {
-               if (nregdescadr[i] == REG_SAV)
-                       frame->sfi->adrregs[j++] = es->adrregs[i];
-       }
-# endif
-
-       /* XXX leave float registers untouched here */
-#endif
-
-       /* restore saved registers */
-
-       j = 0;
-       for (i=0; i<INT_REG_CNT; ++i) {
-               if (nregdescint[i] == REG_SAV)
-                       es->intregs[i] = frame->nativesavint[j++];
-       }
-
-       j = 0;
-       for (i=0; i<FLT_REG_CNT; ++i) {
-               if (nregdescfloat[i] == REG_SAV)
-                       es->fltregs[i] = frame->nativesavflt[j++];
-       }
-
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-       j = 0;
-       for (i=0; i<ADR_REG_CNT; ++i) {
-               if (nregdescadr[i] == REG_SAV)
-                       es->adrregs[i] = frame->nativesavadr[j++];
-       }
-#endif
-
-       /* skip the native frame on the machine stack */
-
-       es->sp -= frame->nativeframesize;
-
-       /* set the pc the next frame must return to */
-
-       es->pc = frame->nativepc;
-}
-
-
-/* replace_recover_source_state ************************************************
-
-   Recover the source state from the given replacement point and execution
-   state.
-
-   IN:
-       rp...............replacement point that has been reached, if any
-          sfi..............stackframeinfo, if called from native code
-          es...............execution state at the replacement point rp
-
-   RETURN VALUE:
-       the source state
-
-*******************************************************************************/
-
-sourcestate_t *replace_recover_source_state(rplpoint *rp,
-                                                                                       stackframeinfo_t *sfi,
-                                                                                   executionstate_t *es)
-{
-       sourcestate_t *ss;
-       u1            *ra;
-       bool           locked;
-#if defined(REPLACE_STATISTICS)
-       s4             depth;
-#endif
-
-       /* create the source frame structure in dump memory */
-
-       ss = DNEW(sourcestate_t);
-       ss->frames = NULL;
-
-       /* each iteration of the loop recovers one source frame */
-
-       depth = 0;
-       locked = false;
-
-       while (rp || sfi) {
-
-               DOLOG( executionstate_println(es); );
-
-               /* if we are not at a replacement point, it is a native frame */
-
-               if (rp == NULL) {
-                       DOLOG( printf("native frame: sfi: "); replace_stackframeinfo_println(sfi); );
-
-                       locked = true;
-                       replace_pop_native_frame(es, ss, sfi);
-                       sfi = sfi->prev;
-
-                       if (es->code == NULL)
-                               continue;
-
-                       goto after_machine_frame;
-               }
-
-               /* read the values for this source frame from the execution state */
-
-               DOLOG( printf("recovering source state for%s:\n",
-                                       (ss->frames == NULL) ? " TOPFRAME" : "");
-                          replace_replacement_point_println(rp, 1); );
-
-               replace_read_executionstate(rp, es, ss, ss->frames == NULL);
-
-#if defined(ENABLE_VMLOG)
-               vmlog_cacao_unrol_method(ss->frames->method);
-#endif
-
-#if defined(REPLACE_STATISTICS)
-               REPLACE_COUNT(stat_frames);
-               depth++;
-               replace_statistics_source_frame(ss->frames);
-#endif
-
-               /* in locked areas (below native frames), identity map the frame */
-
-               if (locked) {
-                       ss->frames->torp = ss->frames->fromrp;
-                       ss->frames->tocode = ss->frames->fromcode;
-               }
-
-               /* unroll to the next (outer) frame */
-
-               if (rp->parent) {
-                       /* this frame is in inlined code */
-
-                       DOLOG( printf("INLINED!\n"); );
-
-                       rp = rp->parent;
-
-                       assert(rp->type == RPLPOINT_TYPE_INLINE);
-                       REPLACE_COUNT(stat_unroll_inline);
-               }
-               else {
-                       /* this frame had been called at machine-level. pop it. */
-
-                       DOLOG( printf("UNWIND\n"); );
-
-                       ra = replace_pop_activation_record(es, ss->frames);
-                       if (ra == NULL) {
-                               DOLOG( printf("REACHED NATIVE CODE\n"); );
-
-                               rp = NULL;
-
-#if !defined(ENABLE_GC_CACAO)
-                               break; /* XXX remove to activate native frames */
-#endif
-                               continue;
-                       }
-
-                       /* find the replacement point at the call site */
-
-after_machine_frame:
-                       rp = replace_find_replacement_point_for_pc(es->code, es->pc, 0);
-
-                       if (rp == NULL)
-                               vm_abort("could not find replacement point while unrolling call");
-
-                       DOLOG( printf("found replacement point.\n");
-                                       replace_replacement_point_println(rp, 1); );
-
-                       assert(rp->type == RPLPOINT_TYPE_CALL);
-                       REPLACE_COUNT(stat_unroll_call);
-               }
-       } /* end loop over source frames */
-
-       REPLACE_COUNT_DIST(stat_dist_frames, depth);
-
-       return ss;
-}
-
-
-/* replace_map_source_state ****************************************************
-
-   Map each source frame in the given source state to a target replacement
-   point and compilation unit. If no valid code is available for a source
-   frame, it is (re)compiled.
-
-   IN:
-       ss...............the source state
-
-   OUT:
-       ss...............the source state, modified: The `torp` and `tocode`
-                           fields of each source frame are set.
-
-   RETURN VALUE:
-       true.............everything went ok
-          false............an exception has been thrown
-
-*******************************************************************************/
-
-static bool replace_map_source_state(sourcestate_t *ss)
-{
-       sourceframe_t *frame;
-       codeinfo      *code;
-       rplpoint      *rp;
-       rplpoint      *parent; /* parent of inlined rplpoint */
-#if defined(REPLACE_STATISTICS)
-       codeinfo      *oldcode;
-#endif
-
-       parent = NULL;
-       code = NULL;
-
-       /* iterate over the source frames from outermost to innermost */
-
-       for (frame = ss->frames; frame != NULL; frame = frame->down) {
-
-               /* XXX skip native frames */
-
-               if (REPLACE_IS_NATIVE_FRAME(frame)) {
-                       parent = NULL;
-                       continue;
-               }
-
-               /* map frames which are not already mapped */
-
-               if (frame->tocode) {
-                       code = frame->tocode;
-                       rp = frame->torp;
-                       assert(rp);
-               }
-               else {
-                       assert(frame->torp == NULL);
-
-                       if (parent == NULL) {
-                               /* find code for this frame */
-
-#if defined(REPLACE_STATISTICS)
-                               oldcode = frame->method->code;
-#endif
-                               /* request optimization of hot methods and their callers */
-
-                               if (frame->method->hitcountdown < 0
-                                       || (frame->down && frame->down->method->hitcountdown < 0))
-                                       jit_request_optimization(frame->method);
-
-                               code = jit_get_current_code(frame->method);
-
-                               if (code == NULL)
-                                       return false; /* exception */
-
-                               REPLACE_COUNT_IF(stat_recompile, code != oldcode);
-                       }
-
-                       assert(code);
-
-                       /* map this frame */
-
-                       rp = replace_find_replacement_point(code, frame, parent);
-
-                       frame->tocode = code;
-                       frame->torp = rp;
-               }
-
-               if (rp->type == RPLPOINT_TYPE_CALL) {
-                       parent = NULL;
-               }
-               else {
-                       /* inlining */
-                       parent = rp;
-               }
-       }
-
-       return true;
-}
-
-
-/* replace_map_source_state_identity *******************************************
-
-   Map each source frame in the given source state to the same replacement
-   point and compilation unit it was derived from. This is mainly used for
-   garbage collection.
-
-   IN:
-       ss...............the source state
-
-   OUT:
-       ss...............the source state, modified: The `torp` and `tocode`
-                           fields of each source frame are set.
-
-*******************************************************************************/
-
-#if defined(ENABLE_GC_CACAO)
-static void replace_map_source_state_identity(sourcestate_t *ss)
-{
-       sourceframe_t *frame;
-
-       /* iterate over the source frames from outermost to innermost */
-
-       for (frame = ss->frames; frame != NULL; frame = frame->down) {
-
-               /* skip native frames */
-
-               if (REPLACE_IS_NATIVE_FRAME(frame)) {
-                       continue;
-               }
-
-               /* map frames using the identity mapping */
-
-               if (frame->tocode) {
-                       assert(frame->tocode == frame->fromcode);
-                       assert(frame->torp   == frame->fromrp);
-               } else {
-                       assert(frame->tocode == NULL);
-                       assert(frame->torp   == NULL);
-                       frame->tocode = frame->fromcode;
-                       frame->torp   = frame->fromrp;
-               }
-       }
-}
-#endif
-
-
-/* replace_build_execution_state ***********************************************
-
-   Build an execution state for the given (mapped) source state.
-
-   !!! CAUTION: This function rewrites the machine stack !!!
-
-   THIS FUNCTION MUST BE CALLED USING A SAFE STACK AREA!
-
-   IN:
-       ss...............the source state. Must have been mapped by
-                                               replace_map_source_state before.
-          es...............the base execution state on which to build
-
-   OUT:
-       *es..............the new execution state
-
-*******************************************************************************/
-
-static void replace_build_execution_state(sourcestate_t *ss,
-                                                                                 executionstate_t *es)
-{
-       rplpoint      *rp;
-       sourceframe_t *prevframe;
-       rplpoint      *parent;
-
-       parent = NULL;
-       prevframe = NULL;
-       rp = NULL;
-
-       while (ss->frames) {
-
-               if (REPLACE_IS_NATIVE_FRAME(ss->frames)) {
-                       prevframe = ss->frames;
-                       replace_push_native_frame(es, ss);
-                       parent = NULL;
-                       rp = NULL;
-                       continue;
-               }
-
-               if (parent == NULL) {
-                       /* create a machine-level stack frame */
-
-                       DOLOG( printf("pushing activation record for:\n");
-                                  if (rp) replace_replacement_point_println(rp, 1);
-                                  else printf("\tfirst frame\n"); );
-
-                       replace_push_activation_record(es, rp, prevframe, ss->frames);
-
-                       DOLOG( executionstate_println(es); );
-               }
-
-               rp = ss->frames->torp;
-               assert(rp);
-
-               DOLOG( printf("creating execution state for%s:\n",
-                               (ss->frames->down == NULL) ? " TOPFRAME" : "");
-                          replace_replacement_point_println(ss->frames->fromrp, 1);
-                          replace_replacement_point_println(rp, 1); );
-
-               es->code = ss->frames->tocode;
-               prevframe = ss->frames;
-
-#if defined(ENABLE_VMLOG)
-               vmlog_cacao_rerol_method(ss->frames->method);
-#endif
-
-               replace_write_executionstate(rp, es, ss, ss->frames->down == NULL);
-
-               DOLOG( executionstate_println(es); );
-
-               if (rp->type == RPLPOINT_TYPE_CALL) {
-                       parent = NULL;
-               }
-               else {
-                       /* inlining */
-                       parent = rp;
-               }
-       }
-}
-
-
-/* replace_me ******************************************************************
-   This function is called by the signal handler when a thread reaches
-   a replacement point. `replace_me` must map the execution state to the
-   target replacement point and let execution continue there.
-
-   THIS FUNCTION MUST BE CALLED USING A SAFE STACK AREA!
-
-   IN:
-       rp...............replacement point that has been reached
-       es...............execution state read by signal handler
-  
-*******************************************************************************/
-
-static void replace_me(rplpoint *rp, executionstate_t *es)
-{
-       stackframeinfo_t    *sfi;
-       sourcestate_t       *ss;
-       sourceframe_t       *frame;
-       codeinfo            *origcode;
-       rplpoint            *origrp;
-#if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
-       threadobject        *thread;
-#endif
-       int32_t              dumpmarker;
-
-       origcode = es->code;
-       origrp   = rp;
-
-#if defined(ENABLE_TLH)
-       /*printf("Replacing in %s/%s\n", rp->method->clazz->name->text, rp->method->name->text);*/
-#endif
-
-       /*if (strcmp(rp->method->clazz->name->text, "antlr/AlternativeElement") == 0 && strcmp(rp->method->name->text, "getAutoGenType") ==0) opt_TraceReplacement = 2; else opt_TraceReplacement = 0;*/
-
-       DOLOG_SHORT( printf("REPLACING(%d %p): (id %d %p) ",
-                                stat_replacements, (void*)THREADOBJECT,
-                                rp->id, (void*)rp);
-                                method_println(es->code->m); );
-
-       DOLOG( replace_replacement_point_println(rp, 1); );
-
-       REPLACE_COUNT(stat_replacements);
-
-       /* mark start of dump memory area */
-
-       DMARKER;
-
-       /* Get the stackframeinfo for the current thread. */
-
-       sfi = threads_get_current_stackframeinfo();
-
-       /* recover source state */
-
-       ss = replace_recover_source_state(rp, sfi, es);
-
-#if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
-       /* if there is a collection pending, we assume the replacement point should
-          suspend this thread */
-
-       if (gc_pending) {
-
-               thread = THREADOBJECT;
-
-               DOLOG_SHORT( printf("REPLACEMENT: Suspending thread for GC now!\n"); );
-
-               /* map the sourcestate using the identity mapping */
-               replace_map_source_state_identity(ss);
-
-               /* since we enter the same method again, we turn off rps now */
-               /* XXX michi: can we really do this? what if the rp was active before
-                  we activated it for the gc? */
-               replace_deactivate_replacement_points(origcode);
-
-               /* remember executionstate and sourcestate for this thread */
-               GC_EXECUTIONSTATE = es;
-               GC_SOURCESTATE    = ss;
-
-               /* really suspend this thread now (PC = 0) */
-               threads_suspend_ack(NULL, NULL);
-
-               DOLOG_SHORT( printf("REPLACEMENT: Resuming thread after GC now!\n"); );
-
-       } else {
-#endif /*defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)*/
-
-       /* map the source state */
-
-       if (!replace_map_source_state(ss))
-               vm_abort("exception during method replacement");
-
-       DOLOG( replace_sourcestate_println(ss); );
-
-       DOLOG_SHORT( replace_sourcestate_println_short(ss); );
-
-#if !defined(NDEBUG)
-       /* avoid infinite loops by self-replacement, only if not in testing mode */
-
-       if (!opt_TestReplacement) {
-               frame = ss->frames;
-               while (frame->down)
-                       frame = frame->down;
-
-               if (frame->torp == origrp) {
-                       DOLOG_SHORT(
-                               printf("WARNING: identity replacement, turning off rps to avoid infinite loop\n");
-                       );
-                       replace_deactivate_replacement_points(origcode);
-               }
-       }
-#endif
-
-#if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
-       }
-#endif
-
-       /* build the new execution state */
-
-       replace_build_execution_state(ss, es);
-
-#if !defined(NDEBUG)
-       /* continue execution after patched machine code, if testing mode enabled */
-
-       if (opt_TestReplacement)
-               es->pc += REPLACEMENT_PATCH_SIZE;
-#endif
-
-       /* release dump area */
-
-       DRELEASE;
-}
-
-
-/* replace_me_wrapper **********************************************************
-
-   This function is called by the signal handler. It determines if there
-   is an active replacement point pending at the given PC and returns
-   accordingly.
-
-   THIS FUNCTION MUST BE CALLED USING A SAFE STACK AREA!
-
-   IN:
-       pc...............the program counter that triggered the replacement.
-       context..........the context (machine state) to which the
-                           replacement should be applied.
-
-   OUT:
-       context..........the context after replacement finished.
-
-   RETURN VALUE:
-       true.............replacement done, everything went ok
-       false............no replacement done, context unchanged
-
-*******************************************************************************/
-
-bool replace_me_wrapper(u1 *pc, void *context)
-{
-       codeinfo         *code;
-       rplpoint         *rp;
-       executionstate_t  es;
-#if defined(ENABLE_RT_TIMING)
-       struct timespec time_start, time_end;
-#endif
-
-       /* search the codeinfo for the given PC */
-
-       code = code_find_codeinfo_for_pc(pc);
-       assert(code);
-
-       /* search for a replacement point at the given PC */
-
-       rp = replace_find_replacement_point_for_pc(code, pc, (RPLPOINT_FLAG_ACTIVE | RPLPOINT_FLAG_COUNTDOWN));
-
-       /* check if the replacement point belongs to given PC and is active */
-
-       if ((rp != NULL) && (rp->pc == pc)
-           && (rp->flags & (RPLPOINT_FLAG_ACTIVE | RPLPOINT_FLAG_COUNTDOWN))) {
-
-               DOLOG( printf("valid replacement point\n"); );
-
-#if !defined(NDEBUG)
-               executionstate_sanity_check(context);
-#endif
-
-               /* set codeinfo pointer in execution state */
-
-               es.code = code;
-
-               /* read execution state from current context */
-
-               md_executionstate_read(&es, context);
-
-               DOLOG( printf("REPLACEMENT READ: ");
-                          executionstate_println(&es); );
-
-               /* do the actual replacement */
-
-#if defined(ENABLE_RT_TIMING)
-               RT_TIMING_GET_TIME(time_start);
-#endif
-
-               replace_me(rp, &es);
-
-#if defined(ENABLE_RT_TIMING)
-               RT_TIMING_GET_TIME(time_end);
-               RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_REPLACE);
-#endif
-
-               /* write execution state to current context */
-
-               md_executionstate_write(&es, context);
-
-               DOLOG( printf("REPLACEMENT WRITE: ");
-                          executionstate_println(&es); );
-
-               /* new code is entered after returning */
-
-               DOLOG( printf("JUMPING IN!\n"); fflush(stdout); );
-               return true;
-       }
-       else
-               return false;
-}
-
-
-/******************************************************************************/
-/* NOTE: Stuff specific to the exact GC is below.                             */
-/******************************************************************************/
-
-#if defined(ENABLE_GC_CACAO)
-void replace_gc_from_native(threadobject *thread, u1 *pc, u1 *sp)
-{
-       stackframeinfo_t *sfi;
-       executionstate_t *es;
-       sourcestate_t    *ss;
-
-       /* Get the stackframeinfo of this thread. */
-
-       assert(thread == THREADOBJECT);
-
-       sfi = threads_get_current_stackframeinfo();
-
-       /* create the execution state */
-       es = DNEW(executionstate_t);
-       es->pc = pc;
-       es->sp = sp;
-       es->pv = 0;      /* since we are in a native, PV is invalid! */
-       es->code = NULL; /* since we are in a native, we do not have a codeinfo */
-
-       /* we assume we are in a native (no replacement point)! */
-       ss = replace_recover_source_state(NULL, sfi, es);
-
-       /* map the sourcestate using the identity mapping */
-       replace_map_source_state_identity(ss);
-
-       /* remember executionstate and sourcestate for this thread */
-       GC_EXECUTIONSTATE = es;
-       GC_SOURCESTATE    = ss;
-}
-#endif
-
-#if defined(ENABLE_GC_CACAO)
-void replace_gc_into_native(threadobject *thread)
-{
-       executionstate_t *es;
-       sourcestate_t    *ss;
-
-       /* get the executionstate and sourcestate for the given thread */
-       es = GC_EXECUTIONSTATE;
-       ss = GC_SOURCESTATE;
-
-       /* rebuild the stack of the given thread */
-       replace_build_execution_state(ss, es);
-}
-#endif
-
-
-/******************************************************************************/
-/* NOTE: No important code below.                                             */
-/******************************************************************************/
-
-
-/* statistics *****************************************************************/
-
-#if defined(REPLACE_STATISTICS)
-static void print_freq(FILE *file,int *array,int limit)
-{
-       int i;
-       int sum = 0;
-       int cum = 0;
-       for (i=0; i<limit; ++i)
-               sum += array[i];
-       sum += array[limit];
-       for (i=0; i<limit; ++i) {
-               cum += array[i];
-               fprintf(file,"      %3d: %8d (cum %3d%%)\n",
-                               i, array[i], (sum) ? ((100*cum)/sum) : 0);
-       }
-       fprintf(file,"    >=%3d: %8d\n",limit,array[limit]);
-}
-#endif /* defined(REPLACE_STATISTICS) */
-
-
-#if defined(REPLACE_STATISTICS)
-
-#define REPLACE_PRINT_DIST(name, array)                              \
-    printf("    " name " distribution:\n");                          \
-    print_freq(stdout, (array), sizeof(array)/sizeof(int) - 1);
-
-void replace_print_statistics(void)
-{
-       printf("replacement statistics:\n");
-       printf("    # of replacements:   %d\n", stat_replacements);
-       printf("    # of frames:         %d\n", stat_frames);
-       printf("    # of recompilations: %d\n", stat_recompile);
-       printf("    patched static calls:%d\n", stat_staticpatch);
-       printf("    unrolled inlines:    %d\n", stat_unroll_inline);
-       printf("    unrolled calls:      %d\n", stat_unroll_call);
-       REPLACE_PRINT_DIST("frame depth", stat_dist_frames);
-       REPLACE_PRINT_DIST("locals per frame", stat_dist_locals);
-       REPLACE_PRINT_DIST("ADR locals per frame", stat_dist_locals_adr);
-       REPLACE_PRINT_DIST("primitive locals per frame", stat_dist_locals_prim);
-       REPLACE_PRINT_DIST("RET locals per frame", stat_dist_locals_ret);
-       REPLACE_PRINT_DIST("void locals per frame", stat_dist_locals_void);
-       REPLACE_PRINT_DIST("stack slots per frame", stat_dist_stack);
-       REPLACE_PRINT_DIST("ADR stack slots per frame", stat_dist_stack_adr);
-       REPLACE_PRINT_DIST("primitive stack slots per frame", stat_dist_stack_prim);
-       REPLACE_PRINT_DIST("RET stack slots per frame", stat_dist_stack_ret);
-       printf("\n");
-       printf("    # of methods:            %d\n", stat_methods);
-       printf("    # of replacement points: %d\n", stat_rploints);
-       printf("    # of regallocs:          %d\n", stat_regallocs);
-       printf("        per rplpoint:        %f\n", (double)stat_regallocs / stat_rploints);
-       printf("        per method:          %f\n", (double)stat_regallocs / stat_methods);
-       REPLACE_PRINT_DIST("replacement points per method", stat_dist_method_rplpoints);
-       printf("\n");
-
-}
-#endif /* defined(REPLACE_STATISTICS) */
-
-
-#if defined(REPLACE_STATISTICS)
-static void replace_statistics_source_frame(sourceframe_t *frame)
-{
-       int adr = 0;
-       int ret = 0;
-       int prim = 0;
-       int vd = 0;
-       int n = 0;
-       int i;
-
-       for (i=0; i<frame->javalocalcount; ++i) {
-               switch (frame->javalocaltype[i]) {
-                       case TYPE_ADR: adr++; break;
-                       case TYPE_RET: ret++; break;
-                       case TYPE_INT: case TYPE_LNG: case TYPE_FLT: case TYPE_DBL: prim++; break;
-                       case TYPE_VOID: vd++; break;
-                       default: assert(0);
-               }
-               n++;
-       }
-       REPLACE_COUNT_DIST(stat_dist_locals, n);
-       REPLACE_COUNT_DIST(stat_dist_locals_adr, adr);
-       REPLACE_COUNT_DIST(stat_dist_locals_void, vd);
-       REPLACE_COUNT_DIST(stat_dist_locals_ret, ret);
-       REPLACE_COUNT_DIST(stat_dist_locals_prim, prim);
-       adr = ret = prim = n = 0;
-       for (i=0; i<frame->javastackdepth; ++i) {
-               switch (frame->javastacktype[i]) {
-                       case TYPE_ADR: adr++; break;
-                       case TYPE_RET: ret++; break;
-                       case TYPE_INT: case TYPE_LNG: case TYPE_FLT: case TYPE_DBL: prim++; break;
-               }
-               n++;
-       }
-       REPLACE_COUNT_DIST(stat_dist_stack, n);
-       REPLACE_COUNT_DIST(stat_dist_stack_adr, adr);
-       REPLACE_COUNT_DIST(stat_dist_stack_ret, ret);
-       REPLACE_COUNT_DIST(stat_dist_stack_prim, prim);
-}
-#endif /* defined(REPLACE_STATISTICS) */
-
-
-/* debugging helpers **********************************************************/
-
-/* replace_replacement_point_println *******************************************
-   Print replacement point info.
-  
-   IN:
-       rp...............the replacement point to print
-  
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-
-#define TYPECHAR(t)  (((t) >= 0 && (t) <= TYPE_RET) ? show_jit_type_letters[t] : '?')
-
-static char *replace_type_str[] = {
-       "STD",
-       "EXH",
-       "SBR",
-       "CALL",
-       "INLINE",
-       "RETURN",
-       "BODY"
-};
-
-void replace_replacement_point_println(rplpoint *rp, int depth)
-{
-       int j;
-       int index;
-
-       if (!rp) {
-               printf("(rplpoint *)NULL\n");
-               return;
-       }
-
-       for (j=0; j<depth; ++j)
-               putchar('\t');
-
-       printf("rplpoint (id %d) %p pc:%p+%d type:%s",
-                       rp->id, (void*)rp,rp->pc,rp->callsize,
-                       replace_type_str[rp->type]);
-       if (rp->flags & RPLPOINT_FLAG_NOTRAP)
-               printf(" NOTRAP");
-       if (rp->flags & RPLPOINT_FLAG_COUNTDOWN)
-               printf(" COUNTDOWN");
-       if (rp->flags & RPLPOINT_FLAG_ACTIVE)
-               printf(" ACTIVE");
-       printf(" parent:%p\n", (void*)rp->parent);
-       for (j=0; j<depth; ++j)
-               putchar('\t');
-       printf("ra:%d = [",     rp->regalloccount);
-
-       for (j=0; j<rp->regalloccount; ++j) {
-               if (j)
-                       putchar(' ');
-               index = rp->regalloc[j].index;
-               switch (index) {
-                       case RPLALLOC_STACK: printf("S"); break;
-                       case RPLALLOC_PARAM: printf("P"); break;
-                       case RPLALLOC_SYNC : printf("Y"); break;
-                       default: printf("%d", index);
-               }
-               printf(":%1c:", TYPECHAR(rp->regalloc[j].type));
-               if (rp->regalloc[j].type == TYPE_RET) {
-                       printf("ret(L%03d)", rp->regalloc[j].regoff);
-               }
-               else {
-                       show_allocation(rp->regalloc[j].type, rp->regalloc[j].flags, rp->regalloc[j].regoff);
-               }
-       }
-
-       printf("]\n");
-       for (j=0; j<depth; ++j)
-               putchar('\t');
-       printf("method: ");
-       method_print(rp->method);
-
-       printf("\n");
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* replace_show_replacement_points *********************************************
-   Print replacement point info.
-  
-   IN:
-       code.............codeinfo whose replacement points should be printed.
-  
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void replace_show_replacement_points(codeinfo *code)
-{
-       int i;
-       int depth;
-       rplpoint *rp;
-       rplpoint *parent;
-
-       if (!code) {
-               printf("(codeinfo *)NULL\n");
-               return;
-       }
-
-       printf("\treplacement points: %d\n",code->rplpointcount);
-
-       printf("\ttotal allocations : %d\n",code->regalloccount);
-       printf("\tsaved int regs    : %d\n",code->savedintcount);
-       printf("\tsaved flt regs    : %d\n",code->savedfltcount);
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-       printf("\tsaved adr regs    : %d\n",code->savedadrcount);
-#endif
-       printf("\tmemuse            : %d\n",code->memuse);
-
-       printf("\n");
-
-       for (i=0; i<code->rplpointcount; ++i) {
-               rp = code->rplpoints + i;
-
-               depth = 1;
-               parent = rp->parent;
-               while (parent) {
-                       depth++;
-                       parent = parent->parent;
-               }
-               replace_replacement_point_println(rp, depth);
-       }
-}
-#endif
-
-
-#if !defined(NDEBUG)
-static void java_value_print(s4 type, replace_val_t value)
-{
-       java_object_t *obj;
-       utf           *u;
-
-       printf("%016llx",(unsigned long long) value.l);
-
-       if (type < 0 || type > TYPE_RET)
-               printf(" <INVALID TYPE:%d>", type);
-       else
-               printf(" %s", show_jit_type_names[type]);
-
-       if (type == TYPE_ADR && value.a != NULL) {
-               obj = value.a;
-               putchar(' ');
-               utf_display_printable_ascii_classname(obj->vftbl->clazz->name);
-
-               if (obj->vftbl->clazz == class_java_lang_String) {
-                       printf(" \"");
-                       u = javastring_toutf(obj, false);
-                       utf_display_printable_ascii(u);
-                       printf("\"");
-               }
-       }
-       else if (type == TYPE_INT) {
-               printf(" %ld", (long) value.i);
-       }
-       else if (type == TYPE_LNG) {
-               printf(" %lld", (long long) value.l);
-       }
-       else if (type == TYPE_FLT) {
-               printf(" %f", value.f);
-       }
-       else if (type == TYPE_DBL) {
-               printf(" %f", value.d);
-       }
-}
-#endif /* !defined(NDEBUG) */
-
-
-#if !defined(NDEBUG)
-void replace_source_frame_println(sourceframe_t *frame)
-{
-       s4 i,j;
-       s4 t;
-
-       if (REPLACE_IS_NATIVE_FRAME(frame)) {
-               printf("\tNATIVE\n");
-               printf("\tsfi: "); replace_stackframeinfo_println(frame->sfi);
-               printf("\tnativepc: %p\n", frame->nativepc);
-               printf("\tframesize: %d\n", frame->nativeframesize);
-
-               j = 0;
-               for (i=0; i<INT_REG_CNT; ++i) {
-                       if (nregdescint[i] == REG_SAV)
-                               printf("\t%s = %p\n", abi_registers_integer_name[i], (void*)frame->nativesavint[j++]);
-               }
-
-               j = 0;
-               for (i=0; i<FLT_REG_CNT; ++i) {
-                       if (nregdescfloat[i] == REG_SAV)
-                               printf("\tF%02d = %f\n", i, frame->nativesavflt[j++]);
-               }
-
-               printf("\n");
-               return;
-       }
-
-       printf("\t");
-       method_println(frame->method);
-       printf("\tid: %d\n", frame->id);
-       printf("\ttype: %s\n", replace_type_str[frame->type]);
-       printf("\n");
-
-       if (frame->instance.a) {
-               printf("\tinstance: ");
-               java_value_print(TYPE_ADR, frame->instance);
-               printf("\n");
-       }
-
-       if (frame->javalocalcount) {
-               printf("\tlocals (%d):\n",frame->javalocalcount);
-               for (i=0; i<frame->javalocalcount; ++i) {
-                       t = frame->javalocaltype[i];
-                       if (t == TYPE_VOID) {
-                               printf("\tlocal[ %2d] = void\n",i);
-                       }
-                       else {
-                               printf("\tlocal[%c%2d] = ",TYPECHAR(t),i);
-                               java_value_print(t, frame->javalocals[i]);
-                               printf("\n");
-                       }
-               }
-               printf("\n");
-       }
-
-       if (frame->javastackdepth) {
-               printf("\tstack (depth %d):\n",frame->javastackdepth);
-               for (i=0; i<frame->javastackdepth; ++i) {
-                       t = frame->javastacktype[i];
-                       if (t == TYPE_VOID) {
-                               printf("\tstack[%2d] = void", i);
-                       }
-                       else {
-                               printf("\tstack[%2d] = ",i);
-                               java_value_print(frame->javastacktype[i], frame->javastack[i]);
-                               printf("\n");
-                       }
-               }
-               printf("\n");
-       }
-
-       if (frame->syncslotcount) {
-               printf("\tsynchronization slots (%d):\n",frame->syncslotcount);
-               for (i=0; i<frame->syncslotcount; ++i) {
-                       printf("\tslot[%2d] = ",i);
-#ifdef HAS_4BYTE_STACKSLOT
-                       printf("%08lx\n",(unsigned long) frame->syncslots[i].p);
-#else
-                       printf("%016llx\n",(unsigned long long) frame->syncslots[i].p);
-#endif
-               }
-               printf("\n");
-       }
-
-       if (frame->fromcode) {
-               printf("\tfrom %p ", (void*)frame->fromcode);
-               method_println(frame->fromcode->m);
-       }
-       if (frame->tocode) {
-               printf("\tto %p ", (void*)frame->tocode);
-               method_println(frame->tocode->m);
-       }
-
-       if (frame->fromrp) {
-               printf("\tfrom replacement point:\n");
-               replace_replacement_point_println(frame->fromrp, 2);
-       }
-       if (frame->torp) {
-               printf("\tto replacement point:\n");
-               replace_replacement_point_println(frame->torp, 2);
-       }
-
-       printf("\n");
-}
-#endif /* !defined(NDEBUG) */
-
-
-/* replace_sourcestate_println *************************************************
-   Print source state
-  
-   IN:
-       ss...............the source state to print
-  
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void replace_sourcestate_println(sourcestate_t *ss)
-{
-       int i;
-       sourceframe_t *frame;
-
-       if (!ss) {
-               printf("(sourcestate_t *)NULL\n");
-               return;
-       }
-
-       printf("sourcestate_t:\n");
-
-       for (i=0, frame = ss->frames; frame != NULL; frame = frame->down, ++i) {
-               printf("    frame %d:\n", i);
-               replace_source_frame_println(frame);
-       }
-}
-#endif
-
-
-/* replace_sourcestate_println_short *******************************************
-
-   Print a compact representation of the given source state.
-
-   IN:
-       ss...............the source state to print
-
-*******************************************************************************/
-
-#if !defined(NDEBUG)
-void replace_sourcestate_println_short(sourcestate_t *ss)
-{
-       sourceframe_t *frame;
-
-       for (frame = ss->frames; frame != NULL; frame = frame->down) {
-               printf("\t");
-
-               if (REPLACE_IS_NATIVE_FRAME(frame)) {
-                       printf("NATIVE (pc %p size %d) ",
-                                  (void*)frame->nativepc, frame->nativeframesize);
-                       replace_stackframeinfo_println(frame->sfi);
-                       continue;
-               }
-
-               if (frame->torp) {
-                       printf("%c", (frame->torp == frame->fromrp) ? '=' : '+');
-               }
-
-               printf("%s", replace_type_str[frame->fromrp->type]);
-
-               if (frame->torp && frame->torp->type != frame->fromrp->type)
-                       printf("->%s", replace_type_str[frame->torp->type]);
-
-               if (frame->tocode != frame->fromcode)
-                       printf(" (%p->%p/%d) ",
-                                  (void*) frame->fromcode, (void*) frame->tocode,
-                                  frame->fromrp->id);
-               else
-                       printf(" (%p/%d) ", (void*) frame->fromcode, frame->fromrp->id);
-
-               method_println(frame->method);
-       }
-}
-#endif
-
-#if !defined(NDEBUG)
-static void replace_stackframeinfo_println(stackframeinfo_t *sfi)
-{
-       printf("prev=%p pv=%p sp=%p ra=%p xpc=%p method=",
-                       (void*)sfi->prev, (void*)sfi->pv, (void*)sfi->sp,
-                       (void*)sfi->ra, (void*)sfi->xpc);
-
-       if (sfi->code)
-               method_println(sfi->code->m);
-       else
-               printf("(nil)\n");
-}
-#endif
-
-
-/*
- * 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/replace.cpp b/src/vm/jit/replace.cpp
new file mode 100644 (file)
index 0000000..a4ea93b
--- /dev/null
@@ -0,0 +1,3609 @@
+/* src/vm/jit/replace.cpp - on-stack replacement of methods
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "arch.h"
+#include "md.h"
+
+#if defined(ENABLE_GC_CACAO)
+# include "mm/cacao-gc/gc.h"
+#endif
+
+#include "mm/memory.h"
+
+#include "threads/thread.hpp"
+
+#include "toolbox/logging.h"
+
+#include "vm/classcache.h"
+#include "vm/globals.hpp"
+#include "vm/options.h"
+#include "vm/string.hpp"
+
+#if defined(ENABLE_RT_TIMING)
+# include "vm/rt-timing.h"
+#endif
+
+#include "vm/jit/abi.h"
+#include "vm/jit/asmpart.h"
+#include "vm/jit/disass.h"
+#include "vm/jit/executionstate.h"
+#include "vm/jit/jit.hpp"
+#include "vm/jit/methodheader.h"
+#include "vm/jit/replace.hpp"
+#include "vm/jit/show.h"
+#include "vm/jit/stack.h"
+
+
+#define REPLACE_PATCH_DYNAMIC_CALL
+/*#define REPLACE_PATCH_ALL*/
+
+#if defined(ENABLE_VMLOG)
+#include <vmlog_cacao.h>
+#endif
+
+/*** architecture-dependent configuration *************************************/
+
+/* first unset the macros (default) */
+#undef REPLACE_RA_BETWEEN_FRAMES
+#undef REPLACE_RA_TOP_OF_FRAME
+#undef REPLACE_RA_LINKAGE_AREA
+#undef REPLACE_LEAFMETHODS_RA_REGISTER
+
+/* i386, x86_64 and m68k */
+#if defined(__I386__) || defined(__X86_64__) || defined(__M68K__)
+#define REPLACE_RA_BETWEEN_FRAMES
+/* alpha */
+#elif defined(__ALPHA__)
+#define REPLACE_RA_TOP_OF_FRAME
+#define REPLACE_LEAFMETHODS_RA_REGISTER
+/* powerpc */
+#elif defined(__POWERPC__)
+#define REPLACE_RA_LINKAGE_AREA
+#define REPLACE_LEAFMETHODS_RA_REGISTER
+/* s390 */
+#elif defined(__S390__)
+#define REPLACE_RA_TOP_OF_FRAME
+#endif
+
+
+/*** configuration of native stack slot size **********************************/
+
+/* XXX this should be in md-abi.h files, probably */
+
+#if defined(HAS_4BYTE_STACKSLOT)
+#define SIZE_OF_STACKSLOT      4
+#define STACK_SLOTS_PER_FLOAT  2
+typedef u4 stackslot_t;
+#else
+#define SIZE_OF_STACKSLOT      8
+#define STACK_SLOTS_PER_FLOAT  1
+typedef u8 stackslot_t;
+#endif
+
+
+/*** debugging ****************************************************************/
+
+#if !defined(NDEBUG)
+static void java_value_print(s4 type, replace_val_t value);
+static void replace_stackframeinfo_println(stackframeinfo_t *sfi);
+#endif
+
+#if !defined(NDEBUG)
+#define DOLOG(code)        do{ if (opt_TraceReplacement > 1) { code; } } while(0)
+#define DOLOG_SHORT(code)  do{ if (opt_TraceReplacement > 0) { code; } } while(0)
+#else
+#define DOLOG(code)
+#define DOLOG_SHORT(code)
+#endif
+
+
+/*** statistics ***************************************************************/
+
+#define REPLACE_STATISTICS
+
+#if defined(REPLACE_STATISTICS)
+
+static int stat_replacements = 0;
+static int stat_frames = 0;
+static int stat_recompile = 0;
+static int stat_staticpatch = 0;
+static int stat_unroll_inline = 0;
+static int stat_unroll_call = 0;
+static int stat_dist_frames[20] = { 0 };
+static int stat_dist_locals[20] = { 0 };
+static int stat_dist_locals_adr[10] = { 0 };
+static int stat_dist_locals_prim[10] = { 0 };
+static int stat_dist_locals_ret[10] = { 0 };
+static int stat_dist_locals_void[10] = { 0 };
+static int stat_dist_stack[10] = { 0 };
+static int stat_dist_stack_adr[10] = { 0 };
+static int stat_dist_stack_prim[10] = { 0 };
+static int stat_dist_stack_ret[10] = { 0 };
+static int stat_methods = 0;
+static int stat_rploints = 0;
+static int stat_regallocs = 0;
+static int stat_dist_method_rplpoints[20] = { 0 };
+
+#define REPLACE_COUNT(cnt)  (cnt)++
+#define REPLACE_COUNT_IF(cnt, cond)  do{ if(cond) (cnt)++; } while(0)
+#define REPLACE_COUNT_INC(cnt, inc)  ((cnt) += (inc))
+
+#define REPLACE_COUNT_DIST(array, val)                               \
+    do {                                                             \
+        int limit = (sizeof(array) / sizeof(int)) - 1;               \
+        if ((val) < (limit)) (array)[val]++;                         \
+        else (array)[limit]++;                                       \
+    } while (0)
+
+static void replace_statistics_source_frame(sourceframe_t *frame);
+
+#else
+
+#define REPLACE_COUNT(cnt)
+#define REPLACE_COUNT_IF(cnt, cond)
+#define REPLACE_COUNT_INC(cnt, inc)
+#define REPLACE_COUNT_DIST(array, val)
+
+#endif /* defined(REPLACE_STATISTICS) */
+
+
+/*** constants used internally ************************************************/
+
+#define TOP_IS_NORMAL    0
+#define TOP_IS_ON_STACK  1
+#define TOP_IS_IN_ITMP1  2
+#define TOP_IS_VOID      3
+
+
+/******************************************************************************/
+/* PART I: Creating / freeing replacement points                              */
+/******************************************************************************/
+
+
+/* replace_create_replacement_point ********************************************
+   Create a replacement point.
+  
+   IN:
+       jd...............current jitdata
+          iinfo............inlining info for the current position
+          rp...............pre-allocated (uninitialized) rplpoint
+          type.............RPLPOINT_TYPE constant
+          iptr.............current instruction
+          *pra.............current rplalloc pointer
+          javalocals.......the javalocals at the current point
+          stackvars........the stack variables at the current point
+          stackdepth.......the stack depth at the current point
+          paramcount.......number of parameters at the start of stackvars
+  
+   OUT:
+       *rpa.............points to the next free rplalloc
+  
+*******************************************************************************/
+
+static void replace_create_replacement_point(jitdata *jd,
+                                                                                        insinfo_inline *iinfo,
+                                                                                        rplpoint *rp,
+                                                                                        s4 type,
+                                                                                        instruction *iptr,
+                                                                                        rplalloc **pra,
+                                                                                        s4 *javalocals,
+                                                                                        s4 *stackvars,
+                                                                                        s4 stackdepth,
+                                                                                        s4 paramcount)
+{
+       rplalloc *ra;
+       s4        i;
+       varinfo  *v;
+       s4        index;
+
+       ra = *pra;
+
+       REPLACE_COUNT(stat_rploints);
+
+       rp->method = (iinfo) ? iinfo->method : jd->m;
+       rp->pc = NULL;        /* set by codegen */
+       rp->callsize = 0;     /* set by codegen */
+       rp->regalloc = ra;
+       rp->flags = 0;
+       rp->type = type;
+       rp->id = iptr->flags.bits >> INS_FLAG_ID_SHIFT;
+
+       /* XXX unify these two fields */
+       rp->parent = (iinfo) ? iinfo->rp : NULL;
+
+       /* store local allocation info of javalocals */
+
+       if (javalocals) {
+               for (i = 0; i < rp->method->maxlocals; ++i) {
+                       index = javalocals[i];
+                       if (index == UNUSED)
+                               continue;
+
+                       ra->index = i;
+                       if (index >= 0) {
+                               v = VAR(index);
+                               ra->flags = v->flags & (INMEMORY);
+                               ra->regoff = v->vv.regoff;
+                               ra->type = v->type;
+                       }
+                       else {
+                               ra->regoff = RETADDR_FROM_JAVALOCAL(index);
+                               ra->type = TYPE_RET;
+                               ra->flags = 0;
+                       }
+                       ra++;
+               }
+       }
+
+       /* store allocation info of java stack vars */
+
+       for (i = 0; i < stackdepth; ++i) {
+               v = VAR(stackvars[i]);
+               ra->flags = v->flags & (INMEMORY);
+               ra->index = (i < paramcount) ? RPLALLOC_PARAM : RPLALLOC_STACK;
+               ra->type  = v->type;
+               /* XXX how to handle locals on the stack containing returnAddresses? */
+               if (v->type == TYPE_RET) {
+                       assert(stackvars[i] >= jd->localcount);
+                       ra->regoff = v->vv.retaddr->nr;
+               }
+               else
+                       ra->regoff = v->vv.regoff;
+               ra++;
+       }
+
+       /* total number of allocations */
+
+       rp->regalloccount = ra - rp->regalloc;
+
+       *pra = ra;
+}
+
+
+/* replace_create_inline_start_replacement_point *******************************
+
+   Create an INLINE_START replacement point.
+
+   IN:
+       jd...............current jitdata
+          rp...............pre-allocated (uninitialized) rplpoint
+          iptr.............current instruction
+          *pra.............current rplalloc pointer
+          javalocals.......the javalocals at the current point
+
+   OUT:
+       *rpa.............points to the next free rplalloc
+
+   RETURN VALUE:
+       the insinfo_inline * for the following inlined body
+
+*******************************************************************************/
+
+static insinfo_inline * replace_create_inline_start_replacement_point(
+                                                                                        jitdata *jd,
+                                                                                        rplpoint *rp,
+                                                                                        instruction *iptr,
+                                                                                        rplalloc **pra,
+                                                                                        s4 *javalocals)
+{
+       insinfo_inline *calleeinfo;
+       rplalloc       *ra;
+
+       calleeinfo = iptr->sx.s23.s3.inlineinfo;
+
+       calleeinfo->rp = rp;
+
+       replace_create_replacement_point(jd, calleeinfo->parent, rp,
+                       RPLPOINT_TYPE_INLINE, iptr, pra,
+                       javalocals,
+                       calleeinfo->stackvars, calleeinfo->stackvarscount,
+                       calleeinfo->paramcount);
+
+       if (calleeinfo->synclocal != UNUSED) {
+               ra = (*pra)++;
+               ra->index  = RPLALLOC_SYNC;
+               ra->regoff = jd->var[calleeinfo->synclocal].vv.regoff;
+               ra->flags  = jd->var[calleeinfo->synclocal].flags & INMEMORY;
+               ra->type   = TYPE_ADR;
+
+               rp->regalloccount++;
+       }
+
+       return calleeinfo;
+}
+
+
+/* replace_create_replacement_points *******************************************
+   Create the replacement points for the given code.
+  
+   IN:
+       jd...............current jitdata, must not have any replacement points
+  
+   OUT:
+       code->rplpoints.......set to the list of replacement points
+          code->rplpointcount...number of replacement points
+          code->regalloc........list of allocation info
+          code->regalloccount...total length of allocation info list
+          code->globalcount.....number of global allocations at the
+                                start of code->regalloc
+  
+   RETURN VALUE:
+       true.............everything ok 
+       false............an exception has been thrown
+   
+*******************************************************************************/
+
+#define CLEAR_javalocals(array, method)                              \
+    do {                                                             \
+        for (i=0; i<(method)->maxlocals; ++i)                        \
+            (array)[i] = UNUSED;                                     \
+    } while (0)
+
+#define COPY_OR_CLEAR_javalocals(dest, array, method)                \
+    do {                                                             \
+        if ((array) != NULL)                                         \
+            MCOPY((dest), (array), s4, (method)->maxlocals);         \
+        else                                                         \
+            CLEAR_javalocals((dest), (method));                      \
+    } while (0)
+
+#define COUNT_javalocals(array, method, counter)                     \
+    do {                                                             \
+        for (i=0; i<(method)->maxlocals; ++i)                        \
+            if ((array)[i] != UNUSED)                                \
+                               (counter)++;                                         \
+    } while (0)
+
+bool replace_create_replacement_points(jitdata *jd)
+{
+       codeinfo        *code;
+       registerdata    *rd;
+       basicblock      *bptr;
+       int              count;
+       methodinfo      *m;
+       rplpoint        *rplpoints;
+       rplpoint        *rp;
+       int              alloccount;
+       rplalloc        *regalloc;
+       rplalloc        *ra;
+       int              i;
+       instruction     *iptr;
+       instruction     *iend;
+       s4              *javalocals;
+       s4              *jl;
+       methoddesc      *md;
+       insinfo_inline  *iinfo;
+       s4               startcount;
+       s4               firstcount;
+#if defined(REPLACE_PATCH_DYNAMIC_CALL)
+       bool             needentry;
+#endif
+
+       REPLACE_COUNT(stat_methods);
+
+       /* get required compiler data */
+
+       code = jd->code;
+       rd   = jd->rd;
+
+       /* assert that we wont overwrite already allocated data */
+
+       assert(code);
+       assert(code->m);
+       assert(code->rplpoints == NULL);
+       assert(code->rplpointcount == 0);
+       assert(code->regalloc == NULL);
+       assert(code->regalloccount == 0);
+       assert(code->globalcount == 0);
+
+       m = code->m;
+
+       /* in instance methods, we may need a rplpoint at the method entry */
+
+#if defined(REPLACE_PATCH_DYNAMIC_CALL)
+       if (!(m->flags & ACC_STATIC)) {
+               jd->basicblocks[0].bitflags |= BBFLAG_REPLACEMENT;
+               needentry = true;
+       }
+       else {
+               needentry = false;
+       }
+#endif /* defined(REPLACE_PATCH_DYNAMIC_CALL) */
+
+       /* iterate over the basic block list to find replacement points */
+
+       count = 0;
+       alloccount = 0;
+
+       javalocals = DMNEW(s4, jd->maxlocals);
+
+       for (bptr = jd->basicblocks; bptr; bptr = bptr->next) {
+
+               /* skip dead code */
+
+               if (bptr->flags < BBFINISHED)
+                       continue;
+
+               /* get info about this block */
+
+               m = bptr->method;
+               iinfo = bptr->inlineinfo;
+
+               /* initialize javalocals at the start of this block */
+
+               COPY_OR_CLEAR_javalocals(javalocals, bptr->javalocals, m);
+
+               /* iterate over the instructions */
+
+               iptr = bptr->iinstr;
+               iend = iptr + bptr->icount;
+               startcount = count;
+               firstcount = count;
+
+               for (; iptr != iend; ++iptr) {
+                       switch (iptr->opc) {
+#if defined(ENABLE_GC_CACAO)
+                               case ICMD_BUILTIN:
+                                       md = iptr->sx.s23.s3.bte->md;
+                                       count++;
+                                       COUNT_javalocals(javalocals, m, alloccount);
+                                       alloccount += iptr->s1.argcount;
+                                       if (iinfo)
+                                               alloccount -= iinfo->throughcount;
+                                       break;
+#endif
+
+                               case ICMD_INVOKESTATIC:
+                               case ICMD_INVOKESPECIAL:
+                               case ICMD_INVOKEVIRTUAL:
+                               case ICMD_INVOKEINTERFACE:
+                                       INSTRUCTION_GET_METHODDESC(iptr, md);
+                                       count++;
+                                       COUNT_javalocals(javalocals, m, alloccount);
+                                       alloccount += iptr->s1.argcount;
+                                       if (iinfo)
+                                               alloccount -= iinfo->throughcount;
+                                       break;
+
+                               case ICMD_ISTORE:
+                               case ICMD_LSTORE:
+                               case ICMD_FSTORE:
+                               case ICMD_DSTORE:
+                               case ICMD_ASTORE:
+                                       stack_javalocals_store(iptr, javalocals);
+                                       break;
+
+                               case ICMD_IRETURN:
+                               case ICMD_LRETURN:
+                               case ICMD_FRETURN:
+                               case ICMD_DRETURN:
+                               case ICMD_ARETURN:
+                                       alloccount += 1;
+                                       /* FALLTHROUGH! */
+                               case ICMD_RETURN:
+                                       count++;
+                                       break;
+
+                               case ICMD_INLINE_START:
+                                       iinfo = iptr->sx.s23.s3.inlineinfo;
+
+                                       count++;
+                                       COUNT_javalocals(javalocals, m, alloccount);
+                                       alloccount += iinfo->stackvarscount;
+                                       if (iinfo->synclocal != UNUSED)
+                                               alloccount++;
+
+                                       m = iinfo->method;
+                                       /* javalocals may be set at next block start, or now */
+                                       COPY_OR_CLEAR_javalocals(javalocals, iinfo->javalocals_start, m);
+                                       break;
+
+                               case ICMD_INLINE_BODY:
+                                       assert(iinfo == iptr->sx.s23.s3.inlineinfo);
+
+                                       jl = iinfo->javalocals_start;
+                                       if (jl == NULL) {
+                                               /* get the javalocals from the following block start */
+                                               assert(bptr->next);
+                                               jl = bptr->next->javalocals;
+                                       }
+                                       count++;
+                                       COUNT_javalocals(jl, m, alloccount);
+                                       break;
+
+                               case ICMD_INLINE_END:
+                                       assert(iinfo == iptr->sx.s23.s3.inlineinfo ||
+                                                  iinfo == iptr->sx.s23.s3.inlineinfo->parent);
+                                       iinfo = iptr->sx.s23.s3.inlineinfo;
+                                       m = iinfo->outer;
+                                       if (iinfo->javalocals_end)
+                                               MCOPY(javalocals, iinfo->javalocals_end, s4, m->maxlocals);
+                                       iinfo = iinfo->parent;
+                                       break;
+                       }
+
+                       if (iptr == bptr->iinstr)
+                               firstcount = count;
+               } /* end instruction loop */
+
+               /* create replacement points at targets of backward branches */
+               /* We only need the replacement point there, if there is no  */
+               /* replacement point inside the block.                       */
+
+               if (bptr->bitflags & BBFLAG_REPLACEMENT) {
+#if defined(REPLACE_PATCH_DYNAMIC_CALL)
+                       int test = (needentry && bptr == jd->basicblocks) ? firstcount : count;
+#else
+                       int test = count;
+#endif
+                       if (test > startcount) {
+                               /* we don't need an extra rplpoint */
+                               bptr->bitflags &= ~BBFLAG_REPLACEMENT;
+                       }
+                       else {
+                               count++;
+                               alloccount += bptr->indepth;
+                               if (bptr->inlineinfo)
+                                       alloccount -= bptr->inlineinfo->throughcount;
+
+                               COUNT_javalocals(bptr->javalocals, bptr->method, alloccount);
+                       }
+               }
+
+       } /* end basicblock loop */
+
+       /* if no points were found, there's nothing to do */
+
+       if (!count)
+               return true;
+
+       /* allocate replacement point array and allocation array */
+
+       rplpoints = MNEW(rplpoint, count);
+       regalloc = MNEW(rplalloc, alloccount);
+       ra = regalloc;
+
+       /* initialize replacement point structs */
+
+       rp = rplpoints;
+
+       /* XXX try to share code with the counting loop! */
+
+       for (bptr = jd->basicblocks; bptr; bptr = bptr->next) {
+               /* skip dead code */
+
+               if (bptr->flags < BBFINISHED)
+                       continue;
+
+               /* get info about this block */
+
+               m = bptr->method;
+               iinfo = bptr->inlineinfo;
+
+               /* initialize javalocals at the start of this block */
+
+               COPY_OR_CLEAR_javalocals(javalocals, bptr->javalocals, m);
+
+               /* create replacement points at targets of backward branches */
+
+               if (bptr->bitflags & BBFLAG_REPLACEMENT) {
+
+                       i = (iinfo) ? iinfo->throughcount : 0;
+                       replace_create_replacement_point(jd, iinfo, rp++,
+                                       bptr->type, bptr->iinstr, &ra,
+                                       bptr->javalocals, bptr->invars + i, bptr->indepth - i, 0);
+
+                       if (JITDATA_HAS_FLAG_COUNTDOWN(jd))
+                               rp[-1].flags |= RPLPOINT_FLAG_COUNTDOWN;
+               }
+
+               /* iterate over the instructions */
+
+               iptr = bptr->iinstr;
+               iend = iptr + bptr->icount;
+
+               for (; iptr != iend; ++iptr) {
+                       switch (iptr->opc) {
+#if defined(ENABLE_GC_CACAO)
+                               case ICMD_BUILTIN:
+                                       md = iptr->sx.s23.s3.bte->md;
+
+                                       i = (iinfo) ? iinfo->throughcount : 0;
+                                       replace_create_replacement_point(jd, iinfo, rp++,
+                                                       RPLPOINT_TYPE_CALL, iptr, &ra,
+                                                       javalocals, iptr->sx.s23.s2.args,
+                                                       iptr->s1.argcount - i,
+                                                       md->paramcount);
+                                       break;
+#endif
+
+                               case ICMD_INVOKESTATIC:
+                               case ICMD_INVOKESPECIAL:
+                               case ICMD_INVOKEVIRTUAL:
+                               case ICMD_INVOKEINTERFACE:
+                                       INSTRUCTION_GET_METHODDESC(iptr, md);
+
+                                       i = (iinfo) ? iinfo->throughcount : 0;
+                                       replace_create_replacement_point(jd, iinfo, rp++,
+                                                       RPLPOINT_TYPE_CALL, iptr, &ra,
+                                                       javalocals, iptr->sx.s23.s2.args,
+                                                       iptr->s1.argcount - i,
+                                                       md->paramcount);
+                                       break;
+
+                               case ICMD_ISTORE:
+                               case ICMD_LSTORE:
+                               case ICMD_FSTORE:
+                               case ICMD_DSTORE:
+                               case ICMD_ASTORE:
+                                       stack_javalocals_store(iptr, javalocals);
+                                       break;
+
+                               case ICMD_IRETURN:
+                               case ICMD_LRETURN:
+                               case ICMD_FRETURN:
+                               case ICMD_DRETURN:
+                               case ICMD_ARETURN:
+                                       replace_create_replacement_point(jd, iinfo, rp++,
+                                                       RPLPOINT_TYPE_RETURN, iptr, &ra,
+                                                       NULL, &(iptr->s1.varindex), 1, 0);
+                                       break;
+
+                               case ICMD_RETURN:
+                                       replace_create_replacement_point(jd, iinfo, rp++,
+                                                       RPLPOINT_TYPE_RETURN, iptr, &ra,
+                                                       NULL, NULL, 0, 0);
+                                       break;
+
+                               case ICMD_INLINE_START:
+                                       iinfo = replace_create_inline_start_replacement_point(
+                                                               jd, rp++, iptr, &ra, javalocals);
+                                       m = iinfo->method;
+                                       /* javalocals may be set at next block start, or now */
+                                       COPY_OR_CLEAR_javalocals(javalocals, iinfo->javalocals_start, m);
+                                       break;
+
+                               case ICMD_INLINE_BODY:
+                                       assert(iinfo == iptr->sx.s23.s3.inlineinfo);
+
+                                       jl = iinfo->javalocals_start;
+                                       if (jl == NULL) {
+                                               /* get the javalocals from the following block start */
+                                               assert(bptr->next);
+                                               jl = bptr->next->javalocals;
+                                       }
+                                       /* create a non-trappable rplpoint */
+                                       replace_create_replacement_point(jd, iinfo, rp++,
+                                                       RPLPOINT_TYPE_BODY, iptr, &ra,
+                                                       jl, NULL, 0, 0);
+                                       rp[-1].flags |= RPLPOINT_FLAG_NOTRAP;
+                                       break;
+
+                               case ICMD_INLINE_END:
+                                       assert(iinfo == iptr->sx.s23.s3.inlineinfo ||
+                                                  iinfo == iptr->sx.s23.s3.inlineinfo->parent);
+                                       iinfo = iptr->sx.s23.s3.inlineinfo;
+                                       m = iinfo->outer;
+                                       if (iinfo->javalocals_end)
+                                               MCOPY(javalocals, iinfo->javalocals_end, s4, m->maxlocals);
+                                       iinfo = iinfo->parent;
+                                       break;
+                       }
+               } /* end instruction loop */
+       } /* end basicblock loop */
+
+       assert((rp - rplpoints) == count);
+       assert((ra - regalloc) == alloccount);
+
+       /* store the data in the codeinfo */
+
+       code->rplpoints     = rplpoints;
+       code->rplpointcount = count;
+       code->regalloc      = regalloc;
+       code->regalloccount = alloccount;
+       code->globalcount   = 0;
+       code->savedintcount = INT_SAV_CNT - rd->savintreguse;
+       code->savedfltcount = FLT_SAV_CNT - rd->savfltreguse;
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       code->savedadrcount = ADR_SAV_CNT - rd->savadrreguse;
+#endif
+       code->memuse        = rd->memuse;
+       code->stackframesize = jd->cd->stackframesize;
+
+       REPLACE_COUNT_DIST(stat_dist_method_rplpoints, count);
+       REPLACE_COUNT_INC(stat_regallocs, alloccount);
+
+       /* everything alright */
+
+       return true;
+}
+
+
+/* replace_free_replacement_points *********************************************
+   Free memory used by replacement points.
+  
+   IN:
+       code.............codeinfo whose replacement points should be freed.
+  
+*******************************************************************************/
+
+void replace_free_replacement_points(codeinfo *code)
+{
+       assert(code);
+
+       if (code->rplpoints)
+               MFREE(code->rplpoints,rplpoint,code->rplpointcount);
+
+       if (code->regalloc)
+               MFREE(code->regalloc,rplalloc,code->regalloccount);
+
+       code->rplpoints = NULL;
+       code->rplpointcount = 0;
+       code->regalloc = NULL;
+       code->regalloccount = 0;
+       code->globalcount = 0;
+}
+
+
+/******************************************************************************/
+/* PART II: Activating / deactivating replacement points                      */
+/******************************************************************************/
+
+
+/* replace_activate_replacement_points *****************************************
+   Activate the replacement points of the given compilation unit. When this
+   function returns, the replacement points are "armed", so each thread
+   reaching one of the points will enter the replacement mechanism.
+   
+   IN:
+       code.............codeinfo of which replacement points should be
+                                               activated
+          mappable.........if true, only mappable replacement points are
+                                               activated
+  
+*******************************************************************************/
+
+void replace_activate_replacement_points(codeinfo *code, bool mappable)
+{
+       rplpoint *rp;
+       s4        i;
+       s4        count;
+       u1       *savedmcode;
+
+       assert(code->savedmcode == NULL);
+
+       /* count trappable replacement points */
+
+       count = 0;
+       i = code->rplpointcount;
+       rp = code->rplpoints;
+       for (; i--; rp++) {
+               if (rp->flags & RPLPOINT_FLAG_NOTRAP)
+                       continue;
+
+               if (mappable && (rp->type == RPLPOINT_TYPE_RETURN))
+                       continue;
+
+               count++;
+       }
+
+       /* allocate buffer for saved machine code */
+
+       savedmcode = MNEW(u1, count * REPLACEMENT_PATCH_SIZE);
+       code->savedmcode = savedmcode;
+       savedmcode += count * REPLACEMENT_PATCH_SIZE;
+
+       /* activate trappable replacement points */
+       /* (in reverse order to handle overlapping points within basic blocks) */
+
+       i = code->rplpointcount;
+       rp = code->rplpoints + i;
+       while (rp--, i--) {
+               assert(!(rp->flags & RPLPOINT_FLAG_ACTIVE));
+
+               if (rp->flags & RPLPOINT_FLAG_NOTRAP)
+                       continue;
+
+               if (mappable && (rp->type == RPLPOINT_TYPE_RETURN))
+                       continue;
+
+               DOLOG( printf("activate replacement point:\n");
+                          replace_replacement_point_println(rp, 1); fflush(stdout); );
+
+               savedmcode -= REPLACEMENT_PATCH_SIZE;
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_DISASSEMBLER)
+               DOLOG( printf("\tinstruction before: ");
+                          disassinstr(rp->pc); fflush(stdout); );
+# endif
+
+               md_patch_replacement_point(rp->pc, savedmcode, false);
+
+# if defined(ENABLE_DISASSEMBLER)
+               DOLOG( printf("\tinstruction after : ");
+                          disassinstr(rp->pc); fflush(stdout); );
+# endif
+#endif
+
+               rp->flags |= RPLPOINT_FLAG_ACTIVE;
+       }
+
+       assert(savedmcode == code->savedmcode);
+}
+
+
+/* replace_deactivate_replacement_points ***************************************
+   Deactivate a replacement points in the given compilation unit.
+   When this function returns, the replacement points will be "un-armed",
+   that is a each thread reaching a point will just continue normally.
+   
+   IN:
+       code.............the compilation unit
+  
+*******************************************************************************/
+
+void replace_deactivate_replacement_points(codeinfo *code)
+{
+       rplpoint *rp;
+       s4        i;
+       s4        count;
+       u1       *savedmcode;
+
+       if (code->savedmcode == NULL) {
+               /* disarm countdown points by patching the branches */
+
+               i = code->rplpointcount;
+               rp = code->rplpoints;
+               for (; i--; rp++) {
+                       if ((rp->flags & (RPLPOINT_FLAG_ACTIVE | RPLPOINT_FLAG_COUNTDOWN))
+                                       == RPLPOINT_FLAG_COUNTDOWN)
+                       {
+#if 0
+                               *(s4*) (rp->pc + 9) = 0; /* XXX machine dependent! */
+#endif
+                       }
+               }
+               return;
+       }
+
+       assert(code->savedmcode != NULL);
+       savedmcode = code->savedmcode;
+
+       /* de-activate each trappable replacement point */
+
+       i = code->rplpointcount;
+       rp = code->rplpoints;
+       count = 0;
+       for (; i--; rp++) {
+               if (!(rp->flags & RPLPOINT_FLAG_ACTIVE))
+                       continue;
+
+               count++;
+
+               DOLOG( printf("deactivate replacement point:\n");
+                          replace_replacement_point_println(rp, 1); fflush(stdout); );
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_DISASSEMBLER)
+               DOLOG( printf("\tinstruction before: ");
+                          disassinstr(rp->pc); fflush(stdout); );
+# endif
+
+               md_patch_replacement_point(rp->pc, savedmcode, true);
+
+# if defined(ENABLE_DISASSEMBLER)
+               DOLOG( printf("\tinstruction before: ");
+                          disassinstr(rp->pc); fflush(stdout); );
+# endif
+#endif
+
+               rp->flags &= ~RPLPOINT_FLAG_ACTIVE;
+
+               savedmcode += REPLACEMENT_PATCH_SIZE;
+       }
+
+       assert(savedmcode == code->savedmcode + count * REPLACEMENT_PATCH_SIZE);
+
+       /* free saved machine code */
+
+       MFREE(code->savedmcode, u1, count * REPLACEMENT_PATCH_SIZE);
+       code->savedmcode = NULL;
+}
+
+
+/******************************************************************************/
+/* PART III: The replacement mechanism                                        */
+/******************************************************************************/
+
+
+/* replace_read_value **********************************************************
+
+   Read a value with the given allocation from the execution state.
+   
+   IN:
+          es...............execution state
+          ra...............allocation
+          javaval..........where to put the value
+
+   OUT:
+       *javaval.........the value
+  
+*******************************************************************************/
+
+static void replace_read_value(executionstate_t *es,
+                                                          rplalloc *ra,
+                                                          replace_val_t *javaval)
+{
+       if (ra->flags & INMEMORY) {
+               /* XXX HAS_4BYTE_STACKSLOT may not be the right discriminant here */
+#ifdef HAS_4BYTE_STACKSLOT
+               if (IS_2_WORD_TYPE(ra->type)) {
+                       javaval->l = *(u8*)(es->sp + ra->regoff);
+               }
+               else {
+#endif
+                       javaval->p = *(ptrint*)(es->sp + ra->regoff);
+#ifdef HAS_4BYTE_STACKSLOT
+               }
+#endif
+       }
+       else {
+               /* allocated register */
+               if (IS_FLT_DBL_TYPE(ra->type)) {
+                       javaval->d = es->fltregs[ra->regoff];
+
+                       if (ra->type == TYPE_FLT)
+                               javaval->f = javaval->d;
+               }
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+               else if (IS_ADR_TYPE(ra->type)) {
+                       javaval->p = es->adrregs[ra->regoff];
+               }
+#endif
+               else {
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                       if (ra->type == TYPE_LNG) {
+                               javaval->words.lo = es->intregs[GET_LOW_REG(ra->regoff)];
+                               javaval->words.hi = es->intregs[GET_HIGH_REG(ra->regoff)];
+                       }
+                       else
+#endif /* defined(SUPPORT_COMBINE_INTEGER_REGISTERS) */
+                               javaval->p = es->intregs[ra->regoff];
+               }
+       }
+}
+
+
+/* replace_write_value *********************************************************
+
+   Write a value to the given allocation in the execution state.
+   
+   IN:
+          es...............execution state
+          ra...............allocation
+          *javaval.........the value
+
+*******************************************************************************/
+
+static void replace_write_value(executionstate_t *es,
+                                                           rplalloc *ra,
+                                                           replace_val_t *javaval)
+{
+       if (ra->flags & INMEMORY) {
+               /* XXX HAS_4BYTE_STACKSLOT may not be the right discriminant here */
+#ifdef HAS_4BYTE_STACKSLOT
+               if (IS_2_WORD_TYPE(ra->type)) {
+                       *(u8*)(es->sp + ra->regoff) = javaval->l;
+               }
+               else {
+#endif
+                       *(ptrint*)(es->sp + ra->regoff) = javaval->p;
+#ifdef HAS_4BYTE_STACKSLOT
+               }
+#endif
+       }
+       else {
+               /* allocated register */
+               switch (ra->type) {
+                       case TYPE_FLT:
+                               es->fltregs[ra->regoff] = (double) javaval->f;
+                               break;
+                       case TYPE_DBL:
+                               es->fltregs[ra->regoff] = javaval->d;
+                               break;
+#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
+                       case TYPE_LNG:
+                               es->intregs[GET_LOW_REG(ra->regoff)] = javaval->words.lo;
+                               es->intregs[GET_HIGH_REG(ra->regoff)] = javaval->words.hi;
+                               break;
+#endif
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+                       case TYPE_ADR:
+                               es->adrregs[ra->regoff] = javaval->p;
+#endif
+                       default:
+                               es->intregs[ra->regoff] = javaval->p;
+               }
+       }
+}
+
+
+/* replace_new_sourceframe *****************************************************
+
+   Allocate a new source frame and insert it at the front of the frame list.
+   
+   IN:
+          ss...............the source state
+
+   OUT:
+          ss->frames.......set to new frame (the new head of the frame list).
+
+   RETURN VALUE:
+       returns the new frame
+
+*******************************************************************************/
+
+static sourceframe_t *replace_new_sourceframe(sourcestate_t *ss)
+{
+       sourceframe_t *frame;
+
+       frame = DNEW(sourceframe_t);
+       MZERO(frame, sourceframe_t, 1);
+
+       frame->down = ss->frames;
+       ss->frames = frame;
+
+       return frame;
+}
+
+
+/* replace_read_executionstate *************************************************
+
+   Read a source frame from the given executions state.
+   The new source frame is pushed to the front of the frame list of the
+   source state.
+
+   IN:
+       rp...............replacement point at which `es` was taken
+          es...............execution state
+          ss...............the source state to add the source frame to
+          topframe.........true, if the first (top-most) source frame on the
+                           stack is to be read
+
+   OUT:
+       *ss..............the source state with the newly created source frame
+                           added
+  
+*******************************************************************************/
+
+static s4 replace_normalize_type_map[] = {
+/* RPLPOINT_TYPE_STD    |--> */ RPLPOINT_TYPE_STD,
+/* RPLPOINT_TYPE_EXH    |--> */ RPLPOINT_TYPE_STD,
+/* RPLPOINT_TYPE_SBR    |--> */ RPLPOINT_TYPE_STD,
+/* RPLPOINT_TYPE_CALL   |--> */ RPLPOINT_TYPE_CALL,
+/* RPLPOINT_TYPE_INLINE |--> */ RPLPOINT_TYPE_CALL,
+/* RPLPOINT_TYPE_RETURN |--> */ RPLPOINT_TYPE_RETURN,
+/* RPLPOINT_TYPE_BODY   |--> */ RPLPOINT_TYPE_STD
+};
+
+
+static void replace_read_executionstate(rplpoint *rp,
+                                                                               executionstate_t *es,
+                                                                               sourcestate_t *ss,
+                                                                               bool topframe)
+{
+       methodinfo    *m;
+       codeinfo      *code;
+       int            count;
+       int            i;
+       rplalloc      *ra;
+       sourceframe_t *frame;
+       int            topslot;
+       stackslot_t   *sp;
+       stackslot_t   *basesp;
+
+       code = code_find_codeinfo_for_pc(rp->pc);
+       m = rp->method;
+       topslot = TOP_IS_NORMAL;
+
+       /* stack pointer */
+
+       sp = (stackslot_t *) es->sp;
+
+       /* in some cases the top stack slot is passed in REG_ITMP1 */
+
+       if (rp->type == BBTYPE_EXH) {
+               topslot = TOP_IS_IN_ITMP1;
+       }
+
+       /* calculate base stack pointer */
+
+       basesp = sp + code->stackframesize;
+
+       /* create the source frame */
+
+       frame = replace_new_sourceframe(ss);
+       frame->method = rp->method;
+       frame->id = rp->id;
+       assert(rp->type >= 0 && rp->type < sizeof(replace_normalize_type_map)/sizeof(s4));
+       frame->type = replace_normalize_type_map[rp->type];
+       frame->fromrp = rp;
+       frame->fromcode = code;
+
+       /* read local variables */
+
+       count = m->maxlocals;
+       frame->javalocalcount = count;
+       frame->javalocals = DMNEW(replace_val_t, count);
+       frame->javalocaltype = DMNEW(u1, count);
+
+       /* mark values as undefined */
+       for (i=0; i<count; ++i) {
+#if !defined(NDEBUG)
+               frame->javalocals[i].l = (u8) 0x00dead0000dead00ULL;
+#endif
+               frame->javalocaltype[i] = TYPE_VOID;
+       }
+
+       /* some entries in the intregs array are not meaningful */
+       /*es->intregs[REG_ITMP3] = (u8) 0x11dead1111dead11ULL;*/
+#if !defined(NDEBUG)
+       es->intregs[REG_SP   ] = (ptrint) 0x11dead1111dead11ULL;
+#ifdef REG_PV
+       es->intregs[REG_PV   ] = (ptrint) 0x11dead1111dead11ULL;
+#endif
+#endif /* !defined(NDEBUG) */
+
+       /* read javalocals */
+
+       count = rp->regalloccount;
+       ra = rp->regalloc;
+
+       while (count && (i = ra->index) >= 0) {
+               assert(i < m->maxlocals);
+               frame->javalocaltype[i] = ra->type;
+               if (ra->type == TYPE_RET)
+                       frame->javalocals[i].i = ra->regoff;
+               else
+                       replace_read_value(es, ra, frame->javalocals + i);
+               ra++;
+               count--;
+       }
+
+       /* read instance, if this is the first rplpoint */
+
+#if defined(REPLACE_PATCH_DYNAMIC_CALL)
+       if (topframe && !(rp->method->flags & ACC_STATIC) && rp == code->rplpoints) {
+#if 1
+               /* we are at the start of the method body, so if local 0 is set, */
+               /* it is the instance.                                           */
+               if (frame->javalocaltype[0] == TYPE_ADR)
+                       frame->instance = frame->javalocals[0];
+#else
+               rplalloc instra;
+               methoddesc *md;
+
+               md = rp->method->parseddesc;
+               assert(md->params);
+               assert(md->paramcount >= 1);
+               instra.type = TYPE_ADR;
+               instra.regoff = md->params[0].regoff;
+               if (md->params[0].inmemory) {
+                       instra.flags = INMEMORY;
+                       instra.regoff += (1 + code->stackframesize) * SIZE_OF_STACKSLOT;
+               }
+               else {
+                       instra.flags = 0;
+               }
+               replace_read_value(es, &instra, &(frame->instance));
+#endif
+       }
+#if defined(__I386__)
+       else if (!(rp->method->flags & ACC_STATIC)) {
+               /* On i386 we always pass the first argument on stack. */
+               frame->instance.a = *(java_object_t **)(basesp + 1);
+       } 
+#endif
+#endif /* defined(REPLACE_PATCH_DYNAMIC_CALL) */
+
+       /* read stack slots */
+
+       frame->javastackdepth = count;
+       frame->javastack = DMNEW(replace_val_t, count);
+       frame->javastacktype = DMNEW(u1, count);
+
+#if !defined(NDEBUG)
+       /* mark values as undefined */
+       for (i=0; i<count; ++i) {
+               frame->javastack[i].l = (u8) 0x00dead0000dead00ULL;
+               frame->javastacktype[i] = TYPE_VOID;
+       }
+#endif /* !defined(NDEBUG) */
+
+       i = 0;
+
+       /* the first stack slot is special in SBR and EXH blocks */
+
+       if (topslot == TOP_IS_ON_STACK) {
+               assert(count);
+
+               assert(ra->index == RPLALLOC_STACK);
+               assert(ra->type == TYPE_ADR);
+               frame->javastack[i].p = sp[-1];
+               frame->javastacktype[i] = TYPE_ADR; /* XXX RET */
+               count--;
+               i++;
+               ra++;
+       }
+       else if (topslot == TOP_IS_IN_ITMP1) {
+               assert(count);
+
+               assert(ra->index == RPLALLOC_STACK);
+               assert(ra->type == TYPE_ADR);
+               frame->javastack[i].p = es->intregs[REG_ITMP1];
+               frame->javastacktype[i] = TYPE_ADR; /* XXX RET */
+               count--;
+               i++;
+               ra++;
+       }
+       else if (topslot == TOP_IS_VOID) {
+               assert(count);
+
+               assert(ra->index == RPLALLOC_STACK);
+               frame->javastack[i].l = 0;
+               frame->javastacktype[i] = TYPE_VOID;
+               count--;
+               i++;
+               ra++;
+       }
+
+       /* read remaining stack slots */
+
+       for (; count--; ra++) {
+               if (ra->index == RPLALLOC_SYNC) {
+                       assert(rp->type == RPLPOINT_TYPE_INLINE);
+
+                       /* only read synchronization slots when traversing an inline point */
+
+                       if (!topframe) {
+                               sourceframe_t *calleeframe = frame->down;
+                               assert(calleeframe);
+                               assert(calleeframe->syncslotcount == 0);
+                               assert(calleeframe->syncslots == NULL);
+
+                               calleeframe->syncslotcount = 1;
+                               calleeframe->syncslots = DMNEW(replace_val_t, 1);
+                               replace_read_value(es,ra,calleeframe->syncslots);
+                       }
+
+                       frame->javastackdepth--;
+                       continue;
+               }
+
+               assert(ra->index == RPLALLOC_STACK || ra->index == RPLALLOC_PARAM);
+
+               /* do not read parameters of calls down the call chain */
+
+               if (!topframe && ra->index == RPLALLOC_PARAM) {
+                       frame->javastackdepth--;
+               }
+               else {
+                       if (ra->type == TYPE_RET)
+                               frame->javastack[i].i = ra->regoff;
+                       else
+                               replace_read_value(es,ra,frame->javastack + i);
+                       frame->javastacktype[i] = ra->type;
+                       i++;
+               }
+       }
+}
+
+
+/* replace_write_executionstate ************************************************
+
+   Pop a source frame from the front of the frame list of the given source state
+   and write its values into the execution state.
+
+   IN:
+       rp...............replacement point for which execution state should be
+                           created
+          es...............the execution state to modify
+          ss...............the given source state
+          topframe.........true, if this is the last (top-most) source frame to be
+                           translated
+
+   OUT:
+       *es..............the execution state derived from the source state
+  
+*******************************************************************************/
+
+static void replace_write_executionstate(rplpoint *rp,
+                                                                                executionstate_t *es,
+                                                                                sourcestate_t *ss,
+                                                                                bool topframe)
+{
+       methodinfo     *m;
+       codeinfo       *code;
+       int             count;
+       int             i;
+       rplalloc       *ra;
+       sourceframe_t  *frame;
+       int             topslot;
+       stackslot_t    *sp;
+       stackslot_t    *basesp;
+
+       code = code_find_codeinfo_for_pc(rp->pc);
+       m = rp->method;
+       topslot = TOP_IS_NORMAL;
+
+       /* pop a source frame */
+
+       frame = ss->frames;
+       assert(frame);
+       ss->frames = frame->down;
+
+       /* calculate stack pointer */
+
+       sp = (stackslot_t *) es->sp;
+
+       basesp = sp + code->stackframesize;
+
+       /* in some cases the top stack slot is passed in REG_ITMP1 */
+
+       if (rp->type == BBTYPE_EXH) {
+               topslot = TOP_IS_IN_ITMP1;
+       }
+
+       /* write javalocals */
+
+       ra = rp->regalloc;
+       count = rp->regalloccount;
+
+       while (count && (i = ra->index) >= 0) {
+               assert(i < m->maxlocals);
+               assert(i < frame->javalocalcount);
+               assert(ra->type == frame->javalocaltype[i]);
+               if (ra->type == TYPE_RET) {
+                       /* XXX assert that it matches this rplpoint */
+               }
+               else
+                       replace_write_value(es, ra, frame->javalocals + i);
+               count--;
+               ra++;
+       }
+
+       /* write stack slots */
+
+       i = 0;
+
+       /* the first stack slot is special in SBR and EXH blocks */
+
+       if (topslot == TOP_IS_ON_STACK) {
+               assert(count);
+
+               assert(ra->index == RPLALLOC_STACK);
+               assert(i < frame->javastackdepth);
+               assert(frame->javastacktype[i] == TYPE_ADR);
+               sp[-1] = frame->javastack[i].p;
+               count--;
+               i++;
+               ra++;
+       }
+       else if (topslot == TOP_IS_IN_ITMP1) {
+               assert(count);
+
+               assert(ra->index == RPLALLOC_STACK);
+               assert(i < frame->javastackdepth);
+               assert(frame->javastacktype[i] == TYPE_ADR);
+               es->intregs[REG_ITMP1] = frame->javastack[i].p;
+               count--;
+               i++;
+               ra++;
+       }
+       else if (topslot == TOP_IS_VOID) {
+               assert(count);
+
+               assert(ra->index == RPLALLOC_STACK);
+               assert(i < frame->javastackdepth);
+               assert(frame->javastacktype[i] == TYPE_VOID);
+               count--;
+               i++;
+               ra++;
+       }
+
+       /* write remaining stack slots */
+
+       for (; count--; ra++) {
+               if (ra->index == RPLALLOC_SYNC) {
+                       assert(rp->type == RPLPOINT_TYPE_INLINE);
+
+                       /* only write synchronization slots when traversing an inline point */
+
+                       if (!topframe) {
+                               assert(frame->down);
+                               assert(frame->down->syncslotcount == 1); /* XXX need to understand more cases */
+                               assert(frame->down->syncslots != NULL);
+
+                               replace_write_value(es,ra,frame->down->syncslots);
+                       }
+                       continue;
+               }
+
+               assert(ra->index == RPLALLOC_STACK || ra->index == RPLALLOC_PARAM);
+
+               /* do not write parameters of calls down the call chain */
+
+               if (!topframe && ra->index == RPLALLOC_PARAM) {
+                       /* skip it */
+                       /*
+                       ra->index = RPLALLOC_PARAM;
+                       replace_val_t v;
+                       v.l = 0;
+                       replace_write_value(es,ra,&v);
+                       */
+               }
+               else {
+                       assert(i < frame->javastackdepth);
+                       assert(ra->type == frame->javastacktype[i]);
+                       if (ra->type == TYPE_RET) {
+                               /* XXX assert that it matches this rplpoint */
+                       }
+                       else {
+                               replace_write_value(es,ra,frame->javastack + i);
+                       }
+                       i++;
+               }
+       }
+
+       /* set new pc */
+
+       es->pc = rp->pc;
+}
+
+
+/* md_pop_stackframe ***********************************************************
+
+   Restore callee-saved registers (including the RA register),
+   set the stack pointer to the next stackframe,
+   set the PC to the return address of the popped frame.
+
+   *** This function imitates the effects of the method epilog ***
+   *** and returning from the method call.                     ***
+
+   IN:
+       es...............execution state
+
+   OUT:
+       *es..............the execution state after popping the stack frame
+                        NOTE: es->code and es->pv are NOT updated.
+
+*******************************************************************************/
+
+void md_pop_stackframe(executionstate_t *es)
+{
+       u1 *ra;
+       s4 ra_align_off;
+       s4 reg;
+       s4 i;
+       stackslot_t *basesp;
+       stackslot_t *sp;
+
+       assert(es->code);
+
+       /* alignment offset of RA */
+
+       ra_align_off = 0;
+#if defined(REPLACE_RA_BETWEEN_FRAMES)
+    if (es->code->stackframesize)
+               ra_align_off = SIZE_OF_STACKSLOT - SIZEOF_VOID_P;
+#endif
+
+       /* read the return address */
+
+#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
+       if (code_is_leafmethod(es->code))
+               ra = es->ra;
+       else
+#endif
+               ra = (u1*) md_stacktrace_get_returnaddress(es->sp,
+                          SIZE_OF_STACKSLOT * es->code->stackframesize + ra_align_off);
+
+       /* calculate the base of the stack frame */
+
+       sp = (stackslot_t *) es->sp;
+       basesp = sp + es->code->stackframesize;
+
+       /* restore return address, if part of frame */
+
+#if defined(REPLACE_RA_TOP_OF_FRAME)
+#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
+       if (!code_is_leafmethod(es->code))
+#endif
+               es->ra = (u1*) (ptrint) *--basesp;
+#endif /* REPLACE_RA_TOP_OF_FRAME */
+
+#if defined(REPLACE_RA_LINKAGE_AREA)
+#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
+       if (!code_is_leafmethod(es->code))
+#endif
+               es->ra = (u1*) (ptrint) basesp[LA_LR_OFFSET / sizeof(stackslot_t)];
+#endif /* REPLACE_RA_LINKAGE_AREA */
+
+       /* restore saved int registers */
+
+       reg = INT_REG_CNT;
+       for (i=0; i<es->code->savedintcount; ++i) {
+               while (nregdescint[--reg] != REG_SAV)
+                       ;
+               es->intregs[reg] = *--basesp;
+       }
+
+       /* restore saved flt registers */
+
+       /* XXX align? */
+       reg = FLT_REG_CNT;
+       for (i=0; i<es->code->savedfltcount; ++i) {
+               while (nregdescfloat[--reg] != REG_SAV)
+                       ;
+               basesp -= STACK_SLOTS_PER_FLOAT;
+               es->fltregs[reg] = *(double*)basesp;
+       }
+
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       /* restore saved adr registers */
+
+       reg = ADR_REG_CNT;
+       for (i=0; i<es->code->savedadrcount; ++i) {
+               while (nregdescadr[--reg] != REG_SAV)
+                       ;
+               es->adrregs[reg] = *--basesp;
+       }
+#endif
+
+       /* adjust the stackpointer */
+
+       es->sp += SIZE_OF_STACKSLOT * es->code->stackframesize;
+
+#if defined(REPLACE_RA_BETWEEN_FRAMES)
+       es->sp += ra_align_off + SIZEOF_VOID_P; /* skip return address */
+#endif
+
+       /* set the program counter to the return address */
+
+       es->pc = ra;
+
+       /* in debugging mode clobber non-saved registers */
+
+#if !defined(NDEBUG)
+       /* for debugging */
+       for (i=0; i<INT_REG_CNT; ++i)
+               if (nregdescint[i] != REG_SAV)
+                       es->intregs[i] = (ptrint) 0x33dead3333dead33ULL;
+       for (i=0; i<FLT_REG_CNT; ++i)
+               if (nregdescfloat[i] != REG_SAV)
+                       *(u8*)&(es->fltregs[i]) = 0x33dead3333dead33ULL;
+# if defined(HAS_ADDRESS_REGISTER_FILE)
+       for (i=0; i<ADR_REG_CNT; ++i)
+               if (nregdescadr[i] != REG_SAV)
+                       es->adrregs[i] = (ptrint) 0x33dead3333dead33ULL;
+# endif
+#endif /* !defined(NDEBUG) */
+}
+
+
+/* md_push_stackframe **********************************************************
+
+   Save the given return address, build the new stackframe,
+   and store callee-saved registers.
+
+   *** This function imitates the effects of a call and the ***
+   *** method prolog of the callee.                         ***
+
+   IN:
+       es...............execution state
+       calleecode.......the code we are "calling"
+       ra...............the return address to save
+
+   OUT:
+       *es..............the execution state after pushing the stack frame
+                        NOTE: es->pc, es->code, and es->pv are NOT updated.
+
+*******************************************************************************/
+
+void md_push_stackframe(executionstate_t *es, codeinfo *calleecode, u1 *ra)
+{
+       s4           reg;
+       s4           i;
+       stackslot_t *basesp;
+       stackslot_t *sp;
+
+       assert(es);
+       assert(calleecode);
+
+       /* write the return address */
+
+#if defined(REPLACE_RA_BETWEEN_FRAMES)
+       es->sp -= SIZEOF_VOID_P;
+       *((void **)es->sp) = (void *) ra;
+       if (calleecode->stackframesize)
+               es->sp -= (SIZE_OF_STACKSLOT - SIZEOF_VOID_P);
+#endif /* REPLACE_RA_BETWEEN_FRAMES */
+
+       es->ra = (u1*) (ptrint) ra;
+
+       /* build the stackframe */
+
+       DOLOG( printf("building stackframe of %d words at %p\n",
+                                 calleecode->stackframesize, (void*)es->sp); );
+
+       sp = (stackslot_t *) es->sp;
+       basesp = sp;
+
+       sp -= calleecode->stackframesize;
+       es->sp = (u1*) sp;
+
+       /* in debug mode, invalidate stack frame first */
+
+       /* XXX may not invalidate linkage area used by native code! */
+
+#if !defined(NDEBUG) && 0
+       for (i=0; i< (basesp - sp) && i < 1; ++i) {
+               sp[i] = 0xdeaddeadU;
+       }
+#endif
+
+#if defined(__I386__)
+       /* Stackslot 0 may contain the object instance for vftbl patching.
+          Destroy it, so there's no undefined value used. */
+       if ((basesp - sp) > 0) {
+               sp[0] = 0;
+       }
+#endif
+
+       /* save the return address register */
+
+#if defined(REPLACE_RA_TOP_OF_FRAME)
+#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
+       if (!code_is_leafmethod(calleecode))
+#endif
+               *--basesp = (ptrint) ra;
+#endif /* REPLACE_RA_TOP_OF_FRAME */
+
+#if defined(REPLACE_RA_LINKAGE_AREA)
+#if defined(REPLACE_LEAFMETHODS_RA_REGISTER)
+       if (!code_is_leafmethod(calleecode))
+#endif
+               basesp[LA_LR_OFFSET / sizeof(stackslot_t)] = (ptrint) ra;
+#endif /* REPLACE_RA_LINKAGE_AREA */
+
+       /* save int registers */
+
+       reg = INT_REG_CNT;
+       for (i=0; i<calleecode->savedintcount; ++i) {
+               while (nregdescint[--reg] != REG_SAV)
+                       ;
+               *--basesp = es->intregs[reg];
+
+               /* XXX may not clobber saved regs used by native code! */
+#if !defined(NDEBUG) && 0
+               es->intregs[reg] = (ptrint) 0x44dead4444dead44ULL;
+#endif
+       }
+
+       /* save flt registers */
+
+       /* XXX align? */
+       reg = FLT_REG_CNT;
+       for (i=0; i<calleecode->savedfltcount; ++i) {
+               while (nregdescfloat[--reg] != REG_SAV)
+                       ;
+               basesp -= STACK_SLOTS_PER_FLOAT;
+               *(double*)basesp = es->fltregs[reg];
+
+               /* XXX may not clobber saved regs used by native code! */
+#if !defined(NDEBUG) && 0
+               *(u8*)&(es->fltregs[reg]) = 0x44dead4444dead44ULL;
+#endif
+       }
+
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       /* save adr registers */
+
+       reg = ADR_REG_CNT;
+       for (i=0; i<calleecode->savedadrcount; ++i) {
+               while (nregdescadr[--reg] != REG_SAV)
+                       ;
+               *--basesp = es->adrregs[reg];
+
+               /* XXX may not clobber saved regs used by native code! */
+#if !defined(NDEBUG) && 0
+               es->adrregs[reg] = (ptrint) 0x44dead4444dead44ULL;
+#endif
+       }
+#endif
+}
+
+
+/* replace_pop_activation_record ***********************************************
+
+   Peel a stack frame from the execution state.
+
+   *** This function imitates the effects of the method epilog ***
+   *** and returning from the method call.                     ***
+
+   IN:
+       es...............execution state
+       frame............source frame, receives synchronization slots
+
+   OUT:
+       *es..............the execution state after popping the stack frame
+
+   RETURN VALUE:
+       the return address of the poped activation record
+
+*******************************************************************************/
+
+u1* replace_pop_activation_record(executionstate_t *es,
+                                                                 sourceframe_t *frame)
+{
+       u1 *ra;
+       s4 i;
+       s4 count;
+       codeinfo *code;
+       stackslot_t *sp;
+
+       assert(es->code);
+       assert(frame);
+
+       /* calculate the base of the stack frame */
+
+       sp = (stackslot_t *) es->sp;
+       assert(frame->syncslotcount == 0);
+       assert(frame->syncslots == NULL);
+       count = code_get_sync_slot_count(es->code);
+       frame->syncslotcount = count;
+       frame->syncslots = DMNEW(replace_val_t, count);
+       for (i=0; i<count; ++i) {
+               frame->syncslots[i].p = sp[es->code->memuse + i]; /* XXX md_ function */
+       }
+
+       /* pop the stackframe */
+
+       md_pop_stackframe(es);
+
+       ra = es->pc;
+
+       DOLOG( printf("RA = %p\n", (void*)ra); );
+
+       /* Subtract one from the PC so we do not hit the replacement point */
+       /* of the instruction following the call, if there is one.         */
+
+       es->pc--;
+
+       /* find the new codeinfo */
+
+       void* pv = md_codegen_get_pv_from_pc(ra);
+       DOLOG( printf("PV = %p\n", pv); );
+
+       code = code_get_codeinfo_for_pv(pv);
+       DOLOG( printf("CODE = %p\n", (void*) code); );
+
+       /* return NULL if we reached native code */
+
+       es->pv   = (uint8_t*) pv;
+       es->code = code;
+
+       return (code) ? ra : NULL;
+}
+
+
+/* replace_patch_method_pointer ************************************************
+
+   Patch a method pointer (may be in code, data segment, vftbl, or interface
+   table).
+
+   IN:
+          mpp..............address of the method pointer to patch
+          entrypoint.......the new entrypoint of the method
+          kind.............kind of call to patch, used only for debugging
+
+*******************************************************************************/
+
+static void replace_patch_method_pointer(methodptr *mpp,
+                                                                                methodptr entrypoint,
+                                                                                const char *kind)
+{
+#if !defined(NDEBUG)
+       codeinfo       *oldcode;
+       codeinfo       *newcode;
+#endif
+
+       DOLOG( printf("patch method pointer from: %p to %p\n",
+                                 (void*) *mpp, (void*)entrypoint); );
+
+#if !defined(NDEBUG)
+       oldcode = code_get_codeinfo_for_pv(*mpp);
+       newcode = code_get_codeinfo_for_pv(entrypoint);
+
+       DOLOG_SHORT( printf("\tpatch %s %p ", kind, (void*) oldcode);
+                                method_println(oldcode->m);
+                                printf("\t      with      %p ", (void*) newcode);
+                                method_println(newcode->m); );
+
+       assert(oldcode->m == newcode->m);
+#endif
+
+       /* write the new entrypoint */
+
+       *mpp = (methodptr) entrypoint;
+}
+
+
+/* replace_patch_class *********************************************************
+
+   Patch a method in the given class.
+
+   IN:
+          vftbl............vftbl of the class
+          m................the method to patch
+          oldentrypoint....the old entrypoint to replace
+          entrypoint.......the new entrypoint
+
+*******************************************************************************/
+
+void replace_patch_class(vftbl_t *vftbl,
+                                                methodinfo *m,
+                                                u1 *oldentrypoint,
+                                                u1 *entrypoint)
+{
+       s4                 i;
+       methodptr         *mpp;
+       methodptr         *mppend;
+
+       /* patch the vftbl of the class */
+
+       replace_patch_method_pointer(vftbl->table + m->vftblindex,
+                                                                entrypoint,
+                                                                "virtual  ");
+
+       /* patch the interface tables */
+
+       assert(oldentrypoint);
+
+       for (i=0; i < vftbl->interfacetablelength; ++i) {
+               mpp = vftbl->interfacetable[-i];
+               mppend = mpp + vftbl->interfacevftbllength[i];
+               for (; mpp != mppend; ++mpp)
+                       if (*mpp == oldentrypoint) {
+                               replace_patch_method_pointer(mpp, entrypoint, "interface");
+                       }
+       }
+}
+
+
+/* replace_patch_class_hierarchy ***********************************************
+
+   Patch a method in all loaded classes.
+
+   IN:
+          m................the method to patch
+          oldentrypoint....the old entrypoint to replace
+          entrypoint.......the new entrypoint
+
+*******************************************************************************/
+
+struct replace_patch_data_t {
+       methodinfo *m;
+       u1         *oldentrypoint;
+       u1         *entrypoint;
+};
+
+void replace_patch_callback(classinfo *c, struct replace_patch_data_t *pd)
+{
+       vftbl_t *vftbl = c->vftbl;
+
+       if (vftbl != NULL
+               && vftbl->vftbllength > pd->m->vftblindex
+               && (void*) vftbl->table[pd->m->vftblindex] != (void*) (uintptr_t) &asm_abstractmethoderror
+               && code_get_methodinfo_for_pv(vftbl->table[pd->m->vftblindex]) == pd->m)
+       {
+               replace_patch_class(c->vftbl, pd->m, pd->oldentrypoint, pd->entrypoint);
+       }
+}
+
+void replace_patch_class_hierarchy(methodinfo *m,
+                                                                  u1 *oldentrypoint,
+                                                                  u1 *entrypoint)
+{
+       struct replace_patch_data_t pd;
+
+       pd.m = m;
+       pd.oldentrypoint = oldentrypoint;
+       pd.entrypoint = entrypoint;
+
+       DOLOG_SHORT( printf("patching class hierarchy: ");
+                            method_println(m); );
+
+       classcache_foreach_loaded_class(
+                       (classcache_foreach_functionptr_t) &replace_patch_callback,
+                       (void*) &pd);
+}
+
+
+/* replace_patch_future_calls **************************************************
+
+   Analyse a call site and depending on the kind of call patch the call, the
+   virtual function table, or the interface table.
+
+   IN:
+          ra...............return address pointing after the call site
+          callerframe......source frame of the caller
+          calleeframe......source frame of the callee, must have been mapped
+
+*******************************************************************************/
+
+void replace_patch_future_calls(u1 *ra,
+                                                               sourceframe_t *callerframe,
+                                                               sourceframe_t *calleeframe)
+{
+       u1            *patchpos;
+       methodptr      entrypoint;
+       methodptr      oldentrypoint;
+       bool           atentry;
+       void          *pv;
+       codeinfo      *calleecode;
+       methodinfo    *calleem;
+       java_object_t *obj;
+       vftbl_t       *vftbl;
+
+       assert(ra);
+       assert(callerframe->down == calleeframe);
+
+       /* get the new codeinfo and the method that shall be entered */
+
+       calleecode = calleeframe->tocode;
+       assert(calleecode);
+
+       calleem = calleeframe->method;
+       assert(calleem == calleecode->m);
+
+       entrypoint = (methodptr) calleecode->entrypoint;
+
+       /* check if we are at an method entry rplpoint at the innermost frame */
+
+       atentry = (calleeframe->down == NULL)
+                       && !(calleem->flags & ACC_STATIC)
+                       && (calleeframe->fromrp->id == 0); /* XXX */
+
+       /* get the position to patch, in case it was a statically bound call   */
+
+       pv = callerframe->fromcode->entrypoint;
+       patchpos = (u1*) md_jit_method_patch_address(pv, ra, NULL);
+
+       if (patchpos == NULL) {
+               /* the call was dispatched dynamically */
+
+               /* we can only patch such calls if we are at the entry point */
+
+#if !defined(__I386__)
+               /* On i386 we always know the instance argument. */
+               if (!atentry)
+                       return;
+#endif
+
+               assert((calleem->flags & ACC_STATIC) == 0);
+
+               oldentrypoint = calleeframe->fromcode->entrypoint;
+
+               /* we need to know the instance */
+
+               if (!calleeframe->instance.a) {
+                       DOLOG_SHORT( printf("WARNING: object instance unknown!\n"); );
+                       replace_patch_class_hierarchy(calleem, oldentrypoint, entrypoint);
+                       return;
+               }
+
+               /* get the vftbl */
+
+               obj = calleeframe->instance.a;
+               vftbl = obj->vftbl;
+
+               assert(vftbl->clazz->vftbl == vftbl);
+
+               DOLOG_SHORT( printf("\tclass: "); class_println(vftbl->clazz); );
+
+               replace_patch_class(vftbl, calleem, oldentrypoint, entrypoint);
+       }
+       else {
+               /* the call was statically bound */
+
+#if defined(__I386__)
+               /* It happens that there is a patcher trap. (pm) */
+               if (*(u2 *)(patchpos - 1) == 0x0b0f) {
+               } else
+#endif
+               replace_patch_method_pointer((methodptr *) patchpos, entrypoint, "static   ");
+       }
+}
+
+
+/* replace_push_activation_record **********************************************
+
+   Push a stack frame onto the execution state.
+   
+   *** This function imitates the effects of a call and the ***
+   *** method prolog of the callee.                         ***
+
+   IN:
+          es...............execution state
+          rpcall...........the replacement point at the call site
+          callerframe......source frame of the caller, or NULL for creating the
+                           first frame
+          calleeframe......source frame of the callee, must have been mapped
+
+   OUT:
+       *es..............the execution state after pushing the stack frame
+  
+*******************************************************************************/
+
+void replace_push_activation_record(executionstate_t *es,
+                                                                       rplpoint *rpcall,
+                                                                       sourceframe_t *callerframe,
+                                                                       sourceframe_t *calleeframe)
+{
+       s4           i;
+       s4           count;
+       stackslot_t *sp;
+       u1          *ra;
+       codeinfo    *calleecode;
+
+       assert(es);
+       assert(!rpcall || callerframe);
+    assert(!rpcall || rpcall->type == RPLPOINT_TYPE_CALL);
+       assert(!rpcall || rpcall == callerframe->torp);
+       assert(calleeframe);
+       assert(!callerframe || calleeframe == callerframe->down);
+
+       /* the compilation unit we are entering */
+
+       calleecode = calleeframe->tocode;
+       assert(calleecode);
+
+       /* calculate the return address */
+
+       if (rpcall)
+               ra = rpcall->pc + rpcall->callsize;
+       else
+               ra = es->pc + 1 /* XXX this is ugly */;
+
+       /* push the stackframe */
+
+       md_push_stackframe(es, calleecode, ra);
+
+       /* we move into a new code unit, set code, PC, PV */
+
+       es->code = calleecode;
+       es->pc = calleecode->entrypoint; /* XXX not needed? */
+       es->pv = calleecode->entrypoint;
+
+       /* write slots used for synchronization */
+
+       sp = (stackslot_t *) es->sp;
+       count = code_get_sync_slot_count(calleecode);
+       assert(count == calleeframe->syncslotcount);
+       for (i=0; i<count; ++i) {
+               sp[calleecode->memuse + i] = calleeframe->syncslots[i].p;
+       }
+
+       /* redirect future invocations */
+
+       if (callerframe && rpcall) {
+#if defined(REPLACE_PATCH_ALL)
+               if (rpcall->type == callerframe->fromrp->type)
+#else
+               if (rpcall == callerframe->fromrp)
+#endif
+                       replace_patch_future_calls(ra, callerframe, calleeframe);
+       }
+}
+
+
+/* replace_find_replacement_point **********************************************
+
+   Find the replacement point in the given code corresponding to the
+   position given in the source frame.
+   
+   IN:
+          code.............the codeinfo in which to search the rplpoint
+          frame............the source frame defining the position to look for
+          parent...........parent replacement point to match
+
+   RETURN VALUE:
+       the replacement point
+  
+*******************************************************************************/
+
+rplpoint * replace_find_replacement_point(codeinfo *code,
+                                                                                 sourceframe_t *frame,
+                                                                                 rplpoint *parent)
+{
+       methodinfo *m;
+       rplpoint *rp;
+       s4        i;
+       s4        j;
+       s4        stacki;
+       rplalloc *ra;
+
+       assert(code);
+       assert(frame);
+
+       DOLOG( printf("searching replacement point for:\n");
+                  replace_source_frame_println(frame); );
+
+       m = frame->method;
+
+       DOLOG( printf("code = %p\n", (void*)code); );
+
+       rp = code->rplpoints;
+       i = code->rplpointcount;
+       while (i--) {
+               if (rp->id == frame->id && rp->method == frame->method
+                               && rp->parent == parent
+                               && replace_normalize_type_map[rp->type] == frame->type)
+               {
+                       /* check if returnAddresses match */
+                       /* XXX optimize: only do this if JSRs in method */
+                       DOLOG( printf("checking match for:");
+                                  replace_replacement_point_println(rp, 1); fflush(stdout); );
+                       ra = rp->regalloc;
+                       stacki = 0;
+                       for (j = rp->regalloccount; j--; ++ra) {
+                               if (ra->type == TYPE_RET) {
+                                       if (ra->index == RPLALLOC_STACK) {
+                                               assert(stacki < frame->javastackdepth);
+                                               if (frame->javastack[stacki].i != ra->regoff)
+                                                       goto no_match;
+                                               stacki++;
+                                       }
+                                       else {
+                                               assert(ra->index >= 0 && ra->index < frame->javalocalcount);
+                                               if (frame->javalocals[ra->index].i != ra->regoff)
+                                                       goto no_match;
+                                       }
+                               }
+                       }
+
+                       /* found */
+                       return rp;
+               }
+no_match:
+               rp++;
+       }
+
+#if !defined(NDEBUG)
+       printf("candidate replacement points were:\n");
+       rp = code->rplpoints;
+       i = code->rplpointcount;
+       for (; i--; ++rp) {
+               replace_replacement_point_println(rp, 1);
+       }
+#endif
+
+       vm_abort("no matching replacement point found");
+       return NULL; /* NOT REACHED */
+}
+
+
+/* replace_find_replacement_point_for_pc ***************************************
+
+   Find the nearest replacement point at or before the given PC. The
+   given PC has to be between (rp->pc) and (rp->pc+rp->callsize) for
+   the replacement point to be found.
+
+   IN:
+       code.............compilation unit the PC is in
+          pc...............the machine code PC
+
+   RETURN VALUE:
+       the replacement point found, or
+          NULL if no replacement point was found
+
+*******************************************************************************/
+
+rplpoint *replace_find_replacement_point_for_pc(codeinfo *code, u1 *pc, unsigned desired_flags)
+{
+       rplpoint *found;
+       rplpoint *rp;
+       s4        i;
+
+       DOLOG( printf("searching for rp at pc:%p in %p ", (void*)pc, (void*)code);
+                  method_println(code->m); );
+
+       found = NULL;
+
+       rp = code->rplpoints;
+       for (i=0; i<code->rplpointcount; ++i, ++rp) {
+               DOLOG( replace_replacement_point_println(rp, 2); );
+               if (rp->pc <= pc && rp->pc + rp->callsize >= pc) {
+                       if (desired_flags) {
+                               if (rp->flags & desired_flags) {
+                                       found = rp;
+                               }
+                       } else {
+                               found = rp;
+                       }
+               }
+       }
+
+       return found;
+}
+
+/* replace_pop_native_frame ****************************************************
+
+   Unroll a native frame in the execution state and create a source frame
+   for it.
+
+   IN:
+          es...............current execution state
+          ss...............the current source state
+          sfi..............stackframeinfo for the native frame
+
+   OUT:
+       es...............execution state after unrolling the native frame
+          ss...............gets the added native source frame
+
+*******************************************************************************/
+
+static void replace_pop_native_frame(executionstate_t *es,
+                                                                        sourcestate_t *ss,
+                                                                        stackframeinfo_t *sfi)
+{
+       sourceframe_t *frame;
+       codeinfo      *code;
+       s4             i,j;
+
+       assert(sfi);
+
+       frame = replace_new_sourceframe(ss);
+
+       frame->sfi = sfi;
+
+       /* remember pc and size of native frame */
+
+       frame->nativepc = es->pc;
+       frame->nativeframesize = (es->sp != 0) ? (((uintptr_t) sfi->sp) - ((uintptr_t) es->sp)) : 0;
+       assert(frame->nativeframesize >= 0);
+
+       /* remember values of saved registers */
+
+       j = 0;
+       for (i=0; i<INT_REG_CNT; ++i) {
+               if (nregdescint[i] == REG_SAV)
+                       frame->nativesavint[j++] = es->intregs[i];
+       }
+
+       j = 0;
+       for (i=0; i<FLT_REG_CNT; ++i) {
+               if (nregdescfloat[i] == REG_SAV)
+                       frame->nativesavflt[j++] = es->fltregs[i];
+       }
+
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       j = 0;
+       for (i=0; i<ADR_REG_CNT; ++i) {
+               if (nregdescadr[i] == REG_SAV)
+                       frame->nativesavadr[j++] = es->adrregs[i];
+       }
+#endif
+
+       /* restore saved registers */
+
+#if defined(ENABLE_GC_CACAO) && !defined(HAS_ADDRESS_REGISTER_FILE)
+       j = 0;
+       for (i=0; i<INT_REG_CNT; ++i) {
+               if (nregdescint[i] == REG_SAV)
+                       es->intregs[i] = sfi->intregs[j++];
+       }
+#else
+       /* XXX we don't have them, yet, in the sfi, so clear them */
+
+       for (i=0; i<INT_REG_CNT; ++i) {
+               if (nregdescint[i] == REG_SAV)
+                       es->intregs[i] = 0;
+       }
+#endif
+
+       /* XXX we don't have float registers in the sfi, so clear them */
+
+       for (i=0; i<FLT_REG_CNT; ++i) {
+               if (nregdescfloat[i] == REG_SAV)
+                       es->fltregs[i] = 0.0;
+       }
+
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+# if defined(ENABLE_GC_CACAO)
+       j = 0;
+       for (i=0; i<ADR_REG_CNT; ++i) {
+               if (nregdescadr[i] == REG_SAV)
+                       es->adrregs[i] = sfi->adrregs[j++];
+       }
+# else
+       for (i=0; i<ADR_REG_CNT; ++i) {
+               if (nregdescadr[i] == REG_SAV)
+                       es->adrregs[i] = 0;
+       }
+# endif
+#endif
+
+       /* restore codeinfo of the native stub */
+
+       code = code_get_codeinfo_for_pv(sfi->pv);
+
+       /* restore sp, pv, pc and codeinfo of the parent method */
+
+       /* XXX michi: use this instead:
+       es->sp = sfi->sp + code->stackframesize; */
+       es->sp   = (uint8_t*) (((uintptr_t) sfi->sp) + (*(s4 *) (((uintptr_t) sfi->pv) + FrameSize)));
+#if defined(REPLACE_RA_BETWEEN_FRAMES)
+       es->sp  += SIZE_OF_STACKSLOT; /* skip return address */
+#endif
+       es->pv   = (uint8_t*) md_codegen_get_pv_from_pc(sfi->ra);
+       es->pc   = (uint8_t*) (((uintptr_t) ((sfi->xpc) ? sfi->xpc : sfi->ra)) - 1);
+       es->code = code_get_codeinfo_for_pv(es->pv);
+}
+
+
+/* replace_push_native_frame ***************************************************
+
+   Rebuild a native frame onto the execution state and remove its source frame.
+
+   Note: The native frame is "rebuild" by setting fields like PC and stack
+         pointer in the execution state accordingly. Values in the
+                stackframeinfo may be modified, but the actual stack frame of the
+                native code is not touched.
+
+   IN:
+          es...............current execution state
+          ss...............the current source state
+
+   OUT:
+       es...............execution state after re-rolling the native frame
+          ss...............the native source frame is removed
+
+*******************************************************************************/
+
+static void replace_push_native_frame(executionstate_t *es, sourcestate_t *ss)
+{
+       sourceframe_t *frame;
+       s4             i,j;
+
+       assert(es);
+       assert(ss);
+
+       DOLOG( printf("pushing native frame\n"); );
+
+       /* remove the frame from the source state */
+
+       frame = ss->frames;
+       assert(frame);
+       assert(REPLACE_IS_NATIVE_FRAME(frame));
+
+       ss->frames = frame->down;
+
+       /* skip sp for the native stub */
+
+       es->sp -= (*(s4 *) (((uintptr_t) frame->sfi->pv) + FrameSize));
+#if defined(REPLACE_RA_BETWEEN_FRAMES)
+       es->sp -= SIZE_OF_STACKSLOT; /* skip return address */
+#endif
+
+       /* assert that the native frame has not moved */
+
+       assert(es->sp == frame->sfi->sp);
+
+       /* update saved registers in the stackframeinfo */
+
+#if defined(ENABLE_GC_CACAO)
+       j = 0;
+# if !defined(HAS_ADDRESS_REGISTER_FILE)
+       for (i=0; i<INT_REG_CNT; ++i) {
+               if (nregdescint[i] == REG_SAV)
+                       frame->sfi->intregs[j++] = es->intregs[i];
+       }
+# else
+       for (i=0; i<ADR_REG_CNT; ++i) {
+               if (nregdescadr[i] == REG_SAV)
+                       frame->sfi->adrregs[j++] = es->adrregs[i];
+       }
+# endif
+
+       /* XXX leave float registers untouched here */
+#endif
+
+       /* restore saved registers */
+
+       j = 0;
+       for (i=0; i<INT_REG_CNT; ++i) {
+               if (nregdescint[i] == REG_SAV)
+                       es->intregs[i] = frame->nativesavint[j++];
+       }
+
+       j = 0;
+       for (i=0; i<FLT_REG_CNT; ++i) {
+               if (nregdescfloat[i] == REG_SAV)
+                       es->fltregs[i] = frame->nativesavflt[j++];
+       }
+
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       j = 0;
+       for (i=0; i<ADR_REG_CNT; ++i) {
+               if (nregdescadr[i] == REG_SAV)
+                       es->adrregs[i] = frame->nativesavadr[j++];
+       }
+#endif
+
+       /* skip the native frame on the machine stack */
+
+       es->sp -= frame->nativeframesize;
+
+       /* set the pc the next frame must return to */
+
+       es->pc = frame->nativepc;
+}
+
+
+/* replace_recover_source_state ************************************************
+
+   Recover the source state from the given replacement point and execution
+   state.
+
+   IN:
+       rp...............replacement point that has been reached, if any
+          sfi..............stackframeinfo, if called from native code
+          es...............execution state at the replacement point rp
+
+   RETURN VALUE:
+       the source state
+
+*******************************************************************************/
+
+sourcestate_t *replace_recover_source_state(rplpoint *rp,
+                                                                                       stackframeinfo_t *sfi,
+                                                                                   executionstate_t *es)
+{
+       sourcestate_t *ss;
+       u1            *ra;
+       bool           locked;
+#if defined(REPLACE_STATISTICS)
+       s4             depth;
+#endif
+
+       /* create the source frame structure in dump memory */
+
+       ss = DNEW(sourcestate_t);
+       ss->frames = NULL;
+
+       /* each iteration of the loop recovers one source frame */
+
+       depth = 0;
+       locked = false;
+
+       while (rp || sfi) {
+
+               DOLOG( executionstate_println(es); );
+
+               /* if we are not at a replacement point, it is a native frame */
+
+               if (rp == NULL) {
+                       DOLOG( printf("native frame: sfi: "); replace_stackframeinfo_println(sfi); );
+
+                       locked = true;
+                       replace_pop_native_frame(es, ss, sfi);
+                       sfi = sfi->prev;
+
+                       if (es->code == NULL)
+                               continue;
+
+                       goto after_machine_frame;
+               }
+
+               /* read the values for this source frame from the execution state */
+
+               DOLOG( printf("recovering source state for%s:\n",
+                                       (ss->frames == NULL) ? " TOPFRAME" : "");
+                          replace_replacement_point_println(rp, 1); );
+
+               replace_read_executionstate(rp, es, ss, ss->frames == NULL);
+
+#if defined(ENABLE_VMLOG)
+               vmlog_cacao_unrol_method(ss->frames->method);
+#endif
+
+#if defined(REPLACE_STATISTICS)
+               REPLACE_COUNT(stat_frames);
+               depth++;
+               replace_statistics_source_frame(ss->frames);
+#endif
+
+               /* in locked areas (below native frames), identity map the frame */
+
+               if (locked) {
+                       ss->frames->torp = ss->frames->fromrp;
+                       ss->frames->tocode = ss->frames->fromcode;
+               }
+
+               /* unroll to the next (outer) frame */
+
+               if (rp->parent) {
+                       /* this frame is in inlined code */
+
+                       DOLOG( printf("INLINED!\n"); );
+
+                       rp = rp->parent;
+
+                       assert(rp->type == RPLPOINT_TYPE_INLINE);
+                       REPLACE_COUNT(stat_unroll_inline);
+               }
+               else {
+                       /* this frame had been called at machine-level. pop it. */
+
+                       DOLOG( printf("UNWIND\n"); );
+
+                       ra = replace_pop_activation_record(es, ss->frames);
+                       if (ra == NULL) {
+                               DOLOG( printf("REACHED NATIVE CODE\n"); );
+
+                               rp = NULL;
+
+#if !defined(ENABLE_GC_CACAO)
+                               break; /* XXX remove to activate native frames */
+#endif
+                               continue;
+                       }
+
+                       /* find the replacement point at the call site */
+
+after_machine_frame:
+                       rp = replace_find_replacement_point_for_pc(es->code, es->pc, 0);
+
+                       if (rp == NULL)
+                               vm_abort("could not find replacement point while unrolling call");
+
+                       DOLOG( printf("found replacement point.\n");
+                                       replace_replacement_point_println(rp, 1); );
+
+                       assert(rp->type == RPLPOINT_TYPE_CALL);
+                       REPLACE_COUNT(stat_unroll_call);
+               }
+       } /* end loop over source frames */
+
+       REPLACE_COUNT_DIST(stat_dist_frames, depth);
+
+       return ss;
+}
+
+
+/* replace_map_source_state ****************************************************
+
+   Map each source frame in the given source state to a target replacement
+   point and compilation unit. If no valid code is available for a source
+   frame, it is (re)compiled.
+
+   IN:
+       ss...............the source state
+
+   OUT:
+       ss...............the source state, modified: The `torp` and `tocode`
+                           fields of each source frame are set.
+
+   RETURN VALUE:
+       true.............everything went ok
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+static bool replace_map_source_state(sourcestate_t *ss)
+{
+       sourceframe_t *frame;
+       codeinfo      *code;
+       rplpoint      *rp;
+       rplpoint      *parent; /* parent of inlined rplpoint */
+#if defined(REPLACE_STATISTICS)
+       codeinfo      *oldcode;
+#endif
+
+       parent = NULL;
+       code = NULL;
+
+       /* iterate over the source frames from outermost to innermost */
+
+       for (frame = ss->frames; frame != NULL; frame = frame->down) {
+
+               /* XXX skip native frames */
+
+               if (REPLACE_IS_NATIVE_FRAME(frame)) {
+                       parent = NULL;
+                       continue;
+               }
+
+               /* map frames which are not already mapped */
+
+               if (frame->tocode) {
+                       code = frame->tocode;
+                       rp = frame->torp;
+                       assert(rp);
+               }
+               else {
+                       assert(frame->torp == NULL);
+
+                       if (parent == NULL) {
+                               /* find code for this frame */
+
+#if defined(REPLACE_STATISTICS)
+                               oldcode = frame->method->code;
+#endif
+                               /* request optimization of hot methods and their callers */
+
+                               if (frame->method->hitcountdown < 0
+                                       || (frame->down && frame->down->method->hitcountdown < 0))
+                                       jit_request_optimization(frame->method);
+
+                               code = jit_get_current_code(frame->method);
+
+                               if (code == NULL)
+                                       return false; /* exception */
+
+                               REPLACE_COUNT_IF(stat_recompile, code != oldcode);
+                       }
+
+                       assert(code);
+
+                       /* map this frame */
+
+                       rp = replace_find_replacement_point(code, frame, parent);
+
+                       frame->tocode = code;
+                       frame->torp = rp;
+               }
+
+               if (rp->type == RPLPOINT_TYPE_CALL) {
+                       parent = NULL;
+               }
+               else {
+                       /* inlining */
+                       parent = rp;
+               }
+       }
+
+       return true;
+}
+
+
+/* replace_map_source_state_identity *******************************************
+
+   Map each source frame in the given source state to the same replacement
+   point and compilation unit it was derived from. This is mainly used for
+   garbage collection.
+
+   IN:
+       ss...............the source state
+
+   OUT:
+       ss...............the source state, modified: The `torp` and `tocode`
+                           fields of each source frame are set.
+
+*******************************************************************************/
+
+#if defined(ENABLE_GC_CACAO)
+static void replace_map_source_state_identity(sourcestate_t *ss)
+{
+       sourceframe_t *frame;
+
+       /* iterate over the source frames from outermost to innermost */
+
+       for (frame = ss->frames; frame != NULL; frame = frame->down) {
+
+               /* skip native frames */
+
+               if (REPLACE_IS_NATIVE_FRAME(frame)) {
+                       continue;
+               }
+
+               /* map frames using the identity mapping */
+
+               if (frame->tocode) {
+                       assert(frame->tocode == frame->fromcode);
+                       assert(frame->torp   == frame->fromrp);
+               } else {
+                       assert(frame->tocode == NULL);
+                       assert(frame->torp   == NULL);
+                       frame->tocode = frame->fromcode;
+                       frame->torp   = frame->fromrp;
+               }
+       }
+}
+#endif
+
+
+/* replace_build_execution_state ***********************************************
+
+   Build an execution state for the given (mapped) source state.
+
+   !!! CAUTION: This function rewrites the machine stack !!!
+
+   THIS FUNCTION MUST BE CALLED USING A SAFE STACK AREA!
+
+   IN:
+       ss...............the source state. Must have been mapped by
+                                               replace_map_source_state before.
+          es...............the base execution state on which to build
+
+   OUT:
+       *es..............the new execution state
+
+*******************************************************************************/
+
+static void replace_build_execution_state(sourcestate_t *ss,
+                                                                                 executionstate_t *es)
+{
+       rplpoint      *rp;
+       sourceframe_t *prevframe;
+       rplpoint      *parent;
+
+       parent = NULL;
+       prevframe = NULL;
+       rp = NULL;
+
+       while (ss->frames) {
+
+               if (REPLACE_IS_NATIVE_FRAME(ss->frames)) {
+                       prevframe = ss->frames;
+                       replace_push_native_frame(es, ss);
+                       parent = NULL;
+                       rp = NULL;
+                       continue;
+               }
+
+               if (parent == NULL) {
+                       /* create a machine-level stack frame */
+
+                       DOLOG( printf("pushing activation record for:\n");
+                                  if (rp) replace_replacement_point_println(rp, 1);
+                                  else printf("\tfirst frame\n"); );
+
+                       replace_push_activation_record(es, rp, prevframe, ss->frames);
+
+                       DOLOG( executionstate_println(es); );
+               }
+
+               rp = ss->frames->torp;
+               assert(rp);
+
+               DOLOG( printf("creating execution state for%s:\n",
+                               (ss->frames->down == NULL) ? " TOPFRAME" : "");
+                          replace_replacement_point_println(ss->frames->fromrp, 1);
+                          replace_replacement_point_println(rp, 1); );
+
+               es->code = ss->frames->tocode;
+               prevframe = ss->frames;
+
+#if defined(ENABLE_VMLOG)
+               vmlog_cacao_rerol_method(ss->frames->method);
+#endif
+
+               replace_write_executionstate(rp, es, ss, ss->frames->down == NULL);
+
+               DOLOG( executionstate_println(es); );
+
+               if (rp->type == RPLPOINT_TYPE_CALL) {
+                       parent = NULL;
+               }
+               else {
+                       /* inlining */
+                       parent = rp;
+               }
+       }
+}
+
+
+/* replace_me ******************************************************************
+   This function is called by the signal handler when a thread reaches
+   a replacement point. `replace_me` must map the execution state to the
+   target replacement point and let execution continue there.
+
+   THIS FUNCTION MUST BE CALLED USING A SAFE STACK AREA!
+
+   IN:
+       rp...............replacement point that has been reached
+       es...............execution state read by signal handler
+  
+*******************************************************************************/
+
+static void replace_me(rplpoint *rp, executionstate_t *es)
+{
+       stackframeinfo_t    *sfi;
+       sourcestate_t       *ss;
+       sourceframe_t       *frame;
+       codeinfo            *origcode;
+       rplpoint            *origrp;
+#if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
+       threadobject        *thread;
+#endif
+       int32_t              dumpmarker;
+
+       origcode = es->code;
+       origrp   = rp;
+
+#if defined(ENABLE_TLH)
+       /*printf("Replacing in %s/%s\n", rp->method->clazz->name->text, rp->method->name->text);*/
+#endif
+
+       /*if (strcmp(rp->method->clazz->name->text, "antlr/AlternativeElement") == 0 && strcmp(rp->method->name->text, "getAutoGenType") ==0) opt_TraceReplacement = 2; else opt_TraceReplacement = 0;*/
+
+       DOLOG_SHORT( printf("REPLACING(%d %p): (id %d %p) ",
+                                stat_replacements, (void*)THREADOBJECT,
+                                rp->id, (void*)rp);
+                                method_println(es->code->m); );
+
+       DOLOG( replace_replacement_point_println(rp, 1); );
+
+       REPLACE_COUNT(stat_replacements);
+
+       /* mark start of dump memory area */
+
+       DMARKER;
+
+       /* Get the stackframeinfo for the current thread. */
+
+       sfi = threads_get_current_stackframeinfo();
+
+       /* recover source state */
+
+       ss = replace_recover_source_state(rp, sfi, es);
+
+#if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
+       /* if there is a collection pending, we assume the replacement point should
+          suspend this thread */
+
+       if (gc_pending) {
+
+               thread = THREADOBJECT;
+
+               DOLOG_SHORT( printf("REPLACEMENT: Suspending thread for GC now!\n"); );
+
+               /* map the sourcestate using the identity mapping */
+               replace_map_source_state_identity(ss);
+
+               /* since we enter the same method again, we turn off rps now */
+               /* XXX michi: can we really do this? what if the rp was active before
+                  we activated it for the gc? */
+               replace_deactivate_replacement_points(origcode);
+
+               /* remember executionstate and sourcestate for this thread */
+               GC_EXECUTIONSTATE = es;
+               GC_SOURCESTATE    = ss;
+
+               /* really suspend this thread now (PC = 0) */
+               threads_suspend_ack(NULL, NULL);
+
+               DOLOG_SHORT( printf("REPLACEMENT: Resuming thread after GC now!\n"); );
+
+       } else {
+#endif /*defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)*/
+
+       /* map the source state */
+
+       if (!replace_map_source_state(ss))
+               vm_abort("exception during method replacement");
+
+       DOLOG( replace_sourcestate_println(ss); );
+
+       DOLOG_SHORT( replace_sourcestate_println_short(ss); );
+
+#if !defined(NDEBUG)
+       /* avoid infinite loops by self-replacement, only if not in testing mode */
+
+       if (!opt_TestReplacement) {
+               frame = ss->frames;
+               while (frame->down)
+                       frame = frame->down;
+
+               if (frame->torp == origrp) {
+                       DOLOG_SHORT(
+                               printf("WARNING: identity replacement, turning off rps to avoid infinite loop\n");
+                       );
+                       replace_deactivate_replacement_points(origcode);
+               }
+       }
+#endif
+
+#if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
+       }
+#endif
+
+       /* build the new execution state */
+
+       replace_build_execution_state(ss, es);
+
+#if !defined(NDEBUG)
+       /* continue execution after patched machine code, if testing mode enabled */
+
+       if (opt_TestReplacement)
+               es->pc += REPLACEMENT_PATCH_SIZE;
+#endif
+
+       /* release dump area */
+
+       DRELEASE;
+}
+
+
+/* replace_me_wrapper **********************************************************
+
+   This function is called by the signal handler. It determines if there
+   is an active replacement point pending at the given PC and returns
+   accordingly.
+
+   THIS FUNCTION MUST BE CALLED USING A SAFE STACK AREA!
+
+   IN:
+       pc...............the program counter that triggered the replacement.
+       context..........the context (machine state) to which the
+                           replacement should be applied.
+
+   OUT:
+       context..........the context after replacement finished.
+
+   RETURN VALUE:
+       true.............replacement done, everything went ok
+       false............no replacement done, context unchanged
+
+*******************************************************************************/
+
+bool replace_me_wrapper(u1 *pc, void *context)
+{
+       codeinfo         *code;
+       rplpoint         *rp;
+       executionstate_t  es;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_end;
+#endif
+
+       /* search the codeinfo for the given PC */
+
+       code = code_find_codeinfo_for_pc(pc);
+       assert(code);
+
+       /* search for a replacement point at the given PC */
+
+       rp = replace_find_replacement_point_for_pc(code, pc, (RPLPOINT_FLAG_ACTIVE | RPLPOINT_FLAG_COUNTDOWN));
+
+       /* check if the replacement point belongs to given PC and is active */
+
+       if ((rp != NULL) && (rp->pc == pc)
+           && (rp->flags & (RPLPOINT_FLAG_ACTIVE | RPLPOINT_FLAG_COUNTDOWN))) {
+
+               DOLOG( printf("valid replacement point\n"); );
+
+#if !defined(NDEBUG)
+               executionstate_sanity_check(context);
+#endif
+
+               /* set codeinfo pointer in execution state */
+
+               es.code = code;
+
+               /* read execution state from current context */
+
+               md_executionstate_read(&es, context);
+
+               DOLOG( printf("REPLACEMENT READ: ");
+                          executionstate_println(&es); );
+
+               /* do the actual replacement */
+
+#if defined(ENABLE_RT_TIMING)
+               RT_TIMING_GET_TIME(time_start);
+#endif
+
+               replace_me(rp, &es);
+
+#if defined(ENABLE_RT_TIMING)
+               RT_TIMING_GET_TIME(time_end);
+               RT_TIMING_TIME_DIFF(time_start, time_end, RT_TIMING_REPLACE);
+#endif
+
+               /* write execution state to current context */
+
+               md_executionstate_write(&es, context);
+
+               DOLOG( printf("REPLACEMENT WRITE: ");
+                          executionstate_println(&es); );
+
+               /* new code is entered after returning */
+
+               DOLOG( printf("JUMPING IN!\n"); fflush(stdout); );
+               return true;
+       }
+       else
+               return false;
+}
+
+
+/******************************************************************************/
+/* NOTE: Stuff specific to the exact GC is below.                             */
+/******************************************************************************/
+
+#if defined(ENABLE_GC_CACAO)
+void replace_gc_from_native(threadobject *thread, u1 *pc, u1 *sp)
+{
+       stackframeinfo_t *sfi;
+       executionstate_t *es;
+       sourcestate_t    *ss;
+
+       /* Get the stackframeinfo of this thread. */
+
+       assert(thread == THREADOBJECT);
+
+       sfi = threads_get_current_stackframeinfo();
+
+       /* create the execution state */
+       es = DNEW(executionstate_t);
+       es->pc = pc;
+       es->sp = sp;
+       es->pv = 0;      /* since we are in a native, PV is invalid! */
+       es->code = NULL; /* since we are in a native, we do not have a codeinfo */
+
+       /* we assume we are in a native (no replacement point)! */
+       ss = replace_recover_source_state(NULL, sfi, es);
+
+       /* map the sourcestate using the identity mapping */
+       replace_map_source_state_identity(ss);
+
+       /* remember executionstate and sourcestate for this thread */
+       GC_EXECUTIONSTATE = es;
+       GC_SOURCESTATE    = ss;
+}
+#endif
+
+#if defined(ENABLE_GC_CACAO)
+void replace_gc_into_native(threadobject *thread)
+{
+       executionstate_t *es;
+       sourcestate_t    *ss;
+
+       /* get the executionstate and sourcestate for the given thread */
+       es = GC_EXECUTIONSTATE;
+       ss = GC_SOURCESTATE;
+
+       /* rebuild the stack of the given thread */
+       replace_build_execution_state(ss, es);
+}
+#endif
+
+
+/******************************************************************************/
+/* NOTE: No important code below.                                             */
+/******************************************************************************/
+
+
+/* statistics *****************************************************************/
+
+#if defined(REPLACE_STATISTICS)
+static void print_freq(FILE *file,int *array,int limit)
+{
+       int i;
+       int sum = 0;
+       int cum = 0;
+       for (i=0; i<limit; ++i)
+               sum += array[i];
+       sum += array[limit];
+       for (i=0; i<limit; ++i) {
+               cum += array[i];
+               fprintf(file,"      %3d: %8d (cum %3d%%)\n",
+                               i, array[i], (sum) ? ((100*cum)/sum) : 0);
+       }
+       fprintf(file,"    >=%3d: %8d\n",limit,array[limit]);
+}
+#endif /* defined(REPLACE_STATISTICS) */
+
+
+#if defined(REPLACE_STATISTICS)
+
+#define REPLACE_PRINT_DIST(name, array)                              \
+    printf("    " name " distribution:\n");                          \
+    print_freq(stdout, (array), sizeof(array)/sizeof(int) - 1);
+
+void replace_print_statistics(void)
+{
+       printf("replacement statistics:\n");
+       printf("    # of replacements:   %d\n", stat_replacements);
+       printf("    # of frames:         %d\n", stat_frames);
+       printf("    # of recompilations: %d\n", stat_recompile);
+       printf("    patched static calls:%d\n", stat_staticpatch);
+       printf("    unrolled inlines:    %d\n", stat_unroll_inline);
+       printf("    unrolled calls:      %d\n", stat_unroll_call);
+       REPLACE_PRINT_DIST("frame depth", stat_dist_frames);
+       REPLACE_PRINT_DIST("locals per frame", stat_dist_locals);
+       REPLACE_PRINT_DIST("ADR locals per frame", stat_dist_locals_adr);
+       REPLACE_PRINT_DIST("primitive locals per frame", stat_dist_locals_prim);
+       REPLACE_PRINT_DIST("RET locals per frame", stat_dist_locals_ret);
+       REPLACE_PRINT_DIST("void locals per frame", stat_dist_locals_void);
+       REPLACE_PRINT_DIST("stack slots per frame", stat_dist_stack);
+       REPLACE_PRINT_DIST("ADR stack slots per frame", stat_dist_stack_adr);
+       REPLACE_PRINT_DIST("primitive stack slots per frame", stat_dist_stack_prim);
+       REPLACE_PRINT_DIST("RET stack slots per frame", stat_dist_stack_ret);
+       printf("\n");
+       printf("    # of methods:            %d\n", stat_methods);
+       printf("    # of replacement points: %d\n", stat_rploints);
+       printf("    # of regallocs:          %d\n", stat_regallocs);
+       printf("        per rplpoint:        %f\n", (double)stat_regallocs / stat_rploints);
+       printf("        per method:          %f\n", (double)stat_regallocs / stat_methods);
+       REPLACE_PRINT_DIST("replacement points per method", stat_dist_method_rplpoints);
+       printf("\n");
+
+}
+#endif /* defined(REPLACE_STATISTICS) */
+
+
+#if defined(REPLACE_STATISTICS)
+static void replace_statistics_source_frame(sourceframe_t *frame)
+{
+       int adr = 0;
+       int ret = 0;
+       int prim = 0;
+       int vd = 0;
+       int n = 0;
+       int i;
+
+       for (i=0; i<frame->javalocalcount; ++i) {
+               switch (frame->javalocaltype[i]) {
+                       case TYPE_ADR: adr++; break;
+                       case TYPE_RET: ret++; break;
+                       case TYPE_INT: case TYPE_LNG: case TYPE_FLT: case TYPE_DBL: prim++; break;
+                       case TYPE_VOID: vd++; break;
+                       default: assert(0);
+               }
+               n++;
+       }
+       REPLACE_COUNT_DIST(stat_dist_locals, n);
+       REPLACE_COUNT_DIST(stat_dist_locals_adr, adr);
+       REPLACE_COUNT_DIST(stat_dist_locals_void, vd);
+       REPLACE_COUNT_DIST(stat_dist_locals_ret, ret);
+       REPLACE_COUNT_DIST(stat_dist_locals_prim, prim);
+       adr = ret = prim = n = 0;
+       for (i=0; i<frame->javastackdepth; ++i) {
+               switch (frame->javastacktype[i]) {
+                       case TYPE_ADR: adr++; break;
+                       case TYPE_RET: ret++; break;
+                       case TYPE_INT: case TYPE_LNG: case TYPE_FLT: case TYPE_DBL: prim++; break;
+               }
+               n++;
+       }
+       REPLACE_COUNT_DIST(stat_dist_stack, n);
+       REPLACE_COUNT_DIST(stat_dist_stack_adr, adr);
+       REPLACE_COUNT_DIST(stat_dist_stack_ret, ret);
+       REPLACE_COUNT_DIST(stat_dist_stack_prim, prim);
+}
+#endif /* defined(REPLACE_STATISTICS) */
+
+
+/* debugging helpers **********************************************************/
+
+/* replace_replacement_point_println *******************************************
+   Print replacement point info.
+  
+   IN:
+       rp...............the replacement point to print
+  
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+
+#define TYPECHAR(t)  (((t) >= 0 && (t) <= TYPE_RET) ? show_jit_type_letters[t] : '?')
+
+static const char *replace_type_str[] = {
+       "STD",
+       "EXH",
+       "SBR",
+       "CALL",
+       "INLINE",
+       "RETURN",
+       "BODY"
+};
+
+void replace_replacement_point_println(rplpoint *rp, int depth)
+{
+       int j;
+       int index;
+
+       if (!rp) {
+               printf("(rplpoint *)NULL\n");
+               return;
+       }
+
+       for (j=0; j<depth; ++j)
+               putchar('\t');
+
+       printf("rplpoint (id %d) %p pc:%p+%d type:%s",
+                       rp->id, (void*)rp,rp->pc,rp->callsize,
+                       replace_type_str[rp->type]);
+       if (rp->flags & RPLPOINT_FLAG_NOTRAP)
+               printf(" NOTRAP");
+       if (rp->flags & RPLPOINT_FLAG_COUNTDOWN)
+               printf(" COUNTDOWN");
+       if (rp->flags & RPLPOINT_FLAG_ACTIVE)
+               printf(" ACTIVE");
+       printf(" parent:%p\n", (void*)rp->parent);
+       for (j=0; j<depth; ++j)
+               putchar('\t');
+       printf("ra:%d = [",     rp->regalloccount);
+
+       for (j=0; j<rp->regalloccount; ++j) {
+               if (j)
+                       putchar(' ');
+               index = rp->regalloc[j].index;
+               switch (index) {
+                       case RPLALLOC_STACK: printf("S"); break;
+                       case RPLALLOC_PARAM: printf("P"); break;
+                       case RPLALLOC_SYNC : printf("Y"); break;
+                       default: printf("%d", index);
+               }
+               printf(":%1c:", TYPECHAR(rp->regalloc[j].type));
+               if (rp->regalloc[j].type == TYPE_RET) {
+                       printf("ret(L%03d)", rp->regalloc[j].regoff);
+               }
+               else {
+                       show_allocation(rp->regalloc[j].type, rp->regalloc[j].flags, rp->regalloc[j].regoff);
+               }
+       }
+
+       printf("]\n");
+       for (j=0; j<depth; ++j)
+               putchar('\t');
+       printf("method: ");
+       method_print(rp->method);
+
+       printf("\n");
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* replace_show_replacement_points *********************************************
+   Print replacement point info.
+  
+   IN:
+       code.............codeinfo whose replacement points should be printed.
+  
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void replace_show_replacement_points(codeinfo *code)
+{
+       int i;
+       int depth;
+       rplpoint *rp;
+       rplpoint *parent;
+
+       if (!code) {
+               printf("(codeinfo *)NULL\n");
+               return;
+       }
+
+       printf("\treplacement points: %d\n",code->rplpointcount);
+
+       printf("\ttotal allocations : %d\n",code->regalloccount);
+       printf("\tsaved int regs    : %d\n",code->savedintcount);
+       printf("\tsaved flt regs    : %d\n",code->savedfltcount);
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       printf("\tsaved adr regs    : %d\n",code->savedadrcount);
+#endif
+       printf("\tmemuse            : %d\n",code->memuse);
+
+       printf("\n");
+
+       for (i=0; i<code->rplpointcount; ++i) {
+               rp = code->rplpoints + i;
+
+               depth = 1;
+               parent = rp->parent;
+               while (parent) {
+                       depth++;
+                       parent = parent->parent;
+               }
+               replace_replacement_point_println(rp, depth);
+       }
+}
+#endif
+
+
+#if !defined(NDEBUG)
+static void java_value_print(s4 type, replace_val_t value)
+{
+       java_object_t *obj;
+       utf           *u;
+
+       printf("%016llx",(unsigned long long) value.l);
+
+       if (type < 0 || type > TYPE_RET)
+               printf(" <INVALID TYPE:%d>", type);
+       else
+               printf(" %s", show_jit_type_names[type]);
+
+       if (type == TYPE_ADR && value.a != NULL) {
+               obj = value.a;
+               putchar(' ');
+               utf_display_printable_ascii_classname(obj->vftbl->clazz->name);
+
+               if (obj->vftbl->clazz == class_java_lang_String) {
+                       printf(" \"");
+                       u = javastring_toutf(obj, false);
+                       utf_display_printable_ascii(u);
+                       printf("\"");
+               }
+       }
+       else if (type == TYPE_INT) {
+               printf(" %ld", (long) value.i);
+       }
+       else if (type == TYPE_LNG) {
+               printf(" %lld", (long long) value.l);
+       }
+       else if (type == TYPE_FLT) {
+               printf(" %f", value.f);
+       }
+       else if (type == TYPE_DBL) {
+               printf(" %f", value.d);
+       }
+}
+#endif /* !defined(NDEBUG) */
+
+
+#if !defined(NDEBUG)
+void replace_source_frame_println(sourceframe_t *frame)
+{
+       s4 i,j;
+       s4 t;
+
+       if (REPLACE_IS_NATIVE_FRAME(frame)) {
+               printf("\tNATIVE\n");
+               printf("\tsfi: "); replace_stackframeinfo_println(frame->sfi);
+               printf("\tnativepc: %p\n", frame->nativepc);
+               printf("\tframesize: %d\n", frame->nativeframesize);
+
+               j = 0;
+               for (i=0; i<INT_REG_CNT; ++i) {
+                       if (nregdescint[i] == REG_SAV)
+                               printf("\t%s = %p\n", abi_registers_integer_name[i], (void*)frame->nativesavint[j++]);
+               }
+
+               j = 0;
+               for (i=0; i<FLT_REG_CNT; ++i) {
+                       if (nregdescfloat[i] == REG_SAV)
+                               printf("\tF%02d = %f\n", i, frame->nativesavflt[j++]);
+               }
+
+               printf("\n");
+               return;
+       }
+
+       printf("\t");
+       method_println(frame->method);
+       printf("\tid: %d\n", frame->id);
+       printf("\ttype: %s\n", replace_type_str[frame->type]);
+       printf("\n");
+
+       if (frame->instance.a) {
+               printf("\tinstance: ");
+               java_value_print(TYPE_ADR, frame->instance);
+               printf("\n");
+       }
+
+       if (frame->javalocalcount) {
+               printf("\tlocals (%d):\n",frame->javalocalcount);
+               for (i=0; i<frame->javalocalcount; ++i) {
+                       t = frame->javalocaltype[i];
+                       if (t == TYPE_VOID) {
+                               printf("\tlocal[ %2d] = void\n",i);
+                       }
+                       else {
+                               printf("\tlocal[%c%2d] = ",TYPECHAR(t),i);
+                               java_value_print(t, frame->javalocals[i]);
+                               printf("\n");
+                       }
+               }
+               printf("\n");
+       }
+
+       if (frame->javastackdepth) {
+               printf("\tstack (depth %d):\n",frame->javastackdepth);
+               for (i=0; i<frame->javastackdepth; ++i) {
+                       t = frame->javastacktype[i];
+                       if (t == TYPE_VOID) {
+                               printf("\tstack[%2d] = void", i);
+                       }
+                       else {
+                               printf("\tstack[%2d] = ",i);
+                               java_value_print(frame->javastacktype[i], frame->javastack[i]);
+                               printf("\n");
+                       }
+               }
+               printf("\n");
+       }
+
+       if (frame->syncslotcount) {
+               printf("\tsynchronization slots (%d):\n",frame->syncslotcount);
+               for (i=0; i<frame->syncslotcount; ++i) {
+                       printf("\tslot[%2d] = ",i);
+#ifdef HAS_4BYTE_STACKSLOT
+                       printf("%08lx\n",(unsigned long) frame->syncslots[i].p);
+#else
+                       printf("%016llx\n",(unsigned long long) frame->syncslots[i].p);
+#endif
+               }
+               printf("\n");
+       }
+
+       if (frame->fromcode) {
+               printf("\tfrom %p ", (void*)frame->fromcode);
+               method_println(frame->fromcode->m);
+       }
+       if (frame->tocode) {
+               printf("\tto %p ", (void*)frame->tocode);
+               method_println(frame->tocode->m);
+       }
+
+       if (frame->fromrp) {
+               printf("\tfrom replacement point:\n");
+               replace_replacement_point_println(frame->fromrp, 2);
+       }
+       if (frame->torp) {
+               printf("\tto replacement point:\n");
+               replace_replacement_point_println(frame->torp, 2);
+       }
+
+       printf("\n");
+}
+#endif /* !defined(NDEBUG) */
+
+
+/* replace_sourcestate_println *************************************************
+   Print source state
+  
+   IN:
+       ss...............the source state to print
+  
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void replace_sourcestate_println(sourcestate_t *ss)
+{
+       int i;
+       sourceframe_t *frame;
+
+       if (!ss) {
+               printf("(sourcestate_t *)NULL\n");
+               return;
+       }
+
+       printf("sourcestate_t:\n");
+
+       for (i=0, frame = ss->frames; frame != NULL; frame = frame->down, ++i) {
+               printf("    frame %d:\n", i);
+               replace_source_frame_println(frame);
+       }
+}
+#endif
+
+
+/* replace_sourcestate_println_short *******************************************
+
+   Print a compact representation of the given source state.
+
+   IN:
+       ss...............the source state to print
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+void replace_sourcestate_println_short(sourcestate_t *ss)
+{
+       sourceframe_t *frame;
+
+       for (frame = ss->frames; frame != NULL; frame = frame->down) {
+               printf("\t");
+
+               if (REPLACE_IS_NATIVE_FRAME(frame)) {
+                       printf("NATIVE (pc %p size %d) ",
+                                  (void*)frame->nativepc, frame->nativeframesize);
+                       replace_stackframeinfo_println(frame->sfi);
+                       continue;
+               }
+
+               if (frame->torp) {
+                       printf("%c", (frame->torp == frame->fromrp) ? '=' : '+');
+               }
+
+               printf("%s", replace_type_str[frame->fromrp->type]);
+
+               if (frame->torp && frame->torp->type != frame->fromrp->type)
+                       printf("->%s", replace_type_str[frame->torp->type]);
+
+               if (frame->tocode != frame->fromcode)
+                       printf(" (%p->%p/%d) ",
+                                  (void*) frame->fromcode, (void*) frame->tocode,
+                                  frame->fromrp->id);
+               else
+                       printf(" (%p/%d) ", (void*) frame->fromcode, frame->fromrp->id);
+
+               method_println(frame->method);
+       }
+}
+#endif
+
+#if !defined(NDEBUG)
+static void replace_stackframeinfo_println(stackframeinfo_t *sfi)
+{
+       printf("prev=%p pv=%p sp=%p ra=%p xpc=%p method=",
+                       (void*)sfi->prev, (void*)sfi->pv, (void*)sfi->sp,
+                       (void*)sfi->ra, (void*)sfi->xpc);
+
+       if (sfi->code)
+               method_println(sfi->code->m);
+       else
+               printf("(nil)\n");
+}
+#endif
+
+
+/*
+ * 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/replace.h b/src/vm/jit/replace.h
deleted file mode 100644 (file)
index e27c6ce..0000000
+++ /dev/null
@@ -1,289 +0,0 @@
-/* src/vm/jit/replace.h - on-stack replacement of methods
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#ifndef _REPLACE_H
-#define _REPLACE_H
-
-#include "config.h"
-#include "vm/types.h"
-
-#if !defined(ENABLE_REPLACEMENT)
-
-/*** macros for the codegens (disabled version) ************************/
-
-#define REPLACEMENT_POINTS_INIT(cd, jd)
-#define REPLACEMENT_POINTS_RESET(cd, jd)
-#define REPLACEMENT_POINT_BLOCK_START(cd, bptr)
-#define REPLACEMENT_POINT_INLINE_START(cd, iptr)
-#define REPLACEMENT_POINT_INLINE_BODY(cd, iptr)
-#define REPLACEMENT_POINT_RETURN(cd, iptr)
-#define REPLACEMENT_POINT_INVOKE(cd, iptr)
-#define REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr)
-#define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr)
-#define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr)
-
-#else /* defined(ENABLE_REPLACEMENT) */
-
-/* forward typedefs ***********************************************************/
-
-typedef struct rplalloc rplalloc;
-typedef struct rplpoint rplpoint;
-typedef struct sourcestate_t sourcestate_t;
-typedef struct sourceframe_t sourceframe_t;
-typedef union  replace_val_t replace_val_t;
-
-#include "arch.h"
-#include "md-abi.h"
-
-#include "vm/method.h"
-
-#include "vm/jit/reg.h"
-#include "vm/jit/stacktrace.hpp"
-
-
-/*** structs *********************************************************/
-
-#define RPLALLOC_STACK  -1
-#define RPLALLOC_PARAM  -2
-#define RPLALLOC_SYNC   -3
-
-/* `rplalloc` is a compact struct for register allocation info        */
-
-/* XXX optimize this for space efficiency */
-struct rplalloc {
-       s4           index;     /* local index, -1 for stack slot         */
-       s4           regoff;    /* register index / stack slot offset     */
-       unsigned int flags:4;   /* OR of (INMEMORY,...)                   */
-       unsigned int type:4;    /* TYPE_... constant                      */
-};
-
-#if INMEMORY > 0x08
-#error value of INMEMORY is too big to fit in rplalloc.flags
-#endif
-
-
-/* XXX what to do about overlapping rplpoints? */
-/* CAUTION: Do not change the numerical values. These are used as     */
-/*          indices into replace_normalize_type_map.                  */
-#define RPLPOINT_TYPE_STD     BBTYPE_STD
-#define RPLPOINT_TYPE_EXH     BBTYPE_EXH
-#define RPLPOINT_TYPE_SBR     BBTYPE_SBR
-#define RPLPOINT_TYPE_CALL    3
-#define RPLPOINT_TYPE_INLINE  4
-#define RPLPOINT_TYPE_RETURN  5
-#define RPLPOINT_TYPE_BODY    6
-
-#define RPLPOINT_FLAG_NOTRAP     0x01  /* rplpoint cannot be trapped */
-#define RPLPOINT_FLAG_COUNTDOWN  0x02  /* count down hits            */
-#define RPLPOINT_FLAG_ACTIVE     0x08  /* trap is active             */
-
-
-#if !defined(NDEBUG)
-#define RPLPOINT_CHECK(type)     , RPLPOINT_TYPE_##type
-#define RPLPOINT_CHECK_BB(bptr)  , (bptr)->type
-#else
-#define RPLPOINT_CHECK(type)
-#define RPLPOINT_CHECK_BB(bptr)
-#endif
-
-
-/* An `rplpoint` represents a replacement point in a compiled method  */
-
-struct rplpoint {
-       u1          *pc;           /* machine code PC of this point       */
-       methodinfo  *method;       /* source method this point is in      */
-       rplpoint    *parent;       /* rplpoint of the inlined body        */ /* XXX unify with code */
-       rplalloc    *regalloc;     /* pointer to register index table     */
-       s4           id;           /* id of the rplpoint within method    */
-       s4           callsize;     /* size of call code in bytes          */
-       unsigned int regalloccount:20; /* number of local allocations     */
-       unsigned int type:4;           /* RPLPOINT_TYPE_... constant      */
-       unsigned int flags:8;          /* OR of RPLPOINT_... constants    */
-};
-
-
-union replace_val_t {
-       s4             i;
-       s8             l;
-       ptrint         p;
-       struct {
-               u4 lo;
-               u4 hi;
-       }              words;
-       float          f;
-       double         d;
-       java_object_t *a;
-};
-
-
-struct sourceframe_t {
-       sourceframe_t *down;           /* source frame down the call chain */
-
-       methodinfo    *method;                  /* method this frame is in */
-       s4             id;
-       s4             type;
-
-       /* values */
-       replace_val_t  instance;
-
-       replace_val_t *javastack;                  /* values of stack vars */
-       u1            *javastacktype;              /*  types of stack vars */
-       s4             javastackdepth;             /* number of stack vars */
-
-       replace_val_t *javalocals;                 /* values of javalocals */
-       u1            *javalocaltype;              /*  types of javalocals */
-       s4             javalocalcount;             /* number of javalocals */
-
-       replace_val_t *syncslots;
-       s4             syncslotcount; /* XXX do we need more than one? */
-
-       /* mapping info */
-       rplpoint      *fromrp;         /* rplpoint used to read this frame */
-       codeinfo      *fromcode;              /* code this frame was using */
-       rplpoint      *torp;          /* rplpoint this frame was mapped to */
-       codeinfo      *tocode;            /* code this frame was mapped to */
-
-       /* info for native frames */
-       stackframeinfo_t *sfi;      /* sfi for native frames, otherwise NULL */
-       s4             nativeframesize;    /* size (bytes) of native frame */
-       u1            *nativepc;
-       ptrint         nativesavint[INT_SAV_CNT]; /* XXX temporary */
-       double         nativesavflt[FLT_REG_CNT]; /* XXX temporary */
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-       ptrint         nativesavadr[ADR_SAV_CNT]; /* XXX temporary */
-#endif
-};
-
-#define REPLACE_IS_NATIVE_FRAME(frame)  ((frame)->sfi != NULL)
-#define REPLACE_IS_JAVA_FRAME(frame)    ((frame)->sfi == NULL)
-
-
-struct sourcestate_t {
-       sourceframe_t *frames;    /* list of source frames, from bottom up */
-};
-
-
-/*** macros for the codegens *******************************************/
-
-#define REPLACEMENT_POINTS_INIT(cd, jd)                              \
-    if (!replace_create_replacement_points(jd))                      \
-        return false;                                                \
-    (cd)->replacementpoint = (jd)->code->rplpoints;
-
-#define REPLACEMENT_POINTS_RESET(cd, jd)                             \
-    (cd)->replacementpoint = (jd)->code->rplpoints;
-
-#define REPLACEMENT_POINT_BLOCK_START(cd, bptr)                      \
-    if ((bptr)->bitflags & BBFLAG_REPLACEMENT)                       \
-        codegen_set_replacement_point((cd) RPLPOINT_CHECK_BB(bptr));
-
-#define REPLACEMENT_POINT_INLINE_START(cd, iptr)                     \
-    codegen_set_replacement_point(cd RPLPOINT_CHECK(INLINE));
-
-#define REPLACEMENT_POINT_INLINE_BODY(cd, iptr)                      \
-    codegen_set_replacement_point_notrap(cd RPLPOINT_CHECK(BODY));
-
-#define REPLACEMENT_POINT_RETURN(cd, iptr)                           \
-    codegen_set_replacement_point(cd RPLPOINT_CHECK(RETURN));
-
-#define REPLACEMENT_POINT_INVOKE(cd, iptr)                           \
-    codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
-
-#define REPLACEMENT_POINT_INVOKE_RETURN(cd,  iptr)                   \
-    if (iptr->opc != ICMD_BUILTIN)                                   \
-        cd->replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase)\
-                    - (ptrint) cd->replacementpoint[-1].pc;
-
-
-/*** macros for the codegens (for GC) **********************************/
-
-#if defined(ENABLE_GC_CACAO)
-
-#define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr)                    \
-       codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
-
-#define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr)             \
-       if (iptr->opc == ICMD_BUILTIN)                                   \
-               cd->replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase)\
-                                       - (ptrint) cd->replacementpoint[-1].pc;
-
-#else /* defined(ENABLE_GC_CACAO) */
-
-#define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr)
-#define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr)
-
-#endif /* defined(ENABLE_GC_CACAO) */
-
-
-/*** prototypes ********************************************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-bool replace_create_replacement_points(jitdata *jd);
-void replace_free_replacement_points(codeinfo *code);
-
-void replace_activate_replacement_points(codeinfo *code, bool mappable);
-void replace_deactivate_replacement_points(codeinfo *code);
-
-bool replace_me_wrapper(u1 *pc, void *context);
-
-#if !defined(NDEBUG)
-void replace_show_replacement_points(codeinfo *code);
-void replace_replacement_point_println(rplpoint *rp, int depth);
-void replace_sourcestate_println(sourcestate_t *ss);
-void replace_sourcestate_println_short(sourcestate_t *ss);
-void replace_source_frame_println(sourceframe_t *frame);
-#endif
-
-/* machine dependent functions (code in ARCH_DIR/md.c) */
-
-#if defined(ENABLE_JIT)
-void md_patch_replacement_point(u1 *pc, u1 *savedmcode, bool revert);
-#endif
-
-#endif /* defined(ENABLE_REPLACEMENT) */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _REPLACE_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/replace.hpp b/src/vm/jit/replace.hpp
new file mode 100644 (file)
index 0000000..adad8cd
--- /dev/null
@@ -0,0 +1,289 @@
+/* src/vm/jit/replace.hpp - on-stack replacement of methods
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#ifndef _REPLACE_HPP
+#define _REPLACE_HPP
+
+#include "config.h"
+#include "vm/types.h"
+
+#if !defined(ENABLE_REPLACEMENT)
+
+/*** macros for the codegens (disabled version) ************************/
+
+#define REPLACEMENT_POINTS_INIT(cd, jd)
+#define REPLACEMENT_POINTS_RESET(cd, jd)
+#define REPLACEMENT_POINT_BLOCK_START(cd, bptr)
+#define REPLACEMENT_POINT_INLINE_START(cd, iptr)
+#define REPLACEMENT_POINT_INLINE_BODY(cd, iptr)
+#define REPLACEMENT_POINT_RETURN(cd, iptr)
+#define REPLACEMENT_POINT_INVOKE(cd, iptr)
+#define REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr)
+#define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr)
+#define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr)
+
+#else /* defined(ENABLE_REPLACEMENT) */
+
+/* forward typedefs ***********************************************************/
+
+typedef struct rplalloc rplalloc;
+typedef struct rplpoint rplpoint;
+typedef struct sourcestate_t sourcestate_t;
+typedef struct sourceframe_t sourceframe_t;
+typedef union  replace_val_t replace_val_t;
+
+#include "arch.h"
+#include "md-abi.h"
+
+#include "vm/method.h"
+
+#include "vm/jit/reg.h"
+#include "vm/jit/stacktrace.hpp"
+
+
+/*** structs *********************************************************/
+
+#define RPLALLOC_STACK  -1
+#define RPLALLOC_PARAM  -2
+#define RPLALLOC_SYNC   -3
+
+/* `rplalloc` is a compact struct for register allocation info        */
+
+/* XXX optimize this for space efficiency */
+struct rplalloc {
+       s4           index;     /* local index, -1 for stack slot         */
+       s4           regoff;    /* register index / stack slot offset     */
+       unsigned int flags:4;   /* OR of (INMEMORY,...)                   */
+       unsigned int type:4;    /* TYPE_... constant                      */
+};
+
+#if INMEMORY > 0x08
+#error value of INMEMORY is too big to fit in rplalloc.flags
+#endif
+
+
+/* XXX what to do about overlapping rplpoints? */
+/* CAUTION: Do not change the numerical values. These are used as     */
+/*          indices into replace_normalize_type_map.                  */
+#define RPLPOINT_TYPE_STD     BBTYPE_STD
+#define RPLPOINT_TYPE_EXH     BBTYPE_EXH
+#define RPLPOINT_TYPE_SBR     BBTYPE_SBR
+#define RPLPOINT_TYPE_CALL    3
+#define RPLPOINT_TYPE_INLINE  4
+#define RPLPOINT_TYPE_RETURN  5
+#define RPLPOINT_TYPE_BODY    6
+
+#define RPLPOINT_FLAG_NOTRAP     0x01  /* rplpoint cannot be trapped */
+#define RPLPOINT_FLAG_COUNTDOWN  0x02  /* count down hits            */
+#define RPLPOINT_FLAG_ACTIVE     0x08  /* trap is active             */
+
+
+#if !defined(NDEBUG)
+#define RPLPOINT_CHECK(type)     , RPLPOINT_TYPE_##type
+#define RPLPOINT_CHECK_BB(bptr)  , (bptr)->type
+#else
+#define RPLPOINT_CHECK(type)
+#define RPLPOINT_CHECK_BB(bptr)
+#endif
+
+
+/* An `rplpoint` represents a replacement point in a compiled method  */
+
+struct rplpoint {
+       u1          *pc;           /* machine code PC of this point       */
+       methodinfo  *method;       /* source method this point is in      */
+       rplpoint    *parent;       /* rplpoint of the inlined body        */ /* XXX unify with code */
+       rplalloc    *regalloc;     /* pointer to register index table     */
+       s4           id;           /* id of the rplpoint within method    */
+       s4           callsize;     /* size of call code in bytes          */
+       unsigned int regalloccount:20; /* number of local allocations     */
+       unsigned int type:4;           /* RPLPOINT_TYPE_... constant      */
+       unsigned int flags:8;          /* OR of RPLPOINT_... constants    */
+};
+
+
+union replace_val_t {
+       s4             i;
+       s8             l;
+       ptrint         p;
+       struct {
+               u4 lo;
+               u4 hi;
+       }              words;
+       float          f;
+       double         d;
+       java_object_t *a;
+};
+
+
+struct sourceframe_t {
+       sourceframe_t *down;           /* source frame down the call chain */
+
+       methodinfo    *method;                  /* method this frame is in */
+       s4             id;
+       s4             type;
+
+       /* values */
+       replace_val_t  instance;
+
+       replace_val_t *javastack;                  /* values of stack vars */
+       u1            *javastacktype;              /*  types of stack vars */
+       s4             javastackdepth;             /* number of stack vars */
+
+       replace_val_t *javalocals;                 /* values of javalocals */
+       u1            *javalocaltype;              /*  types of javalocals */
+       s4             javalocalcount;             /* number of javalocals */
+
+       replace_val_t *syncslots;
+       s4             syncslotcount; /* XXX do we need more than one? */
+
+       /* mapping info */
+       rplpoint      *fromrp;         /* rplpoint used to read this frame */
+       codeinfo      *fromcode;              /* code this frame was using */
+       rplpoint      *torp;          /* rplpoint this frame was mapped to */
+       codeinfo      *tocode;            /* code this frame was mapped to */
+
+       /* info for native frames */
+       stackframeinfo_t *sfi;      /* sfi for native frames, otherwise NULL */
+       s4             nativeframesize;    /* size (bytes) of native frame */
+       u1            *nativepc;
+       ptrint         nativesavint[INT_SAV_CNT]; /* XXX temporary */
+       double         nativesavflt[FLT_REG_CNT]; /* XXX temporary */
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       ptrint         nativesavadr[ADR_SAV_CNT]; /* XXX temporary */
+#endif
+};
+
+#define REPLACE_IS_NATIVE_FRAME(frame)  ((frame)->sfi != NULL)
+#define REPLACE_IS_JAVA_FRAME(frame)    ((frame)->sfi == NULL)
+
+
+struct sourcestate_t {
+       sourceframe_t *frames;    /* list of source frames, from bottom up */
+};
+
+
+/*** macros for the codegens *******************************************/
+
+#define REPLACEMENT_POINTS_INIT(cd, jd)                              \
+    if (!replace_create_replacement_points(jd))                      \
+        return false;                                                \
+    (cd)->replacementpoint = (jd)->code->rplpoints;
+
+#define REPLACEMENT_POINTS_RESET(cd, jd)                             \
+    (cd)->replacementpoint = (jd)->code->rplpoints;
+
+#define REPLACEMENT_POINT_BLOCK_START(cd, bptr)                      \
+    if ((bptr)->bitflags & BBFLAG_REPLACEMENT)                       \
+        codegen_set_replacement_point((cd) RPLPOINT_CHECK_BB(bptr));
+
+#define REPLACEMENT_POINT_INLINE_START(cd, iptr)                     \
+    codegen_set_replacement_point(cd RPLPOINT_CHECK(INLINE));
+
+#define REPLACEMENT_POINT_INLINE_BODY(cd, iptr)                      \
+    codegen_set_replacement_point_notrap(cd RPLPOINT_CHECK(BODY));
+
+#define REPLACEMENT_POINT_RETURN(cd, iptr)                           \
+    codegen_set_replacement_point(cd RPLPOINT_CHECK(RETURN));
+
+#define REPLACEMENT_POINT_INVOKE(cd, iptr)                           \
+    codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
+
+#define REPLACEMENT_POINT_INVOKE_RETURN(cd,  iptr)                   \
+    if (iptr->opc != ICMD_BUILTIN)                                   \
+        cd->replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase)\
+                    - (ptrint) cd->replacementpoint[-1].pc;
+
+
+/*** macros for the codegens (for GC) **********************************/
+
+#if defined(ENABLE_GC_CACAO)
+
+#define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr)                    \
+       codegen_set_replacement_point(cd RPLPOINT_CHECK(CALL));
+
+#define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr)             \
+       if (iptr->opc == ICMD_BUILTIN)                                   \
+               cd->replacementpoint[-1].callsize = (cd->mcodeptr - cd->mcodebase)\
+                                       - (ptrint) cd->replacementpoint[-1].pc;
+
+#else /* defined(ENABLE_GC_CACAO) */
+
+#define REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr)
+#define REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr)
+
+#endif /* defined(ENABLE_GC_CACAO) */
+
+
+/*** prototypes ********************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool replace_create_replacement_points(jitdata *jd);
+void replace_free_replacement_points(codeinfo *code);
+
+void replace_activate_replacement_points(codeinfo *code, bool mappable);
+void replace_deactivate_replacement_points(codeinfo *code);
+
+bool replace_me_wrapper(u1 *pc, void *context);
+
+#if !defined(NDEBUG)
+void replace_show_replacement_points(codeinfo *code);
+void replace_replacement_point_println(rplpoint *rp, int depth);
+void replace_sourcestate_println(sourcestate_t *ss);
+void replace_sourcestate_println_short(sourcestate_t *ss);
+void replace_source_frame_println(sourceframe_t *frame);
+#endif
+
+/* machine dependent functions (code in ARCH_DIR/md.c) */
+
+#if defined(ENABLE_JIT)
+void md_patch_replacement_point(u1 *pc, u1 *savedmcode, bool revert);
+#endif
+
+#endif /* defined(ENABLE_REPLACEMENT) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _REPLACE_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 e10a1239a267bc8ab14a543a4be8da81ff41a623..88b8ad4d4729e2127759296403f1bbb18103d7c7 100644 (file)
@@ -64,7 +64,7 @@
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/reg.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
index e395099dc077e9123a0fe3cf861017998e1a6e65..25a7d3bb4ea2216d18674c8b7766c9d85805e7fa 100644 (file)
@@ -47,7 +47,7 @@
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.hpp"
 #include "vm/jit/patcher-common.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/trace.hpp"
 #include "vm/jit/trap.h"
 
index 0712c8c8c32b99a432cdc6e3e8b88b1c10924dd9..2457cae337c6fd633322173300360f23f8917dba 100644 (file)
@@ -58,7 +58,7 @@
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher.h"
 #include "vm/jit/reg.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/stacktrace.hpp"
 
 #include "vm/jit/sparc64/solaris/macro_rename.h"
index 9fc43a4fa95076df9c59830a6437b772b94c2216..9eedcb3290ec2388dda1f5b8e0333c33d525cd6b 100644 (file)
@@ -44,7 +44,7 @@
 #include "vm/jit/dseg.h"
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.hpp"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 
 #include "vm/jit/sparc64/solaris/macro_rename.h"
 
index 376b597be468448f1443fa72099489fb44e0c392..2d449c3dc2a62559dbce14c824b3792ffe05c1e9 100644 (file)
@@ -132,7 +132,7 @@ u1 *md_get_pv_from_stackframe(u1 *sp);
 #endif
 
 #if defined(ENABLE_INTRP)
-u1 *intrp_md_stacktrace_get_returnaddress(u1 *sp, u4 framesize);
+void* intrp_md_stacktrace_get_returnaddress(void* sp, int32_t framesize);
 #endif
 
 #if defined(ENABLE_CYCLES_STATS)
index 0b8b1bca6f5ee6ca19df7b76031e048c0e501d2a..c40c5f31d33158ca13eafec901591bde9596489d 100644 (file)
@@ -47,7 +47,7 @@
 #include "vm/jit/jit.hpp"
 #include "vm/jit/methodtree.h"
 #include "vm/jit/patcher-common.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/stacktrace.hpp"
 
 
index 623978d42c2ebedc8a8e21b0c05e630bc9fea2db..3667689aff3122e109bd1b4186e4ce06ce43a25b 100644 (file)
@@ -66,7 +66,7 @@
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher-common.h"
 #include "vm/jit/reg.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/stacktrace.hpp"
 #include "vm/jit/trap.h"
 
index 240be04005a55c83cdbd147b461f184b4a318f16..fe9a944d9db07e2396710efb5e808038cd10f8b5 100644 (file)
@@ -46,7 +46,7 @@
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.hpp"
 #include "vm/jit/patcher-common.h"
-#include "vm/jit/replace.h"
+#include "vm/jit/replace.hpp"
 #include "vm/jit/trace.hpp"
 #include "vm/jit/trap.h"