*/
#include "Dalvik.h"
#include "JniInternal.h"
+#include "Misc.h"
#include "ScopedPthreadMutexLock.h"
#include "UniquePtr.h"
*/
+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);
if (crc != stackCrc) {
const Method* meth = dvmGetCurrentJNIMethod();
if (dvmComputeExactFrameDepth(self->interpSave.curFrame) == 1) {
- LOGD("JNI: bad stack CRC (0x%08x) -- okay during init", stackCrc);
+ ALOGD("JNI: bad stack CRC (0x%08x) -- okay during init", stackCrc);
} else if (strcmp(meth->name, "nativeLoad") == 0 &&
(strcmp(meth->clazz->descriptor, "Ljava/lang/Runtime;") == 0)) {
- LOGD("JNI: bad stack CRC (0x%08x) -- okay during JNI_OnLoad", stackCrc);
+ ALOGD("JNI: bad stack CRC (0x%08x) -- okay during JNI_OnLoad", stackCrc);
} else {
- LOGW("JNI: bad stack CRC (%08x vs %08x)", crc, stackCrc);
- dvmAbort();
+ ALOGW("JNI: bad stack CRC (%08x vs %08x)", crc, stackCrc);
+ ReportJniError();
}
}
self->stackCrc = (u4) -1; /* make logic errors more noticeable */
// that we use the correct per-thread indirect reference table.
Thread* self = gDvmJni.workAroundAppJniBugs ? dvmThreadSelf() : mSelf;
if (self != mSelf) {
- LOGE("JNI ERROR: env->self != thread-self (%p vs. %p); auto-correcting", mSelf, self);
+ ALOGE("JNI ERROR: env->self != thread-self (%p vs. %p); auto-correcting", mSelf, self);
mSelf = self;
}
}
{
Object* result = self->jniLocalRefTable.get(jobj);
if (UNLIKELY(result == NULL)) {
- LOGE("JNI ERROR (app bug): use of deleted local reference (%p)", jobj);
- dvmAbort();
+ ALOGE("JNI ERROR (app bug): use of deleted local reference (%p)", jobj);
+ ReportJniError();
}
return result;
}
ScopedPthreadMutexLock lock(&gDvm.jniGlobalRefLock);
Object* result = pRefTable->get(jobj);
if (UNLIKELY(result == NULL)) {
- LOGE("JNI ERROR (app bug): use of deleted global reference (%p)", jobj);
- dvmAbort();
+ ALOGE("JNI ERROR (app bug): use of deleted global reference (%p)", jobj);
+ ReportJniError();
}
return result;
}
if (result == kClearedJniWeakGlobal) {
result = NULL;
} else if (UNLIKELY(result == NULL)) {
- LOGE("JNI ERROR (app bug): use of deleted weak global reference (%p)", jobj);
- dvmAbort();
+ ALOGE("JNI ERROR (app bug): use of deleted weak global reference (%p)", jobj);
+ ReportJniError();
}
return result;
}
// Assume an invalid local reference is actually a direct pointer.
return reinterpret_cast<Object*>(jobj);
}
- LOGW("Invalid indirect reference %p in decodeIndirectRef", jobj);
- dvmAbort();
+ ALOGW("Invalid indirect reference %p in decodeIndirectRef", jobj);
+ ReportJniError();
return kInvalidIndirectRefObject;
}
}
static void AddLocalReferenceFailure(IndirectRefTable* pRefTable) {
pRefTable->dump("JNI local");
- LOGE("Failed adding to JNI local ref table (has %zd entries)", pRefTable->capacity());
- dvmDumpThread(dvmThreadSelf(), false);
- dvmAbort(); // spec says call FatalError; this is equivalent
+ ALOGE("Failed adding to JNI local ref table (has %zd entries)", pRefTable->capacity());
+ ReportJniError(); // spec says call FatalError; this is equivalent
}
/*
if (UNLIKELY(jobj == NULL)) {
AddLocalReferenceFailure(pRefTable);
}
+
if (UNLIKELY(gDvmJni.workAroundAppJniBugs)) {
// Hand out direct pointers to support broken old apps.
return reinterpret_cast<jobject>(obj);
* complain about it so the user will notice that things aren't
* going quite the way they expect.
*/
- LOGW("JNI WARNING: DeleteLocalRef(%p) failed to find entry", jobj);
+ ALOGW("JNI WARNING: DeleteLocalRef(%p) failed to find entry", jobj);
}
}
return NULL;
}
- //LOGI("adding obj=%p", obj);
+ //ALOGI("adding obj=%p", obj);
//dvmDumpThread(dvmThreadSelf(), false);
if (false && dvmIsClassObject((Object*)obj)) {
ClassObject* clazz = (ClassObject*) obj;
- LOGI("-------");
- LOGI("Adding global ref on class %s", clazz->descriptor);
+ ALOGI("-------");
+ ALOGI("Adding global ref on class %s", clazz->descriptor);
dvmDumpThread(dvmThreadSelf(), false);
}
if (false && ((Object*)obj)->clazz == gDvm.classJavaLangString) {
StringObject* strObj = (StringObject*) obj;
char* str = dvmCreateCstrFromString(strObj);
if (strcmp(str, "sync-response") == 0) {
- LOGI("-------");
- LOGI("Adding global ref on string '%s'", str);
+ ALOGI("-------");
+ ALOGI("Adding global ref on string '%s'", str);
dvmDumpThread(dvmThreadSelf(), false);
//dvmAbort();
}
if (arrayObj->length == 8192 /*&&
dvmReferenceTableEntries(&gDvm.jniGlobalRefTable) > 400*/)
{
- LOGI("Adding global ref on byte array %p (len=%d)",
+ ALOGI("Adding global ref on byte array %p (len=%d)",
arrayObj, arrayObj->length);
dvmDumpThread(dvmThreadSelf(), false);
}
jobject jobj = (jobject) gDvm.jniGlobalRefTable.add(IRT_FIRST_SEGMENT, obj);
if (jobj == NULL) {
gDvm.jniGlobalRefTable.dump("JNI global");
- LOGE("Failed adding to JNI global ref table (%zd entries)",
+ ALOGE("Failed adding to JNI global ref table (%zd entries)",
gDvm.jniGlobalRefTable.capacity());
- dvmAbort();
+ ReportJniError();
}
LOGVV("GREF add %p (%s.%s)", obj,
int count = gDvm.jniGlobalRefTable.capacity();
// TODO: adjust for "holes"
if (count > gDvm.jniGlobalRefHiMark) {
- LOGD("GREF has increased to %d", count);
+ ALOGD("GREF has increased to %d", count);
gDvm.jniGlobalRefHiMark += kGrefWaterInterval;
gDvm.jniGlobalRefLoMark += kGrefWaterInterval;
/* watch for "excessive" use; not generally appropriate */
if (count >= gDvm.jniGrefLimit) {
if (gDvmJni.warnOnly) {
- LOGW("Excessive JNI global references (%d)", count);
+ ALOGW("Excessive JNI global references (%d)", count);
} else {
gDvm.jniGlobalRefTable.dump("JNI global");
- LOGE("Excessive JNI global references (%d)", count);
- dvmAbort();
+ ALOGE("Excessive JNI global references (%d)", count);
+ ReportJniError();
}
}
}
jobject jobj = (jobject) table->add(IRT_FIRST_SEGMENT, obj);
if (jobj == NULL) {
gDvm.jniWeakGlobalRefTable.dump("JNI weak global");
- LOGE("Failed adding to JNI weak global ref table (%zd entries)", table->capacity());
- dvmAbort();
+ ALOGE("Failed adding to JNI weak global ref table (%zd entries)", table->capacity());
+ ReportJniError();
}
return jobj;
}
ScopedPthreadMutexLock lock(&gDvm.jniWeakGlobalRefLock);
IndirectRefTable *table = &gDvm.jniWeakGlobalRefTable;
if (!table->remove(IRT_FIRST_SEGMENT, jobj)) {
- LOGW("JNI: DeleteWeakGlobalRef(%p) failed to find entry", jobj);
+ ALOGW("JNI: DeleteWeakGlobalRef(%p) failed to find entry", jobj);
}
}
ScopedPthreadMutexLock lock(&gDvm.jniGlobalRefLock);
if (!gDvm.jniGlobalRefTable.remove(IRT_FIRST_SEGMENT, jobj)) {
- LOGW("JNI: DeleteGlobalRef(%p) failed to find entry", jobj);
+ ALOGW("JNI: DeleteGlobalRef(%p) failed to find entry", jobj);
return;
}
int count = gDvm.jniGlobalRefTable.capacity();
// TODO: not quite right, need to subtract holes
if (count < gDvm.jniGlobalRefLoMark) {
- LOGD("GREF has decreased to %d", count);
+ ALOGD("GREF has decreased to %d", count);
gDvm.jniGlobalRefHiMark -= kGrefWaterInterval;
gDvm.jniGlobalRefLoMark -= kGrefWaterInterval;
}
if (!dvmAddToReferenceTable(&gDvm.jniPinRefTable, (Object*)arrayObj)) {
dvmDumpReferenceTable(&gDvm.jniPinRefTable, "JNI pinned array");
- LOGE("Failed adding to JNI pinned array ref table (%d entries)",
+ ALOGE("Failed adding to JNI pinned array ref table (%d entries)",
(int) dvmReferenceTableEntries(&gDvm.jniPinRefTable));
- dvmDumpThread(dvmThreadSelf(), false);
- dvmAbort();
+ ReportJniError();
}
/*
}
if (count > kPinComplainThreshold) {
- LOGW("JNI: pin count on array %p (%s) is now %d",
+ ALOGW("JNI: pin count on array %p (%s) is now %d",
arrayObj, arrayObj->clazz->descriptor, count);
/* keep going */
}
if (!dvmRemoveFromReferenceTable(&gDvm.jniPinRefTable,
gDvm.jniPinRefTable.table, (Object*) arrayObj))
{
- LOGW("JNI: unpinPrimitiveArray(%p) failed to find entry (valid=%d)",
+ ALOGW("JNI: unpinPrimitiveArray(%p) failed to find entry (valid=%d)",
arrayObj, dvmIsHeapAddress((Object*) arrayObj));
return;
}
dvmDumpReferenceTable(&gDvm.jniPinRefTable, "JNI pinned array");
}
+void dvmDumpJniStats(DebugOutputTarget* target) {
+ dvmPrintDebugMessage(target, "JNI: CheckJNI is %s", gDvmJni.useCheckJni ? "on" : "off");
+ if (gDvmJni.forceCopy) {
+ dvmPrintDebugMessage(target, " (with forcecopy)");
+ }
+ dvmPrintDebugMessage(target, "; workarounds are %s", gDvmJni.workAroundAppJniBugs ? "on" : "off");
+
+ dvmLockMutex(&gDvm.jniPinRefLock);
+ dvmPrintDebugMessage(target, "; pins=%d", dvmReferenceTableEntries(&gDvm.jniPinRefTable));
+ dvmUnlockMutex(&gDvm.jniPinRefLock);
+
+ dvmLockMutex(&gDvm.jniGlobalRefLock);
+ dvmPrintDebugMessage(target, "; globals=%d", gDvm.jniGlobalRefTable.capacity());
+ dvmUnlockMutex(&gDvm.jniGlobalRefLock);
+
+ dvmLockMutex(&gDvm.jniWeakGlobalRefLock);
+ size_t weaks = gDvm.jniWeakGlobalRefTable.capacity();
+ if (weaks > 0) {
+ dvmPrintDebugMessage(target, " (plus %d weak)", weaks);
+ }
+ dvmUnlockMutex(&gDvm.jniWeakGlobalRefLock);
+
+ dvmPrintDebugMessage(target, "\n\n");
+}
+
/*
* Verify that a reference passed in from native code is one that the
* code is allowed to have.
Method* method = &methods[i];
if (strcmp(name, method->name) == 0) {
char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
- LOGE("Candidate: %s.%s:%s", method->clazz->descriptor, name, desc);
+ ALOGE("Candidate: %s.%s:%s", method->clazz->descriptor, name, desc);
free(desc);
}
}
}
static void dumpCandidateMethods(ClassObject* clazz, const char* methodName, const char* signature) {
- LOGE("ERROR: couldn't find native method");
- LOGE("Requested: %s.%s:%s", clazz->descriptor, methodName, signature);
+ ALOGE("ERROR: couldn't find native method");
+ ALOGE("Requested: %s.%s:%s", clazz->descriptor, methodName, signature);
dumpMethods(clazz->virtualMethods, clazz->virtualMethodCount, methodName);
dumpMethods(clazz->directMethods, clazz->directMethodCount, methodName);
}
}
if (!dvmIsNativeMethod(method)) {
- LOGW("Unable to register: not native: %s.%s:%s", clazz->descriptor, methodName, signature);
+ ALOGW("Unable to register: not native: %s.%s:%s", clazz->descriptor, methodName, signature);
return false;
}
if (dvmIsSynchronizedMethod(method)) {
// Synchronization is usually provided by the JNI bridge,
// but we won't have one.
- LOGE("fast JNI method %s.%s:%s cannot be synchronized",
+ ALOGE("fast JNI method %s.%s:%s cannot be synchronized",
clazz->descriptor, methodName, signature);
return false;
}
// There's no real reason for this constraint, but since we won't
// be supplying a JNIEnv* or a jobject 'this', you're effectively
// static anyway, so it seems clearer to say so.
- LOGE("fast JNI method %s.%s:%s cannot be non-static",
+ ALOGE("fast JNI method %s.%s:%s cannot be non-static",
clazz->descriptor, methodName, signature);
return false;
}
std::string className(dvmHumanReadableDescriptor(method->clazz->descriptor));
char* signature = dexProtoCopyMethodDescriptor(&method->prototype);
- LOGI("-> %s %s%s %s(%s)", className.c_str(), method->name, signature, thisString, argsString);
+ ALOGI("-> %s %s%s %s(%s)", className.c_str(), method->name, signature, thisString, argsString);
free(signature);
}
if (dvmCheckException(self)) {
Object* exception = dvmGetException(self);
std::string exceptionClassName(dvmHumanReadableDescriptor(exception->clazz->descriptor));
- LOGI("<- %s %s%s threw %s", className.c_str(),
+ ALOGI("<- %s %s%s threw %s", className.c_str(),
method->name, signature, exceptionClassName.c_str());
} else {
char returnValueString[128] = { 0 };
char returnType = method->shorty[0];
appendValue(returnType, returnValue, returnValueString, sizeof(returnValueString), false);
- LOGI("<- %s %s%s returned %s", className.c_str(),
+ ALOGI("<- %s %s%s returned %s", className.c_str(),
method->name, signature, returnValueString);
}
free(signature);
assert(refTable->maxEntries == 0);
if (!dvmInitReferenceTable(refTable, kInitialSize, INT_MAX)) {
- LOGE("Unable to initialize monitor tracking table");
- dvmAbort();
+ ALOGE("Unable to initialize monitor tracking table");
+ ReportJniError();
}
}
if (!dvmAddToReferenceTable(refTable, obj)) {
/* ran out of memory? could throw exception instead */
- LOGE("Unable to add entry to monitor tracking table");
- dvmAbort();
+ ALOGE("Unable to add entry to monitor tracking table");
+ ReportJniError();
} else {
LOGVV("--- added monitor %p", obj);
}
ReferenceTable* pRefTable = &self->jniMonitorRefTable;
if (!dvmRemoveFromReferenceTable(pRefTable, pRefTable->table, obj)) {
- LOGE("JNI monitor %p not found in tracking list", obj);
+ ALOGE("JNI monitor %p not found in tracking list", obj);
/* keep going? */
} else {
LOGVV("--- removed monitor %p", obj);
Object** ptr = pRefTable->nextEntry;
while (--ptr >= top) {
if (!dvmUnlockObject(self, *ptr)) {
- LOGW("Unable to unlock monitor %p at thread detach", *ptr);
+ ALOGW("Unable to unlock monitor %p at thread detach", *ptr);
} else {
LOGVV("--- detach-releasing monitor %p", *ptr);
}
u4 accessFlags = method->accessFlags;
bool isSynchronized = (accessFlags & ACC_SYNCHRONIZED) != 0;
- //LOGI("JNI calling %p (%s.%s:%s):", method->insns,
+ //ALOGI("JNI calling %p (%s.%s:%s):", method->insns,
// method->clazz->descriptor, method->name, method->shorty);
/*
while (*shorty != '\0') {
switch (*shorty++) {
case 'L':
- //LOGI(" local %d: 0x%08x", idx, modArgs[idx]);
+ //ALOGI(" local %d: 0x%08x", idx, modArgs[idx]);
if (modArgs[idx] != 0) {
modArgs[idx] = (u4) addLocalReference(self, (Object*) modArgs[idx]);
}
UNUSED_PARAMETER(bufLen);
ScopedJniThreadState ts(env);
- LOGW("JNI DefineClass is not supported");
+ ALOGW("JNI DefineClass is not supported");
return NULL;
}
* there was no exception, even though it's pretty much raining
* exceptions in here.
*/
- LOGW("JNI WARNING: addLocal/exception combo");
+ ALOGW("JNI WARNING: addLocal/exception combo");
}
return localException;
}
if (exception != NULL) {
dvmPrintExceptionStackTrace();
} else {
- LOGI("Odd: ExceptionDescribe called, but no exception pending");
+ ALOGI("Odd: ExceptionDescribe called, but no exception pending");
}
}
*/
static void FatalError(JNIEnv* env, const char* msg) {
//dvmChangeStatus(NULL, THREAD_RUNNING);
- LOGE("JNI posting fatal error: %s", msg);
- dvmAbort();
+ ALOGE("JNI posting fatal error: %s", msg);
+ ReportJniError();
}
/*
ScopedJniThreadState ts(env);
Object* result = dvmDecodeIndirectRef(ts.self(), jresult);
if (!dvmPopLocalFrame(ts.self())) {
- LOGW("JNI WARNING: too many PopLocalFrame calls");
+ ALOGW("JNI WARNING: too many PopLocalFrame calls");
dvmClearException(ts.self());
dvmThrowRuntimeException("too many PopLocalFrame calls");
}
meth = dvmFindDirectMethodByDescriptor(clazz, name, sig);
}
if (meth != NULL && dvmIsStaticMethod(meth)) {
- IF_LOGD() {
+ IF_ALOGD() {
char* desc = dexProtoCopyMethodDescriptor(&meth->prototype);
- LOGD("GetMethodID: not returning static method %s.%s %s",
+ ALOGD("GetMethodID: not returning static method %s.%s %s",
clazz->descriptor, meth->name, desc);
free(desc);
}
/* make sure it's static, not virtual+private */
if (meth != NULL && !dvmIsStaticMethod(meth)) {
- IF_LOGD() {
+ IF_ALOGD() {
char* desc = dexProtoCopyMethodDescriptor(&meth->prototype);
- LOGD("GetStaticMethodID: not returning nonstatic method %s.%s %s",
+ ALOGD("GetStaticMethodID: not returning nonstatic method %s.%s %s",
clazz->descriptor, meth->name, desc);
free(desc);
}
return;
}
+ Object* obj = dvmDecodeIndirectRef(ts.self(), jobj);
+
+ if (obj != NULL && !dvmCanPutArrayElement(obj->clazz, arrayObj->clazz)) {
+ ALOGV("Can't put a '%s'(%p) into array type='%s'(%p)",
+ obj->clazz->descriptor, obj,
+ arrayObj->clazz->descriptor, arrayObj);
+ dvmThrowArrayStoreExceptionIncompatibleElement(obj->clazz, arrayObj->clazz);
+ return;
+ }
+
//ALOGV("JNI: set element %d in array %p to %p", index, array, value);
- Object* obj = dvmDecodeIndirectRef(ts.self(), jobj);
dvmSetObjectArrayElement(arrayObj, index, obj);
}
ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz);
if (gDvm.verboseJni) {
- LOGI("[Registering JNI native methods for class %s]",
+ ALOGI("[Registering JNI native methods for class %s]",
clazz->descriptor);
}
ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz);
if (gDvm.verboseJni) {
- LOGI("[Unregistering JNI native methods for class %s]",
+ ALOGI("[Unregistering JNI native methods for class %s]",
clazz->descriptor);
}
dvmUnregisterJNINativeMethods(clazz);
/*
* 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);
- /* create an instance of java.nio.ReadWriteDirectByteBuffer */
- ClassObject* bufferClazz = gDvm.classJavaNioReadWriteDirectByteBuffer;
+ 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.DirectByteBuffer */
+ ClassObject* bufferClazz = gDvm.classJavaNioDirectByteBuffer;
if (!dvmIsClassInitialized(bufferClazz) && !dvmInitClass(bufferClazz)) {
return NULL;
}
/* call the constructor */
jobject result = addLocalReference(ts.self(), newObj);
JValue unused;
- dvmCallMethod(ts.self(), gDvm.methJavaNioReadWriteDirectByteBuffer_init,
- newObj, &unused, (jint) address, (jint) capacity);
+ dvmCallMethod(ts.self(), gDvm.methJavaNioDirectByteBuffer_init,
+ newObj, &unused, (jlong) address, (jint) capacity);
if (dvmGetException(ts.self()) != NULL) {
deleteLocalReference(ts.self(), result);
return NULL;
// All Buffer objects have an effectiveDirectAddress field.
Object* bufObj = dvmDecodeIndirectRef(ts.self(), jbuf);
- return (void*) dvmGetFieldInt(bufObj, gDvm.offJavaNioBuffer_effectiveDirectAddress);
+ return (void*) dvmGetFieldLong(bufObj, gDvm.offJavaNioBuffer_effectiveDirectAddress);
}
/*
argsCopy.name = NULL;
argsCopy.group = (jobject) dvmGetMainThreadGroup();
} else {
- assert(args->version >= JNI_VERSION_1_2);
-
argsCopy.version = args->version;
argsCopy.name = args->name;
if (args->group != NULL) {
}
if (gDvm.verboseShutdown) {
- LOGD("DestroyJavaVM waiting for non-daemon threads to exit");
+ ALOGD("DestroyJavaVM waiting for non-daemon threads to exit");
}
/*
// (this may not return -- figure out how this should work)
if (gDvm.verboseShutdown) {
- LOGD("DestroyJavaVM shutting VM down");
+ ALOGD("DestroyJavaVM shutting VM down");
}
dvmShutdown();
JavaVMExt* vm = (JavaVMExt*) gDvmJni.jniVm;
//if (self != NULL)
- // LOGI("Ent CreateJNIEnv: threadid=%d %p", self->threadId, self);
+ // ALOGI("Ent CreateJNIEnv: threadid=%d %p", self->threadId, self);
assert(vm != NULL);
vm->envList = newEnv;
//if (self != NULL)
- // LOGI("Xit CreateJNIEnv: threadid=%d %p", self->threadId, self);
+ // ALOGI("Xit CreateJNIEnv: threadid=%d %p", self->threadId, self);
return (JNIEnv*) newEnv;
}
return;
}
- //LOGI("Ent DestroyJNIEnv: threadid=%d %p", self->threadId, self);
+ //ALOGI("Ent DestroyJNIEnv: threadid=%d %p", self->threadId, self);
JNIEnvExt* extEnv = (JNIEnvExt*) env;
JavaVMExt* vm = (JavaVMExt*) gDvmJni.jniVm;
}
free(env);
- //LOGI("Xit DestroyJNIEnv: threadid=%d %p", self->threadId, self);
+ //ALOGI("Xit DestroyJNIEnv: threadid=%d %p", self->threadId, self);
}
/*
void dvmLateEnableCheckedJni() {
JNIEnvExt* extEnv = dvmGetJNIEnvForThread();
if (extEnv == NULL) {
- LOGE("dvmLateEnableCheckedJni: thread has no JNIEnv");
+ ALOGE("dvmLateEnableCheckedJni: thread has no JNIEnv");
return;
}
JavaVMExt* extVm = (JavaVMExt*) gDvmJni.jniVm;
assert(extVm != NULL);
if (!gDvmJni.useCheckJni) {
- LOGD("Late-enabling CheckJNI");
+ ALOGD("Late-enabling CheckJNI");
dvmUseCheckedJniVm(extVm);
dvmUseCheckedJniEnv(extEnv);
} else {
- LOGD("Not late-enabling CheckJNI (already on)");
+ ALOGD("Not late-enabling CheckJNI (already on)");
}
}
/*
* Set up structures for JNIEnv and VM.
*/
- JavaVMExt* pVM = (JavaVMExt*) malloc(sizeof(JavaVMExt));
- memset(pVM, 0, sizeof(JavaVMExt));
+ JavaVMExt* pVM = (JavaVMExt*) calloc(1, sizeof(JavaVMExt));
pVM->funcTable = &gInvokeInterface;
pVM->envList = NULL;
dvmInitMutex(&pVM->envListLock);
if (!status.empty()) {
free(pEnv);
free(pVM);
- LOGW("CreateJavaVM failed: %s", status.c_str());
+ ALOGW("CreateJavaVM failed: %s", status.c_str());
return JNI_ERR;
}