Abandon a JIT trace if it contains static fields that are not fully initialized
Also turn some asserts into aborts to capture future contract changes between
the VM and the JIT.
Bug: 2655384
Change-Id: I8bb0226c7ae26fedf6b4ad25a1cd1aa7013b60d4
diff --git a/vm/mterp/out/InterpC-portstd.c b/vm/mterp/out/InterpC-portstd.c
index b6e30c8..1937bd1 100644
--- a/vm/mterp/out/InterpC-portstd.c
+++ b/vm/mterp/out/InterpC-portstd.c
@@ -1129,6 +1129,11 @@
} \
FINISH(2);
+/*
+ * The JIT needs dvmDexGetResolvedField() to return non-null.
+ * Since we use the portable interpreter to build the trace, the extra
+ * checks in HANDLE_SGET_X and HANDLE_SPUT_X are not needed for mterp.
+ */
#define HANDLE_SGET_X(_opcode, _opname, _ftype, _regsize) \
HANDLE_OPCODE(_opcode /*vAA, field@BBBB*/) \
{ \
@@ -1142,6 +1147,9 @@
sfield = dvmResolveStaticField(curMethod->clazz, ref); \
if (sfield == NULL) \
GOTO_exceptionThrown(); \
+ if (dvmDexGetResolvedField(methodClassDex, ref) == NULL) { \
+ ABORT_JIT_TSELECT(); \
+ } \
} \
SET_REGISTER##_regsize(vdst, dvmGetStaticField##_ftype(sfield)); \
ILOGV("+ SGET '%s'=0x%08llx", \
@@ -1163,6 +1171,9 @@
sfield = dvmResolveStaticField(curMethod->clazz, ref); \
if (sfield == NULL) \
GOTO_exceptionThrown(); \
+ if (dvmDexGetResolvedField(methodClassDex, ref) == NULL) { \
+ ABORT_JIT_TSELECT(); \
+ } \
} \
dvmSetStaticField##_ftype(sfield, GET_REGISTER##_regsize(vdst)); \
ILOGV("+ SPUT '%s'=0x%08llx", \
@@ -1171,7 +1182,6 @@
} \
FINISH(2);
-
/* File: portable/entry.c */
/*
* Main interpreter loop.
@@ -1795,6 +1805,16 @@
GOTO_exceptionThrown();
/*
+ * The JIT needs dvmDexGetResolvedClass() to return non-null.
+ * Since we use the portable interpreter to build the trace, this extra
+ * check is not needed for mterp.
+ */
+ if (!dvmDexGetResolvedClass(methodClassDex, ref)) {
+ /* Class initialization is still ongoing - abandon the trace */
+ ABORT_JIT_TSELECT();
+ }
+
+ /*
* Verifier now tests for interface/abstract class.
*/
//if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
@@ -3502,6 +3522,16 @@
ILOGV("+ unknown method\n");
GOTO_exceptionThrown();
}
+
+ /*
+ * The JIT needs dvmDexGetResolvedMethod() to return non-null.
+ * Since we use the portable interpreter to build the trace, this extra
+ * check is not needed for mterp.
+ */
+ if (dvmDexGetResolvedMethod(methodClassDex, ref) == NULL) {
+ /* Class initialization is still ongoing */
+ ABORT_JIT_TSELECT();
+ }
}
GOTO_invokeMethod(methodCallRange, methodToCall, vsrc1, vdst);
GOTO_TARGET_END