comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java @ 16464:76081918079d

Truffle: move TraceRewrites code to NodeUtil
author Andreas Woess <andreas.woess@jku.at>
date Thu, 10 Jul 2014 18:08:29 +0200
parents 76895499bc88
children 17f7331dcc4f
comparison
equal deleted inserted replaced
16463:f1d839174e71 16464:76081918079d
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.*;
28 import java.lang.annotation.*; 27 import java.lang.annotation.*;
29 import java.util.*; 28 import java.util.*;
30 import java.util.concurrent.*; 29 import java.util.concurrent.*;
31 30
32 import com.oracle.truffle.api.*; 31 import com.oracle.truffle.api.*;
278 this.parent.adoptHelper(newNode); 277 this.parent.adoptHelper(newNode);
279 } else { 278 } else {
280 this.parent.adoptUnadoptedHelper(newNode); 279 this.parent.adoptUnadoptedHelper(newNode);
281 } 280 }
282 reportReplace(this, newNode, reason); 281 reportReplace(this, newNode, reason);
283 if (TruffleOptions.TraceASTJSON) {
284 JSONHelper.dumpReplaceChild(this, newNode, reason);
285 }
286 onReplace(newNode, reason); 282 onReplace(newNode, reason);
287 } 283 }
288 284
289 /** 285 /**
290 * Checks if this node is properly adopted by a parent and can be replaced. 286 * Checks if this node is properly adopted by a parent and can be replaced.
308 CallTarget target = rootNode.getCallTarget(); 304 CallTarget target = rootNode.getCallTarget();
309 if (target instanceof ReplaceObserver) { 305 if (target instanceof ReplaceObserver) {
310 ((ReplaceObserver) target).nodeReplaced(oldNode, newNode, reason); 306 ((ReplaceObserver) target).nodeReplaced(oldNode, newNode, reason);
311 } 307 }
312 } 308 }
309 if (TruffleOptions.TraceRewrites) {
310 NodeUtil.traceRewrite(this, newNode, reason);
311 }
312 if (TruffleOptions.TraceASTJSON) {
313 JSONHelper.dumpReplaceChild(this, newNode, reason);
314 }
313 } 315 }
314 316
315 /** 317 /**
316 * Intended to be implemented by subclasses of {@link Node} to receive a notification when the 318 * Intended to be implemented by subclasses of {@link Node} to receive a notification when the
317 * node is rewritten. This method is invoked before the actual replace has happened. 319 * node is rewritten. This method is invoked before the actual replace has happened.
318 * 320 *
319 * @param newNode the replacement node 321 * @param newNode the replacement node
320 * @param reason the reason the replace supplied 322 * @param reason the reason the replace supplied
321 */ 323 */
322 protected void onReplace(Node newNode, CharSequence reason) { 324 protected void onReplace(Node newNode, CharSequence reason) {
323 if (TruffleOptions.TraceRewrites) { 325 // empty default
324 traceRewrite(newNode, reason);
325 }
326 }
327
328 private void traceRewrite(Node newNode, CharSequence reason) {
329 if (TruffleOptions.TraceRewritesFilterFromCost != null) {
330 if (filterByKind(this, TruffleOptions.TraceRewritesFilterFromCost)) {
331 return;
332 }
333 }
334
335 if (TruffleOptions.TraceRewritesFilterToCost != null) {
336 if (filterByKind(newNode, TruffleOptions.TraceRewritesFilterToCost)) {
337 return;
338 }
339 }
340
341 String filter = TruffleOptions.TraceRewritesFilterClass;
342 Class<? extends Node> from = getClass();
343 Class<? extends Node> to = newNode.getClass();
344 if (filter != null && (filterByContainsClassName(from, filter) || filterByContainsClassName(to, filter))) {
345 return;
346 }
347
348 final SourceSection reportedSourceSection = getEncapsulatingSourceSection();
349
350 PrintStream out = System.out;
351 out.printf("[truffle] rewrite %-50s |From %-40s |To %-40s |Reason %s%s%n", this.toString(), formatNodeInfo(this), formatNodeInfo(newNode), reason != null && reason.length() > 0 ? reason
352 : "unknown", reportedSourceSection != null ? " at " + reportedSourceSection.getShortDescription() : "");
353 } 326 }
354 327
355 /** 328 /**
356 * Subclasses of {@link Node} can implement this method to execute extra functionality when a 329 * Subclasses of {@link Node} can implement this method to execute extra functionality when a
357 * node is effectively inserted into the AST. The {@code onAdopt} callback is called after the 330 * node is effectively inserted into the AST. The {@code onAdopt} callback is called after the
358 * node has been effectively inserted, and it is guaranteed to be called only once for any given 331 * node has been effectively inserted, and it is guaranteed to be called only once for any given
359 * node. 332 * node.
360 */ 333 */
361 protected void onAdopt() { 334 protected void onAdopt() {
362 // empty default 335 // empty default
363 }
364
365 private static String formatNodeInfo(Node node) {
366 String cost = "?";
367 switch (node.getCost()) {
368 case NONE:
369 cost = "G";
370 break;
371 case MONOMORPHIC:
372 cost = "M";
373 break;
374 case POLYMORPHIC:
375 cost = "P";
376 break;
377 case MEGAMORPHIC:
378 cost = "G";
379 break;
380 default:
381 cost = "?";
382 break;
383 }
384 return cost + " " + node.getClass().getSimpleName();
385 }
386
387 private static boolean filterByKind(Node node, NodeCost cost) {
388 return node.getCost() == cost;
389 }
390
391 private static boolean filterByContainsClassName(Class<? extends Node> from, String filter) {
392 Class<?> currentFrom = from;
393 while (currentFrom != null) {
394 if (currentFrom.getName().contains(filter)) {
395 return false;
396 }
397 currentFrom = currentFrom.getSuperclass();
398 }
399 return true;
400 } 336 }
401 337
402 /** 338 /**
403 * Invokes the {@link NodeVisitor#visit(Node)} method for this node and recursively also for all 339 * Invokes the {@link NodeVisitor#visit(Node)} method for this node and recursively also for all
404 * child nodes. 340 * child nodes.