summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2014-11-15 13:07:39 -0800
committerMathieu Chartier <mathieuc@google.com>2014-11-17 10:16:34 -0800
commit41da59665556e8dd5601178185c68d48d645500b (patch)
treec1f8b5844e3243907a060f663c35370464328609 /runtime
parent410709facb361c5503c7825f01edd264f4450666 (diff)
downloadandroid_art-41da59665556e8dd5601178185c68d48d645500b.tar.gz
android_art-41da59665556e8dd5601178185c68d48d645500b.tar.bz2
android_art-41da59665556e8dd5601178185c68d48d645500b.zip
Fix reference leaks in ToReflectedMethod and ToReflectedField
Used ScopedLocalRef to fix, added regression tests. Bug: 18396311 (cherry picked from commit 8c41753e5eda8322b4d992fe88855058f4c0c2e1) Change-Id: I0ddfc20ac2384c90ff18586242c1f1d9a6d6eb6d
Diffstat (limited to 'runtime')
-rw-r--r--runtime/jni_internal.cc8
-rw-r--r--runtime/jni_internal_test.cc10
2 files changed, 14 insertions, 4 deletions
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index 3b0656e4c6..1dcfcabf9d 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -360,7 +360,7 @@ class JNI {
ScopedObjectAccess soa(env);
mirror::ArtMethod* m = soa.DecodeMethod(mid);
CHECK(!kMovingMethods);
- jobject art_method = soa.AddLocalReference<jobject>(m);
+ ScopedLocalRef<jobject> art_method(env, soa.AddLocalReference<jobject>(m));
jobject reflect_method;
if (m->IsConstructor()) {
reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Constructor);
@@ -371,7 +371,7 @@ class JNI {
return nullptr;
}
SetObjectField(env, reflect_method,
- WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod, art_method);
+ WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod, art_method.get());
return reflect_method;
}
@@ -379,13 +379,13 @@ class JNI {
CHECK_NON_NULL_ARGUMENT(fid);
ScopedObjectAccess soa(env);
mirror::ArtField* f = soa.DecodeField(fid);
- jobject art_field = soa.AddLocalReference<jobject>(f);
+ ScopedLocalRef<jobject> art_field(env, soa.AddLocalReference<jobject>(f));
jobject reflect_field = env->AllocObject(WellKnownClasses::java_lang_reflect_Field);
if (env->ExceptionCheck()) {
return nullptr;
}
SetObjectField(env, reflect_field,
- WellKnownClasses::java_lang_reflect_Field_artField, art_field);
+ WellKnownClasses::java_lang_reflect_Field_artField, art_field.get());
return reflect_field;
}
diff --git a/runtime/jni_internal_test.cc b/runtime/jni_internal_test.cc
index ccad137164..e5923deb6f 100644
--- a/runtime/jni_internal_test.cc
+++ b/runtime/jni_internal_test.cc
@@ -799,6 +799,11 @@ TEST_F(JniInternalTest, FromReflectedField_ToReflectedField) {
ASSERT_NE(fid, nullptr);
// Turn the fid into a java.lang.reflect.Field...
jobject field = env_->ToReflectedField(c, fid, JNI_FALSE);
+ for (size_t i = 0; i <= 512; ++i) {
+ // Regression test for b/18396311, ToReflectedField leaking local refs causing a local
+ // reference table overflows with 512 references to ArtField
+ env_->DeleteLocalRef(env_->ToReflectedField(c, fid, JNI_FALSE));
+ }
ASSERT_NE(c, nullptr);
ASSERT_TRUE(env_->IsInstanceOf(field, jlrField));
// ...and back again.
@@ -825,6 +830,11 @@ TEST_F(JniInternalTest, FromReflectedMethod_ToReflectedMethod) {
ASSERT_NE(mid, nullptr);
// Turn the mid into a java.lang.reflect.Constructor...
jobject method = env_->ToReflectedMethod(c, mid, JNI_FALSE);
+ for (size_t i = 0; i <= 512; ++i) {
+ // Regression test for b/18396311, ToReflectedMethod leaking local refs causing a local
+ // reference table overflows with 512 references to ArtMethod
+ env_->DeleteLocalRef(env_->ToReflectedMethod(c, mid, JNI_FALSE));
+ }
ASSERT_NE(method, nullptr);
ASSERT_TRUE(env_->IsInstanceOf(method, jlrConstructor));
// ...and back again.