SF.net SVN: jikesrvm:[15712] rvmroot/trunk

View: New views
1 Messages — Rating Filter:   Alert me  

SF.net SVN: jikesrvm:[15712] rvmroot/trunk

by dgrove-oss :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Revision: 15712
          http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15712&view=rev
Author:   dgrove-oss
Date:     2009-06-18 02:29:11 +0000 (Thu, 18 Jun 2009)

Log Message:
-----------
RVM-831 : Fix bugs in GetFieldId and GetStaticField id.  Code wasn't traversing inheritance hierarchy in proper fashion, which could result in the wrong instance field being found (if an instance field was shadowed) and in not finding static fields declared in superclasses/interfaces.

Also added modified test cases provided in the JIRA by BK to jni test suite.

Modified Paths:
--------------
    rvmroot/trunk/rvm/src/org/jikesrvm/jni/JNIFunctions.java
    rvmroot/trunk/testing/tests/jni/build.xml

Added Paths:
-----------
    rvmroot/trunk/testing/tests/jni/src/TestJNIGetFieldID.c
    rvmroot/trunk/testing/tests/jni/src/TestJNIGetFieldID.java

Modified: rvmroot/trunk/rvm/src/org/jikesrvm/jni/JNIFunctions.java
===================================================================
--- rvmroot/trunk/rvm/src/org/jikesrvm/jni/JNIFunctions.java 2009-06-16 10:41:03 UTC (rev 15711)
+++ rvmroot/trunk/rvm/src/org/jikesrvm/jni/JNIFunctions.java 2009-06-18 02:29:11 UTC (rev 15712)
@@ -2238,9 +2238,12 @@
       String descriptorString = JNIHelpers.createStringFromC(descriptorAddress);
       Atom descriptor = Atom.findOrCreateAsciiAtom(descriptorString);
 
-      // list of all instance fields including superclasses
+      // list of all instance fields including superclasses.
+      // Iterate in reverse order since if there are multiple instance
+      // fields of the same name & descriptor we want to find the most derived one.
       RVMField[] fields = java.lang.JikesRVMSupport.getTypeForClass(cls).getInstanceFields();
-      for (RVMField f : fields) {
+      for (int i = fields.length-1; i>=0; i--) {
+        RVMField f = fields[i];
         if (f.getName() == fieldName && f.getDescriptor() == descriptor) {
           return f.getId();
         }
@@ -3434,12 +3437,24 @@
       String descriptorString = JNIHelpers.createStringFromC(descriptorAddress);
       Atom descriptor = Atom.findOrCreateAsciiAtom(descriptorString);
 
-      // list of all instance fields including superclasses
-      RVMField[] fields = java.lang.JikesRVMSupport.getTypeForClass(cls).getStaticFields();
-      for (RVMField field : fields) {
-        if (field.getName() == fieldName && field.getDescriptor() == descriptor) {
-          return field.getId();
+      RVMType rvmType = java.lang.JikesRVMSupport.getTypeForClass(cls);
+      if (rvmType.isClassType()) {
+        // First search for the fields in the class and its superclasses
+        for (RVMClass curClass = rvmType.asClass(); curClass != null; curClass = curClass.getSuperClass()) {
+          for (RVMField field : curClass.getStaticFields()) {
+            if (field.getName() == fieldName && field.getDescriptor() == descriptor) {
+              return field.getId();
+            }
+          }
         }
+        // Now search all implemented interfaces (includes inherited interfaces)
+        for (RVMClass curClass : rvmType.asClass().getAllImplementedInterfaces()) {
+          for (RVMField field : curClass.getStaticFields()) {
+            if (field.getName() == fieldName && field.getDescriptor() == descriptor) {
+              return field.getId();
+            }
+          }
+        }
       }
 
       env.recordException(new NoSuchFieldError(fieldString + ", " + descriptorString + " of " + cls));

Modified: rvmroot/trunk/testing/tests/jni/build.xml
===================================================================
--- rvmroot/trunk/testing/tests/jni/build.xml 2009-06-16 10:41:03 UTC (rev 15711)
+++ rvmroot/trunk/testing/tests/jni/build.xml 2009-06-18 02:29:11 UTC (rev 15712)
@@ -103,6 +103,7 @@
 
     <!-- JNI 1.4 -->
     <jniTest class="TestJNIDirectBuffers"/>
+    <jniTest class="TestJNIGetFieldID"/>
 
     <finishResults/>
   </target>

Added: rvmroot/trunk/testing/tests/jni/src/TestJNIGetFieldID.c
===================================================================
--- rvmroot/trunk/testing/tests/jni/src/TestJNIGetFieldID.c                        (rev 0)
+++ rvmroot/trunk/testing/tests/jni/src/TestJNIGetFieldID.c 2009-06-18 02:29:11 UTC (rev 15712)
@@ -0,0 +1,36 @@
+/*
+ *  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.
+ */
+
+#include <jni.h>
+
+JNIEXPORT jint JNICALL Java_TestJNIGetFieldID_getInstanceFieldA(JNIEnv *env, jclass clazz, jobject o)
+{
+  jclass o_clazz = (*env)->GetObjectClass(env, o);
+  jfieldID fid = (*env)->GetFieldID(env, o_clazz, "a", "I");
+  if (fid == NULL) {return 0;}
+  return (*env)->GetIntField(env, o, fid);
+}
+
+JNIEXPORT jint JNICALL Java_TestJNIGetFieldID_getStaticFieldS(JNIEnv *env, jclass clazz, jclass b_clazz)
+{
+  jfieldID fid = (*env)->GetStaticFieldID(env, b_clazz, "s", "I");
+  if (fid == NULL) {return 0;}
+  return (*env)->GetStaticIntField(env, b_clazz, fid);
+}
+
+JNIEXPORT jint JNICALL Java_TestJNIGetFieldID_getStaticFinalF(JNIEnv *env, jclass clazz, jclass b_clazz)
+{
+  jfieldID fid = (*env)->GetStaticFieldID(env, b_clazz, "f", "I");
+  if (fid == NULL) {return 0;}
+  return (*env)->GetStaticIntField(env, b_clazz, fid);
+}


Property changes on: rvmroot/trunk/testing/tests/jni/src/TestJNIGetFieldID.c
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native

Added: rvmroot/trunk/testing/tests/jni/src/TestJNIGetFieldID.java
===================================================================
--- rvmroot/trunk/testing/tests/jni/src/TestJNIGetFieldID.java                        (rev 0)
+++ rvmroot/trunk/testing/tests/jni/src/TestJNIGetFieldID.java 2009-06-18 02:29:11 UTC (rev 15712)
@@ -0,0 +1,87 @@
+/*
+ *  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.
+ */
+
+public class TestJNIGetFieldID {
+  static {System.loadLibrary("TestJNIGetFieldID");}
+
+  // set to true to get messages for each test
+  static boolean verbose = true;
+  static boolean allTestPass = true;
+
+  static class A {
+    public static int s = 1;
+    public int a = 0;
+  }
+
+  static interface I {
+    int f = 1;
+  }
+
+  static class B extends A implements I {
+    public int a = 1;
+  }
+
+  public static void main(String[] args) {
+    if (args.length!=0) {
+      if (args[0].equals("-quiet")) {
+        verbose = false;
+      }
+    }
+
+    try {
+      if (getInstanceFieldA(new B()) == 1) {
+        if (verbose) System.out.println("instance_a: pass");
+      } else {
+        if (verbose) System.out.println("instance_a: fail");
+        allTestPass = false;
+      }
+    } catch(Throwable e) {
+      if (verbose) System.out.println("instance_a: fail");
+      allTestPass = false;
+    }
+
+    try {
+      if (getStaticFieldS(B.class) == 1) {
+        if (verbose) System.out.println("static_s: pass");
+      } else {
+        if (verbose) System.out.println("static_s: fail");
+        allTestPass = false;
+      }
+    } catch(Throwable e) {
+      if (verbose) System.out.println("static_s: fail");
+      allTestPass = false;
+    }
+
+    try {
+      if (getStaticFinalF(B.class) == 1) {
+        if (verbose) System.out.println("static_f: pass");
+      } else {
+        if (verbose) System.out.println("static_f: fail");
+        allTestPass = false;
+      }
+    } catch(Throwable e) {
+      if (verbose) System.out.println("static_f: fail");
+      allTestPass = false;
+    }
+
+    if (allTestPass) {
+      System.out.println("PASS: TestJNIGetFieldID");
+    } else {
+      System.out.println("FAIL: TestJNIGetFieldID");
+    }
+  }
+
+  private static native int getInstanceFieldA(B b);
+  private static native int getStaticFieldS(Class c);
+  private static native int getStaticFinalF(Class c);
+}


Property changes on: rvmroot/trunk/testing/tests/jni/src/TestJNIGetFieldID.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.

------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________
Jikesrvm-commits mailing list
Jikesrvm-commits@...
https://lists.sourceforge.net/lists/listinfo/jikesrvm-commits