diff options
-rw-r--r-- | vm/CheckJni.cpp | 75 | ||||
-rw-r--r-- | vm/Jni.cpp | 385 | ||||
-rw-r--r-- | vm/JniInternal.h | 9 | ||||
-rw-r--r-- | vm/interp/Stack.cpp | 6 |
4 files changed, 204 insertions, 271 deletions
diff --git a/vm/CheckJni.cpp b/vm/CheckJni.cpp index 237b88a2d..021ae42a8 100644 --- a/vm/CheckJni.cpp +++ b/vm/CheckJni.cpp @@ -162,20 +162,20 @@ static inline const JNIInvokeInterface* baseVm(JavaVM* vm) { return ((JavaVMExt*) vm)->baseFuncTable; } -class ScopedJniThreadState { +class ScopedCheckJniThreadState { public: - explicit ScopedJniThreadState(JNIEnv* env) { + explicit ScopedCheckJniThreadState(JNIEnv* env) { dvmChangeStatus(NULL, THREAD_RUNNING); } - ~ScopedJniThreadState() { + ~ScopedCheckJniThreadState() { dvmChangeStatus(NULL, THREAD_NATIVE); } private: // Disallow copy and assignment. - ScopedJniThreadState(const ScopedJniThreadState&); - void operator=(const ScopedJniThreadState&); + ScopedCheckJniThreadState(const ScopedCheckJniThreadState&); + void operator=(const ScopedCheckJniThreadState&); }; /* @@ -290,8 +290,8 @@ public: bool printWarn = false; Field* field = (Field*) fieldID; if ((field->signature[0] == 'L' || field->signature[0] == '[') && jobj != NULL) { - ScopedJniThreadState ts(mEnv); - Object* obj = dvmDecodeIndirectRef(mEnv, jobj); + ScopedCheckJniThreadState ts(mEnv); + Object* obj = dvmDecodeIndirectRef(self(), jobj); /* * If jobj is a weak global ref whose referent has been cleared, * obj will be NULL. Otherwise, obj should always be non-NULL @@ -339,9 +339,9 @@ public: * Assumes "jobj" has already been validated. */ void checkInstanceFieldID(jobject jobj, jfieldID fieldID) { - ScopedJniThreadState ts(mEnv); + ScopedCheckJniThreadState ts(mEnv); - Object* obj = dvmDecodeIndirectRef(mEnv, jobj); + Object* obj = dvmDecodeIndirectRef(self(), jobj); if (!dvmIsHeapAddress(obj)) { LOGW("JNI ERROR: field operation on invalid reference (%p)", jobj); dvmAbort(); @@ -412,8 +412,8 @@ public: * Assumes "jclazz" has already been validated. */ void checkStaticFieldID(jclass jclazz, jfieldID fieldID) { - ScopedJniThreadState ts(mEnv); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(mEnv, jclazz); + ScopedCheckJniThreadState ts(mEnv); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(self(), jclazz); StaticField* base = &clazz->sfields[0]; int fieldCount = clazz->sfieldCount; if ((StaticField*) fieldID < base || (StaticField*) fieldID >= base + fieldCount) { @@ -435,9 +435,9 @@ public: * Instances of "jclazz" must be instances of the method's declaring class. */ void checkStaticMethod(jclass jclazz, jmethodID methodID) { - ScopedJniThreadState ts(mEnv); + ScopedCheckJniThreadState ts(mEnv); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(mEnv, jclazz); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(self(), jclazz); const Method* method = (const Method*) methodID; if (!dvmInstanceof(clazz, method->clazz)) { @@ -456,9 +456,9 @@ public: * will be handled automatically by the instanceof check.) */ void checkVirtualMethod(jobject jobj, jmethodID methodID) { - ScopedJniThreadState ts(mEnv); + ScopedCheckJniThreadState ts(mEnv); - Object* obj = dvmDecodeIndirectRef(mEnv, jobj); + Object* obj = dvmDecodeIndirectRef(self(), jobj); const Method* method = (const Method*) methodID; if (!dvmInstanceof(obj->clazz, method->clazz)) { @@ -579,7 +579,7 @@ public: msg += (b ? "JNI_TRUE" : "JNI_FALSE"); } else if (ch == 'c') { // jclass jclass jc = va_arg(ap, jclass); - Object* c = dvmDecodeIndirectRef(mEnv, jc); + Object* c = dvmDecodeIndirectRef(self(), jc); if (c == NULL) { msg += "NULL"; } else if (c == kInvalidIndirectRefObject || !dvmIsHeapAddress(c)) { @@ -702,6 +702,11 @@ public: } } + // Only safe after checkThread returns. + Thread* self() { + return ((JNIEnvExt*) mEnv)->self; + } + private: JNIEnv* mEnv; const char* mFunctionName; @@ -735,10 +740,10 @@ private: return; } - ScopedJniThreadState ts(mEnv); + ScopedCheckJniThreadState ts(mEnv); bool printWarn = false; - Object* obj = dvmDecodeIndirectRef(mEnv, jarr); + Object* obj = dvmDecodeIndirectRef(self(), jarr); if (!dvmIsHeapAddress(obj)) { LOGW("JNI WARNING: jarray is an invalid %s reference (%p)", indirectRefKindName(jarr), jarr); @@ -777,14 +782,14 @@ private: return; } - ScopedJniThreadState ts(mEnv); + ScopedCheckJniThreadState ts(mEnv); bool printWarn = false; - if (dvmGetJNIRefType(mEnv, jobj) == JNIInvalidRefType) { + if (dvmGetJNIRefType(self(), jobj) == JNIInvalidRefType) { LOGW("JNI WARNING: %p is not a valid JNI reference", jobj); printWarn = true; } else { - Object* obj = dvmDecodeIndirectRef(mEnv, jobj); + Object* obj = dvmDecodeIndirectRef(self(), jobj); if (obj == kInvalidIndirectRefObject) { LOGW("JNI WARNING: native code passing in invalid reference %p", jobj); printWarn = true; @@ -945,10 +950,10 @@ private: return; } - ScopedJniThreadState ts(mEnv); + ScopedCheckJniThreadState ts(mEnv); bool printWarn = false; - Object* obj = dvmDecodeIndirectRef(mEnv, jobj); + Object* obj = dvmDecodeIndirectRef(self(), jobj); if (!dvmIsHeapAddress(obj)) { LOGW("JNI WARNING: %s is an invalid %s reference (%p)", argName, indirectRefKindName(jobj), jobj); @@ -1253,9 +1258,9 @@ static int dvmPrimitiveTypeWidth(PrimitiveType primType) { * data are allowed. Returns a pointer to the copied data. */ static void* createGuardedPACopy(JNIEnv* env, const jarray jarr, jboolean* isCopy) { - ScopedJniThreadState ts(env); + ScopedCheckJniThreadState ts(env); - ArrayObject* arrObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr); + ArrayObject* arrObj = (ArrayObject*) dvmDecodeIndirectRef(dvmThreadSelf(), jarr); PrimitiveType primType = arrObj->clazz->elementClass->primitiveType; int len = arrObj->length * dvmPrimitiveTypeWidth(primType); void* result = GuardedCopy::create(arrObj->contents, len, true); @@ -1270,8 +1275,8 @@ static void* createGuardedPACopy(JNIEnv* env, const jarray jarr, jboolean* isCop * back into the VM, and may or may not release the underlying storage. */ static void* releaseGuardedPACopy(JNIEnv* env, jarray jarr, void* dataBuf, int mode) { - ScopedJniThreadState ts(env); - ArrayObject* arrObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr); + ScopedCheckJniThreadState ts(env); + ArrayObject* arrObj = (ArrayObject*) dvmDecodeIndirectRef(dvmThreadSelf(), jarr); if (!GuardedCopy::check(dataBuf, true)) { LOGE("JNI: failed guarded copy check in releaseGuardedPACopy"); @@ -1420,9 +1425,9 @@ static jobject Check_NewGlobalRef(JNIEnv* env, jobject obj) { static void Check_DeleteGlobalRef(JNIEnv* env, jobject globalRef) { CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, globalRef); - if (globalRef != NULL && dvmGetJNIRefType(env, globalRef) != JNIGlobalRefType) { + if (globalRef != NULL && dvmGetJNIRefType(sc.self(), globalRef) != JNIGlobalRefType) { LOGW("JNI WARNING: DeleteGlobalRef on non-global %p (type=%d)", - globalRef, dvmGetJNIRefType(env, globalRef)); + globalRef, dvmGetJNIRefType(sc.self(), globalRef)); abortMaybe(); } else { baseEnv(env)->DeleteGlobalRef(env, globalRef); @@ -1437,9 +1442,9 @@ static jobject Check_NewLocalRef(JNIEnv* env, jobject ref) { static void Check_DeleteLocalRef(JNIEnv* env, jobject localRef) { CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, localRef); - if (localRef != NULL && dvmGetJNIRefType(env, localRef) != JNILocalRefType) { + if (localRef != NULL && dvmGetJNIRefType(sc.self(), localRef) != JNILocalRefType) { LOGW("JNI WARNING: DeleteLocalRef on non-local %p (type=%d)", - localRef, dvmGetJNIRefType(env, localRef)); + localRef, dvmGetJNIRefType(sc.self(), localRef)); abortMaybe(); } else { baseEnv(env)->DeleteLocalRef(env, localRef); @@ -1687,8 +1692,8 @@ static const jchar* Check_GetStringChars(JNIEnv* env, jstring string, jboolean* CHECK_JNI_ENTRY(kFlag_CritOkay, "Esp", env, string, isCopy); const jchar* result = baseEnv(env)->GetStringChars(env, string, isCopy); if (gDvmJni.forceCopy && result != NULL) { - ScopedJniThreadState ts(env); - StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, string); + ScopedCheckJniThreadState ts(env); + StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(dvmThreadSelf(), string); int byteCount = strObj->length() * 2; result = (const jchar*) GuardedCopy::create(result, byteCount, false); if (isCopy != NULL) { @@ -1930,8 +1935,8 @@ static const jchar* Check_GetStringCritical(JNIEnv* env, jstring string, jboolea CHECK_JNI_ENTRY(kFlag_CritGet, "Esp", env, string, isCopy); const jchar* result = baseEnv(env)->GetStringCritical(env, string, isCopy); if (gDvmJni.forceCopy && result != NULL) { - ScopedJniThreadState ts(env); - StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, string); + ScopedCheckJniThreadState ts(env); + StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(dvmThreadSelf(), string); int byteCount = strObj->length() * 2; result = (const jchar*) GuardedCopy::create(result, byteCount, false); if (isCopy != NULL) { diff --git a/vm/Jni.cpp b/vm/Jni.cpp index 3115b62b4..fac669644 100644 --- a/vm/Jni.cpp +++ b/vm/Jni.cpp @@ -195,18 +195,6 @@ static void checkStackSum(Thread* self) { * =========================================================================== */ -static inline Thread* self(JNIEnv* env) { - Thread* envSelf = ((JNIEnvExt*) env)->self; - // When emulating direct pointers with indirect references, it's critical - // that we use the correct per-thread indirect reference table. - Thread* self = gDvmJni.workAroundAppJniBugs ? dvmThreadSelf() : envSelf; - if (self != envSelf) { - LOGE("JNI ERROR: env->self != thread-self (%p vs. %p); auto-correcting", - envSelf, self); - } - return self; -} - /* * Entry/exit processing for all JNI calls. * @@ -219,7 +207,18 @@ static inline Thread* self(JNIEnv* env) { class ScopedJniThreadState { public: explicit ScopedJniThreadState(JNIEnv* env) { - mSelf = ::self(env); + mSelf = ((JNIEnvExt*) env)->self; + + if (UNLIKELY(gDvmJni.workAroundAppJniBugs)) { + // When emulating direct pointers with indirect references, it's critical + // 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); + mSelf = self; + } + } + CHECK_STACK_SUM(mSelf); dvmChangeStatus(mSelf, THREAD_RUNNING); } @@ -229,7 +228,7 @@ public: COMPUTE_STACK_SUM(mSelf); } - Thread* self() { + inline Thread* self() { return mSelf; } @@ -299,16 +298,6 @@ JNIEnvExt* dvmGetJNIEnvForThread() { } /* - * Retrieve the ReferenceTable struct for the current thread. - * - * Going through "env" rather than dvmThreadSelf() is faster but will - * get weird if the JNI code is passing the wrong JNIEnv around. - */ -static inline IndirectRefTable* getLocalRefTable(JNIEnv* env) { - return &self(env)->jniLocalRefTable; -} - -/* * Convert an indirect reference to an Object reference. The indirect * reference may be local, global, or weak-global. * @@ -318,7 +307,7 @@ static inline IndirectRefTable* getLocalRefTable(JNIEnv* env) { * * Note "env" may be NULL when decoding global references. */ -Object* dvmDecodeIndirectRef(JNIEnv* env, jobject jobj) { +Object* dvmDecodeIndirectRef(Thread* self, jobject jobj) { if (jobj == NULL) { return NULL; } @@ -326,8 +315,8 @@ Object* dvmDecodeIndirectRef(JNIEnv* env, jobject jobj) { switch (indirectRefKind(jobj)) { case kIndirectKindLocal: { - Object* result = getLocalRefTable(env)->get(jobj); - if (result == NULL) { + Object* result = self->jniLocalRefTable.get(jobj); + if (UNLIKELY(result == NULL)) { LOGE("JNI ERROR (app bug): use of deleted local reference (%p)", jobj); dvmAbort(); } @@ -339,7 +328,7 @@ Object* dvmDecodeIndirectRef(JNIEnv* env, jobject jobj) { IndirectRefTable* pRefTable = &gDvm.jniGlobalRefTable; ScopedPthreadMutexLock lock(&gDvm.jniGlobalRefLock); Object* result = pRefTable->get(jobj); - if (result == NULL) { + if (UNLIKELY(result == NULL)) { LOGE("JNI ERROR (app bug): use of deleted global reference (%p)", jobj); dvmAbort(); } @@ -353,7 +342,7 @@ Object* dvmDecodeIndirectRef(JNIEnv* env, jobject jobj) { Object* result = pRefTable->get(jobj); if (result == kClearedJniWeakGlobal) { result = NULL; - } else if (result == NULL) { + } else if (UNLIKELY(result == NULL)) { LOGE("JNI ERROR (app bug): use of deleted weak global reference (%p)", jobj); dvmAbort(); } @@ -361,7 +350,7 @@ Object* dvmDecodeIndirectRef(JNIEnv* env, jobject jobj) { } case kIndirectKindInvalid: default: - if (gDvmJni.workAroundAppJniBugs) { + if (UNLIKELY(gDvmJni.workAroundAppJniBugs)) { // Assume an invalid local reference is actually a direct pointer. return reinterpret_cast<Object*>(jobj); } @@ -371,6 +360,13 @@ Object* dvmDecodeIndirectRef(JNIEnv* env, jobject jobj) { } } +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 +} + /* * Add a local reference for an object to the current stack frame. When * the native function returns, the reference will be discarded. @@ -379,47 +375,20 @@ Object* dvmDecodeIndirectRef(JNIEnv* env, jobject jobj) { * * This will be called on otherwise unreferenced objects. We cannot do * GC allocations here, and it's best if we don't grab a mutex. - * - * Returns the local reference (currently just the same pointer that was - * passed in), or NULL on failure. */ -static jobject addLocalReference(JNIEnv* env, Object* obj) { +static inline jobject addLocalReference(Thread* self, Object* obj) { if (obj == NULL) { return NULL; } - IndirectRefTable* pRefTable = getLocalRefTable(env); - void* curFrame = self(env)->interpSave.curFrame; + IndirectRefTable* pRefTable = &self->jniLocalRefTable; + void* curFrame = self->interpSave.curFrame; u4 cookie = SAVEAREA_FROM_FP(curFrame)->xtra.localRefCookie; jobject jobj = (jobject) pRefTable->add(cookie, obj); - if (jobj == NULL) { - 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 - } else { - if (false) { - LOGI("LREF add %p (%s.%s) (ent=%zd)", obj, - dvmGetCurrentJNIMethod()->clazz->descriptor, - dvmGetCurrentJNIMethod()->name, - pRefTable->capacity()); - } - } - -#if 0 // TODO: fix this to understand PushLocalFrame, so we can turn it on. - if (gDvmJni.useCheckJni) { - size_t entryCount = pRefTable->capacity(); - if (entryCount > 16) { - LOGW("Warning: more than 16 JNI local references: %d (most recent was a %s)", entryCount, obj->clazz->descriptor); - pRefTable->dump("JNI local"); - dvmDumpThread(dvmThreadSelf(), false); - //dvmAbort(); - } + if (UNLIKELY(jobj == NULL)) { + AddLocalReferenceFailure(pRefTable); } -#endif - - if (gDvmJni.workAroundAppJniBugs) { + if (UNLIKELY(gDvmJni.workAroundAppJniBugs)) { // Hand out direct pointers to support broken old apps. return reinterpret_cast<jobject>(obj); } @@ -430,9 +399,8 @@ static jobject addLocalReference(JNIEnv* env, Object* obj) { * Ensure that at least "capacity" references can be held in the local * refs table of the current thread. */ -static bool ensureLocalCapacity(JNIEnv* env, int capacity) { - IndirectRefTable* pRefTable = getLocalRefTable(env); - int numEntries = pRefTable->capacity(); +static bool ensureLocalCapacity(Thread* self, int capacity) { + int numEntries = self->jniLocalRefTable.capacity(); // TODO: this isn't quite right, since "numEntries" includes holes return ((kJniLocalRefMax - numEntries) >= capacity); } @@ -440,13 +408,13 @@ static bool ensureLocalCapacity(JNIEnv* env, int capacity) { /* * Explicitly delete a reference from the local list. */ -static void deleteLocalReference(JNIEnv* env, jobject jobj) { +static void deleteLocalReference(Thread* self, jobject jobj) { if (jobj == NULL) { return; } - IndirectRefTable* pRefTable = getLocalRefTable(env); - void* curFrame = self(env)->interpSave.curFrame; + IndirectRefTable* pRefTable = &self->jniLocalRefTable; + void* curFrame = self->interpSave.curFrame; u4 cookie = SAVEAREA_FROM_FP(curFrame)->xtra.localRefCookie; if (!pRefTable->remove(cookie, jobj)) { /* @@ -677,9 +645,7 @@ static void unpinPrimitiveArray(ArrayObject* arrayObj) { */ void dvmDumpJniReferenceTables() { Thread* self = dvmThreadSelf(); - JNIEnv* env = self->jniEnv; - IndirectRefTable* pLocalRefs = getLocalRefTable(env); - pLocalRefs->dump("JNI local"); + self->jniLocalRefTable.dump("JNI local"); gDvm.jniGlobalRefTable.dump("JNI global"); dvmDumpReferenceTable(&gDvm.jniPinRefTable, "JNI pinned array"); } @@ -696,7 +662,7 @@ void dvmDumpJniReferenceTables() { * * Used by -Xcheck:jni and GetObjectRefType. */ -jobjectRefType dvmGetJNIRefType(JNIEnv* env, jobject jobj) { +jobjectRefType dvmGetJNIRefType(Thread* self, jobject jobj) { /* * IndirectRefKind is currently defined as an exact match of * jobjectRefType, so this is easy. We have to decode it to determine @@ -704,11 +670,11 @@ jobjectRefType dvmGetJNIRefType(JNIEnv* env, jobject jobj) { */ assert(jobj != NULL); - Object* obj = dvmDecodeIndirectRef(env, jobj); + Object* obj = dvmDecodeIndirectRef(self, jobj); if (obj == reinterpret_cast<Object*>(jobj) && gDvmJni.workAroundAppJniBugs) { // If we're handing out direct pointers, check whether 'jobj' is a direct reference // to a local reference. - return getLocalRefTable(env)->contains(obj) ? JNILocalRefType : JNIInvalidRefType; + return self->jniLocalRefTable.contains(obj) ? JNILocalRefType : JNIInvalidRefType; } else if (obj == kInvalidIndirectRefObject) { return JNIInvalidRefType; } else { @@ -1114,7 +1080,7 @@ static inline void convertReferenceResult(JNIEnv* env, JValue* pResult, const Method* method, Thread* self) { if (method->shorty[0] == 'L' && !dvmCheckException(self) && pResult->l != NULL) { - pResult->l = dvmDecodeIndirectRef(env, (jobject) pResult->l); + pResult->l = dvmDecodeIndirectRef(self, (jobject) pResult->l); } } @@ -1124,10 +1090,9 @@ static inline void convertReferenceResult(JNIEnv* env, JValue* pResult, void dvmCallJNIMethod(const u4* args, JValue* pResult, const Method* method, Thread* self) { u4* modArgs = (u4*) args; jclass staticMethodClass = NULL; - JNIEnv* env = self->jniEnv; - bool isSynchronized = dvmIsSynchronizedMethod(method); - Object* lockObj; + u4 accessFlags = method->accessFlags; + bool isSynchronized = (accessFlags & ACC_SYNCHRONIZED) != 0; //LOGI("JNI calling %p (%s.%s:%s):", method->insns, // method->clazz->descriptor, method->name, method->shorty); @@ -1137,26 +1102,15 @@ void dvmCallJNIMethod(const u4* args, JValue* pResult, const Method* method, Thr * arguments. */ int idx = 0; - if (dvmIsStaticMethod(method)) { + Object* lockObj; + if ((accessFlags & ACC_STATIC) != 0) { lockObj = (Object*) method->clazz; - /* add the class object we pass in */ - staticMethodClass = (jclass) addLocalReference(env, (Object*) method->clazz); - if (staticMethodClass == NULL) { - assert(dvmCheckException(self)); - return; - } + staticMethodClass = (jclass) addLocalReference(self, (Object*) method->clazz); } else { lockObj = (Object*) args[0]; - /* add "this" */ - jobject thisObj = addLocalReference(env, (Object*) modArgs[0]); - if (thisObj == NULL) { - assert(dvmCheckException(self)); - return; - } - modArgs[idx] = (u4) thisObj; - idx = 1; + modArgs[idx++] = (u4) addLocalReference(self, (Object*) modArgs[0]); } if (!method->noRef) { @@ -1166,12 +1120,7 @@ void dvmCallJNIMethod(const u4* args, JValue* pResult, const Method* method, Thr case 'L': //LOGI(" local %d: 0x%08x", idx, modArgs[idx]); if (modArgs[idx] != 0) { - jobject argObj = addLocalReference(env, (Object*) modArgs[idx]); - if (argObj == NULL) { - assert(dvmCheckException(self)); - return; - } - modArgs[idx] = (u4) argObj; + modArgs[idx] = (u4) addLocalReference(self, (Object*) modArgs[idx]); } break; case 'D': @@ -1186,10 +1135,10 @@ void dvmCallJNIMethod(const u4* args, JValue* pResult, const Method* method, Thr } } - if (method->shouldTrace) { + if (UNLIKELY(method->shouldTrace)) { logNativeMethodEntry(method, args); } - if (isSynchronized) { + if (UNLIKELY(isSynchronized)) { dvmLockObject(self, lockObj); } @@ -1198,8 +1147,9 @@ void dvmCallJNIMethod(const u4* args, JValue* pResult, const Method* method, Thr ANDROID_MEMBAR_FULL(); /* guarantee ordering on method->insns */ assert(method->insns != NULL); + JNIEnv* env = self->jniEnv; COMPUTE_STACK_SUM(self); - dvmPlatformInvoke(method->fastJni ? NULL : env, + dvmPlatformInvoke(env, (ClassObject*) staticMethodClass, method->jniArgInfo, method->insSize, modArgs, method->shorty, (void*) method->insns, pResult); @@ -1209,22 +1159,15 @@ void dvmCallJNIMethod(const u4* args, JValue* pResult, const Method* method, Thr convertReferenceResult(env, pResult, method, self); - if (isSynchronized) { + if (UNLIKELY(isSynchronized)) { dvmUnlockObject(self, lockObj); } - if (method->shouldTrace) { + if (UNLIKELY(method->shouldTrace)) { logNativeMethodExit(method, self, *pResult); } } /* - * Extract the return type enum from the "jniArgInfo" field. - */ -DalvikJniReturnType dvmGetArgInfoReturnType(int jniArgInfo) { - return static_cast<DalvikJniReturnType>((jniArgInfo & DALVIK_JNI_RETURN_MASK) >> DALVIK_JNI_RETURN_SHIFT); -} - -/* * =========================================================================== * JNI implementation * =========================================================================== @@ -1306,7 +1249,7 @@ static jclass FindClass(JNIEnv* env, const char* name) { ClassObject* clazz = dvmFindClassNoInit(descriptor, loader); free(descriptor); - jclass jclazz = (jclass) addLocalReference(env, (Object*) clazz); + jclass jclazz = (jclass) addLocalReference(ts.self(), (Object*) clazz); dvmReleaseTrackedAlloc(trackedLoader, ts.self()); return jclazz; } @@ -1316,8 +1259,8 @@ static jclass FindClass(JNIEnv* env, const char* name) { */ static jclass GetSuperclass(JNIEnv* env, jclass jclazz) { ScopedJniThreadState ts(env); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz); - return (jclass) addLocalReference(env, (Object*)clazz->super); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz); + return (jclass) addLocalReference(ts.self(), (Object*)clazz->super); } /* @@ -1327,8 +1270,8 @@ static jclass GetSuperclass(JNIEnv* env, jclass jclazz) { */ static jboolean IsAssignableFrom(JNIEnv* env, jclass jclazz1, jclass jclazz2) { ScopedJniThreadState ts(env); - ClassObject* clazz1 = (ClassObject*) dvmDecodeIndirectRef(env, jclazz1); - ClassObject* clazz2 = (ClassObject*) dvmDecodeIndirectRef(env, jclazz2); + ClassObject* clazz1 = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz1); + ClassObject* clazz2 = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz2); return dvmInstanceof(clazz1, clazz2); } @@ -1337,7 +1280,7 @@ static jboolean IsAssignableFrom(JNIEnv* env, jclass jclazz1, jclass jclazz2) { */ static jmethodID FromReflectedMethod(JNIEnv* env, jobject jmethod) { ScopedJniThreadState ts(env); - Object* method = dvmDecodeIndirectRef(env, jmethod); + Object* method = dvmDecodeIndirectRef(ts.self(), jmethod); return (jmethodID) dvmGetMethodFromReflectObj(method); } @@ -1346,7 +1289,7 @@ static jmethodID FromReflectedMethod(JNIEnv* env, jobject jmethod) { */ static jfieldID FromReflectedField(JNIEnv* env, jobject jfield) { ScopedJniThreadState ts(env); - Object* field = dvmDecodeIndirectRef(env, jfield); + Object* field = dvmDecodeIndirectRef(ts.self(), jfield); return (jfieldID) dvmGetFieldFromReflectObj(field); } @@ -1359,10 +1302,10 @@ static jfieldID FromReflectedField(JNIEnv* env, jobject jfield) { */ static jobject ToReflectedMethod(JNIEnv* env, jclass jcls, jmethodID methodID, jboolean isStatic) { ScopedJniThreadState ts(env); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jcls); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jcls); Object* obj = dvmCreateReflectObjForMethod(clazz, (Method*) methodID); dvmReleaseTrackedAlloc(obj, NULL); - return addLocalReference(env, obj); + return addLocalReference(ts.self(), obj); } /* @@ -1374,10 +1317,10 @@ static jobject ToReflectedMethod(JNIEnv* env, jclass jcls, jmethodID methodID, j */ static jobject ToReflectedField(JNIEnv* env, jclass jcls, jfieldID fieldID, jboolean isStatic) { ScopedJniThreadState ts(env); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jcls); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jcls); Object* obj = dvmCreateReflectObjForField(clazz, (Field*) fieldID); dvmReleaseTrackedAlloc(obj, NULL); - return addLocalReference(env, obj); + return addLocalReference(ts.self(), obj); } /* @@ -1386,7 +1329,7 @@ static jobject ToReflectedField(JNIEnv* env, jclass jcls, jfieldID fieldID, jboo static jint Throw(JNIEnv* env, jthrowable jobj) { ScopedJniThreadState ts(env); if (jobj != NULL) { - Object* obj = dvmDecodeIndirectRef(env, jobj); + Object* obj = dvmDecodeIndirectRef(ts.self(), jobj); dvmSetException(ts.self(), obj); return JNI_OK; } @@ -1399,7 +1342,7 @@ static jint Throw(JNIEnv* env, jthrowable jobj) { */ static jint ThrowNew(JNIEnv* env, jclass jclazz, const char* message) { ScopedJniThreadState ts(env); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz); dvmThrowException(clazz, message); // TODO: should return failure if this didn't work (e.g. OOM) return JNI_OK; @@ -1416,7 +1359,7 @@ static jint ThrowNew(JNIEnv* env, jclass jclazz, const char* message) { static jthrowable ExceptionOccurred(JNIEnv* env) { ScopedJniThreadState ts(env); Object* exception = dvmGetException(ts.self()); - jthrowable localException = (jthrowable) addLocalReference(env, exception); + jthrowable localException = (jthrowable) addLocalReference(ts.self(), exception); if (localException == NULL && exception != NULL) { /* * We were unable to add a new local reference, and threw a new @@ -1470,7 +1413,7 @@ static void FatalError(JNIEnv* env, const char* msg) { */ static jint PushLocalFrame(JNIEnv* env, jint capacity) { ScopedJniThreadState ts(env); - if (!ensureLocalCapacity(env, capacity) || + if (!ensureLocalCapacity(ts.self(), capacity) || !dvmPushLocalFrame(ts.self(), dvmGetCurrentJNIMethod())) { /* yes, OutOfMemoryError, not StackOverflowError */ @@ -1487,13 +1430,13 @@ static jint PushLocalFrame(JNIEnv* env, jint capacity) { */ static jobject PopLocalFrame(JNIEnv* env, jobject jresult) { ScopedJniThreadState ts(env); - Object* result = dvmDecodeIndirectRef(env, jresult); + Object* result = dvmDecodeIndirectRef(ts.self(), jresult); if (!dvmPopLocalFrame(ts.self())) { LOGW("JNI WARNING: too many PopLocalFrame calls"); dvmClearException(ts.self()); dvmThrowRuntimeException("too many PopLocalFrame calls"); } - return addLocalReference(env, result); + return addLocalReference(ts.self(), result); } /* @@ -1501,7 +1444,7 @@ static jobject PopLocalFrame(JNIEnv* env, jobject jresult) { */ static jobject NewGlobalRef(JNIEnv* env, jobject jobj) { ScopedJniThreadState ts(env); - Object* obj = dvmDecodeIndirectRef(env, jobj); + Object* obj = dvmDecodeIndirectRef(ts.self(), jobj); return addGlobalReference(obj); } @@ -1519,8 +1462,8 @@ static void DeleteGlobalRef(JNIEnv* env, jobject jglobalRef) { */ static jobject NewLocalRef(JNIEnv* env, jobject jobj) { ScopedJniThreadState ts(env); - Object* obj = dvmDecodeIndirectRef(env, jobj); - return addLocalReference(env, obj); + Object* obj = dvmDecodeIndirectRef(ts.self(), jobj); + return addLocalReference(ts.self(), obj); } /* @@ -1528,7 +1471,7 @@ static jobject NewLocalRef(JNIEnv* env, jobject jobj) { */ static void DeleteLocalRef(JNIEnv* env, jobject jlocalRef) { ScopedJniThreadState ts(env); - deleteLocalReference(env, jlocalRef); + deleteLocalReference(ts.self(), jlocalRef); } /* @@ -1537,7 +1480,7 @@ static void DeleteLocalRef(JNIEnv* env, jobject jlocalRef) { */ static jint EnsureLocalCapacity(JNIEnv* env, jint capacity) { ScopedJniThreadState ts(env); - bool okay = ensureLocalCapacity(env, capacity); + bool okay = ensureLocalCapacity(ts.self(), capacity); if (!okay) { dvmThrowOutOfMemoryError("can't ensure local reference capacity"); } @@ -1550,8 +1493,8 @@ static jint EnsureLocalCapacity(JNIEnv* env, jint capacity) { */ static jboolean IsSameObject(JNIEnv* env, jobject jref1, jobject jref2) { ScopedJniThreadState ts(env); - Object* obj1 = dvmDecodeIndirectRef(env, jref1); - Object* obj2 = dvmDecodeIndirectRef(env, jref2); + Object* obj1 = dvmDecodeIndirectRef(ts.self(), jref1); + Object* obj2 = dvmDecodeIndirectRef(ts.self(), jref2); return (obj1 == obj2); } @@ -1561,7 +1504,7 @@ static jboolean IsSameObject(JNIEnv* env, jobject jref1, jobject jref2) { static jobject AllocObject(JNIEnv* env, jclass jclazz) { ScopedJniThreadState ts(env); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz); if (!canAllocClass(clazz) || (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz))) { @@ -1570,7 +1513,7 @@ static jobject AllocObject(JNIEnv* env, jclass jclazz) { } Object* newObj = dvmAllocObject(clazz, ALLOC_DONT_TRACK); - return addLocalReference(env, newObj); + return addLocalReference(ts.self(), newObj); } /* @@ -1578,7 +1521,7 @@ static jobject AllocObject(JNIEnv* env, jclass jclazz) { */ static jobject NewObject(JNIEnv* env, jclass jclazz, jmethodID methodID, ...) { ScopedJniThreadState ts(env); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz); if (!canAllocClass(clazz) || (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz))) { assert(dvmCheckException(ts.self())); @@ -1586,7 +1529,7 @@ static jobject NewObject(JNIEnv* env, jclass jclazz, jmethodID methodID, ...) { } Object* newObj = dvmAllocObject(clazz, ALLOC_DONT_TRACK); - jobject result = addLocalReference(env, newObj); + jobject result = addLocalReference(ts.self(), newObj); if (newObj != NULL) { JValue unused; va_list args; @@ -1599,7 +1542,7 @@ static jobject NewObject(JNIEnv* env, jclass jclazz, jmethodID methodID, ...) { static jobject NewObjectV(JNIEnv* env, jclass jclazz, jmethodID methodID, va_list args) { ScopedJniThreadState ts(env); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz); if (!canAllocClass(clazz) || (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz))) { assert(dvmCheckException(ts.self())); @@ -1607,7 +1550,7 @@ static jobject NewObjectV(JNIEnv* env, jclass jclazz, jmethodID methodID, va_lis } Object* newObj = dvmAllocObject(clazz, ALLOC_DONT_TRACK); - jobject result = addLocalReference(env, newObj); + jobject result = addLocalReference(ts.self(), newObj); if (newObj != NULL) { JValue unused; dvmCallMethodV(ts.self(), (Method*) methodID, newObj, true, &unused, args); @@ -1617,7 +1560,7 @@ static jobject NewObjectV(JNIEnv* env, jclass jclazz, jmethodID methodID, va_lis static jobject NewObjectA(JNIEnv* env, jclass jclazz, jmethodID methodID, jvalue* args) { ScopedJniThreadState ts(env); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz); if (!canAllocClass(clazz) || (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz))) { assert(dvmCheckException(ts.self())); @@ -1625,7 +1568,7 @@ static jobject NewObjectA(JNIEnv* env, jclass jclazz, jmethodID methodID, jvalue } Object* newObj = dvmAllocObject(clazz, ALLOC_DONT_TRACK); - jobject result = addLocalReference(env, newObj); + jobject result = addLocalReference(ts.self(), newObj); if (newObj != NULL) { JValue unused; dvmCallMethodA(ts.self(), (Method*) methodID, newObj, true, &unused, args); @@ -1643,8 +1586,8 @@ static jclass GetObjectClass(JNIEnv* env, jobject jobj) { assert(jobj != NULL); - Object* obj = dvmDecodeIndirectRef(env, jobj); - return (jclass) addLocalReference(env, (Object*) obj->clazz); + Object* obj = dvmDecodeIndirectRef(ts.self(), jobj); + return (jclass) addLocalReference(ts.self(), (Object*) obj->clazz); } /* @@ -1658,8 +1601,8 @@ static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass jclazz) { return true; } - Object* obj = dvmDecodeIndirectRef(env, jobj); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz); + Object* obj = dvmDecodeIndirectRef(ts.self(), jobj); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz); return dvmInstanceof(obj->clazz, clazz); } @@ -1680,7 +1623,7 @@ static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass jclazz) { static jmethodID GetMethodID(JNIEnv* env, jclass jclazz, const char* name, const char* sig) { ScopedJniThreadState ts(env); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz); if (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz)) { assert(dvmCheckException(ts.self())); } else if (dvmIsInterfaceClass(clazz)) { @@ -1727,7 +1670,7 @@ static jmethodID GetMethodID(JNIEnv* env, jclass jclazz, const char* name, const static jfieldID GetFieldID(JNIEnv* env, jclass jclazz, const char* name, const char* sig) { ScopedJniThreadState ts(env); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz); if (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz)) { assert(dvmCheckException(ts.self())); @@ -1749,7 +1692,7 @@ static jfieldID GetFieldID(JNIEnv* env, jclass jclazz, const char* name, const c static jmethodID GetStaticMethodID(JNIEnv* env, jclass jclazz, const char* name, const char* sig) { ScopedJniThreadState ts(env); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz); if (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz)) { assert(dvmCheckException(ts.self())); return NULL; @@ -1783,7 +1726,7 @@ static jmethodID GetStaticMethodID(JNIEnv* env, jclass jclazz, const char* name, static jfieldID GetStaticFieldID(JNIEnv* env, jclass jclazz, const char* name, const char* sig) { ScopedJniThreadState ts(env); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz); if (!dvmIsClassInitialized(clazz) && !dvmInitClass(clazz)) { assert(dvmCheckException(ts.self())); return NULL; @@ -1814,14 +1757,14 @@ static jfieldID GetStaticFieldID(JNIEnv* env, jclass jclazz, const char* name, c if (dvmIsVolatileField(sfield)) { \ if (_isref) { /* only when _ctype==jobject */ \ Object* obj = dvmGetStaticFieldObjectVolatile(sfield); \ - value = (_ctype)(u4)addLocalReference(env, obj); \ + value = (_ctype)(u4)addLocalReference(ts.self(), obj); \ } else { \ value = (_ctype) dvmGetStaticField##_jname##Volatile(sfield);\ } \ } else { \ if (_isref) { \ Object* obj = dvmGetStaticFieldObject(sfield); \ - value = (_ctype)(u4)addLocalReference(env, obj); \ + value = (_ctype)(u4)addLocalReference(ts.self(), obj); \ } else { \ value = (_ctype) dvmGetStaticField##_jname(sfield); \ } \ @@ -1850,16 +1793,14 @@ GET_STATIC_TYPE_FIELD(jdouble, Double, false); StaticField* sfield = (StaticField*) fieldID; \ if (dvmIsVolatileField(sfield)) { \ if (_isref) { /* only when _ctype==jobject */ \ - Object* valObj = \ - dvmDecodeIndirectRef(env, (jobject)(u4)value); \ + Object* valObj = dvmDecodeIndirectRef(ts.self(), (jobject)(u4)value); \ dvmSetStaticFieldObjectVolatile(sfield, valObj); \ } else { \ dvmSetStaticField##_jname##Volatile(sfield, (_ctype2)value);\ } \ } else { \ if (_isref) { \ - Object* valObj = \ - dvmDecodeIndirectRef(env, (jobject)(u4)value); \ + Object* valObj = dvmDecodeIndirectRef(ts.self(), (jobject)(u4)value); \ dvmSetStaticFieldObject(sfield, valObj); \ } else { \ dvmSetStaticField##_jname(sfield, (_ctype2)value); \ @@ -1886,14 +1827,14 @@ SET_STATIC_TYPE_FIELD(jdouble, double, Double, false); jfieldID fieldID) \ { \ ScopedJniThreadState ts(env); \ - Object* obj = dvmDecodeIndirectRef(env, jobj); \ + Object* obj = dvmDecodeIndirectRef(ts.self(), jobj); \ InstField* field = (InstField*) fieldID; \ _ctype value; \ if (dvmIsVolatileField(field)) { \ if (_isref) { /* only when _ctype==jobject */ \ Object* valObj = \ dvmGetFieldObjectVolatile(obj, field->byteOffset); \ - value = (_ctype)(u4)addLocalReference(env, valObj); \ + value = (_ctype)(u4)addLocalReference(ts.self(), valObj); \ } else { \ value = (_ctype) \ dvmGetField##_jname##Volatile(obj, field->byteOffset); \ @@ -1901,7 +1842,7 @@ SET_STATIC_TYPE_FIELD(jdouble, double, Double, false); } else { \ if (_isref) { \ Object* valObj = dvmGetFieldObject(obj, field->byteOffset); \ - value = (_ctype)(u4)addLocalReference(env, valObj); \ + value = (_ctype)(u4)addLocalReference(ts.self(), valObj); \ } else { \ value = (_ctype) dvmGetField##_jname(obj, field->byteOffset);\ } \ @@ -1926,12 +1867,11 @@ GET_TYPE_FIELD(jdouble, Double, false); jfieldID fieldID, _ctype value) \ { \ ScopedJniThreadState ts(env); \ - Object* obj = dvmDecodeIndirectRef(env, jobj); \ + Object* obj = dvmDecodeIndirectRef(ts.self(), jobj); \ InstField* field = (InstField*) fieldID; \ if (dvmIsVolatileField(field)) { \ if (_isref) { /* only when _ctype==jobject */ \ - Object* valObj = \ - dvmDecodeIndirectRef(env, (jobject)(u4)value); \ + Object* valObj = dvmDecodeIndirectRef(ts.self(), (jobject)(u4)value); \ dvmSetFieldObjectVolatile(obj, field->byteOffset, valObj); \ } else { \ dvmSetField##_jname##Volatile(obj, \ @@ -1939,8 +1879,7 @@ GET_TYPE_FIELD(jdouble, Double, false); } \ } else { \ if (_isref) { \ - Object* valObj = \ - dvmDecodeIndirectRef(env, (jobject)(u4)value); \ + Object* valObj = dvmDecodeIndirectRef(ts.self(), (jobject)(u4)value); \ dvmSetFieldObject(obj, field->byteOffset, valObj); \ } else { \ dvmSetField##_jname(obj, \ @@ -1969,7 +1908,7 @@ SET_TYPE_FIELD(jdouble, double, Double, false); jmethodID methodID, ...) \ { \ ScopedJniThreadState ts(env); \ - Object* obj = dvmDecodeIndirectRef(env, jobj); \ + Object* obj = dvmDecodeIndirectRef(ts.self(), jobj); \ const Method* meth; \ va_list args; \ JValue result; \ @@ -1981,14 +1920,14 @@ SET_TYPE_FIELD(jdouble, double, Double, false); dvmCallMethodV(ts.self(), meth, obj, true, &result, args); \ va_end(args); \ if (_isref && !dvmCheckException(ts.self())) \ - result.l = (Object*)addLocalReference(env, result.l); \ + result.l = (Object*)addLocalReference(ts.self(), result.l); \ return _retok; \ } \ static _ctype Call##_jname##MethodV(JNIEnv* env, jobject jobj, \ jmethodID methodID, va_list args) \ { \ ScopedJniThreadState ts(env); \ - Object* obj = dvmDecodeIndirectRef(env, jobj); \ + Object* obj = dvmDecodeIndirectRef(ts.self(), jobj); \ const Method* meth; \ JValue result; \ meth = dvmGetVirtualizedMethod(obj->clazz, (Method*)methodID); \ @@ -1997,14 +1936,14 @@ SET_TYPE_FIELD(jdouble, double, Double, false); } \ dvmCallMethodV(ts.self(), meth, obj, true, &result, args); \ if (_isref && !dvmCheckException(ts.self())) \ - result.l = (Object*)addLocalReference(env, result.l); \ + result.l = (Object*)addLocalReference(ts.self(), result.l); \ return _retok; \ } \ static _ctype Call##_jname##MethodA(JNIEnv* env, jobject jobj, \ jmethodID methodID, jvalue* args) \ { \ ScopedJniThreadState ts(env); \ - Object* obj = dvmDecodeIndirectRef(env, jobj); \ + Object* obj = dvmDecodeIndirectRef(ts.self(), jobj); \ const Method* meth; \ JValue result; \ meth = dvmGetVirtualizedMethod(obj->clazz, (Method*)methodID); \ @@ -2013,7 +1952,7 @@ SET_TYPE_FIELD(jdouble, double, Double, false); } \ dvmCallMethodA(ts.self(), meth, obj, true, &result, args); \ if (_isref && !dvmCheckException(ts.self())) \ - result.l = (Object*)addLocalReference(env, result.l); \ + result.l = (Object*)addLocalReference(ts.self(), result.l); \ return _retok; \ } CALL_VIRTUAL(jobject, Object, NULL, (jobject) result.l, true); @@ -2039,9 +1978,8 @@ CALL_VIRTUAL(void, Void, , , false); jclass jclazz, jmethodID methodID, ...) \ { \ ScopedJniThreadState ts(env); \ - Object* obj = dvmDecodeIndirectRef(env, jobj); \ - ClassObject* clazz = \ - (ClassObject*) dvmDecodeIndirectRef(env, jclazz); \ + Object* obj = dvmDecodeIndirectRef(ts.self(), jobj); \ + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz); \ const Method* meth; \ va_list args; \ JValue result; \ @@ -2052,7 +1990,7 @@ CALL_VIRTUAL(void, Void, , , false); va_start(args, methodID); \ dvmCallMethodV(ts.self(), meth, obj, true, &result, args); \ if (_isref && !dvmCheckException(ts.self())) \ - result.l = (Object*)addLocalReference(env, result.l); \ + result.l = (Object*)addLocalReference(ts.self(), result.l); \ va_end(args); \ return _retok; \ } \ @@ -2060,9 +1998,8 @@ CALL_VIRTUAL(void, Void, , , false); jclass jclazz, jmethodID methodID, va_list args) \ { \ ScopedJniThreadState ts(env); \ - Object* obj = dvmDecodeIndirectRef(env, jobj); \ - ClassObject* clazz = \ - (ClassObject*) dvmDecodeIndirectRef(env, jclazz); \ + Object* obj = dvmDecodeIndirectRef(ts.self(), jobj); \ + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz); \ const Method* meth; \ JValue result; \ meth = dvmGetVirtualizedMethod(clazz, (Method*)methodID); \ @@ -2071,16 +2008,15 @@ CALL_VIRTUAL(void, Void, , , false); } \ dvmCallMethodV(ts.self(), meth, obj, true, &result, args); \ if (_isref && !dvmCheckException(ts.self())) \ - result.l = (Object*)addLocalReference(env, result.l); \ + result.l = (Object*)addLocalReference(ts.self(), result.l); \ return _retok; \ } \ static _ctype CallNonvirtual##_jname##MethodA(JNIEnv* env, jobject jobj,\ jclass jclazz, jmethodID methodID, jvalue* args) \ { \ ScopedJniThreadState ts(env); \ - Object* obj = dvmDecodeIndirectRef(env, jobj); \ - ClassObject* clazz = \ - (ClassObject*) dvmDecodeIndirectRef(env, jclazz); \ + Object* obj = dvmDecodeIndirectRef(ts.self(), jobj); \ + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz); \ const Method* meth; \ JValue result; \ meth = dvmGetVirtualizedMethod(clazz, (Method*)methodID); \ @@ -2089,7 +2025,7 @@ CALL_VIRTUAL(void, Void, , , false); } \ dvmCallMethodA(ts.self(), meth, obj, true, &result, args); \ if (_isref && !dvmCheckException(ts.self())) \ - result.l = (Object*)addLocalReference(env, result.l); \ + result.l = (Object*)addLocalReference(ts.self(), result.l); \ return _retok; \ } CALL_NONVIRTUAL(jobject, Object, NULL, (jobject) result.l, true); @@ -2119,7 +2055,7 @@ CALL_NONVIRTUAL(void, Void, , , false); dvmCallMethodV(ts.self(), (Method*)methodID, NULL, true, &result, args);\ va_end(args); \ if (_isref && !dvmCheckException(ts.self())) \ - result.l = (Object*)addLocalReference(env, result.l); \ + result.l = (Object*)addLocalReference(ts.self(), result.l); \ return _retok; \ } \ static _ctype CallStatic##_jname##MethodV(JNIEnv* env, jclass jclazz, \ @@ -2130,7 +2066,7 @@ CALL_NONVIRTUAL(void, Void, , , false); JValue result; \ dvmCallMethodV(ts.self(), (Method*)methodID, NULL, true, &result, args);\ if (_isref && !dvmCheckException(ts.self())) \ - result.l = (Object*)addLocalReference(env, result.l); \ + result.l = (Object*)addLocalReference(ts.self(), result.l); \ return _retok; \ } \ static _ctype CallStatic##_jname##MethodA(JNIEnv* env, jclass jclazz, \ @@ -2141,7 +2077,7 @@ CALL_NONVIRTUAL(void, Void, , , false); JValue result; \ dvmCallMethodA(ts.self(), (Method*)methodID, NULL, true, &result, args);\ if (_isref && !dvmCheckException(ts.self())) \ - result.l = (Object*)addLocalReference(env, result.l); \ + result.l = (Object*)addLocalReference(ts.self(), result.l); \ return _retok; \ } CALL_STATIC(jobject, Object, NULL, (jobject) result.l, true); @@ -2168,7 +2104,7 @@ static jstring NewString(JNIEnv* env, const jchar* unicodeChars, jsize len) { return NULL; } dvmReleaseTrackedAlloc((Object*) jstr, NULL); - return (jstring) addLocalReference(env, (Object*) jstr); + return (jstring) addLocalReference(ts.self(), (Object*) jstr); } /* @@ -2176,7 +2112,7 @@ static jstring NewString(JNIEnv* env, const jchar* unicodeChars, jsize len) { */ static jsize GetStringLength(JNIEnv* env, jstring jstr) { ScopedJniThreadState ts(env); - StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr); + StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(ts.self(), jstr); return strObj->length(); } @@ -2190,7 +2126,7 @@ static jsize GetStringLength(JNIEnv* env, jstring jstr) { static const jchar* GetStringChars(JNIEnv* env, jstring jstr, jboolean* isCopy) { ScopedJniThreadState ts(env); - StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr); + StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(ts.self(), jstr); ArrayObject* strChars = strObj->array(); pinPrimitiveArray(strChars); @@ -2207,7 +2143,7 @@ static const jchar* GetStringChars(JNIEnv* env, jstring jstr, jboolean* isCopy) */ static void ReleaseStringChars(JNIEnv* env, jstring jstr, const jchar* chars) { ScopedJniThreadState ts(env); - StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr); + StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(ts.self(), jstr); ArrayObject* strChars = strObj->array(); unpinPrimitiveArray(strChars); } @@ -2225,7 +2161,7 @@ static jstring NewStringUTF(JNIEnv* env, const char* bytes) { } /* note newStr could come back NULL on OOM */ StringObject* newStr = dvmCreateStringFromCstr(bytes); - jstring result = (jstring) addLocalReference(env, (Object*) newStr); + jstring result = (jstring) addLocalReference(ts.self(), (Object*) newStr); dvmReleaseTrackedAlloc((Object*)newStr, NULL); return result; } @@ -2235,7 +2171,7 @@ static jstring NewStringUTF(JNIEnv* env, const char* bytes) { */ static jsize GetStringUTFLength(JNIEnv* env, jstring jstr) { ScopedJniThreadState ts(env); - StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr); + StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(ts.self(), jstr); if (strObj == NULL) { return 0; // Should we throw something or assert? } @@ -2265,7 +2201,7 @@ static const char* GetStringUTFChars(JNIEnv* env, jstring jstr, jboolean* isCopy if (isCopy != NULL) { *isCopy = JNI_TRUE; } - StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr); + StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(ts.self(), jstr); char* newStr = dvmCreateCstrFromString(strObj); if (newStr == NULL) { /* assume memory failure */ @@ -2287,7 +2223,7 @@ static void ReleaseStringUTFChars(JNIEnv* env, jstring jstr, const char* utf) { */ static jsize GetArrayLength(JNIEnv* env, jarray jarr) { ScopedJniThreadState ts(env); - ArrayObject* arrObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr); + ArrayObject* arrObj = (ArrayObject*) dvmDecodeIndirectRef(ts.self(), jarr); return arrObj->length; } @@ -2304,21 +2240,21 @@ static jobjectArray NewObjectArray(JNIEnv* env, jsize length, return NULL; } - ClassObject* elemClassObj = (ClassObject*) dvmDecodeIndirectRef(env, jelementClass); + ClassObject* elemClassObj = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jelementClass); ClassObject* arrayClass = dvmFindArrayClassForElement(elemClassObj); ArrayObject* newObj = dvmAllocArrayByClass(arrayClass, length, ALLOC_DEFAULT); if (newObj == NULL) { assert(dvmCheckException(ts.self())); return NULL; } - jobjectArray newArray = (jobjectArray) addLocalReference(env, (Object*) newObj); + jobjectArray newArray = (jobjectArray) addLocalReference(ts.self(), (Object*) newObj); dvmReleaseTrackedAlloc((Object*) newObj, NULL); /* * Initialize the array. */ if (jinitialElement != NULL) { - Object* initialElement = dvmDecodeIndirectRef(env, jinitialElement); + Object* initialElement = dvmDecodeIndirectRef(ts.self(), jinitialElement); Object** arrayData = (Object**) (void*) newObj->contents; for (jsize i = 0; i < length; ++i) { arrayData[i] = initialElement; @@ -2345,13 +2281,13 @@ static bool checkArrayElementBounds(ArrayObject* arrayObj, jsize index) { static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray jarr, jsize index) { ScopedJniThreadState ts(env); - ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr); + ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(ts.self(), jarr); if (!checkArrayElementBounds(arrayObj, index)) { return NULL; } Object* value = ((Object**) (void*) arrayObj->contents)[index]; - return addLocalReference(env, value); + return addLocalReference(ts.self(), value); } /* @@ -2360,14 +2296,14 @@ static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray jarr, jsize index static void SetObjectArrayElement(JNIEnv* env, jobjectArray jarr, jsize index, jobject jobj) { ScopedJniThreadState ts(env); - ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr); + ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(ts.self(), jarr); if (!checkArrayElementBounds(arrayObj, index)) { return; } //LOGV("JNI: set element %d in array %p to %p", index, array, value); - Object* obj = dvmDecodeIndirectRef(env, jobj); + Object* obj = dvmDecodeIndirectRef(ts.self(), jobj); dvmSetObjectArrayElement(arrayObj, index, obj); } @@ -2381,7 +2317,7 @@ static void SetObjectArrayElement(JNIEnv* env, jobjectArray jarr, jsize index, j if (arrayObj == NULL) { \ return NULL; \ } \ - _artype result = (_artype) addLocalReference(env, (Object*) arrayObj); \ + _artype result = (_artype) addLocalReference(ts.self(), (Object*) arrayObj); \ dvmReleaseTrackedAlloc((Object*) arrayObj, NULL); \ return result; \ } @@ -2408,7 +2344,7 @@ NEW_PRIMITIVE_ARRAY(jdoubleArray, Double, 'D'); _ctype##Array jarr, jboolean* isCopy) \ { \ ScopedJniThreadState ts(env); \ - ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr); \ + ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(ts.self(), jarr); \ pinPrimitiveArray(arrayObj); \ _ctype* data = (_ctype*) (void*) arrayObj->contents; \ if (isCopy != NULL) { \ @@ -2431,8 +2367,7 @@ NEW_PRIMITIVE_ARRAY(jdoubleArray, Double, 'D'); UNUSED_PARAMETER(elems); \ if (mode != JNI_COMMIT) { \ ScopedJniThreadState ts(env); \ - ArrayObject* arrayObj = \ - (ArrayObject*) dvmDecodeIndirectRef(env, jarr); \ + ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(ts.self(), jarr); \ unpinPrimitiveArray(arrayObj); \ } \ } @@ -2454,7 +2389,7 @@ static void throwArrayRegionOutOfBounds(ArrayObject* arrayObj, jsize start, _ctype##Array jarr, jsize start, jsize len, _ctype* buf) \ { \ ScopedJniThreadState ts(env); \ - ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr); \ + ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(ts.self(), jarr); \ _ctype* data = (_ctype*) (void*) arrayObj->contents; \ if (start < 0 || len < 0 || start + len > (int) arrayObj->length) { \ throwArrayRegionOutOfBounds(arrayObj, start, len, "src"); \ @@ -2471,7 +2406,7 @@ static void throwArrayRegionOutOfBounds(ArrayObject* arrayObj, jsize start, _ctype##Array jarr, jsize start, jsize len, const _ctype* buf) \ { \ ScopedJniThreadState ts(env); \ - ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr); \ + ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(ts.self(), jarr); \ _ctype* data = (_ctype*) (void*) arrayObj->contents; \ if (start < 0 || len < 0 || start + len > (int) arrayObj->length) { \ throwArrayRegionOutOfBounds(arrayObj, start, len, "dst"); \ @@ -2513,7 +2448,7 @@ static jint RegisterNatives(JNIEnv* env, jclass jclazz, { ScopedJniThreadState ts(env); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz); if (gDvm.verboseJni) { LOGI("[Registering JNI native methods for class %s]", @@ -2559,7 +2494,7 @@ static jint RegisterNatives(JNIEnv* env, jclass jclazz, static jint UnregisterNatives(JNIEnv* env, jclass jclazz) { ScopedJniThreadState ts(env); - ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz); + ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(ts.self(), jclazz); if (gDvm.verboseJni) { LOGI("[Unregistering JNI native methods for class %s]", clazz->descriptor); @@ -2576,7 +2511,7 @@ static jint UnregisterNatives(JNIEnv* env, jclass jclazz) { */ static jint MonitorEnter(JNIEnv* env, jobject jobj) { ScopedJniThreadState ts(env); - Object* obj = dvmDecodeIndirectRef(env, jobj); + Object* obj = dvmDecodeIndirectRef(ts.self(), jobj); dvmLockObject(ts.self(), obj); trackMonitorEnter(ts.self(), obj); return JNI_OK; @@ -2593,7 +2528,7 @@ static jint MonitorEnter(JNIEnv* env, jobject jobj) { */ static jint MonitorExit(JNIEnv* env, jobject jobj) { ScopedJniThreadState ts(env); - Object* obj = dvmDecodeIndirectRef(env, jobj); + Object* obj = dvmDecodeIndirectRef(ts.self(), jobj); bool success = dvmUnlockObject(ts.self(), obj); if (success) { trackMonitorExit(ts.self(), obj); @@ -2615,7 +2550,7 @@ static jint GetJavaVM(JNIEnv* env, JavaVM** vm) { */ static void GetStringRegion(JNIEnv* env, jstring jstr, jsize start, jsize len, jchar* buf) { ScopedJniThreadState ts(env); - StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr); + StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(ts.self(), jstr); int strLen = strObj->length(); if (((start|len) < 0) || (start + len > strLen)) { dvmThrowStringIndexOutOfBoundsExceptionWithRegion(strLen, start, len); @@ -2630,7 +2565,7 @@ static void GetStringRegion(JNIEnv* env, jstring jstr, jsize start, jsize len, j */ static void GetStringUTFRegion(JNIEnv* env, jstring jstr, jsize start, jsize len, char* buf) { ScopedJniThreadState ts(env); - StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr); + StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(ts.self(), jstr); int strLen = strObj->length(); if (((start|len) < 0) || (start + len > strLen)) { dvmThrowStringIndexOutOfBoundsExceptionWithRegion(strLen, start, len); @@ -2649,10 +2584,10 @@ static void GetStringUTFRegion(JNIEnv* env, jstring jstr, jsize start, jsize len */ static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray jarr, jboolean* isCopy) { ScopedJniThreadState ts(env); - ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr); + ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(ts.self(), jarr); pinPrimitiveArray(arrayObj); void* data = arrayObj->contents; - if (isCopy != NULL) { + if (UNLIKELY(isCopy != NULL)) { *isCopy = JNI_FALSE; } return data; @@ -2664,7 +2599,7 @@ static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray jarr, jboolean* isCop static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray jarr, void* carray, jint mode) { if (mode != JNI_COMMIT) { ScopedJniThreadState ts(env); - ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr); + ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(ts.self(), jarr); unpinPrimitiveArray(arrayObj); } } @@ -2675,7 +2610,7 @@ static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray jarr, void* carray static const jchar* GetStringCritical(JNIEnv* env, jstring jstr, jboolean* isCopy) { ScopedJniThreadState ts(env); - StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr); + StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(ts.self(), jstr); ArrayObject* strChars = strObj->array(); pinPrimitiveArray(strChars); @@ -2692,7 +2627,7 @@ static const jchar* GetStringCritical(JNIEnv* env, jstring jstr, jboolean* isCop */ static void ReleaseStringCritical(JNIEnv* env, jstring jstr, const jchar* carray) { ScopedJniThreadState ts(env); - StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, jstr); + StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(ts.self(), jstr); ArrayObject* strChars = strObj->array(); unpinPrimitiveArray(strChars); } @@ -2702,7 +2637,7 @@ static void ReleaseStringCritical(JNIEnv* env, jstring jstr, const jchar* carray */ static jweak NewWeakGlobalRef(JNIEnv* env, jobject jobj) { ScopedJniThreadState ts(env); - Object *obj = dvmDecodeIndirectRef(env, jobj); + Object *obj = dvmDecodeIndirectRef(ts.self(), jobj); return (jweak) addWeakGlobalReference(obj); } @@ -2734,7 +2669,7 @@ static jboolean ExceptionCheck(JNIEnv* env) { */ static jobjectRefType GetObjectRefType(JNIEnv* env, jobject jobj) { ScopedJniThreadState ts(env); - return dvmGetJNIRefType(env, jobj); + return dvmGetJNIRefType(ts.self(), jobj); } /* @@ -2756,12 +2691,12 @@ static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) { return NULL; } /* call the constructor */ - jobject result = addLocalReference(env, newObj); + jobject result = addLocalReference(ts.self(), newObj); JValue unused; dvmCallMethod(ts.self(), gDvm.methJavaNioReadWriteDirectByteBuffer_init, newObj, &unused, (jint) address, (jint) capacity); if (dvmGetException(ts.self()) != NULL) { - deleteLocalReference(env, result); + deleteLocalReference(ts.self(), result); return NULL; } return result; @@ -2776,7 +2711,7 @@ static void* GetDirectBufferAddress(JNIEnv* env, jobject jbuf) { ScopedJniThreadState ts(env); // All Buffer objects have an effectiveDirectAddress field. - Object* bufObj = dvmDecodeIndirectRef(env, jbuf); + Object* bufObj = dvmDecodeIndirectRef(ts.self(), jbuf); return (void*) dvmGetFieldInt(bufObj, gDvm.offJavaNioBuffer_effectiveDirectAddress); } @@ -2796,7 +2731,7 @@ static jlong GetDirectBufferCapacity(JNIEnv* env, jobject jbuf) { * (The "check" version should verify that this is actually a Buffer, * but we're not required to do so here.) */ - Object* buf = dvmDecodeIndirectRef(env, jbuf); + Object* buf = dvmDecodeIndirectRef(ts.self(), jbuf); return dvmGetFieldInt(buf, gDvm.offJavaNioBuffer_capacity); } diff --git a/vm/JniInternal.h b/vm/JniInternal.h index 5fbfd78fa..df92df651 100644 --- a/vm/JniInternal.h +++ b/vm/JniInternal.h @@ -124,13 +124,13 @@ void dvmLateEnableCheckedJni(void); /* * Decode a local, global, or weak-global reference. */ -Object* dvmDecodeIndirectRef(JNIEnv* env, jobject jobj); +Object* dvmDecodeIndirectRef(Thread* self, jobject jobj); /* * Verify that a reference passed in from native code is valid. Returns * an indication of local/global/invalid. */ -jobjectRefType dvmGetJNIRefType(JNIEnv* env, jobject jobj); +jobjectRefType dvmGetJNIRefType(Thread* self, jobject jobj); /* * Get the last method called on the interp stack. This is the method @@ -150,11 +150,6 @@ void dvmDestroyJNIEnv(JNIEnv* env); JNIEnvExt* dvmGetJNIEnvForThread(void); /* - * Extract the return type enum from the "jniArgInfo" value. - */ -DalvikJniReturnType dvmGetArgInfoReturnType(int jniArgInfo); - -/* * Release all MonitorEnter-acquired locks that are still held. Called at * DetachCurrentThread time. */ diff --git a/vm/interp/Stack.cpp b/vm/interp/Stack.cpp index ad6af823d..49e68f19f 100644 --- a/vm/interp/Stack.cpp +++ b/vm/interp/Stack.cpp @@ -462,7 +462,6 @@ void dvmCallMethodV(Thread* self, const Method* method, Object* obj, verifyCount++; } - JNIEnv* env = self->jniEnv; while (*desc != '\0') { switch (*(desc++)) { case 'D': case 'J': { @@ -484,7 +483,7 @@ void dvmCallMethodV(Thread* self, const Method* method, Object* obj, assert(obj == NULL || dvmIsHeapAddress(obj)); jobject argObj = reinterpret_cast<jobject>(arg); if (fromJni) - *ins++ = (u4) dvmDecodeIndirectRef(env, argObj); + *ins++ = (u4) dvmDecodeIndirectRef(self, argObj); else *ins++ = (u4) argObj; verifyCount++; @@ -565,7 +564,6 @@ void dvmCallMethodA(Thread* self, const Method* method, Object* obj, verifyCount++; } - JNIEnv* env = self->jniEnv; while (*desc != '\0') { switch (*desc++) { case 'D': /* 64-bit quantity; have to use */ @@ -576,7 +574,7 @@ void dvmCallMethodA(Thread* self, const Method* method, Object* obj, break; case 'L': /* includes array refs */ if (fromJni) - *ins++ = (u4) dvmDecodeIndirectRef(env, args->l); + *ins++ = (u4) dvmDecodeIndirectRef(self, args->l); else *ins++ = (u4) args->l; break; |