Suppress compilation of malformed dexfiles to prevent compiler segfault.
Generic failures detected at compile time will not be fixed at runtime,
so classes with generic failures are now added to a rejected classes
set and not compiled at all. This prevents the compiler from
segfaulting on certain occasions when registers and indexes are out of
range, etc. There is one remaining segfault in the vm-tests now.
Change-Id: Id67c12fd13f3e993a6a16a8625620daa0ea496cb
diff --git a/src/compiler.cc b/src/compiler.cc
index 9a49cdd..b7583d9 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -60,6 +60,14 @@
ByteArray* CreateJniDlsymLookupStub();
}
+namespace verifier {
+ class DexVerifier {
+ public:
+ static const std::vector<uint8_t>* GetGcMap(Compiler::MethodReference ref);
+ static bool IsClassRejected(Compiler::ClassReference ref);
+ };
+}
+
static double Percentage(size_t x, size_t y) {
return 100.0 * ((double)x) / ((double)(x + y));
}
@@ -920,6 +928,11 @@
if (SkipClass(class_loader, dex_file, class_def)) {
return;
}
+ ClassReference ref(&dex_file, class_def_index);
+ // Skip compiling classes with generic verifier failures since they will still fail at runtime
+ if (verifier::DexVerifier::IsClassRejected(ref)) {
+ return;
+ }
const byte* class_data = dex_file.GetClassData(class_def);
if (class_data == NULL) {
// empty class, probably a marker interface
@@ -1114,13 +1127,6 @@
}
}
-namespace verifier {
- class DexVerifier {
- public:
- static const std::vector<uint8_t>* GetGcMap(Compiler::MethodReference ref);
- };
-}
-
void Compiler::SetGcMapsMethod(const DexFile& dex_file, Method* method) {
if (method == NULL) {
Thread::Current()->ClearException();