#if !defined(NDEBUG)
static void java_value_print(s4 type, replace_val_t value);
static void replace_stackframeinfo_println(stackframeinfo_t *sfi);
+static void replace_sanity_check_read_write(void *context);
#endif
#if !defined(NDEBUG)
if ((rp != NULL) && (rp->pc == pc) && (rp->flags & RPLPOINT_FLAG_ACTIVE)) {
+#if !defined(NDEBUG)
+ replace_sanity_check_read_write(context);
+#endif
+
/* set codeinfo pointer in execution state */
es.code = code;
}
#endif
+
+/* replace_sanity_check_read_write *********************************************
+
+ Perform some sanity checks for the md_replace_executionstate_read
+ and md_replace_executionstate_write functions.
+
+*******************************************************************************/
+
+#if !defined(NDEBUG)
+static void replace_sanity_check_read_write(void *context)
+{
+ /* estimate a minimum for the context size */
+
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+#define MINIMUM_CONTEXT_SIZE (SIZEOF_VOID_P * ADR_REG_CNT \
+ + sizeof(double) * FLT_REG_CNT \
+ + sizeof(int) * INT_REG_CNT)
+#else
+#define MINIMUM_CONTEXT_SIZE (SIZEOF_VOID_P * INT_REG_CNT \
+ + sizeof(double) * FLT_REG_CNT)
+#endif
+
+ executionstate_t es1;
+ executionstate_t es2;
+ executionstate_t es3;
+ unsigned int i;
+ unsigned char reference[MINIMUM_CONTEXT_SIZE];
+
+ /* keep a copy of (a prefix of) the context for reference */
+
+ memcpy(&reference, context, MINIMUM_CONTEXT_SIZE);
+
+ /* different poisons */
+
+ memset(&es1, 0xc9, sizeof(executionstate_t));
+ memset(&es2, 0xb5, sizeof(executionstate_t));
+ memset(&es3, 0x6f, sizeof(executionstate_t));
+
+ md_replace_executionstate_read(&es1, context);
+
+ /* verify that item-by-item copying preserves the state */
+
+ es2.pc = es1.pc;
+ es2.sp = es1.sp;
+ es2.pv = es1.pv;
+ es2.code = es1.code;
+ for (i = 0; i < INT_REG_CNT; ++i)
+ es2.intregs[i] = es1.intregs[i];
+ for (i = 0; i < FLT_REG_CNT; ++i)
+ es2.fltregs[i] = es1.fltregs[i];
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+ for (i = 0; i < ADR_REG_CNT; ++i)
+ es2.adrregs[i] = es1.adrregs[i];
+#endif
+
+ /* write it back - this should not change the context */
+ /* We cannot check that completely, unfortunately, as we don't know */
+ /* the size of the (OS-dependent) context. */
+
+ md_replace_executionstate_write(&es2, context);
+
+ /* Read it again, Sam! */
+
+ md_replace_executionstate_read(&es3, context);
+
+ /* Compare. Note: Because of the NAN madness, we cannot compare
+ * doubles using '=='. */
+
+ assert(es3.pc == es1.pc);
+ assert(es3.sp == es1.sp);
+ assert(es3.pv == es1.pv);
+ for (i = 0; i < INT_REG_CNT; ++i)
+ assert(es3.intregs[i] == es1.intregs[i]);
+ for (i = 0; i < FLT_REG_CNT; ++i)
+ assert(memcmp(es3.fltregs+i, es1.fltregs+i, sizeof(double)) == 0);
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+ for (i = 0; i < ADR_REG_CNT; ++i)
+ assert(es3.adrregs[i] == es1.adrregs[i]);
+#endif
+
+ /* "code" is not set by the md_* functions */
+
+ assert(es3.code != es1.code);
+
+ /* assert that we have not messed up the context */
+
+ assert(memcmp(&reference, context, MINIMUM_CONTEXT_SIZE) == 0);
+}
+#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