ART: Fix string reporting
Correctly report zero-length strings.
Bug: 31385354
Test: m test-art-host-run-test-906-iterate-heap
Test: m test-art-host-run-test-913-heaps
Change-Id: Ic37d5c4b350cc8d04faebec54494ed6fe19eece8
diff --git a/runtime/openjdkjvmti/ti_heap.cc b/runtime/openjdkjvmti/ti_heap.cc
index 976ce66..c7294a9 100644
--- a/runtime/openjdkjvmti/ti_heap.cc
+++ b/runtime/openjdkjvmti/ti_heap.cc
@@ -50,25 +50,28 @@
if (UNLIKELY(cb->string_primitive_value_callback != nullptr) && obj->IsString()) {
art::ObjPtr<art::mirror::String> str = obj->AsString();
int32_t string_length = str->GetLength();
- jvmtiError alloc_error;
- JvmtiUniquePtr<uint16_t[]> data = AllocJvmtiUniquePtr<uint16_t[]>(env,
- string_length,
- &alloc_error);
- if (data == nullptr) {
- // TODO: Not really sure what to do here. Should we abort the iteration and go all the way
- // back? For now just warn.
- LOG(WARNING) << "Unable to allocate buffer for string reporting! Silently dropping value.";
- return 0;
- }
+ JvmtiUniquePtr<uint16_t[]> data;
- if (str->IsCompressed()) {
- uint8_t* compressed_data = str->GetValueCompressed();
- for (int32_t i = 0; i != string_length; ++i) {
- data[i] = compressed_data[i];
+ if (string_length > 0) {
+ jvmtiError alloc_error;
+ data = AllocJvmtiUniquePtr<uint16_t[]>(env, string_length, &alloc_error);
+ if (data == nullptr) {
+ // TODO: Not really sure what to do here. Should we abort the iteration and go all the way
+ // back? For now just warn.
+ LOG(WARNING) << "Unable to allocate buffer for string reporting! Silently dropping value."
+ << " >" << str->ToModifiedUtf8() << "<";
+ return 0;
}
- } else {
- // Can copy directly.
- memcpy(data.get(), str->GetValue(), string_length * sizeof(uint16_t));
+
+ if (str->IsCompressed()) {
+ uint8_t* compressed_data = str->GetValueCompressed();
+ for (int32_t i = 0; i != string_length; ++i) {
+ data[i] = compressed_data[i];
+ }
+ } else {
+ // Can copy directly.
+ memcpy(data.get(), str->GetValue(), string_length * sizeof(uint16_t));
+ }
}
const jlong class_tag = tag_table->GetTagOrZero(obj->GetClass());
diff --git a/test/913-heaps/expected.txt b/test/913-heaps/expected.txt
index 46805d7..c96edef 100644
--- a/test/913-heaps/expected.txt
+++ b/test/913-heaps/expected.txt
@@ -79,8 +79,9 @@
5@1002 --(field@28)--> 1@1000 [size=16, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
-[1@0 (32, 'HelloWorld')]
+[1@0 (32, 'HelloWorld'), 2@0 (16, '')]
2
+3
2@0 (15, 3xB '010203')
3@0 (16, 2xC '41005a00')
8@0 (32, 2xD '0000000000000000000000000000f03f')
@@ -128,7 +129,6 @@
---- untagged objects
root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestNonRoot,vreg=13,location= 32])--> 1@1000 [size=16, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vreg=1,location= 28])--> 3000@0 [size=132, length=-1]
-root@root --(system-class)--> 2@0 [size=32, length=-1]
root@root --(thread)--> 3000@0 [size=132, length=-1]
0@0 --(array-element@0)--> 1@1000 [size=16, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
@@ -170,7 +170,6 @@
root@root --(stack-local[id=1,tag=3000,depth=1,method=doFollowReferencesTestImpl,vreg=13,location= 10])--> 1@1000 [size=16, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=1,method=doFollowReferencesTestImpl,vreg=5,location= 10])--> 1@1000 [size=16, length=-1]
root@root --(stack-local[id=1,tag=3000,depth=2,method=doFollowReferencesTestRoot,vreg=4,location= 19])--> 1@1000 [size=16, length=-1]
-root@root --(system-class)--> 2@0 [size=32, length=-1]
root@root --(thread)--> 1@1000 [size=16, length=-1]
root@root --(thread)--> 3000@0 [size=132, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
@@ -209,7 +208,6 @@
---
---- tagged classes
root@root --(stack-local[id=1,tag=3000,depth=3,method=doFollowReferencesTest,vreg=1,location= 28])--> 3000@0 [size=132, length=-1]
-root@root --(system-class)--> 2@0 [size=32, length=-1]
root@root --(thread)--> 3000@0 [size=132, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
1002@0 --(interface)--> 2001@0 [size=124, length=-1]
@@ -233,7 +231,6 @@
5@1002 --(class)--> 1002@0 [size=123, length=-1]
6@1000 --(class)--> 1000@0 [size=123, length=-1]
---
-root@root --(system-class)--> 2@0 [size=32, length=-1]
root@root --(thread)--> 3000@0 [size=132, length=-1]
1001@0 --(superclass)--> 1000@0 [size=123, length=-1]
1002@0 --(interface)--> 2001@0 [size=124, length=-1]
diff --git a/test/913-heaps/src/Main.java b/test/913-heaps/src/Main.java
index df89f34..14ee268 100644
--- a/test/913-heaps/src/Main.java
+++ b/test/913-heaps/src/Main.java
@@ -25,9 +25,19 @@
doTest();
new TestConfig().doFollowReferencesTest();
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().gc();
+
doStringTest();
+
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().gc();
+
doPrimitiveArrayTest();
+ Runtime.getRuntime().gc();
+ Runtime.getRuntime().gc();
+
// Test klass filter.
System.out.println("--- klass ---");
new TestConfig(A.class, 0).doFollowReferencesTest();
@@ -53,14 +63,18 @@
}
public static void doStringTest() throws Exception {
- final String str = "HelloWorld";
+ final String str = new String("HelloWorld");
+ final String str2 = new String("");
Object o = new Object() {
String s = str;
+ String s2 = str2;
};
setTag(str, 1);
+ setTag(str2, 2);
System.out.println(Arrays.toString(followReferencesString(o)));
System.out.println(getTag(str));
+ System.out.println(getTag(str2));
}
public static void doPrimitiveArrayTest() throws Exception {