summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorJeff Hao <jeffhao@google.com>2015-05-19 20:30:23 -0700
committerJeff Hao <jeffhao@google.com>2015-05-20 18:32:14 -0700
commit15e9ad1d028d7f12cb598b075453173532a00d91 (patch)
treef31edd7f7e10d8372c452229b4f9eb749647864f /test
parent5d52f3dca52548f4a4598abd06432cad3dca6b8a (diff)
downloadandroid_art-15e9ad1d028d7f12cb598b075453173532a00d91.tar.gz
android_art-15e9ad1d028d7f12cb598b075453173532a00d91.tar.bz2
android_art-15e9ad1d028d7f12cb598b075453173532a00d91.zip
Intercept JNI invocation of String.<init> methods.
libmono uses JNI AllocObject and CallNonvirtualVoidMethod to create and initialize a string instead of using the recommended NewObject. This change adds an intercept to change the String.<init> call to a StringFactory call instead. Then, it uses the object id of the original string object referrer and maps it to the result of the StringFactory. Bug: 21288130 Change-Id: Ib4db402c178bc37188d5c5faf30b6e4fdc747b17
Diffstat (limited to 'test')
-rw-r--r--test/004-JniTest/jni_test.cc63
-rw-r--r--test/020-string/src/Main.java36
2 files changed, 86 insertions, 13 deletions
diff --git a/test/004-JniTest/jni_test.cc b/test/004-JniTest/jni_test.cc
index cdc546155d..1ec0cf2d43 100644
--- a/test/004-JniTest/jni_test.cc
+++ b/test/004-JniTest/jni_test.cc
@@ -550,21 +550,58 @@ extern "C" void JNICALL Java_Main_testCallNonvirtual(JNIEnv* env, jclass) {
}
extern "C" JNIEXPORT void JNICALL Java_Main_testNewStringObject(JNIEnv* env, jclass) {
- const char* string = "Test";
- int length = strlen(string);
jclass c = env->FindClass("java/lang/String");
- assert(c != NULL);
- jmethodID method = env->GetMethodID(c, "<init>", "([B)V");
- assert(method != NULL);
+ assert(c != nullptr);
+
+ jmethodID mid1 = env->GetMethodID(c, "<init>", "()V");
+ assert(mid1 != nullptr);
+ assert(!env->ExceptionCheck());
+ jmethodID mid2 = env->GetMethodID(c, "<init>", "([B)V");
+ assert(mid2 != nullptr);
+ assert(!env->ExceptionCheck());
+ jmethodID mid3 = env->GetMethodID(c, "<init>", "([C)V");
+ assert(mid3 != nullptr);
+ assert(!env->ExceptionCheck());
+ jmethodID mid4 = env->GetMethodID(c, "<init>", "(Ljava/lang/String;)V");
+ assert(mid4 != nullptr);
assert(!env->ExceptionCheck());
- jbyteArray array = env->NewByteArray(length);
- env->SetByteArrayRegion(array, 0, length, reinterpret_cast<const jbyte*>(string));
- jobject o = env->NewObject(c, method, array);
- assert(o != NULL);
- jstring s = reinterpret_cast<jstring>(o);
- assert(env->GetStringLength(s) == length);
- assert(env->GetStringUTFLength(s) == length);
+
+ const char* test_array = "Test";
+ int byte_array_length = strlen(test_array);
+ jbyteArray byte_array = env->NewByteArray(byte_array_length);
+ env->SetByteArrayRegion(byte_array, 0, byte_array_length, reinterpret_cast<const jbyte*>(test_array));
+
+ // Test NewObject
+ jstring s = reinterpret_cast<jstring>(env->NewObject(c, mid2, byte_array));
+ assert(s != nullptr);
+ assert(env->GetStringLength(s) == byte_array_length);
+ assert(env->GetStringUTFLength(s) == byte_array_length);
const char* chars = env->GetStringUTFChars(s, nullptr);
- assert(strcmp(string, chars) == 0);
+ assert(strcmp(test_array, chars) == 0);
env->ReleaseStringUTFChars(s, chars);
+
+ // Test AllocObject and Call(Nonvirtual)VoidMethod
+ jstring s1 = reinterpret_cast<jstring>(env->AllocObject(c));
+ assert(s1 != nullptr);
+ jstring s2 = reinterpret_cast<jstring>(env->AllocObject(c));
+ assert(s2 != nullptr);
+ jstring s3 = reinterpret_cast<jstring>(env->AllocObject(c));
+ assert(s3 != nullptr);
+ jstring s4 = reinterpret_cast<jstring>(env->AllocObject(c));
+ assert(s4 != nullptr);
+
+ jcharArray char_array = env->NewCharArray(5);
+ jstring string_arg = env->NewStringUTF("helloworld");
+
+ // With Var Args
+ env->CallVoidMethod(s1, mid1);
+ env->CallNonvirtualVoidMethod(s2, c, mid2, byte_array);
+
+ // With JValues
+ jvalue args3[1];
+ args3[0].l = char_array;
+ jvalue args4[1];
+ args4[0].l = string_arg;
+ env->CallVoidMethodA(s3, mid3, args3);
+ env->CallNonvirtualVoidMethodA(s4, c, mid4, args4);
}
diff --git a/test/020-string/src/Main.java b/test/020-string/src/Main.java
index bb8ce1fa51..b876e6ad21 100644
--- a/test/020-string/src/Main.java
+++ b/test/020-string/src/Main.java
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+import java.nio.charset.Charset;
+import java.io.UnsupportedEncodingException;
+
/**
* Simple string test.
*/
@@ -21,6 +24,7 @@ public class Main {
public static void main(String args[]) {
basicTest();
indexTest();
+ constructorTest();
}
public static void basicTest() {
@@ -81,4 +85,36 @@ public class Main {
subStr.indexOf('&') + ":" +
baseStr.indexOf(0x12341234));
}
+
+ public static void constructorTest() {
+ byte[] byteArray = "byteArray".getBytes();
+ char[] charArray = new char[] { 'c', 'h', 'a', 'r', 'A', 'r', 'r', 'a', 'y' };
+ String charsetName = "US-ASCII";
+ Charset charset = Charset.forName("UTF-8");
+ String string = "string";
+ StringBuffer stringBuffer = new StringBuffer("stringBuffer");
+ int [] codePoints = new int[] { 65, 66, 67, 68, 69 };
+ StringBuilder stringBuilder = new StringBuilder("stringBuilder");
+
+ String s1 = new String();
+ String s2 = new String(byteArray);
+ String s3 = new String(byteArray, 1);
+ String s4 = new String(byteArray, 0, 4);
+ String s5 = new String(byteArray, 2, 4, 5);
+
+ try {
+ String s6 = new String(byteArray, 2, 4, charsetName);
+ String s7 = new String(byteArray, charsetName);
+ } catch (UnsupportedEncodingException e) {
+ System.out.println("Got unexpected UnsupportedEncodingException");
+ }
+ String s8 = new String(byteArray, 3, 3, charset);
+ String s9 = new String(byteArray, charset);
+ String s10 = new String(charArray);
+ String s11 = new String(charArray, 0, 4);
+ String s12 = new String(string);
+ String s13 = new String(stringBuffer);
+ String s14 = new String(codePoints, 1, 3);
+ String s15 = new String(stringBuilder);
+ }
}