/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Eclipse Public License (EPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/eclipse-1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ class ArrayFunctions { static boolean verbose = true; // set to true to get messages for each test static boolean allTestPass = true; static int[] intArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; static boolean[] booleanArray = {true, true, false, false, true, true, false, false, true, true}; static short[] shortArray = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}; static byte[] byteArray = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20}; static char[] charArray = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}; static long[] longArray = {0x80001000, 0x80001000, 0x80001000, 0x80001000, 0x80001000, 0x80001000, 0x80001000, 0x80001000, 0x80001000, 0x80001000}; static double[] doubleArray = {115.1, 115.1, 115.1, 115.1, 115.1, 115.1, 115.1, 115.1, 115.1, 115.1}; static float[] floatArray = {(float) 115.1, (float) 115.1, (float) 115.1, (float) 115.1, (float) 115.1, (float) 115.1, (float) 115.1, (float) 115.1, (float) 115.1, (float) 115.1}; public static native void setVerboseOff(); /** * Declare native methods that will call the JNI Array Functions */ static native int[] accessNewIntArray(int length); static native boolean[] accessNewBooleanArray(int length); static native short[] accessNewShortArray(int length); static native byte[] accessNewByteArray(int length); static native char[] accessNewCharArray(int length); static native long[] accessNewLongArray(int length); static native double[] accessNewDoubleArray(int length); static native float[] accessNewFloatArray(int length); static native Object[] accessNewObjectArray(int length, Class<?> cls, Object initElement); static native int[] testIntArrayRegion(int[] sourceArray); static native boolean[] testBooleanArrayRegion(boolean[] sourceArray); static native short[] testShortArrayRegion(short[] sourceArray); static native byte[] testByteArrayRegion(byte[] sourceArray); static native char[] testCharArrayRegion(char[] sourceArray); static native long[] testLongArrayRegion(long[] sourceArray); static native double[] testDoubleArrayRegion(double[] sourceArray); static native float[] testFloatArrayRegion(float[] sourceArray); static native int[] testIntArrayElements(int[] sourceArray, int testMode); static native boolean[] testBooleanArrayElements(boolean[] sourceArray, int testMode); static native short[] testShortArrayElements(short[] sourceArray, int testMode); static native byte[] testByteArrayElements(byte[] sourceArray, int testMode); static native char[] testCharArrayElements(char[] sourceArray, int testMode); static native long[] testLongArrayElements(long[] sourceArray, int testMode); static native double[] testDoubleArrayElements(double[] sourceArray, int testMode); static native float[] testFloatArrayElements(float[] sourceArray, int testMode); static native Object testObjectArrayElement(Object[] sourceArray, Object toAssign, int index); static native int testArrayLength(int[] sourceArray); static native boolean lastGetArrayElementsWasCopy(); /*******************************************************/ public static boolean testObjectArray() { String[] objectArray = new String[10]; for (int i=0; i<objectArray.length; i++) objectArray[i] = new String("object " + i); String toAssign = new String("yet another one"); Object returnObject = testObjectArrayElement(objectArray, toAssign, 7); return ((String)returnObject).equals("object 7") && objectArray[7]==toAssign; } /*******************************************************/ public static boolean testBooleanArray() { boolean arrayFlag = true; boolean updateSucceeded, wasCopied; // first part: update but don't release the copy for (int i=0; i<booleanArray.length; i++) booleanArray[i] = false; boolean [] returnArray = testBooleanArrayElements(booleanArray, 0); wasCopied = lastGetArrayElementsWasCopy(); if (verbose) System.out.println("INFO: GetBooleanArrayElements "+ (wasCopied ? "copied" : "did not copy")+" the array"); updateSucceeded = (returnArray[0] && !returnArray[1] && returnArray[2] && !returnArray[3] && returnArray[4] && !returnArray[5] && returnArray[6] && !returnArray[7] && returnArray[8] && !returnArray[9]); if (verbose) System.out.println("INFO: update(1) "+(updateSucceeded ? "succeeded" : "failed")); arrayFlag &= updateSucceeded; // second part: update and release the copy for (int i=0; i<booleanArray.length; i++) booleanArray[i] = false; returnArray = testBooleanArrayElements(booleanArray, 1); updateSucceeded = (!returnArray[0] && returnArray[1] && !returnArray[2] && returnArray[3] && !returnArray[4] && returnArray[5] && !returnArray[6] && returnArray[7] && !returnArray[8] && returnArray[9]); // Should always succeed if (verbose) System.out.println("INFO: update(2) "+(updateSucceeded ? "succeeded" : "failed")); arrayFlag &= updateSucceeded; // third part: release the copy with no update for (int i=0; i<booleanArray.length; i++) booleanArray[i] = true; returnArray = testBooleanArrayElements(booleanArray, 2); wasCopied = lastGetArrayElementsWasCopy(); updateSucceeded = !(returnArray[0] && returnArray[1] && returnArray[2] && returnArray[3] && returnArray[4] && returnArray[5] && returnArray[6] && returnArray[7] && returnArray[8] && returnArray[9]); if (verbose) System.out.println("INFO: update(3) "+(updateSucceeded ? "succeeded" : "failed")); arrayFlag &= updateSucceeded != wasCopied; return arrayFlag; } /*******************************************************/ public static boolean testByteArray() { boolean arrayFlag = true; boolean wasCopied; // first part: update but don't release the copy for (int i=0; i<byteArray.length; i++) byteArray[i] = (byte) i; byte [] returnArray = testByteArrayElements(byteArray, 0); wasCopied = lastGetArrayElementsWasCopy(); if (verbose) System.out.println("INFO: GetByteArrayElements "+ (wasCopied ? "copied" : "did not copy")+" the array"); for (int i=0; i<returnArray.length; i++) { //if (verbose) System.out.println(" first: " + i + " = " + returnArray[i]); if (returnArray[i]!=((byte) (i+4))) arrayFlag = false; } // second part: update and release the copy /* If the array is copied, this will have no effect */ for (int i=0; i<byteArray.length; i++) byteArray[i] = (byte) i; returnArray = testByteArrayElements(byteArray, 1); for (int i=0; i<returnArray.length; i++) { //if (verbose) System.out.println(" second: " + i + " = " + returnArray[i]); if (returnArray[i]!=((byte) (i+(wasCopied ? 9 : 5)))) arrayFlag = false; } // third part: release the copy with no update for (int i=0; i<byteArray.length; i++) byteArray[i] = (byte) i; returnArray = testByteArrayElements(byteArray, 2); wasCopied = lastGetArrayElementsWasCopy(); for (int i=0; i<returnArray.length; i++) { //if (verbose) System.out.println(" third: " + i + " = " + returnArray[i]); if (returnArray[i]!=(byte) i + (wasCopied ? 0 : 6)) arrayFlag = false; } return arrayFlag; } /*******************************************************/ public static boolean testIntArray() { boolean arrayFlag = true; boolean wasCopied; // first part: update but don't release the copy for (int i=0; i<intArray.length; i++) intArray[i] = i; int [] returnIntArray = testIntArrayElements(intArray, 0); wasCopied = lastGetArrayElementsWasCopy(); if (verbose) System.out.println("INFO: GetIntArrayElements "+ (wasCopied ? "copied" : "did not copy")+" the array"); for (int i=0; i<returnIntArray.length; i++) { // System.out.println(" first: " + i + " = " + returnIntArray[i]); if (returnIntArray[i]!=i+1) arrayFlag = false; } // second part: update and release the copy for (int i=0; i<intArray.length; i++) intArray[i] = i; returnIntArray = testIntArrayElements(intArray, 1); for (int i=0; i<returnIntArray.length; i++) { // System.out.println(" second: " + i + " = " + returnIntArray[i]); if (returnIntArray[i]!=i+(wasCopied ? 3 : 2)) arrayFlag = false; } // third part: release the copy with no update for (int i=0; i<intArray.length; i++) intArray[i] = i; returnIntArray = testIntArrayElements(intArray, 2); wasCopied = lastGetArrayElementsWasCopy(); for (int i=0; i<returnIntArray.length; i++) { // System.out.println(" third: " + i + " = " + returnIntArray[i]); if (returnIntArray[i]!= i + (wasCopied ? 0 : 3)) arrayFlag = false; } return arrayFlag; } /*******************************************************/ public static boolean testShortArray() { boolean arrayFlag = true; boolean wasCopied; // first part: update but don't release the copy for (int i=0; i<shortArray.length; i++) shortArray[i] = (short) i; short [] returnArray = testShortArrayElements(shortArray, 0); wasCopied = lastGetArrayElementsWasCopy(); if (verbose) System.out.println("INFO: GetShortArrayElements "+ (lastGetArrayElementsWasCopy() ? "copied" : "did not copy")+" the array"); for (int i=0; i<returnArray.length; i++) { // System.out.println(" first: " + i + " = " + returnArray[i]); if (returnArray[i]!=i+7) arrayFlag = false; } // second part: update and release the copy for (int i=0; i<shortArray.length; i++) shortArray[i] = (short) i; returnArray = testShortArrayElements(shortArray, 1); for (int i=0; i<returnArray.length; i++) { // System.out.println(" second: " + i + " = " + returnArray[i]); if (returnArray[i]!=i+(wasCopied ? 15 : 8)) arrayFlag = false; } // third part: release the copy with no update for (int i=0; i<shortArray.length; i++) shortArray[i] = (short) i; returnArray = testShortArrayElements(shortArray, 2); wasCopied = lastGetArrayElementsWasCopy(); for (int i=0; i<returnArray.length; i++) { // System.out.println(" third: " + i + " = " + returnArray[i]); if (returnArray[i]!=i + (wasCopied ? 0 : 9)) arrayFlag = false; } return arrayFlag; } /*******************************************************/ public static boolean testCharArray() { boolean arrayFlag = true; boolean wasCopied; // first part: update but don't release the copy for (int i=0; i<charArray.length; i++) charArray[i] = 'a'; char [] returnArray = testCharArrayElements(charArray, 0); wasCopied = lastGetArrayElementsWasCopy(); if (verbose) System.out.println("INFO: GetCharArrayElements "+ (lastGetArrayElementsWasCopy() ? "copied" : "did not copy")+" the array"); if (returnArray[0]!='a' || returnArray[1]!='b' || returnArray[2]!='c' || returnArray[3]!='d' || returnArray[4]!='e' || returnArray[5]!='f' || returnArray[6]!='g' || returnArray[7]!='h' || returnArray[8]!='i' || returnArray[9]!='j') arrayFlag = false; // second part: update and release the copy for (int i=0; i<charArray.length; i++) charArray[i] = 'b'; returnArray = testCharArrayElements(charArray, 1); if (returnArray[0]!='j' || returnArray[1]!='a' || returnArray[2]!='l' || returnArray[3]!='e' || returnArray[4]!='p' || returnArray[5]!='e' || returnArray[6]!='n' || returnArray[7]!='o' || returnArray[8]!='v' || returnArray[9]!='m') arrayFlag = false; // third part: release the copy with no update for (int i=0; i<charArray.length; i++) charArray[i] = 'c'; returnArray = testCharArrayElements(charArray, 2); wasCopied = lastGetArrayElementsWasCopy(); for (int i=0; i<returnArray.length; i++) { // System.out.println(" third: " + i + " = " + returnArray[i]); if (returnArray[i]!= (wasCopied ? 'c' : 'x')) arrayFlag = false; } return arrayFlag; } /*******************************************************/ public static boolean testLongArray() { boolean arrayFlag = true; boolean wasCopied; // first part: update but don't release the copy for (int i=0; i<longArray.length; i++) longArray[i] = (long) i; long [] returnArray = testLongArrayElements(longArray, 0); wasCopied = lastGetArrayElementsWasCopy(); if (verbose) System.out.println("INFO: GetLongArrayElements "+ (lastGetArrayElementsWasCopy() ? "copied" : "did not copy")+" the array"); for (int i=0; i<returnArray.length; i++) { // System.out.println(" first: " + i + " = " + returnArray[i]); if (returnArray[i]!=((long) i + 10)) arrayFlag = false; } // second part: update and release the copy for (int i=0; i<longArray.length; i++) longArray[i] = (long) i; returnArray = testLongArrayElements(longArray, 1); for (int i=0; i<returnArray.length; i++) { // System.out.println(" second: " + i + " = " + returnArray[i]); if (returnArray[i]!=((long) i + (wasCopied ? 21 : 11))) arrayFlag = false; } // third part: release the copy with no update for (int i=0; i<longArray.length; i++) longArray[i] = (long) i; returnArray = testLongArrayElements(longArray, 2); wasCopied = lastGetArrayElementsWasCopy(); for (int i=0; i<returnArray.length; i++) { // System.out.println(" third: " + i + " = " + returnArray[i]); if (returnArray[i]!=((long) i) + (wasCopied ? 0 : 12)) arrayFlag = false; } return arrayFlag; } /*******************************************************/ public static boolean testFloatArray() { boolean arrayFlag = true; boolean wasCopied; // first part: update but don't release the copy for (int i=0; i<floatArray.length; i++) floatArray[i] = i; float [] returnArray = testFloatArrayElements(floatArray, 0); wasCopied = lastGetArrayElementsWasCopy(); if (verbose) System.out.println("INFO: GetFloatArrayElements "+ (lastGetArrayElementsWasCopy() ? "copied" : "did not copy")+" the array"); for (int i=0; i<returnArray.length; i++) { // System.out.println(" first: " + i + " = " + returnArray[i]); if (returnArray[i]!=((float)i + 16.0f)) arrayFlag = false; } // second part: update and release the copy for (int i=0; i<floatArray.length; i++) floatArray[i] = i; returnArray = testFloatArrayElements(floatArray, 1); for (int i=0; i<returnArray.length; i++) { // System.out.println(" second: " + i + " = " + returnArray[i]); if (returnArray[i]!=((float)i + (wasCopied ? 33.0f : 17.0f))) arrayFlag = false; } // third part: release the copy with no update for (int i=0; i<floatArray.length; i++) floatArray[i] = i; returnArray = testFloatArrayElements(floatArray, 2); wasCopied = lastGetArrayElementsWasCopy(); for (int i=0; i<returnArray.length; i++) { // System.out.println(" third: " + i + " = " + returnArray[i]); if (returnArray[i]!=(float) i + (wasCopied ? 0f : 18f)) arrayFlag = false; } return arrayFlag; } /*******************************************************/ public static boolean testDoubleArray() { boolean arrayFlag = true; boolean wasCopied; // first part: update but don't release the copy for (int i=0; i<doubleArray.length; i++) doubleArray[i] = (double) i; double [] returnArray = testDoubleArrayElements(doubleArray, 0); wasCopied = lastGetArrayElementsWasCopy(); if (verbose) System.out.println("INFO: GetDoubleArrayElements "+ (lastGetArrayElementsWasCopy() ? "copied" : "did not copy")+" the array"); for (int i=0; i<returnArray.length; i++) { // System.out.println(" first: " + i + " = " + returnArray[i]); if (returnArray[i]!=((double) i + 13.0)) arrayFlag = false; } // second part: update and release the copy for (int i=0; i<doubleArray.length; i++) doubleArray[i] = (double) i; returnArray = testDoubleArrayElements(doubleArray, 1); for (int i=0; i<returnArray.length; i++) { // System.out.println(" second: " + i + " = " + returnArray[i]); if (returnArray[i]!=((double) i + (wasCopied ? 27.0 : 14.0))) arrayFlag = false; } // third part: release the copy with no update for (int i=0; i<shortArray.length; i++) doubleArray[i] = (double) i; returnArray = testDoubleArrayElements(doubleArray, 2); wasCopied = lastGetArrayElementsWasCopy(); for (int i=0; i<returnArray.length; i++) { // System.out.println(" third: " + i + " = " + returnArray[i]); if (returnArray[i]!= (double) i + (wasCopied ? 0.0 : 15.0)) arrayFlag = false; } return arrayFlag; } /** * constructor */ public ArrayFunctions() { } public static void main(String[] args) { int returnValue; Object returnObject; System.loadLibrary("ArrayFunctions"); if (args.length!=0) { if (args[0].equals("-quiet")) { verbose = false; setVerboseOff(); } } /** * Test GetArrayLength */ returnValue = testArrayLength(intArray); checkTest(0, (returnValue==intArray.length), "GetArrayLength"); /** * Test New<type>Array: creating Java array from native */ returnObject = accessNewIntArray(31); // printVerbose("accessNewIntArray returns: " + returnObject.getClass().getName()); checkTest(0, (((int[]) returnObject).length==31) && returnObject.getClass().getName().equals("[I"), "NewIntArray"); returnObject = accessNewBooleanArray(31); // printVerbose("accessNewBooleanArray returns: " + returnObject.getClass().getName()); checkTest(0, (((boolean[]) returnObject).length==31) && returnObject.getClass().getName().equals("[Z"), "NewBooleanArray"); returnObject = accessNewShortArray(31); // printVerbose("accessNewShortArray returns: " + returnObject.getClass().getName()); checkTest(0, (((short[]) returnObject).length==31) && returnObject.getClass().getName().equals("[S"), "NewShortArray"); returnObject = accessNewByteArray(31); // printVerbose("accessNewByteArray returns: " + returnObject.getClass().getName()); checkTest(0, (((byte[]) returnObject).length==31) && returnObject.getClass().getName().equals("[B"), "NewByteArray"); returnObject = accessNewCharArray(31); // printVerbose("accessNewCharArray returns: " + returnObject.getClass().getName()); checkTest(0, (((char[]) returnObject).length==31) && returnObject.getClass().getName().equals("[C"), "NewCharArray"); returnObject = accessNewLongArray(31); // printVerbose("accessNewLongArray returns: " + returnObject.getClass().getName()); checkTest(0, (((long[]) returnObject).length==31) && returnObject.getClass().getName().equals("[J"), "NewLongArray"); returnObject = accessNewFloatArray(31); // printVerbose("accessNewFloatArray returns: " + returnObject.getClass().getName()); checkTest(0, (((float[]) returnObject).length==31) && returnObject.getClass().getName().equals("[F"), "NewFloatArray"); returnObject = accessNewDoubleArray(31); // printVerbose("accessNewDoubleArray returns: " + returnObject.getClass().getName()); checkTest(0, (((double[]) returnObject).length==31) && returnObject.getClass().getName().equals("[D"), "NewDoubleArray"); try { returnObject = accessNewObjectArray(31, Class.forName("java.lang.String"), null); // printVerbose("accessNewObjectArray returns: " + returnObject.getClass().getName()); checkTest(0, (((Object[]) returnObject).length==31) && returnObject.getClass().getName().equals("[Ljava.lang.String;"), "NewObjectArray"); } catch (ClassNotFoundException e) { System.out.println("Cannot run accessNewObjectArray"); } /** * Test Set/Get<type>ArrayRegion: access to array section */ int [] returnIntArray = testIntArrayRegion(intArray); boolean arrayFlag = true; for (int i=0; i<returnIntArray.length; i++) { if (returnIntArray[i]!=i+2) arrayFlag = false; } checkTest(0, arrayFlag, "Get/SetIntArrayRegion"); boolean [] returnBooleanArray = testBooleanArrayRegion(booleanArray); arrayFlag = true; if (returnBooleanArray[0] || returnBooleanArray[1] || returnBooleanArray[4] || returnBooleanArray[5] || returnBooleanArray[8] || returnBooleanArray[9]) arrayFlag = false; if (!returnBooleanArray[2] || !returnBooleanArray[3] || !returnBooleanArray[6] || !returnBooleanArray[7]) arrayFlag = false; checkTest(0, arrayFlag, "Get/SetBooleanArrayRegion"); short[] returnShortArray = testShortArrayRegion(shortArray); arrayFlag = true; for (int i=0; i<returnShortArray.length; i++) { if (returnShortArray[i]!=((i+1)*2)) arrayFlag = false; } checkTest(0, arrayFlag, "Get/SetShortArrayRegion"); byte[] returnByteArray = testByteArrayRegion(byteArray); arrayFlag = true; for (int i=0; i<returnByteArray.length; i++) { if (returnByteArray[i]!=(i*2+3)) arrayFlag = false; } checkTest(0, arrayFlag, "Get/SetByteArrayRegion"); char[] returnCharArray = testCharArrayRegion(charArray); arrayFlag = true; if (returnCharArray[0]!='j' || returnCharArray[1]!='a' || returnCharArray[2]!='l' || returnCharArray[3]!='a' || returnCharArray[4]!='p' || returnCharArray[5]!='e' || returnCharArray[6]!='n' || returnCharArray[7]!='o' || returnCharArray[8]!='v' || returnCharArray[9]!='m') arrayFlag = false; checkTest(0, arrayFlag, "Get/SetCharArrayRegion"); long[] returnLongArray = testLongArrayRegion(longArray); arrayFlag = true; for (int i=0; i<returnLongArray.length; i++) { if (returnLongArray[i]!=0x80001000+i) { printVerbose("Get/SetLongArrayRegion returns: " + i + " = " + Integer.toHexString((int) returnLongArray[i]>>32) + " " + Integer.toHexString((int) returnLongArray[i])); arrayFlag = false; } } checkTest(0, arrayFlag, "Get/SetLongArrayRegion"); double[] returnDoubleArray = testDoubleArrayRegion(doubleArray); arrayFlag = true; for (int i=0; i<returnDoubleArray.length; i++) { if (returnDoubleArray[i]!=(115.1 + i)) { printVerbose("Get/SetDoubleArrayRegion returns: " + i + " = " + returnDoubleArray[i]); arrayFlag = false; } } checkTest(0, arrayFlag, "Get/SetDoubleArrayRegion"); float[] returnFloatArray = testFloatArrayRegion(floatArray); arrayFlag = true; for (int i=0; i<returnFloatArray.length; i++) { if (returnFloatArray[i]!=((float) 115.1 + (float) i)) { printVerbose("Get/SetFloatArrayRegion returns: " + i + " = " + returnFloatArray[i]); arrayFlag = false; } } checkTest(0, arrayFlag, "Get/SetFloatArrayRegion"); /** * Test Set/Get<type>ArrayElements: access to entire array */ boolean rc = testIntArray(); checkTest(0, rc, "Get/SetIntArrayElements"); rc = testBooleanArray(); checkTest(0, rc, "Get/SetBooleanArrayElements"); rc = testByteArray(); checkTest(0, rc, "Get/SetByteArrayElements"); rc = testShortArray(); checkTest(0, rc, "Get/SetShortArrayElements"); rc = testCharArray(); checkTest(0, rc, "Get/SetCharArrayElements"); rc = testLongArray(); checkTest(0, rc, "Get/SetLongArrayElements"); rc = testFloatArray(); checkTest(0, rc, "Get/SetFloatArrayElements"); rc = testDoubleArray(); checkTest(0, rc, "Get/SetDoubleArrayElements"); rc = testObjectArray(); checkTest(0, rc, "Get/SetObjectArrayElement"); // Summarize if (allTestPass) System.out.println("PASS: ArrayFunctions"); else System.out.println("FAIL: ArrayFunctions"); } static void printVerbose(String str) { if (verbose) System.out.println(str); } static void checkTest(int returnValue, boolean postCheck, String testName) { if (returnValue==0 && postCheck) { printVerbose("PASS: " + testName); } else { allTestPass = false; printVerbose("FAIL: " + testName); } } }