comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java @ 12692:ffd4b6b4ae68

Truffle Node class refactoring.
author Andreas Woess <andreas.woess@jku.at>
date Wed, 06 Nov 2013 13:54:25 +0100
parents b7c8b843dc7b
children 641f22b1c6b8
comparison
equal deleted inserted replaced
12691:426786412db6 12692:ffd4b6b4ae68
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 java.io.*;
27 import java.lang.annotation.*; 28 import java.lang.annotation.*;
28 import java.util.*; 29 import java.util.*;
29 30
30 import com.oracle.truffle.api.*; 31 import com.oracle.truffle.api.*;
31 import com.oracle.truffle.api.nodes.NodeInfo.Kind; 32 import com.oracle.truffle.api.nodes.NodeInfo.Kind;
182 onReplace(newNode, reason); 183 onReplace(newNode, reason);
183 ((Node) newNode).parent = this.parent; 184 ((Node) newNode).parent = this.parent;
184 if (!NodeUtil.replaceChild(this.parent, this, newNode)) { 185 if (!NodeUtil.replaceChild(this.parent, this, newNode)) {
185 fixupTree(); 186 fixupTree();
186 } 187 }
188 reportReplace();
187 return newNode; 189 return newNode;
188 } 190 }
189 191
190 /** 192 /**
191 * Rewrite has failed; the tree is likely inconsistent, so fix any stale parent references. 193 * Rewrite has failed; the tree is likely inconsistent, so fix any stale parent references.
192 * 194 *
193 * This is a rather expensive operation but rare to occur. 195 * This is a rather expensive operation but rare to occur.
194 */ 196 */
195 private void fixupTree() { 197 private void fixupTree() {
196 Node rootNode = NodeUtil.findParent(this, RootNode.class); 198 Node rootNode = getRootNode();
197 if (rootNode == null) { 199 if (rootNode == null) {
198 throw new UnsupportedOperationException("Tree does not have a root node."); 200 throw new UnsupportedOperationException("Tree does not have a root node.");
199 } 201 }
200 int fixCount = rootNode.fixupChildren(); 202 int fixCount = rootNode.fixupChildren();
201 assert fixCount != 0 : "sanity check failed: missing @Child[ren] or adoptChild?"; 203 assert fixCount != 0 : "sanity check failed: missing @Child[ren] or adoptChild?";
241 } 243 }
242 } 244 }
243 return false; 245 return false;
244 } 246 }
245 247
246 /** 248 private void reportReplace() {
247 * Intended to be implemented by subclasses of {@link Node} to receive a notification when the 249 RootNode rootNode = getRootNode();
248 * node is rewritten. This method is invoked before the actual replace has happened.
249 *
250 * @param newNode the replacement node
251 * @param reason the reason the replace supplied
252 */
253 protected void onReplace(Node newNode, String reason) {
254 RootNode rootNode = NodeUtil.findParent(this, RootNode.class);
255 if (rootNode != null) { 250 if (rootNode != null) {
256 if (rootNode.getCallTarget() instanceof ReplaceObserver) { 251 if (rootNode.getCallTarget() instanceof ReplaceObserver) {
257 ((ReplaceObserver) rootNode.getCallTarget()).nodeReplaced(); 252 ((ReplaceObserver) rootNode.getCallTarget()).nodeReplaced();
258 } 253 }
259 } 254 }
255 }
256
257 /**
258 * Intended to be implemented by subclasses of {@link Node} to receive a notification when the
259 * node is rewritten. This method is invoked before the actual replace has happened.
260 *
261 * @param newNode the replacement node
262 * @param reason the reason the replace supplied
263 */
264 protected void onReplace(Node newNode, String reason) {
260 if (TruffleOptions.TraceRewrites) { 265 if (TruffleOptions.TraceRewrites) {
261 Class<? extends Node> from = getClass(); 266 traceRewrite(newNode, reason);
262 Class<? extends Node> to = newNode.getClass(); 267 }
263 268 }
264 if (TruffleOptions.TraceRewritesFilterFromKind != null) { 269
265 if (filterByKind(from, TruffleOptions.TraceRewritesFilterFromKind)) { 270 private void traceRewrite(Node newNode, String reason) {
266 return; 271 Class<? extends Node> from = getClass();
267 } 272 Class<? extends Node> to = newNode.getClass();
268 } 273
269 274 if (TruffleOptions.TraceRewritesFilterFromKind != null) {
270 if (TruffleOptions.TraceRewritesFilterToKind != null) { 275 if (filterByKind(from, TruffleOptions.TraceRewritesFilterFromKind)) {
271 if (filterByKind(to, TruffleOptions.TraceRewritesFilterToKind)) {
272 return;
273 }
274 }
275
276 String filter = TruffleOptions.TraceRewritesFilterClass;
277 if (filter != null && (filterByContainsClassName(from, filter) || filterByContainsClassName(to, filter))) {
278 return; 276 return;
279 } 277 }
280 278 }
281 // CheckStyle: stop system..print check 279
282 System.out.printf("[truffle] rewrite %-50s |From %-40s |To %-40s |Reason %s.%n", this.toString(), formatNodeInfo(from), formatNodeInfo(to), reason); 280 if (TruffleOptions.TraceRewritesFilterToKind != null) {
283 // CheckStyle: resume system..print check 281 if (filterByKind(to, TruffleOptions.TraceRewritesFilterToKind)) {
284 } 282 return;
283 }
284 }
285
286 String filter = TruffleOptions.TraceRewritesFilterClass;
287 if (filter != null && (filterByContainsClassName(from, filter) || filterByContainsClassName(to, filter))) {
288 return;
289 }
290
291 PrintStream out = System.out;
292 out.printf("[truffle] rewrite %-50s |From %-40s |To %-40s |Reason %s.%n", this.toString(), formatNodeInfo(from), formatNodeInfo(to), reason);
285 } 293 }
286 294
287 private static String formatNodeInfo(Class<? extends Node> clazz) { 295 private static String formatNodeInfo(Class<? extends Node> clazz) {
288 NodeInfo nodeInfo = clazz.getAnnotation(NodeInfo.class); 296 NodeInfo nodeInfo = clazz.getAnnotation(NodeInfo.class);
289 String kind = "?"; 297 String kind = "?";
381 protected final Object clone() throws CloneNotSupportedException { 389 protected final Object clone() throws CloneNotSupportedException {
382 throw new IllegalStateException("This method should never be called, use the copy method instead!"); 390 throw new IllegalStateException("This method should never be called, use the copy method instead!");
383 } 391 }
384 392
385 /** 393 /**
394 * Get the root node of the tree a node belongs to.
395 *
396 * @return the {@link RootNode} or {@code null} if there is none.
397 */
398 protected final RootNode getRootNode() {
399 Node rootNode = this;
400 while (rootNode.getParent() != null) {
401 assert !(rootNode instanceof RootNode) : "root node must not have a parent";
402 rootNode = rootNode.getParent();
403 }
404 if (rootNode instanceof RootNode) {
405 return (RootNode) rootNode;
406 }
407 return null;
408 }
409
410 /**
386 * Converts this node to a textual representation useful for debugging. 411 * Converts this node to a textual representation useful for debugging.
387 */ 412 */
388 @Override 413 @Override
389 public String toString() { 414 public String toString() {
390 StringBuilder sb = new StringBuilder(getClass().getSimpleName()); 415 StringBuilder sb = new StringBuilder(getClass().getSimpleName());