Mercurial > hg > truffle
comparison truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeClass.java @ 22398:07c98b5a9496
NodeClass: avoid unnecessary array copying during initialization
author | Andreas Woess <andreas.woess@oracle.com> |
---|---|
date | Thu, 19 Nov 2015 18:49:55 +0100 |
parents | 6598b9b7aafd |
children | efbc311e9ff2 |
comparison
equal
deleted
inserted
replaced
22397:27cf58ec97ae | 22398:07c98b5a9496 |
---|---|
22 * or visit www.oracle.com if you need additional information or have any | 22 * or visit www.oracle.com if you need additional information or have any |
23 * questions. | 23 * questions. |
24 */ | 24 */ |
25 package com.oracle.truffle.api.nodes; | 25 package com.oracle.truffle.api.nodes; |
26 | 26 |
27 import com.oracle.truffle.api.nodes.Node.Child; | |
28 import com.oracle.truffle.api.nodes.Node.Children; | |
29 import com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind; | |
30 import java.lang.reflect.Field; | 27 import java.lang.reflect.Field; |
31 import java.lang.reflect.Modifier; | 28 import java.lang.reflect.Modifier; |
32 import java.security.AccessController; | 29 import java.security.AccessController; |
33 import java.security.PrivilegedAction; | 30 import java.security.PrivilegedAction; |
34 import java.util.ArrayList; | 31 import java.util.ArrayList; |
35 import java.util.Iterator; | 32 import java.util.Iterator; |
36 import java.util.List; | 33 import java.util.List; |
34 | |
35 import com.oracle.truffle.api.nodes.Node.Child; | |
36 import com.oracle.truffle.api.nodes.Node.Children; | |
37 import com.oracle.truffle.api.nodes.NodeFieldAccessor.NodeFieldKind; | |
37 | 38 |
38 /** | 39 /** |
39 * Information about a {@link Node} class. A single instance of this class is allocated for every | 40 * Information about a {@link Node} class. A single instance of this class is allocated for every |
40 * subclass of {@link Node} that is used. | 41 * subclass of {@link Node} that is used. |
41 */ | 42 */ |
73 public static NodeClass get(Node node) { | 74 public static NodeClass get(Node node) { |
74 return node.getNodeClass(); | 75 return node.getNodeClass(); |
75 } | 76 } |
76 | 77 |
77 NodeClass(Class<? extends Node> clazz) { | 78 NodeClass(Class<? extends Node> clazz) { |
79 if (!Node.class.isAssignableFrom(clazz)) { | |
80 throw new IllegalArgumentException(); | |
81 } | |
82 | |
78 List<NodeFieldAccessor> fieldsList = new ArrayList<>(); | 83 List<NodeFieldAccessor> fieldsList = new ArrayList<>(); |
79 NodeFieldAccessor parentFieldTmp = null; | 84 NodeFieldAccessor parentFieldTmp = null; |
80 NodeFieldAccessor nodeClassFieldTmp = null; | 85 NodeFieldAccessor nodeClassFieldTmp = null; |
81 List<NodeFieldAccessor> childFieldList = new ArrayList<>(); | 86 List<NodeFieldAccessor> childFieldList = new ArrayList<>(); |
82 List<NodeFieldAccessor> childrenFieldList = new ArrayList<>(); | 87 List<NodeFieldAccessor> childrenFieldList = new ArrayList<>(); |
83 List<NodeFieldAccessor> cloneableFieldList = new ArrayList<>(); | 88 List<NodeFieldAccessor> cloneableFieldList = new ArrayList<>(); |
84 | 89 |
85 for (Field field : NodeUtil.getAllFields(clazz)) { | 90 try { |
91 Field field = Node.class.getDeclaredField("parent"); | |
92 assert Node.class.isAssignableFrom(field.getType()); | |
93 parentFieldTmp = NodeFieldAccessor.create(NodeFieldKind.PARENT, field); | |
94 field = Node.class.getDeclaredField("nodeClass"); | |
95 assert NodeClass.class.isAssignableFrom(field.getType()); | |
96 nodeClassFieldTmp = NodeFieldAccessor.create(NodeFieldKind.NODE_CLASS, field); | |
97 } catch (NoSuchFieldException e) { | |
98 throw new AssertionError("Node field not found", e); | |
99 } | |
100 | |
101 collectInstanceFields(clazz, fieldsList, childFieldList, childrenFieldList, cloneableFieldList); | |
102 | |
103 this.fields = fieldsList.toArray(EMPTY_NODE_FIELD_ARRAY); | |
104 this.nodeClassField = nodeClassFieldTmp; | |
105 this.parentField = parentFieldTmp; | |
106 this.childFields = childFieldList.toArray(EMPTY_NODE_FIELD_ARRAY); | |
107 this.childrenFields = childrenFieldList.toArray(EMPTY_NODE_FIELD_ARRAY); | |
108 this.cloneableFields = cloneableFieldList.toArray(EMPTY_NODE_FIELD_ARRAY); | |
109 this.clazz = clazz; | |
110 } | |
111 | |
112 private static void collectInstanceFields(Class<? extends Object> clazz, List<NodeFieldAccessor> fieldsList, List<NodeFieldAccessor> childFieldList, List<NodeFieldAccessor> childrenFieldList, | |
113 List<NodeFieldAccessor> cloneableFieldList) { | |
114 if (clazz.getSuperclass() != null) { | |
115 collectInstanceFields(clazz.getSuperclass(), fieldsList, childFieldList, childrenFieldList, cloneableFieldList); | |
116 } | |
117 Field[] declaredFields = clazz.getDeclaredFields(); | |
118 for (Field field : declaredFields) { | |
86 if (Modifier.isStatic(field.getModifiers()) || field.isSynthetic()) { | 119 if (Modifier.isStatic(field.getModifiers()) || field.isSynthetic()) { |
87 continue; | 120 continue; |
88 } | 121 } |
89 | 122 |
90 NodeFieldAccessor nodeField; | 123 NodeFieldAccessor nodeField; |
91 if (field.getDeclaringClass() == Node.class && field.getName().equals("parent")) { | 124 if (field.getDeclaringClass() == Node.class && (field.getName().equals("parent") || field.getName().equals("nodeClass"))) { |
92 assert Node.class.isAssignableFrom(field.getType()); | 125 continue; |
93 nodeField = NodeFieldAccessor.create(NodeFieldKind.PARENT, field); | |
94 parentFieldTmp = nodeField; | |
95 } else if (field.getDeclaringClass() == Node.class && field.getName().equals("nodeClass")) { | |
96 assert NodeClass.class.isAssignableFrom(field.getType()); | |
97 nodeField = NodeFieldAccessor.create(NodeFieldKind.NODE_CLASS, field); | |
98 nodeClassFieldTmp = nodeField; | |
99 } else if (field.getAnnotation(Child.class) != null) { | 126 } else if (field.getAnnotation(Child.class) != null) { |
100 checkChildField(field); | 127 checkChildField(field); |
101 nodeField = NodeFieldAccessor.create(NodeFieldKind.CHILD, field); | 128 nodeField = NodeFieldAccessor.create(NodeFieldKind.CHILD, field); |
102 childFieldList.add(nodeField); | 129 childFieldList.add(nodeField); |
103 } else if (field.getAnnotation(Children.class) != null) { | 130 } else if (field.getAnnotation(Children.class) != null) { |
110 cloneableFieldList.add(nodeField); | 137 cloneableFieldList.add(nodeField); |
111 } | 138 } |
112 } | 139 } |
113 fieldsList.add(nodeField); | 140 fieldsList.add(nodeField); |
114 } | 141 } |
115 | |
116 if (parentFieldTmp == null) { | |
117 throw new AssertionError("parent field not found"); | |
118 } | |
119 | |
120 this.fields = fieldsList.toArray(EMPTY_NODE_FIELD_ARRAY); | |
121 this.nodeClassField = nodeClassFieldTmp; | |
122 this.parentField = parentFieldTmp; | |
123 this.childFields = childFieldList.toArray(EMPTY_NODE_FIELD_ARRAY); | |
124 this.childrenFields = childrenFieldList.toArray(EMPTY_NODE_FIELD_ARRAY); | |
125 this.cloneableFields = cloneableFieldList.toArray(EMPTY_NODE_FIELD_ARRAY); | |
126 this.clazz = clazz; | |
127 } | 142 } |
128 | 143 |
129 public NodeFieldAccessor getNodeClassField() { | 144 public NodeFieldAccessor getNodeClassField() { |
130 return nodeClassField; | 145 return nodeClassField; |
131 } | 146 } |