Add back the work-arounds for broken apps that assume JNI uses direct references.
Note that we'll need to add support for this to jni_compiler too.
Change-Id: I7e31ab4314ba913cde4629544addd0aad9a89b3b
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index cc1d8db..9213056 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -18,6 +18,7 @@
#include "logging.h"
#include "object.h"
#include "runtime.h"
+#include "scoped_jni_thread_state.h"
#include "stringpiece.h"
#include "thread.h"
@@ -50,54 +51,6 @@
namespace {
-// Entry/exit processing for all JNI calls.
-//
-// This performs the necessary thread state switching, lets us amortize the
-// cost of working out the current thread, and lets us check (and repair) apps
-// that are using a JNIEnv on the wrong thread.
-class ScopedJniThreadState {
- public:
- explicit ScopedJniThreadState(JNIEnv* env)
- : env_(reinterpret_cast<JNIEnvExt*>(env)) {
- self_ = ThreadForEnv(env);
- self_->SetState(Thread::kRunnable);
- }
-
- ~ScopedJniThreadState() {
- self_->SetState(Thread::kNative);
- }
-
- JNIEnvExt* Env() {
- return env_;
- }
-
- Thread* Self() {
- return self_;
- }
-
- JavaVMExt* Vm() {
- return env_->vm;
- }
-
- private:
- static Thread* ThreadForEnv(JNIEnv* env) {
- // TODO: need replacement for gDvmJni.
- bool workAroundAppJniBugs = true;
- Thread* env_self = reinterpret_cast<JNIEnvExt*>(env)->self;
- Thread* self = workAroundAppJniBugs ? Thread::Current() : env_self;
- if (self != env_self) {
- LOG(ERROR) << "JNI ERROR: JNIEnv for " << *env_self
- << " used on " << *self;
- // TODO: dump stack
- }
- return self;
- }
-
- JNIEnvExt* env_;
- Thread* self_;
- DISALLOW_COPY_AND_ASSIGN(ScopedJniThreadState);
-};
-
/*
* Add a local reference for an object to the current stack frame. When
* the native function returns, the reference will be discarded.
@@ -142,7 +95,7 @@
}
#endif
- if (false /*gDvmJni.workAroundAppJniBugs*/) { // TODO
+ if (ts.Env()->work_around_app_jni_bugs) {
// Hand out direct pointers to support broken old apps.
return reinterpret_cast<T>(obj);
}
@@ -2313,10 +2266,13 @@
return JNILocalRefType;
}
+ if (!ts.Env()->work_around_app_jni_bugs) {
+ return JNIInvalidRefType;
+ }
+
// If we're handing out direct pointers, check whether it's a direct pointer
// to a local reference.
- // TODO: replace 'false' with the replacement for gDvmJni.workAroundAppJniBugs
- if (false && Decode<Object*>(ts, java_object) == reinterpret_cast<Object*>(java_object)) {
+ if (Decode<Object*>(ts, java_object) == reinterpret_cast<Object*>(java_object)) {
if (ts.Env()->locals.Contains(java_object)) {
return JNILocalRefType;
}
@@ -2573,6 +2529,7 @@
: self(self),
vm(vm),
check_jni(vm->check_jni),
+ work_around_app_jni_bugs(vm->work_around_app_jni_bugs),
critical(false),
monitors("monitors", kMonitorsInitial, kMonitorsMax),
locals(kLocalsInitial, kLocalsMax, kLocal) {
@@ -2698,7 +2655,8 @@
check_jni_abort_hook(NULL),
check_jni(check_jni),
verbose_jni(verbose_jni),
- force_copy(false), // TODO
+ force_copy(false), // TODO: add a way to enable this
+ work_around_app_jni_bugs(false), // TODO: add a way to enable this
pins_lock(Mutex::Create("JNI pin table lock")),
pin_table("pin table", kPinTableInitialSize, kPinTableMaxSize),
globals_lock(Mutex::Create("JNI global reference table lock")),