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

(cherry picked from commit 15e9ad1d028d7f12cb598b075453173532a00d91)

Change-Id: I3421c43722c07397da4a398c2ca9110e1d40bcfa
diff --git a/test/020-string/src/Main.java b/test/020-string/src/Main.java
index bb8ce1f..b876e6a 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 static void main(String args[]) {
         basicTest();
         indexTest();
+        constructorTest();
     }
 
     public static void basicTest() {
@@ -81,4 +85,36 @@
             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);
+    }
 }