Increase size of LinearAlloc region, and warn about massive Mirandizing.
diff --git a/vm/LinearAlloc.c b/vm/LinearAlloc.c
index 77802ee..73d9235 100644
--- a/vm/LinearAlloc.c
+++ b/vm/LinearAlloc.c
@@ -68,7 +68,7 @@
#define BLOCK_ALIGN 8
/* default length of memory segment (worst case is probably "dexopt") */
-#define DEFAULT_MAX_LENGTH (4*1024*1024)
+#define DEFAULT_MAX_LENGTH (5*1024*1024)
/* leave enough space for a length word */
#define HEADER_EXTRA 4
@@ -313,7 +313,8 @@
* works if the users of these functions actually free everything
* they allocate.
*/
- LOGE("LinearAlloc exceeded capacity, last=%d\n", (int) size);
+ LOGE("LinearAlloc exceeded capacity (%d), last=%d\n",
+ pHdr->mapLength, (int) size);
dvmAbort();
}
diff --git a/vm/oo/Class.c b/vm/oo/Class.c
index 0832d99..066d0db 100644
--- a/vm/oo/Class.c
+++ b/vm/oo/Class.c
@@ -3163,6 +3163,7 @@
}
if (mirandaCount != 0) {
+ static const int kManyMirandas = 150; /* arbitrary */
Method* newVirtualMethods;
Method* meth;
int oldMethodCount, oldVtableCount;
@@ -3171,6 +3172,17 @@
LOGVV("MIRANDA %d: %s.%s\n", i,
mirandaList[i]->clazz->descriptor, mirandaList[i]->name);
}
+ if (mirandaCount > kManyMirandas) {
+ /*
+ * Some obfuscators like to create an interface with a huge
+ * pile of methods, declare classes as implementing it, and then
+ * only define a couple of methods. This leads to a rather
+ * massive collection of Miranda methods and a lot of wasted
+ * space, sometimes enough to blow out the LinearAlloc cap.
+ */
+ LOGD("Note: class %s has %d unimplemented (abstract) methods\n",
+ clazz->descriptor, mirandaCount);
+ }
/*
* We found methods in one or more interfaces for which we do not
@@ -3237,6 +3249,9 @@
* Now we need to create the fake methods. We clone the abstract
* method definition from the interface and then replace a few
* things.
+ *
+ * The Method will be an "abstract native", with nativeFunc set to
+ * dvmAbstractMethodStub().
*/
meth = clazz->virtualMethods + oldMethodCount;
for (i = 0; i < mirandaCount; i++, meth++) {