am 5155b31c: Merge "Change NewDirectByteBuffer to allow NULL if capacity == 0."
* commit '5155b31cd96474459cff380621ebb9a77b2b7cbc':
Change NewDirectByteBuffer to allow NULL if capacity == 0.
diff --git a/vm/CheckJni.cpp b/vm/CheckJni.cpp
index ccb5836..8886ea2 100644
--- a/vm/CheckJni.cpp
+++ b/vm/CheckJni.cpp
@@ -1985,12 +1985,6 @@
static jobject Check_NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
CHECK_JNI_ENTRY(kFlag_Default, "EpJ", env, address, capacity);
- if (address == NULL || capacity < 0) {
- ALOGW("JNI WARNING: invalid values for address (%p) or capacity (%ld)",
- address, (long) capacity);
- abortMaybe();
- return NULL;
- }
return CHECK_JNI_EXIT("L", baseEnv(env)->NewDirectByteBuffer(env, address, capacity));
}
diff --git a/vm/Jni.cpp b/vm/Jni.cpp
index 6decaed..29badb7 100644
--- a/vm/Jni.cpp
+++ b/vm/Jni.cpp
@@ -134,6 +134,11 @@
*/
+static void ReportJniError() {
+ dvmDumpThread(dvmThreadSelf(), false);
+ dvmAbort();
+}
+
#ifdef WITH_JNI_STACK_CHECK
# define COMPUTE_STACK_SUM(_self) computeStackSum(_self);
# define CHECK_STACK_SUM(_self) checkStackSum(_self);
@@ -177,7 +182,7 @@
ALOGD("JNI: bad stack CRC (0x%08x) -- okay during JNI_OnLoad", stackCrc);
} else {
ALOGW("JNI: bad stack CRC (%08x vs %08x)", crc, stackCrc);
- dvmAbort();
+ ReportJniError();
}
}
self->stackCrc = (u4) -1; /* make logic errors more noticeable */
@@ -318,7 +323,7 @@
Object* result = self->jniLocalRefTable.get(jobj);
if (UNLIKELY(result == NULL)) {
ALOGE("JNI ERROR (app bug): use of deleted local reference (%p)", jobj);
- dvmAbort();
+ ReportJniError();
}
return result;
}
@@ -330,7 +335,7 @@
Object* result = pRefTable->get(jobj);
if (UNLIKELY(result == NULL)) {
ALOGE("JNI ERROR (app bug): use of deleted global reference (%p)", jobj);
- dvmAbort();
+ ReportJniError();
}
return result;
}
@@ -344,7 +349,7 @@
result = NULL;
} else if (UNLIKELY(result == NULL)) {
ALOGE("JNI ERROR (app bug): use of deleted weak global reference (%p)", jobj);
- dvmAbort();
+ ReportJniError();
}
return result;
}
@@ -355,7 +360,7 @@
return reinterpret_cast<Object*>(jobj);
}
ALOGW("Invalid indirect reference %p in decodeIndirectRef", jobj);
- dvmAbort();
+ ReportJniError();
return kInvalidIndirectRefObject;
}
}
@@ -363,8 +368,7 @@
static void AddLocalReferenceFailure(IndirectRefTable* pRefTable) {
pRefTable->dump("JNI local");
ALOGE("Failed adding to JNI local ref table (has %zd entries)", pRefTable->capacity());
- dvmDumpThread(dvmThreadSelf(), false);
- dvmAbort(); // spec says call FatalError; this is equivalent
+ ReportJniError(); // spec says call FatalError; this is equivalent
}
/*
@@ -388,6 +392,7 @@
if (UNLIKELY(jobj == NULL)) {
AddLocalReferenceFailure(pRefTable);
}
+
if (UNLIKELY(gDvmJni.workAroundAppJniBugs)) {
// Hand out direct pointers to support broken old apps.
return reinterpret_cast<jobject>(obj);
@@ -486,7 +491,7 @@
gDvm.jniGlobalRefTable.dump("JNI global");
ALOGE("Failed adding to JNI global ref table (%zd entries)",
gDvm.jniGlobalRefTable.capacity());
- dvmAbort();
+ ReportJniError();
}
LOGVV("GREF add %p (%s.%s)", obj,
@@ -509,7 +514,7 @@
} else {
gDvm.jniGlobalRefTable.dump("JNI global");
ALOGE("Excessive JNI global references (%d)", count);
- dvmAbort();
+ ReportJniError();
}
}
}
@@ -528,7 +533,7 @@
if (jobj == NULL) {
gDvm.jniWeakGlobalRefTable.dump("JNI weak global");
ALOGE("Failed adding to JNI weak global ref table (%zd entries)", table->capacity());
- dvmAbort();
+ ReportJniError();
}
return jobj;
}
@@ -591,8 +596,7 @@
dvmDumpReferenceTable(&gDvm.jniPinRefTable, "JNI pinned array");
ALOGE("Failed adding to JNI pinned array ref table (%d entries)",
(int) dvmReferenceTableEntries(&gDvm.jniPinRefTable));
- dvmDumpThread(dvmThreadSelf(), false);
- dvmAbort();
+ ReportJniError();
}
/*
@@ -958,14 +962,14 @@
if (!dvmInitReferenceTable(refTable, kInitialSize, INT_MAX)) {
ALOGE("Unable to initialize monitor tracking table");
- dvmAbort();
+ ReportJniError();
}
}
if (!dvmAddToReferenceTable(refTable, obj)) {
/* ran out of memory? could throw exception instead */
ALOGE("Unable to add entry to monitor tracking table");
- dvmAbort();
+ ReportJniError();
} else {
LOGVV("--- added monitor %p", obj);
}
@@ -1402,7 +1406,7 @@
static void FatalError(JNIEnv* env, const char* msg) {
//dvmChangeStatus(NULL, THREAD_RUNNING);
ALOGE("JNI posting fatal error: %s", msg);
- dvmAbort();
+ ReportJniError();
}
/*
@@ -2683,13 +2687,19 @@
/*
* Allocate and return a new java.nio.ByteBuffer for this block of memory.
- *
- * "address" may not be NULL, and "capacity" must be > 0. (These are only
- * verified when CheckJNI is enabled.)
*/
static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
ScopedJniThreadState ts(env);
+ if (capacity < 0) {
+ ALOGE("JNI ERROR (app bug): negative buffer capacity: %lld", capacity);
+ ReportJniError();
+ }
+ if (address == NULL && capacity != 0) {
+ ALOGE("JNI ERROR (app bug): non-zero capacity for NULL pointer: %lld", capacity);
+ ReportJniError();
+ }
+
/* create an instance of java.nio.ReadWriteDirectByteBuffer */
ClassObject* bufferClazz = gDvm.classJavaNioReadWriteDirectByteBuffer;
if (!dvmIsClassInitialized(bufferClazz) && !dvmInitClass(bufferClazz)) {