summaryrefslogtreecommitdiffstats
path: root/runtime/reflection.cc
diff options
context:
space:
mode:
authorJeff Hao <jeffhao@google.com>2015-05-27 19:29:29 -0700
committerJeff Hao <jeffhao@google.com>2015-05-27 19:44:22 -0700
commit1a302fb4f84525289c1cf7a437f5be1999a75251 (patch)
treee69db1a280980ed969d0f993f6e05ba70c1d4bd5 /runtime/reflection.cc
parente0cc299fd258b6ce6f19a201ca9fce09910f6e42 (diff)
downloadart-1a302fb4f84525289c1cf7a437f5be1999a75251.zip
art-1a302fb4f84525289c1cf7a437f5be1999a75251.tar.gz
art-1a302fb4f84525289c1cf7a437f5be1999a75251.tar.bz2
Fix updating of JNI references for String.<init>.
Was missing updates to globals and weak globals. Bug: 21288130 Bug: 21440428 Change-Id: I5f801f68b61f6b066b441b92ace367e6ba434789
Diffstat (limited to 'runtime/reflection.cc')
-rw-r--r--runtime/reflection.cc25
1 files changed, 21 insertions, 4 deletions
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index d321d27..f8c7081 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -464,7 +464,7 @@ JValue InvokeWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, jobject o
InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
if (is_string_init) {
// For string init, remap original receiver to StringFactory result.
- soa.Self()->GetJniEnv()->locals.Update(obj, result.GetL());
+ UpdateReference(soa.Self(), obj, result.GetL());
}
return result;
}
@@ -494,7 +494,7 @@ JValue InvokeWithJValues(const ScopedObjectAccessAlreadyRunnable& soa, jobject o
InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
if (is_string_init) {
// For string init, remap original receiver to StringFactory result.
- soa.Self()->GetJniEnv()->locals.Update(obj, result.GetL());
+ UpdateReference(soa.Self(), obj, result.GetL());
}
return result;
}
@@ -525,7 +525,7 @@ JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccessAlreadyRunnab
InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
if (is_string_init) {
// For string init, remap original receiver to StringFactory result.
- soa.Self()->GetJniEnv()->locals.Update(obj, result.GetL());
+ UpdateReference(soa.Self(), obj, result.GetL());
}
return result;
}
@@ -556,7 +556,7 @@ JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccessAlreadyRunnab
InvokeWithArgArray(soa, method, &arg_array, &result, shorty);
if (is_string_init) {
// For string init, remap original receiver to StringFactory result.
- soa.Self()->GetJniEnv()->locals.Update(obj, result.GetL());
+ UpdateReference(soa.Self(), obj, result.GetL());
}
return result;
}
@@ -882,4 +882,21 @@ void InvalidReceiverError(mirror::Object* o, mirror::Class* c) {
actual_class_name.c_str()).c_str());
}
+// This only works if there's one reference which points to the object in obj.
+// Will need to be fixed if there's cases where it's not.
+void UpdateReference(Thread* self, jobject obj, mirror::Object* result) {
+ IndirectRef ref = reinterpret_cast<IndirectRef>(obj);
+ IndirectRefKind kind = GetIndirectRefKind(ref);
+ if (kind == kLocal) {
+ self->GetJniEnv()->locals.Update(obj, result);
+ } else if (kind == kHandleScopeOrInvalid) {
+ LOG(FATAL) << "Unsupported UpdateReference for kind kHandleScopeOrInvalid";
+ } else if (kind == kGlobal) {
+ self->GetJniEnv()->vm->UpdateGlobal(self, ref, result);
+ } else {
+ DCHECK_EQ(kind, kWeakGlobal);
+ self->GetJniEnv()->vm->UpdateWeakGlobal(self, ref, result);
+ }
+}
+
} // namespace art