changeset 21965:0103d237f6c3

Make NodeFieldAccessor more flexible
author Christian Wimmer <christian.wimmer@oracle.com>
date Mon, 22 Jun 2015 10:15:05 -0700
parents 9d15f06f3537
children 5023b913e2ba
files truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java
diffstat 1 files changed, 37 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java	Sat Jun 20 09:01:47 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java	Mon Jun 22 10:15:05 2015 -0700
@@ -53,15 +53,18 @@
     private static final boolean USE_UNSAFE = Boolean.getBoolean("truffle.unsafe");
 
     private final NodeFieldKind kind;
+    private final Class<?> declaringClass;
     private final String name;
     protected final Class<?> type;
+    /* TODO: This field should be moved to UnsafeNodeField. */
     protected final long offset;
 
-    protected NodeFieldAccessor(NodeFieldKind kind, Field field) {
+    protected NodeFieldAccessor(NodeFieldKind kind, Class<?> declaringClass, String name, Class<?> type, long offset) {
         this.kind = kind;
-        this.type = field.getType();
-        this.name = field.getName();
-        this.offset = unsafeFieldOffsetProvider.objectFieldOffset(field);
+        this.declaringClass = declaringClass;
+        this.name = name;
+        this.type = type;
+        this.offset = offset;
     }
 
     protected static NodeFieldAccessor create(NodeFieldKind kind, Field field) {
@@ -80,10 +83,15 @@
         return type;
     }
 
+    public Class<?> getDeclaringClass() {
+        return declaringClass;
+    }
+
     public String getName() {
         return name;
     }
 
+    /* TODO: This method should be removed from here. It should be an abstract method in AbstractUnsafeNodeFieldAccessor, and implemented in UnsafeNodeField. */
     public long getOffset() {
         return offset;
     }
@@ -94,20 +102,6 @@
 
     public abstract Object loadValue(Node node);
 
-    @Override
-    public int hashCode() {
-        return kind.hashCode() | type.hashCode() | name.hashCode() | ((Long) offset).hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof NodeFieldAccessor) {
-            NodeFieldAccessor other = (NodeFieldAccessor) obj;
-            return offset == other.offset && name.equals(other.name) && type.equals(other.type) && kind.equals(other.kind);
-        }
-        return false;
-    }
-
     private static final Unsafe unsafe = getUnsafe();
 
     private static Unsafe getUnsafe() {
@@ -143,16 +137,18 @@
         }
     };
 
-    private static final class UnsafeNodeField extends NodeFieldAccessor {
+    public abstract static class AbstractUnsafeNodeFieldAccessor extends NodeFieldAccessor {
 
-        protected UnsafeNodeField(NodeFieldKind kind, Field field) {
-            super(kind, field);
+        protected AbstractUnsafeNodeFieldAccessor(NodeFieldKind kind, Class<?> declaringClas, String name, Class<?> type, long offset) {
+            super(kind, declaringClas, name, type, offset);
         }
 
+        /* TODO abstract long getOffset() should be defined here. */
+
         @Override
         public void putObject(Node receiver, Object value) {
             if (!type.isPrimitive() && value == null || type.isInstance(value)) {
-                unsafe.putObject(receiver, offset, value);
+                unsafe.putObject(receiver, getOffset(), value);
             } else {
                 throw new IllegalArgumentException();
             }
@@ -161,7 +157,7 @@
         @Override
         public Object getObject(Node receiver) {
             if (!type.isPrimitive()) {
-                return unsafe.getObject(receiver, offset);
+                return unsafe.getObject(receiver, getOffset());
             } else {
                 throw new IllegalArgumentException();
             }
@@ -170,32 +166,40 @@
         @Override
         public Object loadValue(Node node) {
             if (type == boolean.class) {
-                return unsafe.getBoolean(node, offset);
+                return unsafe.getBoolean(node, getOffset());
             } else if (type == byte.class) {
-                return unsafe.getByte(node, offset);
+                return unsafe.getByte(node, getOffset());
             } else if (type == short.class) {
-                return unsafe.getShort(node, offset);
+                return unsafe.getShort(node, getOffset());
             } else if (type == char.class) {
-                return unsafe.getChar(node, offset);
+                return unsafe.getChar(node, getOffset());
             } else if (type == int.class) {
-                return unsafe.getInt(node, offset);
+                return unsafe.getInt(node, getOffset());
             } else if (type == long.class) {
-                return unsafe.getLong(node, offset);
+                return unsafe.getLong(node, getOffset());
             } else if (type == float.class) {
-                return unsafe.getFloat(node, offset);
+                return unsafe.getFloat(node, getOffset());
             } else if (type == double.class) {
-                return unsafe.getDouble(node, offset);
+                return unsafe.getDouble(node, getOffset());
             } else {
-                return unsafe.getObject(node, offset);
+                return unsafe.getObject(node, getOffset());
             }
         }
     }
 
+    private static final class UnsafeNodeField extends AbstractUnsafeNodeFieldAccessor {
+        /* TODO the offset field should be here, not in NodeFieldAccessor. */
+
+        protected UnsafeNodeField(NodeFieldKind kind, Field field) {
+            super(kind, field.getDeclaringClass(), field.getName(), field.getType(), unsafeFieldOffsetProvider.objectFieldOffset(field));
+        }
+    }
+
     private static final class ReflectionNodeField extends NodeFieldAccessor {
         private final Field field;
 
         protected ReflectionNodeField(NodeFieldKind kind, Field field) {
-            super(kind, field);
+            super(kind, field.getDeclaringClass(), field.getName(), field.getType(), unsafeFieldOffsetProvider.objectFieldOffset(field));
             this.field = field;
             field.setAccessible(true);
         }