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/c/OP_NEW_INSTANCE.c b/vm/mterp/c/OP_NEW_INSTANCE.c
index ce04286..f7d4c64 100644
--- a/vm/mterp/c/OP_NEW_INSTANCE.c
+++ b/vm/mterp/c/OP_NEW_INSTANCE.c
@@ -19,6 +19,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)) {
diff --git a/vm/mterp/c/gotoTargets.c b/vm/mterp/c/gotoTargets.c
index 534d0b0..9d7212f 100644
--- a/vm/mterp/c/gotoTargets.c
+++ b/vm/mterp/c/gotoTargets.c
@@ -373,6 +373,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
diff --git a/vm/mterp/c/opcommon.c b/vm/mterp/c/opcommon.c
index 28d03c9..43ee5bc 100644
--- a/vm/mterp/c/opcommon.c
+++ b/vm/mterp/c/opcommon.c
@@ -602,6 +602,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*/) \
{ \
@@ -615,6 +620,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", \
@@ -636,6 +644,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", \
@@ -643,4 +654,3 @@
UPDATE_FIELD_PUT(&sfield->field); \
} \
FINISH(2);
-
diff --git a/vm/mterp/out/InterpC-allstubs.c b/vm/mterp/out/InterpC-allstubs.c
index 6c90b34..dcb1a34 100644
--- a/vm/mterp/out/InterpC-allstubs.c
+++ b/vm/mterp/out/InterpC-allstubs.c
@@ -1149,6 +1149,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*/) \
{ \
@@ -1162,6 +1167,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", \
@@ -1183,6 +1191,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", \
@@ -1191,7 +1202,6 @@
} \
FINISH(2);
-
/* File: c/OP_NOP.c */
HANDLE_OPCODE(OP_NOP)
FINISH(1);
@@ -1692,6 +1702,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)) {
@@ -3482,6 +3502,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
diff --git a/vm/mterp/out/InterpC-armv4t.c b/vm/mterp/out/InterpC-armv4t.c
index 6c7c2e7..728d1ad 100644
--- a/vm/mterp/out/InterpC-armv4t.c
+++ b/vm/mterp/out/InterpC-armv4t.c
@@ -1149,6 +1149,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*/) \
{ \
@@ -1162,6 +1167,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", \
@@ -1183,6 +1191,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", \
@@ -1191,7 +1202,6 @@
} \
FINISH(2);
-
/* File: cstubs/enddefs.c */
/* undefine "magic" name remapping */
diff --git a/vm/mterp/out/InterpC-armv5te-vfp.c b/vm/mterp/out/InterpC-armv5te-vfp.c
index 2d2de9a..4251b1c 100644
--- a/vm/mterp/out/InterpC-armv5te-vfp.c
+++ b/vm/mterp/out/InterpC-armv5te-vfp.c
@@ -1149,6 +1149,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*/) \
{ \
@@ -1162,6 +1167,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", \
@@ -1183,6 +1191,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", \
@@ -1191,7 +1202,6 @@
} \
FINISH(2);
-
/* File: cstubs/enddefs.c */
/* undefine "magic" name remapping */
diff --git a/vm/mterp/out/InterpC-armv5te.c b/vm/mterp/out/InterpC-armv5te.c
index b2a16aa..1ed734e 100644
--- a/vm/mterp/out/InterpC-armv5te.c
+++ b/vm/mterp/out/InterpC-armv5te.c
@@ -1149,6 +1149,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*/) \
{ \
@@ -1162,6 +1167,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", \
@@ -1183,6 +1191,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", \
@@ -1191,7 +1202,6 @@
} \
FINISH(2);
-
/* File: cstubs/enddefs.c */
/* undefine "magic" name remapping */
diff --git a/vm/mterp/out/InterpC-armv7-a-neon.c b/vm/mterp/out/InterpC-armv7-a-neon.c
index 0930f28..a5d71c3 100644
--- a/vm/mterp/out/InterpC-armv7-a-neon.c
+++ b/vm/mterp/out/InterpC-armv7-a-neon.c
@@ -1149,6 +1149,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*/) \
{ \
@@ -1162,6 +1167,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", \
@@ -1183,6 +1191,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", \
@@ -1191,7 +1202,6 @@
} \
FINISH(2);
-
/* File: cstubs/enddefs.c */
/* undefine "magic" name remapping */
diff --git a/vm/mterp/out/InterpC-armv7-a.c b/vm/mterp/out/InterpC-armv7-a.c
index da058b2..da6bcdd 100644
--- a/vm/mterp/out/InterpC-armv7-a.c
+++ b/vm/mterp/out/InterpC-armv7-a.c
@@ -1149,6 +1149,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*/) \
{ \
@@ -1162,6 +1167,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", \
@@ -1183,6 +1191,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", \
@@ -1191,7 +1202,6 @@
} \
FINISH(2);
-
/* File: cstubs/enddefs.c */
/* undefine "magic" name remapping */
diff --git a/vm/mterp/out/InterpC-portdbg.c b/vm/mterp/out/InterpC-portdbg.c
index bcd4c46..46e3e19 100644
--- a/vm/mterp/out/InterpC-portdbg.c
+++ b/vm/mterp/out/InterpC-portdbg.c
@@ -1135,6 +1135,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*/) \
{ \
@@ -1148,6 +1153,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", \
@@ -1169,6 +1177,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", \
@@ -1177,7 +1188,6 @@
} \
FINISH(2);
-
/* File: portable/debug.c */
/* code in here is only included in portable-debug interpreter */
@@ -2056,6 +2066,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)) {
@@ -3763,6 +3783,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
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
diff --git a/vm/mterp/out/InterpC-x86-atom.c b/vm/mterp/out/InterpC-x86-atom.c
index a922509..8ffd526 100644
--- a/vm/mterp/out/InterpC-x86-atom.c
+++ b/vm/mterp/out/InterpC-x86-atom.c
@@ -1149,6 +1149,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*/) \
{ \
@@ -1162,6 +1167,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", \
@@ -1183,6 +1191,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", \
@@ -1191,7 +1202,6 @@
} \
FINISH(2);
-
/* File: c/OP_IGET_WIDE_VOLATILE.c */
HANDLE_IGET_X(OP_IGET_WIDE_VOLATILE, "-wide-volatile", LongVolatile, _WIDE)
OP_END
@@ -1660,6 +1670,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
diff --git a/vm/mterp/out/InterpC-x86.c b/vm/mterp/out/InterpC-x86.c
index 209b450..6860581 100644
--- a/vm/mterp/out/InterpC-x86.c
+++ b/vm/mterp/out/InterpC-x86.c
@@ -1149,6 +1149,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*/) \
{ \
@@ -1162,6 +1167,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", \
@@ -1183,6 +1191,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", \
@@ -1191,7 +1202,6 @@
} \
FINISH(2);
-
/* File: c/OP_IGET_WIDE_VOLATILE.c */
HANDLE_IGET_X(OP_IGET_WIDE_VOLATILE, "-wide-volatile", LongVolatile, _WIDE)
OP_END
@@ -1629,6 +1639,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