Reland "JNI: Do not inhibit GC in GetStringCritical for compressed string."
It was accidentally reverted in https://r.android.com/1434215.
(cherry-pick of b2568693d783d53aa80f71fde4715995a1f695cc)
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Change-Id: I7a4953ccde5bf4af1b697545c125ad9bdbe18088
diff --git a/runtime/jni/jni_internal.cc b/runtime/jni/jni_internal.cc
index a2e4f22..9e4cc7d 100644
--- a/runtime/jni/jni_internal.cc
+++ b/runtime/jni/jni_internal.cc
@@ -1915,17 +1915,6 @@
ScopedObjectAccess soa(env);
ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
gc::Heap* heap = Runtime::Current()->GetHeap();
- if (heap->IsMovableObject(s)) {
- StackHandleScope<1> hs(soa.Self());
- HandleWrapperObjPtr<mirror::String> h(hs.NewHandleWrapper(&s));
- if (!kUseReadBarrier) {
- heap->IncrementDisableMovingGC(soa.Self());
- } else {
- // For the CC collector, we only need to wait for the thread flip rather than the whole GC
- // to occur thanks to the to-space invariant.
- heap->IncrementDisableThreadFlip(soa.Self());
- }
- }
if (s->IsCompressed()) {
if (is_copy != nullptr) {
*is_copy = JNI_TRUE;
@@ -1937,6 +1926,17 @@
}
return chars;
} else {
+ if (heap->IsMovableObject(s)) {
+ StackHandleScope<1> hs(soa.Self());
+ HandleWrapperObjPtr<mirror::String> h(hs.NewHandleWrapper(&s));
+ if (!kUseReadBarrier) {
+ heap->IncrementDisableMovingGC(soa.Self());
+ } else {
+ // For the CC collector, we only need to wait for the thread flip rather
+ // than the whole GC to occur thanks to the to-space invariant.
+ heap->IncrementDisableThreadFlip(soa.Self());
+ }
+ }
if (is_copy != nullptr) {
*is_copy = JNI_FALSE;
}
@@ -1951,14 +1951,16 @@
ScopedObjectAccess soa(env);
gc::Heap* heap = Runtime::Current()->GetHeap();
ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
- if (heap->IsMovableObject(s)) {
+ if (!s->IsCompressed() && heap->IsMovableObject(s)) {
if (!kUseReadBarrier) {
heap->DecrementDisableMovingGC(soa.Self());
} else {
heap->DecrementDisableThreadFlip(soa.Self());
}
}
- if (s->IsCompressed() || (s->IsCompressed() == false && s->GetValue() != chars)) {
+ // TODO: For uncompressed strings GetStringCritical() always returns `s->GetValue()`.
+ // Should we report an error if the user passes a different `chars`?
+ if (s->IsCompressed() || (!s->IsCompressed() && s->GetValue() != chars)) {
delete[] chars;
}
}