PR144 (aligned patchers on x86_64)
[cacao.git] / src / vm / jit / patcher-common.cpp
index e7ec2086ef2566752fa5a093511e39d5b8e8a2b8..2963cf62b28f47fb8ff0a4e58602dda4ed45664b 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/patcher-common.cpp - architecture independent code patching stuff
 
-   Copyright (C) 2007, 2008, 2009
+   Copyright (C) 1996-2011
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
    Copyright (C) 2008 Theobroma Systems Ltd.
 
@@ -210,38 +210,42 @@ void patcher_list_show(codeinfo *code)
 
    Appends a new patcher reference to the list of patching positions.
 
+   Returns a pointer to the newly created patchref_t.
+
 *******************************************************************************/
 
-void patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp)
+patchref_t *patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp)
 {
-       codegendata *cd;
-       codeinfo    *code;
-       s4           patchmpc;
-
-       cd       = jd->cd;
-       code     = jd->code;
-       patchmpc = cd->mcodeptr - cd->mcodebase;
+       codegendata *cd   = jd->cd;
+       codeinfo    *code = jd->code;
 
 #if defined(ALIGN_PATCHER_TRAP)
        emit_patcher_alignment(cd);
-       patchmpc = cd->mcodeptr - cd->mcodebase;
 #endif
 
+       int32_t patchmpc = cd->mcodeptr - cd->mcodebase;
+
 #if !defined(NDEBUG)
        if (patcher_list_find(code, (void*) (intptr_t) patchmpc) != NULL)
                os::abort("patcher_add_patch_ref: different patchers at same position.");
 #endif
 
+#if defined(USES_PATCHABLE_MEMORY_BARRIER)
+       PATCHER_NOPS;
+#endif
+
        // Set patcher information (mpc is resolved later).
        patchref_t pr;
 
-       pr.mpc     = patchmpc;
-       pr.datap   = 0;
-       pr.disp    = disp;
-       pr.patcher = patcher;
-       pr.ref     = ref;
-       pr.mcode   = 0;
-       pr.done    = false;
+       pr.mpc         = patchmpc;
+       pr.datap       = 0;
+       pr.disp        = disp;
+       pr.disp_mb     = 0;
+       pr.patch_align = 0;
+       pr.patcher     = patcher;
+       pr.ref         = ref;
+       pr.mcode       = 0;
+       pr.done        = false;
 
        // Store patcher in the list (NOTE: structure is copied).
        code->patchers->push_back(pr);
@@ -265,6 +269,8 @@ void patcher_add_patch_ref(jitdata *jd, functionptr patcher, void* ref, s4 disp)
 
        cd->lastmcodeptr = cd->mcodeptr + PATCHER_CALL_SIZE;
 #endif
+
+       return &code->patchers->back();
 }
 
 
@@ -356,7 +362,7 @@ static int patcher_depth = 0;
 #define TRACE_PATCHER_INDENT for (i=0; i<patcher_depth; i++) printf("\t")
 #endif /* !defined(NDEBUG) */
 
-java_handle_t *patcher_handler(u1 *pc)
+bool patcher_handler(u1 *pc)
 {
        codeinfo      *code;
        patchref_t    *pr;
@@ -392,7 +398,7 @@ java_handle_t *patcher_handler(u1 *pc)
                }
 #endif
                code->patchers->unlock();
-               return NULL;
+               return true;
        }
 
 #if !defined(NDEBUG)
@@ -446,24 +452,17 @@ java_handle_t *patcher_handler(u1 *pc)
        }
 #endif
 
-       // Check for return value and exit accordingly.
-       if (result == false) {
-               // Mangle the pending exception.
+       // Check return value and mangle the pending exception.
+       if (result == false)
                resolve_handle_pending_exception(true);
 
-               // Get the exception and return it.
-               java_handle_t* e = exceptions_get_and_clear_exception();
-
-               code->patchers->unlock();
-
-               return e;
-       }
-
-       pr->done = true; /* XXX this is only preliminary to prevent double-patching */
+       // XXX This is only preliminary to prevent double-patching.
+       else
+               pr->done = true;
 
        code->patchers->unlock();
 
-       return NULL;
+       return result;
 }