From b5cfc28f9baab2959792b1a3a93612085313face Mon Sep 17 00:00:00 2001 From: ajordan Date: Sun, 6 May 2007 13:32:49 +0000 Subject: [PATCH] * src/vm/jit/sparc64/codegen.c: Implemented threads support. * src/vm/jit/sparc64/machine-instr.h: Likewise. * src/vm/jit/sparc64/linux/md-os.c: Likewise. --- src/vm/jit/sparc64/codegen.c | 87 ++++++++++++++++++++++++------ src/vm/jit/sparc64/linux/md-os.c | 38 +++++++------ src/vm/jit/sparc64/machine-instr.h | 7 ++- 3 files changed, 99 insertions(+), 33 deletions(-) diff --git a/src/vm/jit/sparc64/codegen.c b/src/vm/jit/sparc64/codegen.c index 28fe4a9b4..f1a4a14b3 100644 --- a/src/vm/jit/sparc64/codegen.c +++ b/src/vm/jit/sparc64/codegen.c @@ -109,7 +109,7 @@ bool codegen_emit(jitdata *jd) codeinfo *code; codegendata *cd; registerdata *rd; - s4 len, s1, s2, s3, d, disp; + s4 len, s1, s2, s3, d, disp, slots; varinfo *var; basicblock *bptr; instruction *iptr; @@ -219,7 +219,55 @@ bool codegen_emit(jitdata *jd) #endif - + /* call monitorenter function */ +#if defined(ENABLE_THREADS) + if (checksync && (m->flags & ACC_SYNCHRONIZED)) { + /* stack offset for monitor argument */ + + s1 = rd->memuse; + + /* save float argument registers */ + + /* XXX jit-c-call */ + slots = FLT_ARG_CNT; + ALIGN_STACK_SLOTS(slots); + + M_LDA(REG_SP, REG_SP, -(slots * 8)); + for (i = 0; i < FLT_ARG_CNT; i++) + M_DST(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8); + + s1 += slots; + + /* get correct lock object */ + + if (m->flags & ACC_STATIC) { + disp = dseg_add_address(cd, &m->class->object.header); + M_ALD(REG_OUT0, REG_PV, disp); + disp = dseg_add_functionptr(cd, LOCK_monitor_enter); + M_ALD(REG_ITMP3, REG_PV, disp); + } + else { + /* copy class pointer: $i0 -> $o0 */ + M_MOV(REG_RESULT_CALLEE, REG_OUT0); + M_BNEZ(REG_OUT0, 3); + disp = dseg_add_functionptr(cd, LOCK_monitor_enter); + M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */ + M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER); + } + + M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); + M_AST(REG_OUT0, REG_SP, CSTACK + s1 * 8); /* branch delay */ + + /* restore float argument registers */ + + for (i = 0; i < FLT_ARG_CNT; i++) + M_DLD(abi_registers_float_argument[i], REG_SP, CSTACK + i * 8); + + M_LDA(REG_SP, REG_SP, slots * 8); + } +#endif + + /* take arguments out of register or stack frame */ md = m->parseddesc; @@ -310,9 +358,6 @@ bool codegen_emit(jitdata *jd) /* release scratch space */ M_ADD_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP); } - - - /* XXX monitor enter */ @@ -2207,24 +2252,32 @@ nowperformreturn: #if defined(ENABLE_THREADS) if (checksync && (m->flags & ACC_SYNCHRONIZED)) { -/* XXX: REG_RESULT is save, but what about FRESULT? */ - M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* XXX: what for ? */ + /* XXX jit-c-call */ + disp = dseg_add_functionptr(cd, LOCK_monitor_exit); + M_ALD(REG_ITMP3, REG_PV, disp); + + /* we need to save fp return value (int saved by window) */ switch (iptr->opc) { case ICMD_FRETURN: case ICMD_DRETURN: - M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); - break; - } + M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8); + M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); + M_DST(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8); /* delay */ - disp = dseg_add_functionptr(cd, BUILTIN_monitorexit); - M_ALD(REG_ITMP3, REG_PV, disp); - M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /*REG_RA_CALLER */ + /* restore the fp return value */ - switch (iptr->opc) { - case ICMD_FRETURN: - case ICMD_DRETURN: - M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8); + M_DLD(REG_FRESULT, REG_SP, CSTACK + rd->memuse * 8); + break; + case ICMD_IRETURN: + case ICMD_LRETURN: + case ICMD_ARETURN: + case ICMD_RETURN: + M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); + M_ALD(REG_OUT0, REG_SP, CSTACK + rd->memuse * 8); /* delay */ + break; + default: + assert(false); break; } } diff --git a/src/vm/jit/sparc64/linux/md-os.c b/src/vm/jit/sparc64/linux/md-os.c index 5f50a10b2..7cb275a51 100644 --- a/src/vm/jit/sparc64/linux/md-os.c +++ b/src/vm/jit/sparc64/linux/md-os.c @@ -152,21 +152,6 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *info , void *_p) } -#if defined(USE_THREADS) && defined(NATIVE_THREADS) -void thread_restartcriticalsection(ucontext_t *_uc) -{ - mcontext_t *_mc; - void *critical; - - _mc = &_uc->uc_mcontext; - - critical = thread_checkcritical((void *) _mc->sc_pc); - - if (critical) - _mc->sc_pc = (ptrint) critical; -} -#endif - /* md_icacheflush ************************************************************** @@ -193,9 +178,32 @@ void md_icacheflush(u1 *addr, s4 nbytes) } } +#if defined(ENABLE_THREADS) +/* thread_restartcriticalsection ********************************************** + + Reads PC and modifies NPC +******************************************************************************/ +void thread_restartcriticalsection(ucontext_t *_uc) +{ + mcontext_t *_mc; + u1 *pc; + u1 *npc; + + _mc = &_uc->uc_mcontext; + + pc = (u1 *) _mc->mc_gregs[MC_PC]; + npc = critical_find_restart_point(pc); + assert(npc); + + _mc->mc_gregs[MC_NPC] = (ptrint) npc; + + assert(false); +} +#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 diff --git a/src/vm/jit/sparc64/machine-instr.h b/src/vm/jit/sparc64/machine-instr.h index c989a2a57..b69caa2cd 100644 --- a/src/vm/jit/sparc64/machine-instr.h +++ b/src/vm/jit/sparc64/machine-instr.h @@ -1,5 +1,8 @@ #ifndef _MACHINE_INSTR_H #define _MACHINE_INSTR_H + +#include "toolbox/logging.h" + /* static inline void __attribute__ ((unused)) @@ -23,6 +26,7 @@ __attribute__ ((unused)) compare_and_swap (volatile long *p, long oldval, long newval) { long ret; + /*dolog("compare_and_swap(%p [%d], %d, %d)", p, *p, oldval, newval);*/ __asm__ __volatile__ ( "mov %3,%0\n\t" @@ -30,6 +34,7 @@ compare_and_swap (volatile long *p, long oldval, long newval) : "=&r"(ret), "=m"(*p) : "r"(oldval), "r"(newval), "m"(*p)); + /*dolog("compare_and_swap() return=%d mem=%d", ret, *p);*/ return ret; } @@ -37,6 +42,6 @@ compare_and_swap (volatile long *p, long oldval, long newval) #define MEMORY_BARRIER_BEFORE_ATOMIC() __asm__ __volatile__ ("mb" : : : "memory"); #define MEMORY_BARRIER_AFTER_ATOMIC() __asm__ __volatile__ ("mb" : : : "memory"); #define MEMORY_BARRIER() __asm__ __volatile__ ( \ - "mb" : : : "memory" ); + "membar 0x0F" : : : "memory" ); #endif -- 2.25.1