Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id$
-
*/
#include "config.h"
#undef REPLACE_LEAFMETHODS_RA_REGISTER
#undef REPLACE_REG_RA
-/* i386 and x86_64 */
-#if defined(__I386__) || defined(__X86_64__)
+/* 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_LINKAGE_AREA
#define REPLACE_LEAFMETHODS_RA_REGISTER
#define REPLACE_REG_RA REG_ITMP3 /* the execution state has the LR in itmp3 */
+/* s390 */
+#elif defined(__S390__)
+#define REPLACE_RA_TOP_OF_FRAME
+#define REPLACE_REG_RA REG_ITMP3
#endif
/*** debugging ****************************************************************/
-/*#define REPLACE_VERBOSE*/
-
#if !defined(NDEBUG)
static void java_value_print(s4 type, replace_val_t value);
static void replace_stackframeinfo_println(stackframeinfo *sfi);
#endif
-#if !defined(NDEBUG) && defined(REPLACE_VERBOSE)
-int replace_verbose = 0;
-#define DOLOG(code) do{ if (replace_verbose > 1) { code; } } while(0)
-#define DOLOG_SHORT(code) do{ if (replace_verbose > 0) { code; } } while(0)
+#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)
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;
savedmcode -= REPLACEMENT_PATCH_SIZE;
-#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__)) && defined(ENABLE_JIT)
+#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__) || defined(__S390__)) && defined(ENABLE_JIT)
md_patch_replacement_point(code, index, rp, savedmcode);
#endif
rp->flags |= RPLPOINT_FLAG_ACTIVE;
DOLOG( printf("deactivate replacement point:\n");
replace_replacement_point_println(rp, 1); fflush(stdout); );
-#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__)) && defined(ENABLE_JIT)
+#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__) || defined(__S390__)) && defined(ENABLE_JIT)
md_patch_replacement_point(code, -1, rp, savedmcode);
#endif
IN:
es...............execution state
- sp...............stack pointer of the execution state (XXX eliminate?)
ra...............allocation
javaval..........where to put the value
*******************************************************************************/
static void replace_read_value(executionstate_t *es,
- stackslot_t *sp,
rplalloc *ra,
replace_val_t *javaval)
{
/* 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*)(sp + ra->regoff);
+ javaval->l = *(u8*)(es->sp + ra->regoff);
}
else {
#endif
- javaval->p = sp[ra->regoff];
+ javaval->p = *(ptrint*)(es->sp + ra->regoff);
#ifdef HAS_4BYTE_STACKSLOT
}
#endif
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) {
IN:
es...............execution state
- sp...............stack pointer of the execution state (XXX eliminate?)
ra...............allocation
*javaval.........the value
*******************************************************************************/
static void replace_write_value(executionstate_t *es,
- stackslot_t *sp,
rplalloc *ra,
replace_val_t *javaval)
{
/* XXX HAS_4BYTE_STACKSLOT may not be the right discriminant here */
#ifdef HAS_4BYTE_STACKSLOT
if (IS_2_WORD_TYPE(ra->type)) {
- *(u8*)(sp + ra->regoff) = javaval->l;
+ *(u8*)(es->sp + ra->regoff) = javaval->l;
}
else {
#endif
- sp[ra->regoff] = javaval->p;
+ *(ptrint*)(es->sp + ra->regoff) = javaval->p;
#ifdef HAS_4BYTE_STACKSLOT
}
#endif
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_read_executionstate *************************************************
+/* replace_new_sourceframe *****************************************************
- Read the given executions state and translate it to a source frame.
+ 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
+ ss->frames.......set to new frame (the new head of the frame list).
RETURN VALUE:
returns the new frame
/* replace_read_executionstate *************************************************
- Read the given executions state and translate it to a source frame.
+ 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...............where to put the source 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 derived from the execution state
+ *ss..............the source state with the newly created source frame
+ added
*******************************************************************************/
/* calculate base stack pointer */
- basesp = sp + code_get_stack_frame_size(code);
+ basesp = sp + code->stackframesize;
/* create the source frame */
if (ra->type == TYPE_RET)
frame->javalocals[i].i = ra->regoff;
else
- replace_read_value(es, sp, ra, frame->javalocals + i);
+ replace_read_value(es, ra, frame->javalocals + i);
ra++;
count--;
}
instra.regoff = md->params[0].regoff;
if (md->params[0].inmemory) {
instra.flags = INMEMORY;
- instra.regoff += (1 + code->stackframesize);
+ instra.regoff += (1 + code->stackframesize) * SIZE_OF_STACKSLOT;
}
else {
instra.flags = 0;
}
- replace_read_value(es, sp, &instra, &(frame->instance));
+ replace_read_value(es, &instra, &(frame->instance));
#endif
}
#endif /* defined(REPLACE_PATCH_DYNAMIC_CALL) */
calleeframe->syncslotcount = 1;
calleeframe->syncslots = DMNEW(replace_val_t, 1);
- replace_read_value(es,sp,ra,calleeframe->syncslots);
+ replace_read_value(es,ra,calleeframe->syncslots);
}
frame->javastackdepth--;
if (ra->type == TYPE_RET)
frame->javastack[i].i = ra->regoff;
else
- replace_read_value(es,sp,ra,frame->javastack + i);
+ replace_read_value(es,ra,frame->javastack + i);
frame->javastacktype[i] = ra->type;
i++;
}
/* replace_write_executionstate ************************************************
- Translate the given source state into an execution state.
-
+ 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
- creates
- es...............where to put the execution state
+ 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
sp = (stackslot_t *) es->sp;
- basesp = sp + code_get_stack_frame_size(code);
+ basesp = sp + code->stackframesize;
/* in some cases the top stack slot is passed in REG_ITMP1 */
/* XXX assert that it matches this rplpoint */
}
else
- replace_write_value(es, sp, ra, frame->javalocals + i);
+ replace_write_value(es, ra, frame->javalocals + i);
count--;
ra++;
}
assert(frame->down->syncslotcount == 1); /* XXX need to understand more cases */
assert(frame->down->syncslots != NULL);
- replace_write_value(es,sp,ra,frame->down->syncslots);
+ replace_write_value(es,ra,frame->down->syncslots);
}
continue;
}
/* XXX assert that it matches this rplpoint */
}
else {
- replace_write_value(es,sp,ra,frame->javastack + i);
+ replace_write_value(es,ra,frame->javastack + i);
}
i++;
}
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;
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) */
return (code) ? ra : NULL;
sourceframe_t *callerframe,
sourceframe_t *calleeframe)
{
- u1 *patchpos;
- methodptr entrypoint;
- methodptr oldentrypoint;
- bool atentry;
- stackframeinfo sfi;
- codeinfo *calleecode;
- methodinfo *calleem;
- java_objectheader *obj;
- vftbl_t *vftbl;
+ u1 *patchpos;
+ methodptr entrypoint;
+ methodptr oldentrypoint;
+ bool atentry;
+ stackframeinfo sfi;
+ codeinfo *calleecode;
+ methodinfo *calleem;
+ java_object_t *obj;
+ vftbl_t *vftbl;
assert(ra);
assert(callerframe->down == calleeframe);
#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
+
/* write slots used for synchronization */
count = code_get_sync_slot_count(calleecode);
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 0
if (nregdescfloat[i] == REG_SAV)
es->fltregs[i] = 0.0;
}
+
+# if defined(HAS_ADDRESS_REGISTER_FILE)
+ for (i=0; i<ADR_REG_CNT; ++i) {
+ if (nregdescadr[i] == REG_SAV)
+ es->adrregs[i] = 0;
+ }
+# endif
#endif
/* restore pv, pc, and sp */
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;
}
+/* replace_me_wrapper **********************************************************
+
+ TODO: Document me!
+
+*******************************************************************************/
+
+bool replace_me_wrapper(u1 *pc)
+{
+ codeinfo *code;
+ rplpoint *rp;
+ executionstate_t es;
+
+ /* 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 */
+
+#if 0
+ rp = replace_find_replacement_point_for_pc(code, pc);
+ assert(rp == NULL || rp->pc == pc);
+#else
+ {
+ int i;
+ rplpoint *rp2;
+ rp = NULL;
+ for (i=0,rp2=code->rplpoints; i<code->rplpointcount; i++,rp2++) {
+ if (rp2->pc == pc)
+ rp = rp2;
+ }
+ }
+#endif
+
+ /* check if the replacement point is active */
+
+ if (rp != NULL && (rp->flags & RPLPOINT_FLAG_ACTIVE)) {
+
+ /*md_replace_executionstate_read(&es, context);*/
+
+ replace_me(rp, &es);
+
+ return true;
+ }
+ else
+ return false;
+}
+
+
/* replace_me ******************************************************************
This function is called by asm_replacement_out when a thread reaches
/* call the assembler code for the last phase of replacement */
-#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__)) && defined(ENABLE_JIT)
- asm_replacement_in(&(safestack->es), safestack);
+#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__) || defined(__MIPS__) || defined(__S390__)) && defined(ENABLE_JIT)
+ /*asm_replacement_in(&(safestack->es), safestack);*/
#endif
abort(); /* NOT REACHED */
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");
if (i%4 == 3)
printf("\n");
}
+# if defined(HAS_ADDRESS_REGISTER_FILE)
+ for (i=0; i<ADR_REG_CNT; ++i) {
+ if (i%4 == 0)
+ printf("\t");
+ else
+ printf(" ");
+ printf("A%02d = %016llx",i,(unsigned long long)es->adrregs[i]);
+ if (i%4 == 3)
+ printf("\n");
+ }
+# endif
#endif
sp = (stackslot_t *) es->sp;
if (es->code) {
methoddesc *md = es->code->m->parseddesc;
- slots = code_get_stack_frame_size(es->code);
+ slots = es->code->stackframesize;
extraslots = 1 + md->memuse;
}
else
#if !defined(NDEBUG)
static void java_value_print(s4 type, replace_val_t value)
{
- java_objectheader *obj;
- utf *u;
+ java_object_t *obj;
+ utf *u;
printf("%016llx",(unsigned long long) value.l);