comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java @ 16467:17f7331dcc4f

Truffle: move iterator to NodeClass
author Andreas Woess <andreas.woess@jku.at>
date Thu, 10 Jul 2014 18:08:29 +0200
parents d41922beb512
children 9fa5872291c1
comparison
equal deleted inserted replaced
16466:d41922beb512 16467:17f7331dcc4f
170 private final NodeField[] fields; 170 private final NodeField[] fields;
171 // Separate arrays for the frequently accessed field offsets. 171 // Separate arrays for the frequently accessed field offsets.
172 private final long parentOffset; 172 private final long parentOffset;
173 private final long[] childOffsets; 173 private final long[] childOffsets;
174 private final long[] childrenOffsets; 174 private final long[] childrenOffsets;
175 private final Class<? extends Node> clazz;
175 176
176 public static NodeClass get(Class<? extends Node> clazz) { 177 public static NodeClass get(Class<? extends Node> clazz) {
177 return nodeClasses.get(clazz); 178 return nodeClasses.get(clazz);
178 } 179 }
179 180
208 this.fields = fieldsList.toArray(new NodeField[fieldsList.size()]); 209 this.fields = fieldsList.toArray(new NodeField[fieldsList.size()]);
209 assert parentOffsetsList.size() == 1 : "must have exactly one parent field"; 210 assert parentOffsetsList.size() == 1 : "must have exactly one parent field";
210 this.parentOffset = parentOffsetsList.get(0); 211 this.parentOffset = parentOffsetsList.get(0);
211 this.childOffsets = toLongArray(childOffsetsList); 212 this.childOffsets = toLongArray(childOffsetsList);
212 this.childrenOffsets = toLongArray(childrenOffsetsList); 213 this.childrenOffsets = toLongArray(childrenOffsetsList);
214 this.clazz = clazz;
213 } 215 }
214 216
215 public NodeField[] getFields() { 217 public NodeField[] getFields() {
216 return fields; 218 return fields;
217 } 219 }
240 return Arrays.equals(fields, other.fields) && Arrays.equals(childOffsets, other.childOffsets) && Arrays.equals(childrenOffsets, other.childrenOffsets) && 242 return Arrays.equals(fields, other.fields) && Arrays.equals(childOffsets, other.childOffsets) && Arrays.equals(childrenOffsets, other.childrenOffsets) &&
241 parentOffset == other.parentOffset; 243 parentOffset == other.parentOffset;
242 } 244 }
243 return false; 245 return false;
244 } 246 }
245 } 247
246 248 public Iterator<Node> makeIterator(Node node) {
247 static class NodeIterator implements Iterator<Node> { 249 assert clazz.isInstance(node);
248 250 return new NodeIterator(node);
249 private final Node node; 251 }
250 private final NodeClass nodeClass; 252
251 private final int childrenCount; 253 private final class NodeIterator implements Iterator<Node> {
252 private int index; 254 private final Node node;
253 255 private final int childrenCount;
254 protected NodeIterator(Node node) { 256 private int index;
255 this.node = node; 257
256 this.index = 0; 258 protected NodeIterator(Node node) {
257 this.nodeClass = NodeClass.get(node.getClass()); 259 this.node = node;
258 this.childrenCount = childrenCount(); 260 this.index = 0;
259 } 261 this.childrenCount = childrenCount();
260 262 }
261 private int childrenCount() { 263
262 int nodeCount = nodeClass.childOffsets.length; 264 private int childrenCount() {
263 for (long fieldOffset : nodeClass.childrenOffsets) { 265 int nodeCount = childOffsets.length;
264 Node[] children = ((Node[]) unsafe.getObject(node, fieldOffset)); 266 for (long fieldOffset : childrenOffsets) {
265 if (children != null) { 267 Node[] children = ((Node[]) unsafe.getObject(node, fieldOffset));
266 nodeCount += children.length; 268 if (children != null) {
267 } 269 nodeCount += children.length;
268 } 270 }
269 return nodeCount; 271 }
270 } 272 return nodeCount;
271 273 }
272 private Node nodeAt(int idx) { 274
273 int nodeCount = nodeClass.childOffsets.length; 275 private Node nodeAt(int idx) {
274 if (idx < nodeCount) { 276 int nodeCount = childOffsets.length;
275 return (Node) unsafe.getObject(node, nodeClass.childOffsets[idx]); 277 if (idx < nodeCount) {
276 } else { 278 return (Node) unsafe.getObject(node, childOffsets[idx]);
277 for (long fieldOffset : nodeClass.childrenOffsets) { 279 } else {
278 Node[] nodeArray = (Node[]) unsafe.getObject(node, fieldOffset); 280 for (long fieldOffset : childrenOffsets) {
279 if (idx < nodeCount + nodeArray.length) { 281 Node[] nodeArray = (Node[]) unsafe.getObject(node, fieldOffset);
280 return nodeArray[idx - nodeCount]; 282 if (idx < nodeCount + nodeArray.length) {
281 } 283 return nodeArray[idx - nodeCount];
282 nodeCount += nodeArray.length; 284 }
283 } 285 nodeCount += nodeArray.length;
284 } 286 }
285 return null; 287 }
286 } 288 return null;
287 289 }
288 private void forward() { 290
289 if (index < childrenCount) { 291 private void forward() {
290 index++; 292 if (index < childrenCount) {
291 } 293 index++;
292 } 294 }
293 295 }
294 @Override 296
295 public boolean hasNext() { 297 public boolean hasNext() {
296 return index < childrenCount; 298 return index < childrenCount;
297 } 299 }
298 300
299 @Override 301 public Node next() {
300 public Node next() { 302 try {
301 try { 303 return nodeAt(index);
302 return nodeAt(index); 304 } finally {
303 } finally { 305 forward();
304 forward(); 306 }
305 } 307 }
306 } 308
307 309 public void remove() {
308 @Override 310 throw new UnsupportedOperationException();
309 public void remove() { 311 }
310 throw new UnsupportedOperationException(); 312 }
311 } 313 }
314
315 static Iterator<Node> makeIterator(Node node) {
316 return NodeClass.get(node.getClass()).makeIterator(node);
312 } 317 }
313 318
314 private static long[] toLongArray(List<Long> list) { 319 private static long[] toLongArray(List<Long> list) {
315 long[] array = new long[list.size()]; 320 long[] array = new long[list.size()];
316 for (int i = 0; i < list.size(); i++) { 321 for (int i = 0; i < list.size(); i++) {