Package org.adoptopenjdk.jitwatch.ui

Source Code of org.adoptopenjdk.jitwatch.ui.CompileChainStage$PlotNode

/*
* Copyright (c) 2013, 2014 Chris Newland.
* Licensed under https://github.com/AdoptOpenJDK/jitwatch/blob/master/LICENSE-BSD
* Instructions: https://github.com/AdoptOpenJDK/jitwatch/wiki
*/
package org.adoptopenjdk.jitwatch.ui;

import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.*;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Tooltip;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.WindowEvent;

import org.adoptopenjdk.jitwatch.chain.CompileNode;
import org.adoptopenjdk.jitwatch.model.IMetaMember;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CompileChainStage extends Stage
{
  //TODO show compilation order markers
 
  private static final Logger logger = LoggerFactory.getLogger(CompileChainStage.class);

  private ScrollPane scrollPane;
  private Pane pane;

  private CompileNode rootNode;

  private static final double X_OFFSET = 16;
  private static final double Y_OFFSET = 16;

  private double y = Y_OFFSET;

  private static final double X_GAP = 25;

  private static final int STROKE_WIDTH = 3;
  private static final double RECT_HEIGHT = 25;
  private static final double RECT_Y_GAP = 16;

  class PlotNode
  {
    public Rectangle rect;
    public Text text;
  }

  public CompileChainStage(final JITWatchUI parent, CompileNode root)
  {
    initStyle(StageStyle.DECORATED);

    this.rootNode = root;

    scrollPane = new ScrollPane();
    pane = new Pane();

    scrollPane.setContent(pane);

    Scene scene = new Scene(scrollPane, JITWatchUI.WINDOW_WIDTH, JITWatchUI.WINDOW_HEIGHT);

    setTitle("Compile Chain: " + root.getMember().toString());

    setScene(scene);

    redraw();

    setOnCloseRequest(new EventHandler<WindowEvent>()
    {
      @Override
      public void handle(WindowEvent arg0)
      {
        parent.handleStageClosed(CompileChainStage.this);
      }
    });
  }

  public void redraw()
  {
    showKey();

    show(rootNode, X_OFFSET, Y_OFFSET, 0);

    if (rootNode.getChildren().size() == 0)
    {
      Text text = new Text("No method calls made by " + rootNode.getMember().toStringUnqualifiedMethodName(false) + " were inlined or JIT compiled");
      text.setX(X_OFFSET);
      text.setY(y);

      pane.getChildren().add(text);
    }
  }

  private void showKey()
  {
    double keyX = scrollPane.getWidth() - 220;
    double keyY = 10;

    Rectangle roundedRect = new Rectangle(keyX - 20, keyY, 210, 180);

    roundedRect.setArcHeight(30);
    roundedRect.setArcWidth(30);

    roundedRect.setStroke(Color.BLACK);
    roundedRect.setFill(Color.TRANSPARENT);

    pane.getChildren().add(roundedRect);

    keyY += 20;

    Text text = new Text("Key");
    text.setX(keyX + 75);
    text.setY(keyY);

    pane.getChildren().add(text);

    keyY += 15;

    buildNode("Not Compiled or Inlined", keyX, keyY, false, false);
    keyY += 35;

    buildNode("Compiled Only", keyX, keyY, false, true);
    keyY += 35;

    buildNode("Inlined Only", keyX, keyY, true, false);
    keyY += 35;

    buildNode("Compiled and Inlined", keyX, keyY, true, true);
  }

  private void show(CompileNode node, double x, double parentY, int depth)
  {
    double lastX = x;

    lastX = plotNode(node, x, parentY, depth);

    y += RECT_HEIGHT + STROKE_WIDTH + RECT_Y_GAP;

    parentY = y - RECT_Y_GAP;

    for (CompileNode child : node.getChildren())
    {
      show(child, lastX, parentY, depth + 1);
    }
  }

  private String getLabelText(CompileNode node)
  {
    IMetaMember member = node.getMember();

    return member == null ? "Unknown" : member.getMemberName();
  }

  private double plotNode(final CompileNode node, final double x, final double parentY, final int depth)
  {
    String labelText = getLabelText(node);

    PlotNode plotNode = buildNode(labelText, x, y, node.isInlined(), node.getMember().isCompiled());

    if (depth > 0)
    {
      double connectX = x - X_GAP;
      double connectY = y + RECT_HEIGHT / 2;
      double upLineY = y + RECT_HEIGHT / 2;

      Line lineUp = new Line(connectX, upLineY, connectX, parentY);
      lineUp.setStrokeWidth(STROKE_WIDTH);
      pane.getChildren().add(lineUp);

      Line lineLeft = new Line(connectX, connectY, x, connectY);
      lineLeft.setStrokeWidth(STROKE_WIDTH);
      pane.getChildren().add(lineLeft);
    }

    double nextX = x + plotNode.rect.getWidth() / 2;

    nextX += X_GAP;

    initialiseRectWithOnMouseClickedEventHandler(node, plotNode.rect);

    Tooltip tip = new Tooltip(getToolTipText(node));
    Tooltip.install(plotNode.rect, tip);
    Tooltip.install(plotNode.text, tip);

    return nextX;
  }

  private PlotNode buildNode(String labelText, double x, double y, boolean inlined, boolean compiled)
  {
    Text text = new Text(labelText);

    text.snapshot(null, null);

    double textWidth = text.getLayoutBounds().getWidth();
    double textHeight = text.getLayoutBounds().getHeight();

    double rectWidth = textWidth + 20;

    Rectangle rect = new Rectangle(x, y, rectWidth, RECT_HEIGHT);
    rect.setArcWidth(16);
    rect.setArcHeight(16);

    text.setX(x + (rectWidth / 2 - textWidth / 2));

    // text plot from bottom left
    text.setY(y + RECT_HEIGHT - STROKE_WIDTH - (RECT_HEIGHT - textHeight) / 2);

    text.setFill(getColorForInlining(inlined));

    rect.setStroke(Color.BLACK);
    rect.setStrokeWidth(STROKE_WIDTH);
    rect.setFill(getColourForCompilation(compiled));

    pane.getChildren().add(rect);
    pane.getChildren().add(text);

    PlotNode result = new PlotNode();
    result.rect = rect;
    result.text = text;

    return result;
  }

  private String getToolTipText(CompileNode node)
  {
    StringBuilder tipBuilder = new StringBuilder();
    tipBuilder.append(node.getMember().toString()).append(C_NEWLINE);

    tipBuilder.append("JIT Compiled: ");

    if (node.getMember().isCompiled())
    {
      tipBuilder.append("Yes\n");
    }
    else
    {
      tipBuilder.append("No\n");
    }

    String inlineReason = node.getInlineReason();

    if (inlineReason != null)
    {
      tipBuilder.append(inlineReason);
    }

    tipBuilder.append(C_NEWLINE);

    return tipBuilder.toString();
  }

  private Color getColourForCompilation(boolean isCompiled)
  {
    if (isCompiled)
    {
      return Color.GREEN;
    }
    else
    {
      return Color.RED;
    }
  }

  private Color getColorForInlining(boolean isInlined)
  {
    if (isInlined)
    {
      return Color.YELLOW;
    }
    else
    {
      return Color.BLACK;
    }
  }

  private void initialiseRectWithOnMouseClickedEventHandler(final CompileNode node, Rectangle rect)
  {
    rect.setOnMouseClicked(new EventHandler<MouseEvent>()
    {
      @Override
      public void handle(MouseEvent arg0)
      {
        logger.info("{}", node.getMember());
        // TODO use for navigation in TriView?
      }
    });
  }

}
TOP

Related Classes of org.adoptopenjdk.jitwatch.ui.CompileChainStage$PlotNode

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.