* compiled directly. */
using namespace java::lang::reflect;
+
+ pc_t pc = NULL;
// FRAME_DESC registers this particular invocation as the top-most
// interpreter frame. This lets the stack tracing code (for
// destructor so it cleans up automatically when the interpreter
// returns.
java::lang::Thread *thread = java::lang::Thread::currentThread();
+
+#ifdef DEBUG
+ _Jv_InterpFrame frame_desc (meth, thread, NULL, &pc);
+#else
_Jv_InterpFrame frame_desc (meth, thread);
+#endif
_Jv_word stack[meth->max_stack];
_Jv_word *sp = stack;
#endif
};
- pc_t pc;
-
#ifdef DIRECT_THREADED
#ifdef DEBUG
#define NEXT_INSN \
do \
{ \
+ pc_t insn = pc++; \
if (JVMTI_REQUESTED_EVENT (SingleStep)) \
{ \
JNIEnv *env = _Jv_GetCurrentJNIEnv (); \
jmethodID method = meth->self; \
- jlocation loc = meth->insn_index (pc); \
+ jlocation loc = meth->insn_index (insn); \
_Jv_JVMTI_PostEvent (JVMTI_EVENT_SINGLE_STEP, thread, \
env, method, loc); \
} \
- goto *((pc++)->insn); \
+ goto *(insn->insn); \
} \
while (0)
+
+#undef REWRITE_INSN
+#define REWRITE_INSN(INSN,SLOT,VALUE) \
+ do { \
+ if (pc[-2].insn == breakpoint_insn->insn) \
+ { \
+ using namespace ::gnu::gcj::jvmti; \
+ jlocation location = meth->insn_index (pc - 2); \
+ _Jv_RewriteBreakpointInsn (meth->self, location, (pc_t) INSN); \
+ } \
+ else \
+ pc[-2].insn = INSN; \
+ \
+ pc[-1].SLOT = VALUE; \
+ } \
+ while (0)
+
#else
#undef NEXT_INSN
#define NEXT_INSN goto *((pc++)->insn)
+#define REWRITE_INSN(INSN,SLOT,VALUE) \
+ do { \
+ pc[-2].insn = INSN; \
+ pc[-1].SLOT = VALUE; \
+ } \
+ while (0)
#endif
#define INTVAL() ((pc++)->int_val)
#ifdef DIRECT_THREADED
// Rewrite instruction so that we use a faster pre-resolved
// method.
- pc[-2].insn = &&invokevirtual_resolved;
- pc[-1].datum = rmeth;
+ REWRITE_INSN (&&invokevirtual_resolved, datum, rmeth);
#endif /* DIRECT_THREADED */
}
goto perform_invoke;
}
#ifdef DIRECT_THREADED
- pc[-2].insn = newinsn;
- pc[-1].datum = field->u.addr;
+ REWRITE_INSN (newinsn, datum, field->u.addr);
#endif /* DIRECT_THREADED */
}
NEXT_INSN;
}
#ifdef DIRECT_THREADED
- pc[-2].insn = newinsn;
- pc[-1].int_val = field_offset;
+ REWRITE_INSN (newinsn, int_val, field_offset);
#endif /* DIRECT_THREADED */
}
NEXT_INSN;
}
#ifdef DIRECT_THREADED
- pc[-2].insn = newinsn;
- pc[-1].datum = field->u.addr;
+ REWRITE_INSN (newinsn, datum, field->u.addr);
#endif /* DIRECT_THREADED */
}
NEXT_INSN;
}
#ifdef DIRECT_THREADED
- pc[-2].insn = newinsn;
- pc[-1].int_val = field_offset;
+ REWRITE_INSN (newinsn, int_val, field_offset);
#endif /* DIRECT_THREADED */
}
NEXT_INSN;
#ifdef DIRECT_THREADED
// Rewrite instruction so that we use a faster pre-resolved
// method.
- pc[-2].insn = &&invokespecial_resolved;
- pc[-1].datum = rmeth;
+ REWRITE_INSN (&&invokespecial_resolved, datum, rmeth);
#endif /* DIRECT_THREADED */
}
goto perform_invoke;
#ifdef DIRECT_THREADED
// Rewrite instruction so that we use a faster pre-resolved
// method.
- pc[-2].insn = &&invokestatic_resolved;
- pc[-1].datum = rmeth;
+ REWRITE_INSN (&&invokestatic_resolved, datum, rmeth);
#endif /* DIRECT_THREADED */
}
goto perform_invoke;
#ifdef DIRECT_THREADED
// Rewrite instruction so that we use a faster pre-resolved
// method.
- pc[-2].insn = &&invokeinterface_resolved;
- pc[-1].datum = rmeth;
+ REWRITE_INSN (&&invokeinterface_resolved, datum, rmeth);
#else
// Skip dummy bytes.
pc += 2;
PUSHA (res);
#ifdef DIRECT_THREADED
- pc[-2].insn = &&new_resolved;
- pc[-1].datum = klass;
+ REWRITE_INSN (&&new_resolved, datum, klass);
#endif /* DIRECT_THREADED */
}
NEXT_INSN;
PUSHA (result);
#ifdef DIRECT_THREADED
- pc[-2].insn = &&anewarray_resolved;
- pc[-1].datum = klass;
+ REWRITE_INSN (&&anewarray_resolved, datum, klass);
#endif /* DIRECT_THREADED */
}
NEXT_INSN;
PUSHA (value);
#ifdef DIRECT_THREADED
- pc[-2].insn = &&checkcast_resolved;
- pc[-1].datum = to;
+ REWRITE_INSN (&&checkcast_resolved, datum, to);
#endif /* DIRECT_THREADED */
}
NEXT_INSN;
PUSHI (to->isInstance (value));
#ifdef DIRECT_THREADED
- pc[-2].insn = &&instanceof_resolved;
- pc[-1].datum = to;
+ REWRITE_INSN (&&instanceof_resolved, datum, to);
#endif /* DIRECT_THREADED */
}
NEXT_INSN;
Thread *thread = Thread::currentThread ();
JNIEnv *jni_env = _Jv_GetCurrentJNIEnv ();
- _Jv_JVMTI_PostEvent (JVMTI_EVENT_BREAKPOINT, thread, jni_env,
- method, location);
-
- // Continue execution
+ // Save the insn here since the breakpoint could be removed
+ // before the JVMTI notification returns.
using namespace gnu::gcj::jvmti;
Breakpoint *bp
= BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
location);
JvAssert (bp != NULL);
-
pc_t opc = reinterpret_cast<pc_t> (bp->getInsn ());
+ _Jv_JVMTI_PostEvent (JVMTI_EVENT_BREAKPOINT, thread, jni_env,
+ method, location);
+
+ // Continue execution
#ifdef DIRECT_THREADED
goto *(opc->insn);
#else