From 790e6ba1a2f5bb24e2e3cc33a4bcc18797b0a703 Mon Sep 17 00:00:00 2001 From: Andreas Woess Date: Mon, 25 Apr 2016 19:42:17 +0200 Subject: [PATCH 1/9] SL: avoid use of Node.getChildren() --- .../oracle/truffle/sl/nodes/controlflow/SLBlockNode.java | 8 ++++++++ .../src/com/oracle/truffle/sl/parser/SLNodeFactory.java | 9 ++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java index 4c94348b7a78..5a51e2f94b90 100644 --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java @@ -40,6 +40,10 @@ */ package com.oracle.truffle.sl.nodes.controlflow; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.ExplodeLoop; @@ -82,4 +86,8 @@ public void executeVoid(VirtualFrame frame) { statement.executeVoid(frame); } } + + public List getStatements() { + return Collections.unmodifiableList(Arrays.asList(bodyNodes)); + } } diff --git a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java index ca056d9c1c6b..b5c589fb84b7 100644 --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SLNodeFactory.java @@ -48,7 +48,6 @@ import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.frame.FrameSlot; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.sl.nodes.SLExpressionNode; @@ -204,12 +203,12 @@ private static boolean isHaltInCondition(SLStatementNode statement) { return (statement instanceof SLIfNode) || (statement instanceof SLWhileNode); } - private void flattenBlocks(Iterable bodyNodes, List flattenedNodes) { - for (Node n : bodyNodes) { + private void flattenBlocks(Iterable bodyNodes, List flattenedNodes) { + for (SLStatementNode n : bodyNodes) { if (n instanceof SLBlockNode) { - flattenBlocks(n.getChildren(), flattenedNodes); + flattenBlocks(((SLBlockNode) n).getStatements(), flattenedNodes); } else { - flattenedNodes.add((SLStatementNode) n); + flattenedNodes.add(n); } } } From d4dd48bf79924ca39870c7124162fb7ae7a351f1 Mon Sep 17 00:00:00 2001 From: Andreas Woess Date: Tue, 26 Apr 2016 15:22:00 +0200 Subject: [PATCH 2/9] NodeClass cleanup * deprecate getFields(), getChildFields(), getChildrenFields(), getCloneableFields() * deprecate getParentField(), getNodeClassField() * introduce protected abstract Iterable getNodeFields() --- .../truffle/api/nodes/GraphPrintVisitor.java | 6 +- .../com/oracle/truffle/api/nodes/Node.java | 4 + .../oracle/truffle/api/nodes/NodeClass.java | 16 +- .../truffle/api/nodes/NodeClassImpl.java | 123 ++++++++-- .../truffle/api/nodes/NodeFieldAccessor.java | 32 ++- .../oracle/truffle/api/nodes/NodeUtil.java | 220 +++++++++--------- .../shell/server/InstrumentationUtils.java | 1 + 7 files changed, 257 insertions(+), 145 deletions(-) diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java index 9042e534ecfb..af8df1619eb7 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java @@ -488,8 +488,8 @@ private void copyDebugProperties(Node node) { } private void readNodeProperties(Node node) { - NodeFieldAccessor[] fields = NodeClass.get(node).getFields(); - for (NodeFieldAccessor field : fields) { + NodeClass nodeClass = NodeClass.get(node); + for (NodeFieldAccessor field : nodeClass.getNodeFields()) { if (field.getKind() == NodeFieldKind.DATA) { String key = field.getName(); if (!getElementByObject(node).getProperties().containsKey(key)) { @@ -564,7 +564,7 @@ private static LinkedHashMap findNamedNodeChildren(Node node) { LinkedHashMap nodes = new LinkedHashMap<>(); NodeClass nodeClass = NodeClass.get(node); - for (NodeFieldAccessor field : nodeClass.getFields()) { + for (NodeFieldAccessor field : nodeClass.getNodeFields()) { NodeFieldKind kind = field.getKind(); if (kind == NodeFieldKind.CHILD || kind == NodeFieldKind.CHILDREN) { Object value = field.loadValue(node); diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java index 9517964435b7..20463b97a4ae 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java @@ -87,6 +87,10 @@ NodeClass getNodeClass() { return nodeClass; } + void setParent(Node parent) { + this.parent = parent; + } + /** * Returns a rough estimate for the cost of this {@link Node}. This estimate can be used by * runtime systems or guest languages to implement heuristics based on Truffle ASTs. This method diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java index 486dec059f5c..153c802330de 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java @@ -31,7 +31,7 @@ /** * Information about a {@link Node} class. A single instance of this class is allocated for every * subclass of {@link Node} that is used. - * + * * @since 0.8 or earlier */ public abstract class NodeClass { @@ -59,35 +59,43 @@ public static NodeClass get(Node node) { } /** @since 0.8 or earlier */ - @SuppressWarnings("unused") - public NodeClass(Class clazz) { + public NodeClass(@SuppressWarnings("unused") Class clazz) { } /** @since 0.8 or earlier */ + @Deprecated public abstract NodeFieldAccessor getNodeClassField(); /** @since 0.8 or earlier */ + @Deprecated public abstract NodeFieldAccessor[] getCloneableFields(); /** @since 0.8 or earlier */ + @Deprecated public abstract NodeFieldAccessor[] getFields(); /** @since 0.8 or earlier */ + @Deprecated public abstract NodeFieldAccessor getParentField(); /** @since 0.8 or earlier */ + @Deprecated public abstract NodeFieldAccessor[] getChildFields(); /** @since 0.8 or earlier */ + @Deprecated public abstract NodeFieldAccessor[] getChildrenFields(); + /** @since 0.14 */ + protected abstract Iterable getNodeFields(); + /** @since 0.8 or earlier */ public abstract Iterator makeIterator(Node node); /** * The {@link Class} this NodeClass has been {@link #NodeClass(java.lang.Class) * created for}. - * + * * @return the clazz of node this NodeClass describes * @since 0.8 or earlier */ diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java index 010ada97cbfe..49a14482f741 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java @@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.NoSuchElementException; import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.nodes.Node.Children; @@ -38,6 +39,7 @@ * Information about a {@link Node} class. A single instance of this class is allocated for every * subclass of {@link Node} that is used. */ +@SuppressWarnings("deprecation") final class NodeClassImpl extends NodeClass { private static final NodeFieldAccessor[] EMPTY_NODE_FIELD_ARRAY = new NodeFieldAccessor[0]; @@ -48,7 +50,6 @@ final class NodeClassImpl extends NodeClass { private final NodeFieldAccessor nodeClassField; private final NodeFieldAccessor[] childFields; private final NodeFieldAccessor[] childrenFields; - private final NodeFieldAccessor[] cloneableFields; private final Class clazz; @@ -83,7 +84,6 @@ final class NodeClassImpl extends NodeClass { this.parentField = parentFieldTmp; this.childFields = childFieldList.toArray(EMPTY_NODE_FIELD_ARRAY); this.childrenFields = childrenFieldList.toArray(EMPTY_NODE_FIELD_ARRAY); - this.cloneableFields = cloneableFieldList.toArray(EMPTY_NODE_FIELD_ARRAY); this.clazz = clazz; } @@ -124,11 +124,6 @@ public NodeFieldAccessor getNodeClassField() { return nodeClassField; } - @Override - public NodeFieldAccessor[] getCloneableFields() { - return cloneableFields; - } - private static boolean isNodeType(Class clazz) { return Node.class.isAssignableFrom(clazz) || (clazz.isInterface() && NodeInterface.class.isAssignableFrom(clazz)); } @@ -151,26 +146,11 @@ private static void checkChildrenField(Field field) { } } - @Override - public NodeFieldAccessor[] getFields() { - return fields; - } - @Override public NodeFieldAccessor getParentField() { return parentField; } - @Override - public NodeFieldAccessor[] getChildFields() { - return childFields; - } - - @Override - public NodeFieldAccessor[] getChildrenFields() { - return childrenFields; - } - @Override public int hashCode() { return clazz.hashCode(); @@ -196,6 +176,101 @@ public Class getType() { return clazz; } + @Override + protected Iterable getNodeFields() { + return getNodeFields(null); + } + + /** + * Functional interface equivalent to {@code Predicate}. + */ + private interface NodeFieldFilter { + boolean test(NodeFieldAccessor field); + } + + private Iterable getNodeFields(final NodeFieldFilter filter) { + return new Iterable() { + public Iterator iterator() { + return new Iterator() { + private int cursor = -1; + { + forward(); + } + + private void forward() { + for (int i = cursor + 1; i < fields.length; i++) { + NodeFieldAccessor field = fields[i]; + if (filter == null || filter.test(field)) { + cursor = i; + return; + } + } + cursor = fields.length; + } + + public boolean hasNext() { + assert cursor >= 0; + return cursor < fields.length; + } + + public NodeFieldAccessor next() { + if (hasNext()) { + NodeFieldAccessor next = fields[cursor]; + forward(); + return next; + } else { + throw new NoSuchElementException(); + } + } + + public void remove() { + throw new UnsupportedOperationException(); + } + }; + } + }; + } + + @Override + public NodeFieldAccessor[] getFields() { + return iterableToArray(getNodeFields()); + } + + @Override + public NodeFieldAccessor[] getChildFields() { + return iterableToArray(getNodeFields(new NodeFieldFilter() { + public boolean test(NodeFieldAccessor field) { + return field.isChildField(); + } + })); + } + + @Override + public NodeFieldAccessor[] getChildrenFields() { + return iterableToArray(getNodeFields(new NodeFieldFilter() { + public boolean test(NodeFieldAccessor field) { + return field.isChildrenField(); + } + })); + } + + @Override + public NodeFieldAccessor[] getCloneableFields() { + return iterableToArray(getNodeFields(new NodeFieldFilter() { + public boolean test(NodeFieldAccessor field) { + return field.isCloneableField(); + } + })); + } + + private static NodeFieldAccessor[] iterableToArray(Iterable fields) { + ArrayList fieldList = new ArrayList<>(); + for (NodeFieldAccessor field : fields) { + fieldList.add(field); + } + return fieldList.toArray(EMPTY_NODE_FIELD_ARRAY); + } + private static final class NodeIterator implements Iterator { private final NodeFieldAccessor[] childFields; private final NodeFieldAccessor[] childrenFields; @@ -204,8 +279,8 @@ private static final class NodeIterator implements Iterator { private int index; protected NodeIterator(NodeClassImpl nodeClass, Node node) { - this.childFields = nodeClass.getChildFields(); - this.childrenFields = nodeClass.getChildrenFields(); + this.childFields = nodeClass.childFields; + this.childrenFields = nodeClass.childrenFields; this.node = node; this.childrenCount = childrenCount(); this.index = 0; diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java index 92102b0a8d18..bcb7bf4e8031 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java @@ -33,7 +33,7 @@ /** * Information about a field in a {@link Node} class. - * + * * @since 0.8 or earlier */ public abstract class NodeFieldAccessor { @@ -41,31 +41,31 @@ public abstract class NodeFieldAccessor { public enum NodeFieldKind { /** * The reference to the {@link NodeClass}. - * + * * @since 0.8 or earlier */ NODE_CLASS, /** * The single {@link Node#getParent() parent} field. - * + * * @since 0.8 or earlier */ PARENT, /** * A field annotated with {@link Child}. - * + * * @since 0.8 or earlier */ CHILD, /** * A field annotated with {@link Children}. - * + * * @since 0.8 or earlier */ CHILDREN, /** * A normal non-child data field of the node. - * + * * @since 0.8 or earlier */ DATA @@ -124,12 +124,28 @@ public String getName() { @Deprecated public abstract void putObject(Node receiver, Object value); - /** @since 0.8 or earlier */ + /** + * @deprecated The visibility of this method will be reduced to protected. Do not use. + * @since 0.8 or earlier + */ + @Deprecated public abstract Object getObject(Node receiver); /** @since 0.8 or earlier */ public abstract Object loadValue(Node node); + boolean isChildField() { + return getKind() == NodeFieldKind.CHILD; + } + + boolean isChildrenField() { + return getKind() == NodeFieldKind.CHILDREN; + } + + boolean isCloneableField() { + return getKind() == NodeFieldKind.DATA && NodeCloneable.class.isAssignableFrom(getType()); + } + /** @since 0.8 or earlier */ public abstract static class AbstractUnsafeNodeFieldAccessor extends NodeFieldAccessor { /** @since 0.8 or earlier */ @@ -152,6 +168,7 @@ public void putObject(Node receiver, Object value) { } /** @since 0.8 or earlier */ + @SuppressWarnings("deprecation") @Override public Object getObject(Node receiver) { if (!type.isPrimitive()) { @@ -236,6 +253,7 @@ public void putObject(Node receiver, Object value) { } } + @SuppressWarnings("deprecation") @Override public Object getObject(Node receiver) { assert !type.isPrimitive(); diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java index bbeae4eb7ee1..d13129e61cd4 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java @@ -141,62 +141,63 @@ static Node deepCopyImpl(Node orig) { final Node clone = orig.copy(); NodeClass nodeClass = clone.getNodeClass(); - nodeClass.getParentField().putObject(clone, null); - - for (NodeFieldAccessor childField : nodeClass.getChildFields()) { - Node child = (Node) childField.getObject(orig); - if (child != null) { - Node clonedChild = child.deepCopy(); - nodeClass.getParentField().putObject(clonedChild, clone); - childField.putObject(clone, clonedChild); - } - } - for (NodeFieldAccessor childrenField : nodeClass.getChildrenFields()) { - Object[] children = (Object[]) childrenField.getObject(orig); - if (children != null) { - Object[] clonedChildren = (Object[]) Array.newInstance(children.getClass().getComponentType(), children.length); - for (int i = 0; i < children.length; i++) { - if (children[i] != null) { - Node clonedChild = ((Node) children[i]).deepCopy(); - clonedChildren[i] = clonedChild; - nodeClass.getParentField().putObject(clonedChild, clone); + clone.setParent(null); + + for (NodeFieldAccessor field : nodeClass.getNodeFields()) { + if (field.isChildField()) { + Node child = (Node) field.getObject(orig); + if (child != null) { + Node clonedChild = child.deepCopy(); + clonedChild.setParent(clone); + field.putObject(clone, clonedChild); + } + } else if (field.isChildrenField()) { + Object[] children = (Object[]) field.getObject(orig); + if (children != null) { + Object[] clonedChildren = (Object[]) Array.newInstance(children.getClass().getComponentType(), children.length); + for (int i = 0; i < children.length; i++) { + if (children[i] != null) { + Node clonedChild = ((Node) children[i]).deepCopy(); + clonedChild.setParent(clone); + clonedChildren[i] = clonedChild; + } } + field.putObject(clone, clonedChildren); + } + } else if (field.isCloneableField()) { + Object cloneable = field.getObject(clone); + if (cloneable != null && cloneable == field.getObject(orig)) { + field.putObject(clone, ((NodeCloneable) cloneable).clone()); } - childrenField.putObject(clone, clonedChildren); - } - } - for (NodeFieldAccessor cloneableField : nodeClass.getCloneableFields()) { - Object cloneable = cloneableField.getObject(clone); - if (cloneable != null && cloneable == cloneableField.getObject(orig)) { - cloneableField.putObject(clone, ((NodeCloneable) cloneable).clone()); } } return clone; } /** @since 0.8 or earlier */ + @SuppressWarnings("deprecation") public static List findNodeChildren(Node node) { CompilerAsserts.neverPartOfCompilation("do not call Node.findNodeChildren from compiled code"); List nodes = new ArrayList<>(); NodeClass nodeClass = node.getNodeClass(); - for (NodeFieldAccessor nodeField : nodeClass.getChildFields()) { - Object child = nodeField.getObject(node); - if (child != null) { - nodes.add((Node) child); - } - } - for (NodeFieldAccessor nodeField : nodeClass.getChildrenFields()) { - Object[] children = (Object[]) nodeField.getObject(node); - if (children != null) { - for (Object child : children) { - if (child != null) { - nodes.add((Node) child); + for (NodeFieldAccessor nodeField : nodeClass.getNodeFields()) { + if (nodeField.isChildField()) { + Object child = nodeField.getObject(node); + if (child != null) { + nodes.add((Node) child); + } + } else if (nodeField.isChildrenField()) { + Object[] children = (Object[]) nodeField.getObject(node); + if (children != null) { + for (Object child : children) { + if (child != null) { + nodes.add((Node) child); + } } } } } - return nodes; } @@ -216,33 +217,34 @@ static boolean replaceChild(Node parent, Node oldChild, Node newChild, boolean a CompilerAsserts.neverPartOfCompilation("do not replace Node child from compiled code"); NodeClass nodeClass = parent.getNodeClass(); - for (NodeFieldAccessor nodeField : nodeClass.getChildFields()) { - if (nodeField.getObject(parent) == oldChild) { - assert assertAssignable(nodeField, newChild); - if (adopt) { - parent.adoptHelper(newChild); + for (NodeFieldAccessor nodeField : nodeClass.getNodeFields()) { + if (nodeField.isChildField()) { + if (nodeField.getObject(parent) == oldChild) { + assert assertAssignable(nodeField, newChild); + if (adopt) { + parent.adoptHelper(newChild); + } + nodeField.putObject(parent, newChild); + return true; } - nodeField.putObject(parent, newChild); - return true; - } - } - - for (NodeFieldAccessor nodeField : nodeClass.getChildrenFields()) { - Object arrayObject = nodeField.getObject(parent); - if (arrayObject != null) { - Object[] array = (Object[]) arrayObject; - for (int i = 0; i < array.length; i++) { - if (array[i] == oldChild) { - assert assertAssignable(nodeField, newChild); - if (adopt) { - parent.adoptHelper(newChild); + } else if (nodeField.isChildrenField()) { + Object arrayObject = nodeField.getObject(parent); + if (arrayObject != null) { + Object[] array = (Object[]) arrayObject; + for (int i = 0; i < array.length; i++) { + if (array[i] == oldChild) { + assert assertAssignable(nodeField, newChild); + if (adopt) { + parent.adoptHelper(newChild); + } + array[i] = newChild; + return true; } - array[i] = newChild; - return true; } } } } + return false; } @@ -274,23 +276,24 @@ private static boolean assertAssignable(NodeFieldAccessor field, Object newValue * @return the field (possibly an array) holding the child, {@code null} if not found. * @since 0.8 or earlier */ + @SuppressWarnings("deprecation") public static NodeFieldAccessor findChildField(Node parent, Node child) { assert child != null; NodeClass parentNodeClass = parent.getNodeClass(); - for (NodeFieldAccessor field : parentNodeClass.getChildFields()) { - if (field.getObject(parent) == child) { - return field; - } - } - - for (NodeFieldAccessor field : parentNodeClass.getChildrenFields()) { - Object arrayObject = field.getObject(parent); - if (arrayObject != null) { - Object[] array = (Object[]) arrayObject; - for (int i = 0; i < array.length; i++) { - if (array[i] == child) { - return field; + for (NodeFieldAccessor field : parentNodeClass.getFields()) { + if (field.isChildField()) { + if (field.getObject(parent) == child) { + return field; + } + } else if (field.isChildrenField()) { + Object arrayObject = field.getObject(parent); + if (arrayObject != null) { + Object[] array = (Object[]) arrayObject; + for (int i = 0; i < array.length; i++) { + if (array[i] == child) { + return field; + } } } } @@ -327,29 +330,30 @@ public static boolean isReplacementSafe(Node parent, Node oldChild, Node newChil * @return {@code true} if all children were visited, {@code false} otherwise * @since 0.8 or earlier */ + @SuppressWarnings("deprecation") public static boolean forEachChild(Node parent, NodeVisitor visitor) { CompilerAsserts.neverPartOfCompilation("do not iterate over Node children from compiled code"); Objects.requireNonNull(visitor); NodeClass parentNodeClass = parent.getNodeClass(); - for (NodeFieldAccessor field : parentNodeClass.getChildFields()) { - Object child = field.getObject(parent); - if (child != null) { - if (!visitor.visit((Node) child)) { - return false; + for (NodeFieldAccessor field : parentNodeClass.getNodeFields()) { + if (field.isChildField()) { + Object child = field.getObject(parent); + if (child != null) { + if (!visitor.visit((Node) child)) { + return false; + } } - } - } - - for (NodeFieldAccessor field : parentNodeClass.getChildrenFields()) { - Object arrayObject = field.getObject(parent); - if (arrayObject != null) { - Object[] array = (Object[]) arrayObject; - for (int i = 0; i < array.length; i++) { - Object child = array[i]; - if (child != null) { - if (!visitor.visit((Node) child)) { - return false; + } else if (field.isChildrenField()) { + Object arrayObject = field.getObject(parent); + if (arrayObject != null) { + Object[] array = (Object[]) arrayObject; + for (int i = 0; i < array.length; i++) { + Object child = array[i]; + if (child != null) { + if (!visitor.visit((Node) child)) { + return false; + } } } } @@ -359,25 +363,26 @@ public static boolean forEachChild(Node parent, NodeVisitor visitor) { return true; } + @SuppressWarnings("deprecation") static boolean forEachChildRecursive(Node parent, NodeVisitor visitor) { NodeClass parentNodeClass = parent.getNodeClass(); - for (NodeFieldAccessor field : parentNodeClass.getChildFields()) { - if (!visitChild((Node) field.getObject(parent), visitor)) { - return false; - } - } - - for (NodeFieldAccessor field : parentNodeClass.getChildrenFields()) { - Object arrayObject = field.getObject(parent); - if (arrayObject == null) { - continue; - } - Object[] array = (Object[]) arrayObject; - for (int i = 0; i < array.length; i++) { - if (!visitChild((Node) array[i], visitor)) { + for (NodeFieldAccessor field : parentNodeClass.getNodeFields()) { + if (field.isChildField()) { + if (!visitChild((Node) field.getObject(parent), visitor)) { return false; } + } else if (field.isChildrenField()) { + Object arrayObject = field.getObject(parent); + if (arrayObject == null) { + continue; + } + Object[] array = (Object[]) arrayObject; + for (int i = 0; i < array.length; i++) { + if (!visitChild((Node) array[i], visitor)) { + return false; + } + } } } @@ -625,8 +630,8 @@ private static void printSourceAttributionTree(PrintWriter p, Node parent, Node } private static String getNodeFieldName(Node parent, Node node, String defaultName) { - NodeFieldAccessor[] fields = parent.getNodeClass().getFields(); - for (NodeFieldAccessor field : fields) { + NodeClass nodeClass = parent.getNodeClass(); + for (NodeFieldAccessor field : nodeClass.getNodeFields()) { Object value = field.loadValue(parent); if (field.getKind() == NodeFieldKind.CHILD && value == node) { return field.getName(); @@ -692,7 +697,8 @@ private static void printTree(PrintWriter p, Node node, int level) { ArrayList childFields = new ArrayList<>(); String sep = ""; p.print("("); - for (NodeFieldAccessor field : NodeClass.get(node).getFields()) { + NodeClass nodeClass = NodeClass.get(node); + for (NodeFieldAccessor field : nodeClass.getNodeFields()) { if (field.getKind() == NodeFieldKind.CHILD || field.getKind() == NodeFieldKind.CHILDREN) { childFields.add(field); } else if (field.getKind() == NodeFieldKind.DATA) { diff --git a/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/InstrumentationUtils.java b/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/InstrumentationUtils.java index 06b09e7ea9a8..5e5a24b49199 100644 --- a/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/InstrumentationUtils.java +++ b/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/InstrumentationUtils.java @@ -120,6 +120,7 @@ protected String displayTags(final Object node) { return ""; } + @SuppressWarnings("deprecation") protected void printTree(PrintWriter p, Node node, int maxDepth, Node markNode, int level) { if (node == null) { p.print("null"); From 1f98a92dd6a4eb4c52726f0a36bfe49e8c013382 Mon Sep 17 00:00:00 2001 From: Andreas Woess Date: Tue, 26 Apr 2016 16:48:22 +0200 Subject: [PATCH 3/9] Remove child and children field arrays and rewrite NodeIterator to not need them --- .../truffle/api/nodes/NodeClassImpl.java | 97 ++++++++----------- 1 file changed, 43 insertions(+), 54 deletions(-) diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java index 49a14482f741..a37f98684894 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java @@ -45,11 +45,8 @@ final class NodeClassImpl extends NodeClass { // The comprehensive list of all fields. private final NodeFieldAccessor[] fields; - // Separate arrays for the frequently accessed fields. private final NodeFieldAccessor parentField; private final NodeFieldAccessor nodeClassField; - private final NodeFieldAccessor[] childFields; - private final NodeFieldAccessor[] childrenFields; private final Class clazz; @@ -62,9 +59,6 @@ final class NodeClassImpl extends NodeClass { List fieldsList = new ArrayList<>(); NodeFieldAccessor parentFieldTmp = null; NodeFieldAccessor nodeClassFieldTmp = null; - List childFieldList = new ArrayList<>(); - List childrenFieldList = new ArrayList<>(); - List cloneableFieldList = new ArrayList<>(); try { Field field = Node.class.getDeclaredField("parent"); @@ -77,20 +71,17 @@ final class NodeClassImpl extends NodeClass { throw new AssertionError("Node field not found", e); } - collectInstanceFields(clazz, fieldsList, childFieldList, childrenFieldList, cloneableFieldList); + collectInstanceFields(clazz, fieldsList); this.fields = fieldsList.toArray(EMPTY_NODE_FIELD_ARRAY); this.nodeClassField = nodeClassFieldTmp; this.parentField = parentFieldTmp; - this.childFields = childFieldList.toArray(EMPTY_NODE_FIELD_ARRAY); - this.childrenFields = childrenFieldList.toArray(EMPTY_NODE_FIELD_ARRAY); this.clazz = clazz; } - private static void collectInstanceFields(Class clazz, List fieldsList, List childFieldList, List childrenFieldList, - List cloneableFieldList) { + private static void collectInstanceFields(Class clazz, List fieldsList) { if (clazz.getSuperclass() != null) { - collectInstanceFields(clazz.getSuperclass(), fieldsList, childFieldList, childrenFieldList, cloneableFieldList); + collectInstanceFields(clazz.getSuperclass(), fieldsList); } Field[] declaredFields = clazz.getDeclaredFields(); for (Field field : declaredFields) { @@ -104,16 +95,11 @@ private static void collectInstanceFields(Class clazz, List f } private static final class NodeIterator implements Iterator { - private final NodeFieldAccessor[] childFields; - private final NodeFieldAccessor[] childrenFields; + private final NodeFieldAccessor[] fields; private final Node node; - private final int childrenCount; - private int index; + + private int fieldIndex; + private Node next; + private int childrenIndex; + private Object[] children; protected NodeIterator(NodeClassImpl nodeClass, Node node) { - this.childFields = nodeClass.childFields; - this.childrenFields = nodeClass.childrenFields; + this.fields = nodeClass.fields; this.node = node; - this.childrenCount = childrenCount(); - this.index = 0; + advance(); } - private int childrenCount() { - int nodeCount = childFields.length; - for (NodeFieldAccessor childrenField : childrenFields) { - Object[] children = ((Object[]) childrenField.getObject(node)); - if (children != null) { - nodeCount += children.length; - } + private void advance() { + if (advanceChildren()) { + return; } - return nodeCount; - } - - private Node nodeAt(int idx) { - int nodeCount = childFields.length; - if (idx < nodeCount) { - return (Node) childFields[idx].getObject(node); - } else { - for (NodeFieldAccessor childrenField : childrenFields) { - Object[] nodeArray = (Object[]) childrenField.getObject(node); - if (idx < nodeCount + nodeArray.length) { - return (Node) nodeArray[idx - nodeCount]; + while (fieldIndex < fields.length) { + NodeFieldAccessor field = fields[fieldIndex]; + fieldIndex++; + if (field.isChildField()) { + next = (Node) field.getObject(node); + return; + } else if (field.isChildrenField()) { + children = (Object[]) field.getObject(node); + childrenIndex = 0; + if (advanceChildren()) { + return; } - nodeCount += nodeArray.length; } } - return null; + next = null; } - private void forward() { - if (index < childrenCount) { - index++; + private boolean advanceChildren() { + if (children == null) { + return false; + } else if (childrenIndex < children.length) { + next = (Node) children[childrenIndex]; + childrenIndex++; + return true; + } else { + children = null; + childrenIndex = 0; + return false; } } public boolean hasNext() { - return index < childrenCount; + return next != null; } public Node next() { - try { - return nodeAt(index); - } finally { - forward(); + Node result = next; + if (result == null) { + throw new NoSuchElementException(); } + advance(); + return result; } public void remove() { From 329672d6adbdacbd1c30f891c529d5480249de88 Mon Sep 17 00:00:00 2001 From: Andreas Woess Date: Wed, 27 Apr 2016 17:36:01 +0200 Subject: [PATCH 4/9] Introduce NodeClass.NodeField as replacement for NodeFieldAccessor --- .../truffle/api/nodes/GraphPrintVisitor.java | 39 ++++++----- .../oracle/truffle/api/nodes/NodeClass.java | 29 +++++++- .../truffle/api/nodes/NodeClassImpl.java | 46 ++++++------- .../truffle/api/nodes/NodeFieldAccessor.java | 66 +++++++++++++++---- .../oracle/truffle/api/nodes/NodeUtil.java | 60 ++++++++--------- 5 files changed, 151 insertions(+), 89 deletions(-) diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java index af8df1619eb7..4d71415698fb 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java @@ -50,11 +50,10 @@ import javax.xml.stream.XMLStreamWriter; import com.oracle.truffle.api.TruffleOptions; -import com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind; /** * Utility class for creating output for the ideal graph visualizer. - * + * * @since 0.8 or earlier */ public class GraphPrintVisitor implements Closeable { @@ -489,17 +488,21 @@ private void copyDebugProperties(Node node) { private void readNodeProperties(Node node) { NodeClass nodeClass = NodeClass.get(node); - for (NodeFieldAccessor field : nodeClass.getNodeFields()) { - if (field.getKind() == NodeFieldKind.DATA) { + for (NodeClass.NodeField field : nodeClass.getNodeFields()) { + if (isDataField(field)) { String key = field.getName(); if (!getElementByObject(node).getProperties().containsKey(key)) { - Object value = field.loadValue(node); + Object value = field.getValue(node); setNodeProperty(node, key, value); } } } } + private static boolean isDataField(NodeClass.NodeField field) { + return !field.isChildField() && !field.isChildrenField(); + } + final void connectNodes(Object a, Object b, String label) { NodeElement fromNode = getElementByObject(a); NodeElement toNode = getElementByObject(b); @@ -564,19 +567,19 @@ private static LinkedHashMap findNamedNodeChildren(Node node) { LinkedHashMap nodes = new LinkedHashMap<>(); NodeClass nodeClass = NodeClass.get(node); - for (NodeFieldAccessor field : nodeClass.getNodeFields()) { - NodeFieldKind kind = field.getKind(); - if (kind == NodeFieldKind.CHILD || kind == NodeFieldKind.CHILDREN) { - Object value = field.loadValue(node); + for (NodeClass.NodeField field : nodeClass.getNodeFields()) { + if (field.isChildField()) { + Object value = field.getObject(node); + if (value != null) { + nodes.put(field.getName(), (Node) value); + } + } else if (field.isChildrenField()) { + Object value = field.getObject(node); if (value != null) { - if (kind == NodeFieldKind.CHILD) { - nodes.put(field.getName(), (Node) value); - } else if (kind == NodeFieldKind.CHILDREN) { - Object[] children = (Object[]) value; - for (int i = 0; i < children.length; i++) { - if (children[i] != null) { - nodes.put(field.getName() + "[" + i + "]", (Node) children[i]); - } + Object[] children = (Object[]) value; + for (int i = 0; i < children.length; i++) { + if (children[i] != null) { + nodes.put(field.getName() + "[" + i + "]", (Node) children[i]); } } } @@ -598,7 +601,7 @@ private static String safeToString(Object value) { public class GraphPrintAdapter { /** * Default constructor. - * + * * @since 0.8 or earlier */ public GraphPrintAdapter() { diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java index 153c802330de..a39e5d9849aa 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java @@ -87,7 +87,7 @@ public NodeClass(@SuppressWarnings("unused") Class clazz) { public abstract NodeFieldAccessor[] getChildrenFields(); /** @since 0.14 */ - protected abstract Iterable getNodeFields(); + protected abstract Iterable getNodeFields(); /** @since 0.8 or earlier */ public abstract Iterator makeIterator(Node node); @@ -100,4 +100,31 @@ public NodeClass(@SuppressWarnings("unused") Class clazz) { * @since 0.8 or earlier */ public abstract Class getType(); + + /** @since 0.14 */ + protected interface NodeField { + /** @since 0.14 */ + void putObject(Node receiver, Object value); + + /** @since 0.14 */ + Object getObject(Node receiver); + + /** @since 0.14 */ + Object getValue(Node receiver); + + /** @since 0.14 */ + Class getFieldType(); + + /** @since 0.14 */ + String getName(); + + /** @since 0.14 */ + boolean isChildField(); + + /** @since 0.14 */ + boolean isChildrenField(); + + /** @since 0.14 */ + boolean isCloneableField(); + } } diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java index a37f98684894..9ee9ee6728ec 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java @@ -41,10 +41,10 @@ */ @SuppressWarnings("deprecation") final class NodeClassImpl extends NodeClass { - private static final NodeFieldAccessor[] EMPTY_NODE_FIELD_ARRAY = new NodeFieldAccessor[0]; + private static final NodeField[] EMPTY_NODE_FIELD_ARRAY = new NodeField[0]; // The comprehensive list of all fields. - private final NodeFieldAccessor[] fields; + private final NodeField[] fields; private final NodeFieldAccessor parentField; private final NodeFieldAccessor nodeClassField; @@ -56,7 +56,7 @@ final class NodeClassImpl extends NodeClass { throw new IllegalArgumentException(); } - List fieldsList = new ArrayList<>(); + List fieldsList = new ArrayList<>(); NodeFieldAccessor parentFieldTmp = null; NodeFieldAccessor nodeClassFieldTmp = null; @@ -79,7 +79,7 @@ final class NodeClassImpl extends NodeClass { this.clazz = clazz; } - private static void collectInstanceFields(Class clazz, List fieldsList) { + private static void collectInstanceFields(Class clazz, List fieldsList) { if (clazz.getSuperclass() != null) { collectInstanceFields(clazz.getSuperclass(), fieldsList); } @@ -101,7 +101,7 @@ private static void collectInstanceFields(Class clazz, List getType() { } @Override - protected Iterable getNodeFields() { + protected Iterable getNodeFields() { return getNodeFields(null); } @@ -171,13 +171,13 @@ protected Iterable getNodeFields() { * Functional interface equivalent to {@code Predicate}. */ private interface NodeFieldFilter { - boolean test(NodeFieldAccessor field); + boolean test(NodeField field); } - private Iterable getNodeFields(final NodeFieldFilter filter) { - return new Iterable() { - public Iterator iterator() { - return new Iterator() { + private Iterable getNodeFields(final NodeFieldFilter filter) { + return new Iterable() { + public Iterator iterator() { + return new Iterator() { private int cursor = -1; { forward(); @@ -185,7 +185,7 @@ public Iterator iterator() { private void forward() { for (int i = cursor + 1; i < fields.length; i++) { - NodeFieldAccessor field = fields[i]; + NodeField field = fields[i]; if (filter == null || filter.test(field)) { cursor = i; return; @@ -199,9 +199,9 @@ public boolean hasNext() { return cursor < fields.length; } - public NodeFieldAccessor next() { + public NodeField next() { if (hasNext()) { - NodeFieldAccessor next = fields[cursor]; + NodeField next = fields[cursor]; forward(); return next; } else { @@ -225,7 +225,7 @@ public NodeFieldAccessor[] getFields() { @Override public NodeFieldAccessor[] getChildFields() { return iterableToArray(getNodeFields(new NodeFieldFilter() { - public boolean test(NodeFieldAccessor field) { + public boolean test(NodeField field) { return field.isChildField(); } })); @@ -234,7 +234,7 @@ public boolean test(NodeFieldAccessor field) { @Override public NodeFieldAccessor[] getChildrenFields() { return iterableToArray(getNodeFields(new NodeFieldFilter() { - public boolean test(NodeFieldAccessor field) { + public boolean test(NodeField field) { return field.isChildrenField(); } })); @@ -243,22 +243,22 @@ public boolean test(NodeFieldAccessor field) { @Override public NodeFieldAccessor[] getCloneableFields() { return iterableToArray(getNodeFields(new NodeFieldFilter() { - public boolean test(NodeFieldAccessor field) { + public boolean test(NodeField field) { return field.isCloneableField(); } })); } - private static NodeFieldAccessor[] iterableToArray(Iterable fields) { + private static NodeFieldAccessor[] iterableToArray(Iterable fields) { ArrayList fieldList = new ArrayList<>(); - for (NodeFieldAccessor field : fields) { - fieldList.add(field); + for (NodeField field : fields) { + fieldList.add((NodeFieldAccessor) field); } - return fieldList.toArray(EMPTY_NODE_FIELD_ARRAY); + return fieldList.toArray(new NodeFieldAccessor[0]); } private static final class NodeIterator implements Iterator { - private final NodeFieldAccessor[] fields; + private final NodeField[] fields; private final Node node; private int fieldIndex; @@ -277,7 +277,7 @@ private void advance() { return; } while (fieldIndex < fields.length) { - NodeFieldAccessor field = fields[fieldIndex]; + NodeField field = fields[fieldIndex]; fieldIndex++; if (field.isChildField()) { next = (Node) field.getObject(node); diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java index bcb7bf4e8031..c8910d4adb22 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java @@ -134,18 +134,6 @@ public String getName() { /** @since 0.8 or earlier */ public abstract Object loadValue(Node node); - boolean isChildField() { - return getKind() == NodeFieldKind.CHILD; - } - - boolean isChildrenField() { - return getKind() == NodeFieldKind.CHILDREN; - } - - boolean isCloneableField() { - return getKind() == NodeFieldKind.DATA && NodeCloneable.class.isAssignableFrom(getType()); - } - /** @since 0.8 or earlier */ public abstract static class AbstractUnsafeNodeFieldAccessor extends NodeFieldAccessor { /** @since 0.8 or earlier */ @@ -219,7 +207,7 @@ private static Unsafe getUnsafe() { } } - private static final class UnsafeNodeField extends AbstractUnsafeNodeFieldAccessor { + private static final class UnsafeNodeField extends AbstractUnsafeNodeFieldAccessor implements NodeClass.NodeField { private final long offset; protected UnsafeNodeField(NodeFieldKind kind, Field field) { @@ -231,9 +219,34 @@ protected UnsafeNodeField(NodeFieldKind kind, Field field) { public long getOffset() { return offset; } + + @Override + public Class getFieldType() { + return getType(); + } + + @Override + public Object getValue(Node receiver) { + return loadValue(receiver); + } + + @Override + public boolean isChildField() { + return getKind() == NodeFieldKind.CHILD; + } + + @Override + public boolean isChildrenField() { + return getKind() == NodeFieldKind.CHILDREN; + } + + @Override + public boolean isCloneableField() { + return getKind() == NodeFieldKind.DATA && NodeCloneable.class.isAssignableFrom(getType()); + } } - private static final class ReflectionNodeField extends NodeFieldAccessor { + private static final class ReflectionNodeField extends NodeFieldAccessor implements NodeClass.NodeField { private final Field field; protected ReflectionNodeField(NodeFieldKind kind, Field field) { @@ -290,6 +303,31 @@ public Object loadValue(Node node) { throw new AssertionError(e); } } + + @Override + public Object getValue(Node receiver) { + return loadValue(receiver); + } + + @Override + public Class getFieldType() { + return getType(); + } + + @Override + public boolean isChildField() { + return getKind() == NodeFieldKind.CHILD; + } + + @Override + public boolean isChildrenField() { + return getKind() == NodeFieldKind.CHILDREN; + } + + @Override + public boolean isCloneableField() { + return getKind() == NodeFieldKind.DATA && NodeCloneable.class.isAssignableFrom(getType()); + } } } diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java index d13129e61cd4..f9819959ce11 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java @@ -135,7 +135,6 @@ public static T cloneNode(T orig) { return (T) orig.deepCopy(); } - @SuppressWarnings("deprecation") static Node deepCopyImpl(Node orig) { CompilerAsserts.neverPartOfCompilation("do not call Node.deepCopyImpl from compiled code"); final Node clone = orig.copy(); @@ -143,7 +142,7 @@ static Node deepCopyImpl(Node orig) { clone.setParent(null); - for (NodeFieldAccessor field : nodeClass.getNodeFields()) { + for (NodeClass.NodeField field : nodeClass.getNodeFields()) { if (field.isChildField()) { Node child = (Node) field.getObject(orig); if (child != null) { @@ -175,13 +174,12 @@ static Node deepCopyImpl(Node orig) { } /** @since 0.8 or earlier */ - @SuppressWarnings("deprecation") public static List findNodeChildren(Node node) { CompilerAsserts.neverPartOfCompilation("do not call Node.findNodeChildren from compiled code"); List nodes = new ArrayList<>(); NodeClass nodeClass = node.getNodeClass(); - for (NodeFieldAccessor nodeField : nodeClass.getNodeFields()) { + for (NodeClass.NodeField nodeField : nodeClass.getNodeFields()) { if (nodeField.isChildField()) { Object child = nodeField.getObject(node); if (child != null) { @@ -212,12 +210,11 @@ public static boolean replaceChild(Node parent, Node oldChild, Node newChild) { return replaceChild(parent, oldChild, newChild, false); } - @SuppressWarnings("deprecation") static boolean replaceChild(Node parent, Node oldChild, Node newChild, boolean adopt) { CompilerAsserts.neverPartOfCompilation("do not replace Node child from compiled code"); NodeClass nodeClass = parent.getNodeClass(); - for (NodeFieldAccessor nodeField : nodeClass.getNodeFields()) { + for (NodeClass.NodeField nodeField : nodeClass.getNodeFields()) { if (nodeField.isChildField()) { if (nodeField.getObject(parent) == oldChild) { assert assertAssignable(nodeField, newChild); @@ -248,22 +245,22 @@ static boolean replaceChild(Node parent, Node oldChild, Node newChild, boolean a return false; } - private static boolean assertAssignable(NodeFieldAccessor field, Object newValue) { + private static boolean assertAssignable(NodeClass.NodeField field, Object newValue) { if (newValue == null) { return true; } - if (field.getKind() == NodeFieldKind.CHILD) { - if (field.getType().isAssignableFrom(newValue.getClass())) { + if (field.isChildField()) { + if (field.getFieldType().isAssignableFrom(newValue.getClass())) { return true; } else { - assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field \"" + field.getName() + "\" of type " + field.getType().getName(); + assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field: \"" + field.getName() + "\" of type " + field.getFieldType().getName(); return false; } - } else if (field.getKind() == NodeFieldKind.CHILDREN) { - if (field.getType().getComponentType().isAssignableFrom(newValue.getClass())) { + } else if (field.isChildrenField()) { + if (field.getFieldType().getComponentType().isAssignableFrom(newValue.getClass())) { return true; } else { - assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field \"" + field.getName() + "\" of type " + field.getType().getName(); + assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field: \"" + field.getName() + "\" of type " + field.getFieldType().getName(); return false; } } @@ -282,11 +279,11 @@ public static NodeFieldAccessor findChildField(Node parent, Node child) { NodeClass parentNodeClass = parent.getNodeClass(); for (NodeFieldAccessor field : parentNodeClass.getFields()) { - if (field.isChildField()) { + if (field.getKind() == NodeFieldKind.CHILD) { if (field.getObject(parent) == child) { return field; } - } else if (field.isChildrenField()) { + } else if (field.getKind() == NodeFieldKind.CHILDREN) { Object arrayObject = field.getObject(parent); if (arrayObject != null) { Object[] array = (Object[]) arrayObject; @@ -330,13 +327,12 @@ public static boolean isReplacementSafe(Node parent, Node oldChild, Node newChil * @return {@code true} if all children were visited, {@code false} otherwise * @since 0.8 or earlier */ - @SuppressWarnings("deprecation") public static boolean forEachChild(Node parent, NodeVisitor visitor) { CompilerAsserts.neverPartOfCompilation("do not iterate over Node children from compiled code"); Objects.requireNonNull(visitor); NodeClass parentNodeClass = parent.getNodeClass(); - for (NodeFieldAccessor field : parentNodeClass.getNodeFields()) { + for (NodeClass.NodeField field : parentNodeClass.getNodeFields()) { if (field.isChildField()) { Object child = field.getObject(parent); if (child != null) { @@ -363,11 +359,10 @@ public static boolean forEachChild(Node parent, NodeVisitor visitor) { return true; } - @SuppressWarnings("deprecation") static boolean forEachChildRecursive(Node parent, NodeVisitor visitor) { NodeClass parentNodeClass = parent.getNodeClass(); - for (NodeFieldAccessor field : parentNodeClass.getNodeFields()) { + for (NodeClass.NodeField field : parentNodeClass.getNodeFields()) { if (field.isChildField()) { if (!visitChild((Node) field.getObject(parent), visitor)) { return false; @@ -631,13 +626,12 @@ private static void printSourceAttributionTree(PrintWriter p, Node parent, Node private static String getNodeFieldName(Node parent, Node node, String defaultName) { NodeClass nodeClass = parent.getNodeClass(); - for (NodeFieldAccessor field : nodeClass.getNodeFields()) { - Object value = field.loadValue(parent); - if (field.getKind() == NodeFieldKind.CHILD && value == node) { + for (NodeClass.NodeField field : nodeClass.getNodeFields()) { + if (field.isChildField() && field.getObject(parent) == node) { return field.getName(); - } else if (field.getKind() == NodeFieldKind.CHILDREN) { + } else if (field.isChildrenField()) { int index = 0; - for (Object arrayNode : (Object[]) value) { + for (Object arrayNode : (Object[]) field.getObject(parent)) { if (arrayNode == node) { return field.getName() + "[" + index + "]"; } @@ -694,37 +688,37 @@ private static void printTree(PrintWriter p, Node node, int level) { p.print(nodeName(node)); - ArrayList childFields = new ArrayList<>(); + ArrayList childFields = new ArrayList<>(); String sep = ""; p.print("("); NodeClass nodeClass = NodeClass.get(node); - for (NodeFieldAccessor field : nodeClass.getNodeFields()) { - if (field.getKind() == NodeFieldKind.CHILD || field.getKind() == NodeFieldKind.CHILDREN) { + for (NodeClass.NodeField field : nodeClass.getNodeFields()) { + if (field.isChildField() || field.isChildrenField()) { childFields.add(field); - } else if (field.getKind() == NodeFieldKind.DATA) { + } else { p.print(sep); sep = ", "; p.print(field.getName()); p.print(" = "); - p.print(field.loadValue(node)); + p.print(field.getValue(node)); } } p.print(")"); if (childFields.size() != 0) { p.print(" {"); - for (NodeFieldAccessor field : childFields) { + for (NodeClass.NodeField field : nodeClass.getNodeFields()) { printNewLine(p, level); p.print(field.getName()); - Object value = field.loadValue(node); + Object value = field.getValue(node); if (value == null) { p.print(" = null "); - } else if (field.getKind() == NodeFieldKind.CHILD) { + } else if (field.isChildField()) { p.print(" = "); printTree(p, (Node) value, level + 1); - } else if (field.getKind() == NodeFieldKind.CHILDREN) { + } else if (field.isChildrenField()) { printChildren(p, level, value); } } From 43e1a968797383f9f2328668c7ff919303fe0ab7 Mon Sep 17 00:00:00 2001 From: Andreas Woess Date: Thu, 28 Apr 2016 13:58:45 +0200 Subject: [PATCH 5/9] Deprecate NodeFieldAccessor --- .../truffle/api/instrument/ProbeFailure.java | 4 +-- .../instrument/impl/DefaultASTPrinter.java | 20 +++++------ .../oracle/truffle/api/nodes/NodeClass.java | 6 ++++ .../truffle/api/nodes/NodeClassImpl.java | 11 +++---- .../truffle/api/nodes/NodeFieldAccessor.java | 8 ++--- .../oracle/truffle/api/nodes/NodeUtil.java | 33 +++++++++++-------- .../shell/server/InstrumentationUtils.java | 21 ++++++------ 7 files changed, 56 insertions(+), 47 deletions(-) diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeFailure.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeFailure.java index 115657725185..76d61741eca4 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeFailure.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeFailure.java @@ -25,7 +25,6 @@ package com.oracle.truffle.api.instrument; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.NodeFieldAccessor; import com.oracle.truffle.api.nodes.NodeUtil; /** @@ -139,13 +138,14 @@ public Object getWrapper() { } /** @since 0.8 or earlier */ + @SuppressWarnings("deprecation") public String getMessage() { final StringBuilder sb = new StringBuilder(reason.message + ": "); if (parent != null) { sb.append("parent=" + parent.getClass().getSimpleName() + " "); if (child != null) { sb.append("child=" + child.getClass().getSimpleName() + " "); - final NodeFieldAccessor field = NodeUtil.findChildField(parent, child); + final com.oracle.truffle.api.nodes.NodeFieldAccessor field = NodeUtil.findChildField(parent, child); if (field != null) { sb.append("field=" + field.getName() + " "); } diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultASTPrinter.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultASTPrinter.java index 50e279caeece..be9bb68a7f69 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultASTPrinter.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultASTPrinter.java @@ -30,8 +30,6 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeClass; -import com.oracle.truffle.api.nodes.NodeFieldAccessor; -import com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind; import com.oracle.truffle.api.nodes.NodeUtil; import com.oracle.truffle.api.source.SourceSection; @@ -105,12 +103,12 @@ protected void printTree(PrintWriter p, Node node, int maxDepth, Node markNode, p.print(NodeUtil.printSyntaxTags(node)); - ArrayList childFields = new ArrayList<>(); + ArrayList childFields = new ArrayList<>(); - for (NodeFieldAccessor field : NodeClass.get(node).getFields()) { - if (field.getKind() == NodeFieldKind.CHILD || field.getKind() == NodeFieldKind.CHILDREN) { + for (com.oracle.truffle.api.nodes.NodeFieldAccessor field : NodeClass.get(node).getFields()) { + if (field.getKind() == com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind.CHILD || field.getKind() == com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind.CHILDREN) { childFields.add(field); - } else if (field.getKind() == NodeFieldKind.DATA) { + } else if (field.getKind() == com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind.DATA) { // p.print(sep); // sep = ", "; // @@ -129,16 +127,16 @@ protected void printTree(PrintWriter p, Node node, int maxDepth, Node markNode, if (childFields.size() != 0) { p.print(" {"); - for (NodeFieldAccessor field : childFields) { + for (com.oracle.truffle.api.nodes.NodeFieldAccessor field : childFields) { Object value = field.loadValue(node); if (value == null) { printNewLine(p, level); p.print(field.getName()); p.print(" = null "); - } else if (field.getKind() == NodeFieldKind.CHILD) { + } else if (field.getKind() == com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind.CHILD) { printChild(p, maxDepth, markNode, level, field, value); - } else if (field.getKind() == NodeFieldKind.CHILDREN) { + } else if (field.getKind() == com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind.CHILDREN) { printChildren(p, maxDepth, markNode, level, field, value); } else { printNewLine(p, level); @@ -151,7 +149,7 @@ protected void printTree(PrintWriter p, Node node, int maxDepth, Node markNode, } } - protected void printChildren(PrintWriter p, int maxDepth, Node markNode, int level, NodeFieldAccessor field, Object value) { + protected void printChildren(PrintWriter p, int maxDepth, Node markNode, int level, com.oracle.truffle.api.nodes.NodeFieldAccessor field, Object value) { printNewLine(p, level); p.print(field.getName()); Node[] children = (Node[]) value; @@ -165,7 +163,7 @@ protected void printChildren(PrintWriter p, int maxDepth, Node markNode, int lev p.print("]"); } - protected void printChild(PrintWriter p, int maxDepth, Node markNode, int level, NodeFieldAccessor field, Object value) { + protected void printChild(PrintWriter p, int maxDepth, Node markNode, int level, com.oracle.truffle.api.nodes.NodeFieldAccessor field, Object value) { final Node valueNode = (Node) value; printNewLine(p, level, valueNode == markNode); p.print(field.getName()); diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java index a39e5d9849aa..abf7923a4775 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java @@ -63,26 +63,32 @@ public NodeClass(@SuppressWarnings("unused") Class clazz) { } /** @since 0.8 or earlier */ + @SuppressWarnings("deprecation") @Deprecated public abstract NodeFieldAccessor getNodeClassField(); /** @since 0.8 or earlier */ + @SuppressWarnings("deprecation") @Deprecated public abstract NodeFieldAccessor[] getCloneableFields(); /** @since 0.8 or earlier */ + @SuppressWarnings("deprecation") @Deprecated public abstract NodeFieldAccessor[] getFields(); /** @since 0.8 or earlier */ + @SuppressWarnings("deprecation") @Deprecated public abstract NodeFieldAccessor getParentField(); /** @since 0.8 or earlier */ + @SuppressWarnings("deprecation") @Deprecated public abstract NodeFieldAccessor[] getChildFields(); /** @since 0.8 or earlier */ + @SuppressWarnings("deprecation") @Deprecated public abstract NodeFieldAccessor[] getChildrenFields(); diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java index 9ee9ee6728ec..f6948b55c725 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java @@ -33,7 +33,6 @@ import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.nodes.Node.Children; -import com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind; /** * Information about a {@link Node} class. A single instance of this class is allocated for every @@ -63,10 +62,10 @@ final class NodeClassImpl extends NodeClass { try { Field field = Node.class.getDeclaredField("parent"); assert Node.class.isAssignableFrom(field.getType()); - parentFieldTmp = NodeFieldAccessor.create(NodeFieldKind.PARENT, field); + parentFieldTmp = NodeFieldAccessor.create(NodeFieldAccessor.NodeFieldKind.PARENT, field); field = Node.class.getDeclaredField("nodeClass"); assert NodeClass.class.isAssignableFrom(field.getType()); - nodeClassFieldTmp = NodeFieldAccessor.create(NodeFieldKind.NODE_CLASS, field); + nodeClassFieldTmp = NodeFieldAccessor.create(NodeFieldAccessor.NodeFieldKind.NODE_CLASS, field); } catch (NoSuchFieldException e) { throw new AssertionError("Node field not found", e); } @@ -94,12 +93,12 @@ private static void collectInstanceFields(Class clazz, List declaringClass, String name, Class type) { @@ -145,7 +147,6 @@ protected AbstractUnsafeNodeFieldAccessor(NodeFieldKind kind, Class declaring public abstract long getOffset(); /** @since 0.8 or earlier */ - @SuppressWarnings("deprecation") @Override public void putObject(Node receiver, Object value) { if (!type.isPrimitive() && value == null || type.isInstance(value)) { @@ -156,7 +157,6 @@ public void putObject(Node receiver, Object value) { } /** @since 0.8 or earlier */ - @SuppressWarnings("deprecation") @Override public Object getObject(Node receiver) { if (!type.isPrimitive()) { @@ -207,6 +207,7 @@ private static Unsafe getUnsafe() { } } + @SuppressWarnings("deprecation") private static final class UnsafeNodeField extends AbstractUnsafeNodeFieldAccessor implements NodeClass.NodeField { private final long offset; @@ -246,6 +247,7 @@ public boolean isCloneableField() { } } + @SuppressWarnings("deprecation") private static final class ReflectionNodeField extends NodeFieldAccessor implements NodeClass.NodeField { private final Field field; @@ -255,7 +257,6 @@ protected ReflectionNodeField(NodeFieldKind kind, Field field) { field.setAccessible(true); } - @SuppressWarnings("deprecation") @Override public void putObject(Node receiver, Object value) { assert !type.isPrimitive() && value == null || type.isInstance(value); @@ -266,7 +267,6 @@ public void putObject(Node receiver, Object value) { } } - @SuppressWarnings("deprecation") @Override public Object getObject(Node receiver) { assert !type.isPrimitive(); diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java index f9819959ce11..601264acd59d 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java @@ -39,7 +39,6 @@ import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.TruffleOptions; -import com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind; import com.oracle.truffle.api.source.SourceSection; /** @@ -274,16 +273,17 @@ private static boolean assertAssignable(NodeClass.NodeField field, Object newVal * @since 0.8 or earlier */ @SuppressWarnings("deprecation") + @Deprecated public static NodeFieldAccessor findChildField(Node parent, Node child) { assert child != null; NodeClass parentNodeClass = parent.getNodeClass(); for (NodeFieldAccessor field : parentNodeClass.getFields()) { - if (field.getKind() == NodeFieldKind.CHILD) { + if (field.getKind() == NodeFieldAccessor.NodeFieldKind.CHILD) { if (field.getObject(parent) == child) { return field; } - } else if (field.getKind() == NodeFieldKind.CHILDREN) { + } else if (field.getKind() == NodeFieldAccessor.NodeFieldKind.CHILDREN) { Object arrayObject = field.getObject(parent); if (arrayObject != null) { Object[] array = (Object[]) arrayObject; @@ -304,17 +304,24 @@ public static NodeFieldAccessor findChildField(Node parent, Node child) { * @since 0.8 or earlier */ public static boolean isReplacementSafe(Node parent, Node oldChild, Node newChild) { - assert newChild != null; + Objects.requireNonNull(oldChild); if (parent != null) { - final NodeFieldAccessor field = findChildField(parent, oldChild); - if (field != null) { - switch (field.getKind()) { - case CHILD: - return field.getType().isAssignableFrom(newChild.getClass()); - case CHILDREN: - return field.getType().getComponentType().isAssignableFrom(newChild.getClass()); - default: - throw new IllegalStateException(); + NodeClass nodeClass = parent.getNodeClass(); + for (NodeClass.NodeField field : nodeClass.getNodeFields()) { + if (field.isChildField()) { + if (field.getObject(parent) == oldChild) { + return field.getFieldType().isAssignableFrom(newChild.getClass()); + } + } else if (field.isChildrenField()) { + Object arrayObject = field.getObject(parent); + if (arrayObject != null) { + Object[] array = (Object[]) arrayObject; + for (int i = 0; i < array.length; i++) { + if (array[i] == oldChild) { + return field.getFieldType().getComponentType().isAssignableFrom(newChild.getClass()); + } + } + } } } } diff --git a/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/InstrumentationUtils.java b/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/InstrumentationUtils.java index 5e5a24b49199..b27ba83825fc 100644 --- a/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/InstrumentationUtils.java +++ b/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/InstrumentationUtils.java @@ -31,13 +31,12 @@ import com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeClass; -import com.oracle.truffle.api.nodes.NodeFieldAccessor; -import com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind; import com.oracle.truffle.api.source.SourceSection; /** * A language-agnostic for printing out various pieces of a Truffle AST. */ +@SuppressWarnings("deprecation") final class InstrumentationUtils { private InstrumentationUtils() { @@ -120,7 +119,6 @@ protected String displayTags(final Object node) { return ""; } - @SuppressWarnings("deprecation") protected void printTree(PrintWriter p, Node node, int maxDepth, Node markNode, int level) { if (node == null) { p.print("null"); @@ -132,24 +130,25 @@ protected void printTree(PrintWriter p, Node node, int maxDepth, Node markNode, p.print(displayNodeWithInstrumentation(node)); } if (level <= maxDepth) { - ArrayList childFields = new ArrayList<>(); - for (NodeFieldAccessor field : NodeClass.get(node).getFields()) { - if (field.getKind() == NodeFieldKind.CHILD || field.getKind() == NodeFieldKind.CHILDREN) { + ArrayList childFields = new ArrayList<>(); + for (com.oracle.truffle.api.nodes.NodeFieldAccessor field : NodeClass.get(node).getFields()) { + if (field.getKind() == com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind.CHILD || + field.getKind() == com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind.CHILDREN) { childFields.add(field); } } if (childFields.size() != 0) { p.print(" {"); - for (NodeFieldAccessor field : childFields) { + for (com.oracle.truffle.api.nodes.NodeFieldAccessor field : childFields) { Object value = field.loadValue(node); if (value == null) { printNewLine(p, level); p.print(field.getName()); p.print(" = null "); - } else if (field.getKind() == NodeFieldKind.CHILD) { + } else if (field.getKind() == com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind.CHILD) { printChild(p, maxDepth, markNode, level, field, value); - } else if (field.getKind() == NodeFieldKind.CHILDREN) { + } else if (field.getKind() == com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind.CHILDREN) { printChildren(p, maxDepth, markNode, level, field, value); } else { printNewLine(p, level); @@ -162,7 +161,7 @@ protected void printTree(PrintWriter p, Node node, int maxDepth, Node markNode, } } - protected void printChildren(PrintWriter p, int maxDepth, Node markNode, int level, NodeFieldAccessor field, Object value) { + protected void printChildren(PrintWriter p, int maxDepth, Node markNode, int level, com.oracle.truffle.api.nodes.NodeFieldAccessor field, Object value) { printNewLine(p, level); p.print(field.getName()); Node[] children = (Node[]) value; @@ -176,7 +175,7 @@ protected void printChildren(PrintWriter p, int maxDepth, Node markNode, int lev p.print("]"); } - protected void printChild(PrintWriter p, int maxDepth, Node markNode, int level, NodeFieldAccessor field, Object value) { + protected void printChild(PrintWriter p, int maxDepth, Node markNode, int level, com.oracle.truffle.api.nodes.NodeFieldAccessor field, Object value) { final Node valueNode = (Node) value; printNewLine(p, level, valueNode == markNode); p.print(field.getName()); From dec0c950aaa20e12bc9ef2b9a4e107ef2969f8dd Mon Sep 17 00:00:00 2001 From: Andreas Woess Date: Wed, 27 Apr 2016 19:16:49 +0200 Subject: [PATCH 6/9] Replace assertAssignable with more descriptive IllegalArgumentException --- .../truffle/api/nodes/NodeFieldAccessor.java | 16 ++++++++-- .../oracle/truffle/api/nodes/NodeUtil.java | 30 +++++-------------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java index 8a115409d84a..99413f0fac7e 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java @@ -26,11 +26,11 @@ import java.lang.reflect.Field; -import sun.misc.Unsafe; - import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.nodes.Node.Children; +import sun.misc.Unsafe; + /** * Information about a field in a {@link Node} class. * @@ -135,6 +135,12 @@ public String getName() { /** @since 0.8 or earlier */ public abstract Object loadValue(Node node); + /** @since 0.14 */ + @Override + public String toString() { + return getDeclaringClass().getName() + "." + getName(); + } + /** @since 0.8 or earlier */ @SuppressWarnings("deprecation") public abstract static class AbstractUnsafeNodeFieldAccessor extends NodeFieldAccessor { @@ -152,10 +158,14 @@ public void putObject(Node receiver, Object value) { if (!type.isPrimitive() && value == null || type.isInstance(value)) { unsafe.putObject(receiver, getOffset(), value); } else { - throw new IllegalArgumentException(); + throw illegalArgumentException(value); } } + private IllegalArgumentException illegalArgumentException(Object value) { + return new IllegalArgumentException("Cannot set " + getType().getName() + " field " + toString() + " to " + (value == null ? "null" : value.getClass().getName())); + } + /** @since 0.8 or earlier */ @Override public Object getObject(Node receiver) { diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java index 601264acd59d..44848730948f 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java @@ -216,7 +216,6 @@ static boolean replaceChild(Node parent, Node oldChild, Node newChild, boolean a for (NodeClass.NodeField nodeField : nodeClass.getNodeFields()) { if (nodeField.isChildField()) { if (nodeField.getObject(parent) == oldChild) { - assert assertAssignable(nodeField, newChild); if (adopt) { parent.adoptHelper(newChild); } @@ -229,11 +228,14 @@ static boolean replaceChild(Node parent, Node oldChild, Node newChild, boolean a Object[] array = (Object[]) arrayObject; for (int i = 0; i < array.length; i++) { if (array[i] == oldChild) { - assert assertAssignable(nodeField, newChild); if (adopt) { parent.adoptHelper(newChild); } - array[i] = newChild; + try { + array[i] = newChild; + } catch (ArrayStoreException e) { + throw replaceChildIllegalArgumentException(nodeField, array.getClass(), newChild); + } return true; } } @@ -244,26 +246,8 @@ static boolean replaceChild(Node parent, Node oldChild, Node newChild, boolean a return false; } - private static boolean assertAssignable(NodeClass.NodeField field, Object newValue) { - if (newValue == null) { - return true; - } - if (field.isChildField()) { - if (field.getFieldType().isAssignableFrom(newValue.getClass())) { - return true; - } else { - assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field: \"" + field.getName() + "\" of type " + field.getFieldType().getName(); - return false; - } - } else if (field.isChildrenField()) { - if (field.getFieldType().getComponentType().isAssignableFrom(newValue.getClass())) { - return true; - } else { - assert false : "Child class " + newValue.getClass().getName() + " is not assignable to field: \"" + field.getName() + "\" of type " + field.getFieldType().getName(); - return false; - } - } - throw new IllegalArgumentException(); + private static IllegalArgumentException replaceChildIllegalArgumentException(NodeClass.NodeField nodeField, Class fieldType, Node newChild) { + return new IllegalArgumentException("Cannot set element of " + fieldType.getName() + " field " + nodeField + " to " + (newChild == null ? "null" : newChild.getClass().getName())); } /** From 79fa52b8c917f6834d6063c8b3bc83b0a4c440d9 Mon Sep 17 00:00:00 2001 From: Andreas Woess Date: Fri, 29 Apr 2016 17:34:14 +0200 Subject: [PATCH 7/9] Sort node fields by kind, so that iteration can be stopped early --- .../com/oracle/truffle/api/nodes/NodeClass.java | 14 ++++++++++++++ .../oracle/truffle/api/nodes/NodeClassImpl.java | 17 +++++++++++++++++ .../com/oracle/truffle/api/nodes/NodeUtil.java | 14 ++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java index abf7923a4775..2a0f74ae1b2d 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java @@ -107,6 +107,20 @@ public NodeClass(@SuppressWarnings("unused") Class clazz) { */ public abstract Class getType(); + /** + * If and only if this method returns {@code true}, {@link #getNodeFields()} adheres to the + * following iteration order. + *
    + *
  • {@link Node.Child @Child} fields + *
  • {@link Node.Children @Children} fields + *
  • {@link NodeCloneable} fields + *
  • Other fields + *
+ */ + boolean nodeFieldsOrderedByKind() { + return false; + } + /** @since 0.14 */ protected interface NodeField { /** @since 0.14 */ diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java index f6948b55c725..f7f6f9b06137 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java @@ -27,6 +27,8 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; @@ -72,6 +74,16 @@ final class NodeClassImpl extends NodeClass { collectInstanceFields(clazz, fieldsList); + Collections.sort(fieldsList, new Comparator() { + public int compare(NodeField o1, NodeField o2) { + return Integer.compare(order(o1), order(o2)); + } + + private int order(NodeField nodeField) { + return nodeField.isChildField() ? 0 : (nodeField.isChildrenField() ? 1 : (nodeField.isCloneableField() ? 2 : 3)); + } + }); + this.fields = fieldsList.toArray(EMPTY_NODE_FIELD_ARRAY); this.nodeClassField = nodeClassFieldTmp; this.parentField = parentFieldTmp; @@ -256,6 +268,11 @@ private static NodeFieldAccessor[] iterableToArray(Iterable fields) { return fieldList.toArray(new NodeFieldAccessor[0]); } + @Override + boolean nodeFieldsOrderedByKind() { + return true; + } + private static final class NodeIterator implements Iterator { private final NodeField[] fields; private final Node node; diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java index 44848730948f..017921e1e91e 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java @@ -167,6 +167,8 @@ static Node deepCopyImpl(Node orig) { if (cloneable != null && cloneable == field.getObject(orig)) { field.putObject(clone, ((NodeCloneable) cloneable).clone()); } + } else if (nodeClass.nodeFieldsOrderedByKind()) { + break; } } return clone; @@ -193,6 +195,8 @@ public static List findNodeChildren(Node node) { } } } + } else if (nodeClass.nodeFieldsOrderedByKind()) { + break; } } return nodes; @@ -240,6 +244,8 @@ static boolean replaceChild(Node parent, Node oldChild, Node newChild, boolean a } } } + } else if (nodeClass.nodeFieldsOrderedByKind()) { + break; } } @@ -306,6 +312,8 @@ public static boolean isReplacementSafe(Node parent, Node oldChild, Node newChil } } } + } else if (nodeClass.nodeFieldsOrderedByKind()) { + break; } } } @@ -344,6 +352,8 @@ public static boolean forEachChild(Node parent, NodeVisitor visitor) { } } } + } else if (parentNodeClass.nodeFieldsOrderedByKind()) { + break; } } @@ -369,6 +379,8 @@ static boolean forEachChildRecursive(Node parent, NodeVisitor visitor) { return false; } } + } else if (parentNodeClass.nodeFieldsOrderedByKind()) { + break; } } @@ -628,6 +640,8 @@ private static String getNodeFieldName(Node parent, Node node, String defaultNam } index++; } + } else if (nodeClass.nodeFieldsOrderedByKind()) { + break; } } return defaultName; From c3556d93a8a600b305b27356cdc1c23303b0bcdc Mon Sep 17 00:00:00 2001 From: Andreas Woess Date: Tue, 3 May 2016 03:09:49 +0200 Subject: [PATCH 8/9] Remove NodeField interface and add equivalent methods to NodeClass instead --- .../truffle/api/nodes/GraphPrintVisitor.java | 26 ++-- .../oracle/truffle/api/nodes/NodeClass.java | 57 ++++----- .../truffle/api/nodes/NodeClassImpl.java | 110 +++++++++++----- .../truffle/api/nodes/NodeFieldAccessor.java | 54 +------- .../oracle/truffle/api/nodes/NodeUtil.java | 120 +++++++++--------- 5 files changed, 179 insertions(+), 188 deletions(-) diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java index 4d71415698fb..bfe9613db505 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java @@ -488,19 +488,19 @@ private void copyDebugProperties(Node node) { private void readNodeProperties(Node node) { NodeClass nodeClass = NodeClass.get(node); - for (NodeClass.NodeField field : nodeClass.getNodeFields()) { - if (isDataField(field)) { - String key = field.getName(); + for (Object field : nodeClass.getNodeFields()) { + if (isDataField(nodeClass, field)) { + String key = nodeClass.getFieldName(field); if (!getElementByObject(node).getProperties().containsKey(key)) { - Object value = field.getValue(node); + Object value = nodeClass.getFieldValue(field, node); setNodeProperty(node, key, value); } } } } - private static boolean isDataField(NodeClass.NodeField field) { - return !field.isChildField() && !field.isChildrenField(); + private static boolean isDataField(NodeClass nodeClass, Object field) { + return !nodeClass.isChildField(field) && !nodeClass.isChildrenField(field); } final void connectNodes(Object a, Object b, String label) { @@ -567,19 +567,19 @@ private static LinkedHashMap findNamedNodeChildren(Node node) { LinkedHashMap nodes = new LinkedHashMap<>(); NodeClass nodeClass = NodeClass.get(node); - for (NodeClass.NodeField field : nodeClass.getNodeFields()) { - if (field.isChildField()) { - Object value = field.getObject(node); + for (Object field : nodeClass.getNodeFields()) { + if (nodeClass.isChildField(field)) { + Object value = nodeClass.getFieldObject(field, node); if (value != null) { - nodes.put(field.getName(), (Node) value); + nodes.put(nodeClass.getFieldName(field), (Node) value); } - } else if (field.isChildrenField()) { - Object value = field.getObject(node); + } else if (nodeClass.isChildrenField(field)) { + Object value = nodeClass.getFieldObject(field, node); if (value != null) { Object[] children = (Object[]) value; for (int i = 0; i < children.length; i++) { if (children[i] != null) { - nodes.put(field.getName() + "[" + i + "]", (Node) children[i]); + nodes.put(nodeClass.getFieldName(field) + "[" + i + "]", (Node) children[i]); } } } diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java index 2a0f74ae1b2d..6fdad1fb53a4 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java @@ -92,9 +92,6 @@ public NodeClass(@SuppressWarnings("unused") Class clazz) { @Deprecated public abstract NodeFieldAccessor[] getChildrenFields(); - /** @since 0.14 */ - protected abstract Iterable getNodeFields(); - /** @since 0.8 or earlier */ public abstract Iterator makeIterator(Node node); @@ -107,6 +104,33 @@ public NodeClass(@SuppressWarnings("unused") Class clazz) { */ public abstract Class getType(); + /** @since 0.14 */ + protected abstract Iterable getNodeFields(); + + /** @since 0.14 */ + protected abstract void putFieldObject(Object field, Node receiver, Object value); + + /** @since 0.14 */ + protected abstract Object getFieldObject(Object field, Node receiver); + + /** @since 0.14 */ + protected abstract Object getFieldValue(Object field, Node receiver); + + /** @since 0.14 */ + protected abstract Class getFieldType(Object field); + + /** @since 0.14 */ + protected abstract String getFieldName(Object field); + + /** @since 0.14 */ + protected abstract boolean isChildField(Object field); + + /** @since 0.14 */ + protected abstract boolean isChildrenField(Object field); + + /** @since 0.14 */ + protected abstract boolean isCloneableField(Object field); + /** * If and only if this method returns {@code true}, {@link #getNodeFields()} adheres to the * following iteration order. @@ -120,31 +144,4 @@ public NodeClass(@SuppressWarnings("unused") Class clazz) { boolean nodeFieldsOrderedByKind() { return false; } - - /** @since 0.14 */ - protected interface NodeField { - /** @since 0.14 */ - void putObject(Node receiver, Object value); - - /** @since 0.14 */ - Object getObject(Node receiver); - - /** @since 0.14 */ - Object getValue(Node receiver); - - /** @since 0.14 */ - Class getFieldType(); - - /** @since 0.14 */ - String getName(); - - /** @since 0.14 */ - boolean isChildField(); - - /** @since 0.14 */ - boolean isChildrenField(); - - /** @since 0.14 */ - boolean isCloneableField(); - } } diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java index f7f6f9b06137..2e65db1656c3 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClassImpl.java @@ -42,10 +42,10 @@ */ @SuppressWarnings("deprecation") final class NodeClassImpl extends NodeClass { - private static final NodeField[] EMPTY_NODE_FIELD_ARRAY = new NodeField[0]; + private static final NodeFieldAccessor[] EMPTY_NODE_FIELD_ARRAY = new NodeFieldAccessor[0]; // The comprehensive list of all fields. - private final NodeField[] fields; + private final NodeFieldAccessor[] fields; private final NodeFieldAccessor parentField; private final NodeFieldAccessor nodeClassField; @@ -57,7 +57,7 @@ final class NodeClassImpl extends NodeClass { throw new IllegalArgumentException(); } - List fieldsList = new ArrayList<>(); + List fieldsList = new ArrayList<>(); NodeFieldAccessor parentFieldTmp = null; NodeFieldAccessor nodeClassFieldTmp = null; @@ -74,13 +74,13 @@ final class NodeClassImpl extends NodeClass { collectInstanceFields(clazz, fieldsList); - Collections.sort(fieldsList, new Comparator() { - public int compare(NodeField o1, NodeField o2) { + Collections.sort(fieldsList, new Comparator() { + public int compare(NodeFieldAccessor o1, NodeFieldAccessor o2) { return Integer.compare(order(o1), order(o2)); } - private int order(NodeField nodeField) { - return nodeField.isChildField() ? 0 : (nodeField.isChildrenField() ? 1 : (nodeField.isCloneableField() ? 2 : 3)); + private int order(NodeFieldAccessor nodeField) { + return isChildField(nodeField) ? 0 : (isChildrenField(nodeField) ? 1 : (isCloneableField(nodeField) ? 2 : 3)); } }); @@ -90,7 +90,7 @@ private int order(NodeField nodeField) { this.clazz = clazz; } - private static void collectInstanceFields(Class clazz, List fieldsList) { + private static void collectInstanceFields(Class clazz, List fieldsList) { if (clazz.getSuperclass() != null) { collectInstanceFields(clazz.getSuperclass(), fieldsList); } @@ -112,7 +112,7 @@ private static void collectInstanceFields(Class clazz, List getType() { } @Override - protected Iterable getNodeFields() { + protected Iterable getNodeFields() { return getNodeFields(null); } @@ -182,13 +182,13 @@ protected Iterable getNodeFields() { * Functional interface equivalent to {@code Predicate}. */ private interface NodeFieldFilter { - boolean test(NodeField field); + boolean test(NodeFieldAccessor field); } - private Iterable getNodeFields(final NodeFieldFilter filter) { - return new Iterable() { - public Iterator iterator() { - return new Iterator() { + private Iterable getNodeFields(final NodeFieldFilter filter) { + return new Iterable() { + public Iterator iterator() { + return new Iterator() { private int cursor = -1; { forward(); @@ -196,7 +196,7 @@ public Iterator iterator() { private void forward() { for (int i = cursor + 1; i < fields.length; i++) { - NodeField field = fields[i]; + NodeFieldAccessor field = fields[i]; if (filter == null || filter.test(field)) { cursor = i; return; @@ -210,9 +210,9 @@ public boolean hasNext() { return cursor < fields.length; } - public NodeField next() { + public NodeFieldAccessor next() { if (hasNext()) { - NodeField next = fields[cursor]; + NodeFieldAccessor next = fields[cursor]; forward(); return next; } else { @@ -236,8 +236,8 @@ public NodeFieldAccessor[] getFields() { @Override public NodeFieldAccessor[] getChildFields() { return iterableToArray(getNodeFields(new NodeFieldFilter() { - public boolean test(NodeField field) { - return field.isChildField(); + public boolean test(NodeFieldAccessor field) { + return isChildField(field); } })); } @@ -245,8 +245,8 @@ public boolean test(NodeField field) { @Override public NodeFieldAccessor[] getChildrenFields() { return iterableToArray(getNodeFields(new NodeFieldFilter() { - public boolean test(NodeField field) { - return field.isChildrenField(); + public boolean test(NodeFieldAccessor field) { + return isChildrenField(field); } })); } @@ -254,27 +254,68 @@ public boolean test(NodeField field) { @Override public NodeFieldAccessor[] getCloneableFields() { return iterableToArray(getNodeFields(new NodeFieldFilter() { - public boolean test(NodeField field) { - return field.isCloneableField(); + public boolean test(NodeFieldAccessor field) { + return isCloneableField(field); } })); } - private static NodeFieldAccessor[] iterableToArray(Iterable fields) { + private static NodeFieldAccessor[] iterableToArray(Iterable fields) { ArrayList fieldList = new ArrayList<>(); - for (NodeField field : fields) { - fieldList.add((NodeFieldAccessor) field); + for (NodeFieldAccessor field : fields) { + fieldList.add(field); } return fieldList.toArray(new NodeFieldAccessor[0]); } + @Override + protected void putFieldObject(Object field, Node receiver, Object value) { + ((NodeFieldAccessor) field).putObject(receiver, value); + } + + @Override + protected Object getFieldObject(Object field, Node receiver) { + return ((NodeFieldAccessor) field).getObject(receiver); + } + + @Override + protected Object getFieldValue(Object field, Node receiver) { + return ((NodeFieldAccessor) field).loadValue(receiver); + } + + @Override + protected Class getFieldType(Object field) { + return ((NodeFieldAccessor) field).getType(); + } + + @Override + protected String getFieldName(Object field) { + return ((NodeFieldAccessor) field).getName(); + } + + @Override + protected boolean isChildField(Object field) { + return ((NodeFieldAccessor) field).getKind() == NodeFieldAccessor.NodeFieldKind.CHILD; + } + + @Override + protected boolean isChildrenField(Object field) { + return ((NodeFieldAccessor) field).getKind() == NodeFieldAccessor.NodeFieldKind.CHILDREN; + } + + @Override + protected boolean isCloneableField(Object field) { + return ((NodeFieldAccessor) field).getKind() == NodeFieldAccessor.NodeFieldKind.DATA && NodeCloneable.class.isAssignableFrom(((NodeFieldAccessor) field).getType()); + } + @Override boolean nodeFieldsOrderedByKind() { return true; } private static final class NodeIterator implements Iterator { - private final NodeField[] fields; + private final NodeClassImpl nodeClass; + private final NodeFieldAccessor[] fields; private final Node node; private int fieldIndex; @@ -283,6 +324,7 @@ private static final class NodeIterator implements Iterator { private Object[] children; protected NodeIterator(NodeClassImpl nodeClass, Node node) { + this.nodeClass = nodeClass; this.fields = nodeClass.fields; this.node = node; advance(); @@ -293,17 +335,19 @@ private void advance() { return; } while (fieldIndex < fields.length) { - NodeField field = fields[fieldIndex]; + NodeFieldAccessor field = fields[fieldIndex]; fieldIndex++; - if (field.isChildField()) { - next = (Node) field.getObject(node); + if (nodeClass.isChildField(field)) { + next = (Node) nodeClass.getFieldObject(field, node); return; - } else if (field.isChildrenField()) { - children = (Object[]) field.getObject(node); + } else if (nodeClass.isChildrenField(field)) { + children = (Object[]) nodeClass.getFieldObject(field, node); childrenIndex = 0; if (advanceChildren()) { return; } + } else if (nodeClass.nodeFieldsOrderedByKind()) { + break; } } next = null; diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java index 99413f0fac7e..00d18f8a6a5a 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeFieldAccessor.java @@ -218,7 +218,7 @@ private static Unsafe getUnsafe() { } @SuppressWarnings("deprecation") - private static final class UnsafeNodeField extends AbstractUnsafeNodeFieldAccessor implements NodeClass.NodeField { + private static final class UnsafeNodeField extends AbstractUnsafeNodeFieldAccessor { private final long offset; protected UnsafeNodeField(NodeFieldKind kind, Field field) { @@ -230,35 +230,10 @@ protected UnsafeNodeField(NodeFieldKind kind, Field field) { public long getOffset() { return offset; } - - @Override - public Class getFieldType() { - return getType(); - } - - @Override - public Object getValue(Node receiver) { - return loadValue(receiver); - } - - @Override - public boolean isChildField() { - return getKind() == NodeFieldKind.CHILD; - } - - @Override - public boolean isChildrenField() { - return getKind() == NodeFieldKind.CHILDREN; - } - - @Override - public boolean isCloneableField() { - return getKind() == NodeFieldKind.DATA && NodeCloneable.class.isAssignableFrom(getType()); - } } @SuppressWarnings("deprecation") - private static final class ReflectionNodeField extends NodeFieldAccessor implements NodeClass.NodeField { + private static final class ReflectionNodeField extends NodeFieldAccessor { private final Field field; protected ReflectionNodeField(NodeFieldKind kind, Field field) { @@ -313,31 +288,6 @@ public Object loadValue(Node node) { throw new AssertionError(e); } } - - @Override - public Object getValue(Node receiver) { - return loadValue(receiver); - } - - @Override - public Class getFieldType() { - return getType(); - } - - @Override - public boolean isChildField() { - return getKind() == NodeFieldKind.CHILD; - } - - @Override - public boolean isChildrenField() { - return getKind() == NodeFieldKind.CHILDREN; - } - - @Override - public boolean isCloneableField() { - return getKind() == NodeFieldKind.DATA && NodeCloneable.class.isAssignableFrom(getType()); - } } } diff --git a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java index 017921e1e91e..6eb51afaad08 100644 --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java @@ -141,16 +141,16 @@ static Node deepCopyImpl(Node orig) { clone.setParent(null); - for (NodeClass.NodeField field : nodeClass.getNodeFields()) { - if (field.isChildField()) { - Node child = (Node) field.getObject(orig); + for (Object field : nodeClass.getNodeFields()) { + if (nodeClass.isChildField(field)) { + Node child = (Node) nodeClass.getFieldObject(field, orig); if (child != null) { Node clonedChild = child.deepCopy(); clonedChild.setParent(clone); - field.putObject(clone, clonedChild); + nodeClass.putFieldObject(field, clone, clonedChild); } - } else if (field.isChildrenField()) { - Object[] children = (Object[]) field.getObject(orig); + } else if (nodeClass.isChildrenField(field)) { + Object[] children = (Object[]) nodeClass.getFieldObject(field, orig); if (children != null) { Object[] clonedChildren = (Object[]) Array.newInstance(children.getClass().getComponentType(), children.length); for (int i = 0; i < children.length; i++) { @@ -160,12 +160,12 @@ static Node deepCopyImpl(Node orig) { clonedChildren[i] = clonedChild; } } - field.putObject(clone, clonedChildren); + nodeClass.putFieldObject(field, clone, clonedChildren); } - } else if (field.isCloneableField()) { - Object cloneable = field.getObject(clone); - if (cloneable != null && cloneable == field.getObject(orig)) { - field.putObject(clone, ((NodeCloneable) cloneable).clone()); + } else if (nodeClass.isCloneableField(field)) { + Object cloneable = nodeClass.getFieldObject(field, clone); + if (cloneable != null && cloneable == nodeClass.getFieldObject(field, orig)) { + nodeClass.putFieldObject(field, clone, ((NodeCloneable) cloneable).clone()); } } else if (nodeClass.nodeFieldsOrderedByKind()) { break; @@ -180,14 +180,14 @@ public static List findNodeChildren(Node node) { List nodes = new ArrayList<>(); NodeClass nodeClass = node.getNodeClass(); - for (NodeClass.NodeField nodeField : nodeClass.getNodeFields()) { - if (nodeField.isChildField()) { - Object child = nodeField.getObject(node); + for (Object nodeField : nodeClass.getNodeFields()) { + if (nodeClass.isChildField(nodeField)) { + Object child = nodeClass.getFieldObject(nodeField, node); if (child != null) { nodes.add((Node) child); } - } else if (nodeField.isChildrenField()) { - Object[] children = (Object[]) nodeField.getObject(node); + } else if (nodeClass.isChildrenField(nodeField)) { + Object[] children = (Object[]) nodeClass.getFieldObject(nodeField, node); if (children != null) { for (Object child : children) { if (child != null) { @@ -217,17 +217,17 @@ static boolean replaceChild(Node parent, Node oldChild, Node newChild, boolean a CompilerAsserts.neverPartOfCompilation("do not replace Node child from compiled code"); NodeClass nodeClass = parent.getNodeClass(); - for (NodeClass.NodeField nodeField : nodeClass.getNodeFields()) { - if (nodeField.isChildField()) { - if (nodeField.getObject(parent) == oldChild) { + for (Object nodeField : nodeClass.getNodeFields()) { + if (nodeClass.isChildField(nodeField)) { + if (nodeClass.getFieldObject(nodeField, parent) == oldChild) { if (adopt) { parent.adoptHelper(newChild); } - nodeField.putObject(parent, newChild); + nodeClass.putFieldObject(nodeField, parent, newChild); return true; } - } else if (nodeField.isChildrenField()) { - Object arrayObject = nodeField.getObject(parent); + } else if (nodeClass.isChildrenField(nodeField)) { + Object arrayObject = nodeClass.getFieldObject(nodeField, parent); if (arrayObject != null) { Object[] array = (Object[]) arrayObject; for (int i = 0; i < array.length; i++) { @@ -252,7 +252,7 @@ static boolean replaceChild(Node parent, Node oldChild, Node newChild, boolean a return false; } - private static IllegalArgumentException replaceChildIllegalArgumentException(NodeClass.NodeField nodeField, Class fieldType, Node newChild) { + private static IllegalArgumentException replaceChildIllegalArgumentException(Object nodeField, Class fieldType, Node newChild) { return new IllegalArgumentException("Cannot set element of " + fieldType.getName() + " field " + nodeField + " to " + (newChild == null ? "null" : newChild.getClass().getName())); } @@ -297,18 +297,18 @@ public static boolean isReplacementSafe(Node parent, Node oldChild, Node newChil Objects.requireNonNull(oldChild); if (parent != null) { NodeClass nodeClass = parent.getNodeClass(); - for (NodeClass.NodeField field : nodeClass.getNodeFields()) { - if (field.isChildField()) { - if (field.getObject(parent) == oldChild) { - return field.getFieldType().isAssignableFrom(newChild.getClass()); + for (Object field : nodeClass.getNodeFields()) { + if (nodeClass.isChildField(field)) { + if (nodeClass.getFieldObject(field, parent) == oldChild) { + return nodeClass.getFieldType(field).isAssignableFrom(newChild.getClass()); } - } else if (field.isChildrenField()) { - Object arrayObject = field.getObject(parent); + } else if (nodeClass.isChildrenField(field)) { + Object arrayObject = nodeClass.getFieldObject(field, parent); if (arrayObject != null) { Object[] array = (Object[]) arrayObject; for (int i = 0; i < array.length; i++) { if (array[i] == oldChild) { - return field.getFieldType().getComponentType().isAssignableFrom(newChild.getClass()); + return nodeClass.getFieldType(field).getComponentType().isAssignableFrom(newChild.getClass()); } } } @@ -329,18 +329,18 @@ public static boolean isReplacementSafe(Node parent, Node oldChild, Node newChil public static boolean forEachChild(Node parent, NodeVisitor visitor) { CompilerAsserts.neverPartOfCompilation("do not iterate over Node children from compiled code"); Objects.requireNonNull(visitor); - NodeClass parentNodeClass = parent.getNodeClass(); + NodeClass nodeClass = parent.getNodeClass(); - for (NodeClass.NodeField field : parentNodeClass.getNodeFields()) { - if (field.isChildField()) { - Object child = field.getObject(parent); + for (Object field : nodeClass.getNodeFields()) { + if (nodeClass.isChildField(field)) { + Object child = nodeClass.getFieldObject(field, parent); if (child != null) { if (!visitor.visit((Node) child)) { return false; } } - } else if (field.isChildrenField()) { - Object arrayObject = field.getObject(parent); + } else if (nodeClass.isChildrenField(field)) { + Object arrayObject = nodeClass.getFieldObject(field, parent); if (arrayObject != null) { Object[] array = (Object[]) arrayObject; for (int i = 0; i < array.length; i++) { @@ -352,7 +352,7 @@ public static boolean forEachChild(Node parent, NodeVisitor visitor) { } } } - } else if (parentNodeClass.nodeFieldsOrderedByKind()) { + } else if (nodeClass.nodeFieldsOrderedByKind()) { break; } } @@ -361,15 +361,15 @@ public static boolean forEachChild(Node parent, NodeVisitor visitor) { } static boolean forEachChildRecursive(Node parent, NodeVisitor visitor) { - NodeClass parentNodeClass = parent.getNodeClass(); + NodeClass nodeClass = parent.getNodeClass(); - for (NodeClass.NodeField field : parentNodeClass.getNodeFields()) { - if (field.isChildField()) { - if (!visitChild((Node) field.getObject(parent), visitor)) { + for (Object field : nodeClass.getNodeFields()) { + if (nodeClass.isChildField(field)) { + if (!visitChild((Node) nodeClass.getFieldObject(field, parent), visitor)) { return false; } - } else if (field.isChildrenField()) { - Object arrayObject = field.getObject(parent); + } else if (nodeClass.isChildrenField(field)) { + Object arrayObject = nodeClass.getFieldObject(field, parent); if (arrayObject == null) { continue; } @@ -379,7 +379,7 @@ static boolean forEachChildRecursive(Node parent, NodeVisitor visitor) { return false; } } - } else if (parentNodeClass.nodeFieldsOrderedByKind()) { + } else if (nodeClass.nodeFieldsOrderedByKind()) { break; } } @@ -629,14 +629,14 @@ private static void printSourceAttributionTree(PrintWriter p, Node parent, Node private static String getNodeFieldName(Node parent, Node node, String defaultName) { NodeClass nodeClass = parent.getNodeClass(); - for (NodeClass.NodeField field : nodeClass.getNodeFields()) { - if (field.isChildField() && field.getObject(parent) == node) { - return field.getName(); - } else if (field.isChildrenField()) { + for (Object field : nodeClass.getNodeFields()) { + if (nodeClass.isChildField(field) && nodeClass.getFieldObject(field, parent) == node) { + return nodeClass.getFieldName(field); + } else if (nodeClass.isChildrenField(field)) { int index = 0; - for (Object arrayNode : (Object[]) field.getObject(parent)) { + for (Object arrayNode : (Object[]) nodeClass.getFieldObject(field, parent)) { if (arrayNode == node) { - return field.getName() + "[" + index + "]"; + return nodeClass.getFieldName(field) + "[" + index + "]"; } index++; } @@ -693,37 +693,37 @@ private static void printTree(PrintWriter p, Node node, int level) { p.print(nodeName(node)); - ArrayList childFields = new ArrayList<>(); + ArrayList childFields = new ArrayList<>(); String sep = ""; p.print("("); NodeClass nodeClass = NodeClass.get(node); - for (NodeClass.NodeField field : nodeClass.getNodeFields()) { - if (field.isChildField() || field.isChildrenField()) { + for (Object field : nodeClass.getNodeFields()) { + if (nodeClass.isChildField(field) || nodeClass.isChildrenField(field)) { childFields.add(field); } else { p.print(sep); sep = ", "; - p.print(field.getName()); + p.print(nodeClass.getFieldName(field)); p.print(" = "); - p.print(field.getValue(node)); + p.print(nodeClass.getFieldValue(field, node)); } } p.print(")"); if (childFields.size() != 0) { p.print(" {"); - for (NodeClass.NodeField field : nodeClass.getNodeFields()) { + for (Object field : nodeClass.getNodeFields()) { printNewLine(p, level); - p.print(field.getName()); + p.print(nodeClass.getFieldName(field)); - Object value = field.getValue(node); + Object value = nodeClass.getFieldValue(field, node); if (value == null) { p.print(" = null "); - } else if (field.isChildField()) { + } else if (nodeClass.isChildField(field)) { p.print(" = "); printTree(p, (Node) value, level + 1); - } else if (field.isChildrenField()) { + } else if (nodeClass.isChildrenField(field)) { printChildren(p, level, value); } } From ce0dc4c77915817754f92f9625f28ccdfe04741c Mon Sep 17 00:00:00 2001 From: Andreas Woess Date: Tue, 3 May 2016 03:29:29 +0200 Subject: [PATCH 9/9] Update sigtest snapshot --- .../com.oracle.truffle.api/snapshot.sigtest | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/truffle/com.oracle.truffle.api/snapshot.sigtest b/truffle/com.oracle.truffle.api/snapshot.sigtest index 83320b5fd309..95083cef5040 100644 --- a/truffle/com.oracle.truffle.api/snapshot.sigtest +++ b/truffle/com.oracle.truffle.api/snapshot.sigtest @@ -695,12 +695,27 @@ intf java.lang.annotation.Annotation CLSS public abstract com.oracle.truffle.api.nodes.NodeClass cons public init(java.lang.Class) +meth protected abstract boolean isChildField(java.lang.Object) +meth protected abstract boolean isChildrenField(java.lang.Object) +meth protected abstract boolean isCloneableField(java.lang.Object) +meth protected abstract java.lang.Class getFieldType(java.lang.Object) +meth protected abstract java.lang.Iterable getNodeFields() +meth protected abstract java.lang.Object getFieldObject(java.lang.Object,com.oracle.truffle.api.nodes.Node) +meth protected abstract java.lang.Object getFieldValue(java.lang.Object,com.oracle.truffle.api.nodes.Node) +meth protected abstract java.lang.String getFieldName(java.lang.Object) +meth protected abstract void putFieldObject(java.lang.Object,com.oracle.truffle.api.nodes.Node,java.lang.Object) meth public abstract com.oracle.truffle.api.nodes.NodeFieldAccessor getNodeClassField() + anno 0 java.lang.Deprecated() meth public abstract com.oracle.truffle.api.nodes.NodeFieldAccessor getParentField() + anno 0 java.lang.Deprecated() meth public abstract com.oracle.truffle.api.nodes.NodeFieldAccessor[] getChildFields() + anno 0 java.lang.Deprecated() meth public abstract com.oracle.truffle.api.nodes.NodeFieldAccessor[] getChildrenFields() + anno 0 java.lang.Deprecated() meth public abstract com.oracle.truffle.api.nodes.NodeFieldAccessor[] getCloneableFields() + anno 0 java.lang.Deprecated() meth public abstract com.oracle.truffle.api.nodes.NodeFieldAccessor[] getFields() + anno 0 java.lang.Deprecated() meth public abstract java.lang.Class getType() meth public abstract java.util.Iterator makeIterator(com.oracle.truffle.api.nodes.Node) meth public static com.oracle.truffle.api.nodes.NodeClass get(com.oracle.truffle.api.nodes.Node) @@ -726,12 +741,14 @@ meth public static com.oracle.truffle.api.nodes.NodeCost[] values() supr java.lang.Enum CLSS public abstract com.oracle.truffle.api.nodes.NodeFieldAccessor + anno 0 java.lang.Deprecated() cons protected init(com.oracle.truffle.api.nodes.NodeFieldAccessor$NodeFieldKind,java.lang.Class,java.lang.String,java.lang.Class) fld protected final java.lang.Class type innr public abstract static AbstractUnsafeNodeFieldAccessor innr public final static !enum NodeFieldKind meth protected static com.oracle.truffle.api.nodes.NodeFieldAccessor create(com.oracle.truffle.api.nodes.NodeFieldAccessor$NodeFieldKind,java.lang.reflect.Field) meth public abstract java.lang.Object getObject(com.oracle.truffle.api.nodes.Node) + anno 0 java.lang.Deprecated() meth public abstract java.lang.Object loadValue(com.oracle.truffle.api.nodes.Node) meth public abstract void putObject(com.oracle.truffle.api.nodes.Node,java.lang.Object) anno 0 java.lang.Deprecated() @@ -739,6 +756,7 @@ meth public com.oracle.truffle.api.nodes.NodeFieldAccessor$NodeFieldKind getKind meth public java.lang.Class getDeclaringClass() meth public java.lang.Class getType() meth public java.lang.String getName() +meth public java.lang.String toString() supr java.lang.Object hfds USE_UNSAFE,declaringClass,kind,name hcls ReflectionNodeField,UnsafeNodeField @@ -793,6 +811,7 @@ meth public static boolean replaceChild(com.oracle.truffle.api.nodes.Node,com.or meth public static boolean verify(com.oracle.truffle.api.nodes.Node) meth public static com.oracle.truffle.api.nodes.Node getNthParent(com.oracle.truffle.api.nodes.Node,int) meth public static com.oracle.truffle.api.nodes.NodeFieldAccessor findChildField(com.oracle.truffle.api.nodes.Node,com.oracle.truffle.api.nodes.Node) + anno 0 java.lang.Deprecated() meth public static int countNodes(com.oracle.truffle.api.nodes.Node) meth public static int countNodes(com.oracle.truffle.api.nodes.Node,com.oracle.truffle.api.nodes.NodeUtil$NodeCountFilter) meth public static java.lang.String printCompactTreeToString(com.oracle.truffle.api.nodes.Node)