# HG changeset patch # User never # Date 1461860847 25200 # Thu Apr 28 09:27:27 2016 -0700 # Node ID 5f993d45eae7a78580200bba947a299946427de0 # Parent 9e21d8c18a7d181e5aeeaa989073171b2896f47b 8154483: update IGV with improvements from Graal diff --git a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java --- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java +++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,11 +25,13 @@ import com.sun.hotspot.igv.coordinator.actions.RemoveCookie; import com.sun.hotspot.igv.data.*; +import com.sun.hotspot.igv.util.PropertiesSheet; import java.awt.Image; import java.util.List; import org.openide.nodes.AbstractNode; import org.openide.nodes.Children; import org.openide.nodes.Node; +import org.openide.nodes.Sheet; import org.openide.util.ImageUtilities; import org.openide.util.lookup.AbstractLookup; import org.openide.util.lookup.InstanceContent; @@ -75,6 +77,16 @@ } @Override + protected Sheet createSheet() { + Sheet s = super.createSheet(); + if (children.folder instanceof Properties.Entity) { + Properties.Entity p = (Properties.Entity) children.folder; + PropertiesSheet.initializeSheet(p.getProperties(), s); + } + return s; + } + + @Override public Image getIcon(int i) { return ImageUtilities.loadImage("com/sun/hotspot/igv/coordinator/images/folder.png"); } diff --git a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java --- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java +++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -124,6 +124,8 @@ public void clear() { document.clear(); + root = new FolderNode(document); + manager.setRootContext(root); } @Override diff --git a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/ImportAction.java b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/ImportAction.java --- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/ImportAction.java +++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/ImportAction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,31 +31,47 @@ import com.sun.hotspot.igv.data.serialization.ParseMonitor; import com.sun.hotspot.igv.data.serialization.Parser; import com.sun.hotspot.igv.settings.Settings; -import java.awt.event.InputEvent; -import java.awt.event.KeyEvent; +import java.awt.event.ActionEvent; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.channels.FileChannel; import java.nio.file.StandardOpenOption; -import javax.swing.Action; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.JFileChooser; -import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.filechooser.FileFilter; import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandleFactory; import org.openide.util.Exceptions; +import org.openide.util.RequestProcessor; +import org.openide.awt.ActionID; +import org.openide.awt.ActionReference; +import org.openide.awt.ActionReferences; +import org.openide.awt.ActionRegistration; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; -import org.openide.util.RequestProcessor; -import org.openide.util.actions.CallableSystemAction; +import org.openide.util.actions.SystemAction; /** * * @author Thomas Wuerthinger */ -public final class ImportAction extends CallableSystemAction { + +@ActionID( + category = "File", + id = "com.sun.hotspot.igv.coordinator.actions.ImportAction" +) +@ActionRegistration( + iconBase = "com/sun/hotspot/igv/coordinator/images/import.png", + displayName = "#CTL_ImportAction" +) +@ActionReferences({ + @ActionReference(path = "Menu/File", position = 0), + @ActionReference(path = "Shortcuts", name = "C-O") +}) +public final class ImportAction extends SystemAction { private static final int WORKUNITS = 10000; public static FileFilter getFileFilter() { @@ -74,74 +90,77 @@ } @Override - public void performAction() { - + public void actionPerformed(ActionEvent e) { JFileChooser fc = new JFileChooser(); fc.setFileFilter(ImportAction.getFileFilter()); fc.setCurrentDirectory(new File(Settings.get().get(Settings.DIRECTORY, Settings.DIRECTORY_DEFAULT))); + fc.setMultiSelectionEnabled(true); if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { - File file = fc.getSelectedFile(); + for (final File file : fc.getSelectedFiles()) { + File dir = file; + if (!dir.isDirectory()) { + dir = dir.getParentFile(); + } - File dir = file; - if (!dir.isDirectory()) { - dir = dir.getParentFile(); - } - - Settings.get().put(Settings.DIRECTORY, dir.getAbsolutePath()); - try { - final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.READ); - final ProgressHandle handle = ProgressHandleFactory.createHandle("Opening file " + file.getName()); - handle.start(WORKUNITS); - final long start = channel.size(); - ParseMonitor monitor = new ParseMonitor() { - @Override - public void updateProgress() { - try { - int prog = (int) (WORKUNITS * (double) channel.position() / (double) start); - handle.progress(prog); - } catch (IOException ex) { - } + Settings.get().put(Settings.DIRECTORY, dir.getAbsolutePath()); + try { + final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.READ); + final ProgressHandle handle = ProgressHandleFactory.createHandle("Opening file " + file.getName()); + handle.start(WORKUNITS); + final long startTime = System.currentTimeMillis(); + final long start = channel.size(); + ParseMonitor monitor = new ParseMonitor() { + @Override + public void updateProgress() { + try { + int prog = (int) (WORKUNITS * (double) channel.position() / (double) start); + handle.progress(prog); + } catch (IOException ex) { + } + } + @Override + public void setState(String state) { + updateProgress(); + handle.progress(state); + } + }; + final GraphParser parser; + final OutlineTopComponent component = OutlineTopComponent.findInstance(); + if (file.getName().endsWith(".xml")) { + parser = new Parser(channel, monitor, null); + } else if (file.getName().endsWith(".bgv")) { + parser = new BinaryParser(channel, monitor, component.getDocument(), null); + } else { + parser = null; } - @Override - public void setState(String state) { - updateProgress(); - handle.progress(state); - } - }; - final GraphParser parser; - final OutlineTopComponent component = OutlineTopComponent.findInstance(); - if (file.getName().endsWith(".xml")) { - parser = new Parser(channel, monitor, null); - } else if (file.getName().endsWith(".bgv")) { - parser = new BinaryParser(channel, monitor, component.getDocument(), null); - } else { - parser = null; + RequestProcessor.getDefault().post(new Runnable() { + @Override + public void run() { + try { + final GraphDocument document = parser.parse(); + if (document != null) { + SwingUtilities.invokeLater(new Runnable(){ + @Override + public void run() { + component.requestActive(); + component.getDocument().addGraphDocument(document); + } + }); + } + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + handle.finish(); + long stop = System.currentTimeMillis(); + Logger.getLogger(getClass().getName()).log(Level.INFO, "Loaded in " + file + " in " + ((stop - startTime) / 1000.0) + " seconds"); + } + }); + } catch (FileNotFoundException ex) { + Exceptions.printStackTrace(ex); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); } - RequestProcessor.getDefault().post(new Runnable() { - @Override - public void run() { - try { - final GraphDocument document = parser.parse(); - if (document != null) { - SwingUtilities.invokeLater(new Runnable(){ - @Override - public void run() { - component.requestActive(); - component.getDocument().addGraphDocument(document); - } - }); - } - } catch (IOException ex) { - Exceptions.printStackTrace(ex); - } - handle.finish(); - } - }); - } catch (FileNotFoundException ex) { - Exceptions.printStackTrace(ex); - } catch (IOException ex) { - Exceptions.printStackTrace(ex); } } } @@ -151,11 +170,6 @@ return NbBundle.getMessage(ImportAction.class, "CTL_ImportAction"); } - public ImportAction() { - putValue(Action.SHORT_DESCRIPTION, "Open XML graph document..."); - putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK)); - } - @Override protected String iconResource() { return "com/sun/hotspot/igv/coordinator/images/import.png"; @@ -165,9 +179,4 @@ public HelpCtx getHelpCtx() { return HelpCtx.DEFAULT_HELP; } - - @Override - protected boolean asynchronous() { - return false; - } } diff --git a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAllAction.java b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAllAction.java --- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAllAction.java +++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAllAction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,14 +29,30 @@ import java.awt.event.KeyEvent; import javax.swing.Action; import javax.swing.KeyStroke; +import org.openide.awt.ActionID; +import org.openide.awt.ActionReference; +import org.openide.awt.ActionReferences; +import org.openide.awt.ActionRegistration; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; import org.openide.util.actions.CallableSystemAction; /** * * @author Thomas Wuerthinger */ +@ActionID( + category = "File", + id = "com.sun.hotspot.igv.coordinator.actions.SaveAllAction" +) +@ActionRegistration( + displayName = "#CTL_SaveAllAction" +) +@ActionReferences({ + @ActionReference(path = "Menu/File", position = 0), + @ActionReference(path = "Shortcuts", name = "C-S") +}) public final class SaveAllAction extends CallableSystemAction { @Override diff --git a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml --- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml +++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml @@ -18,6 +18,8 @@ + + @@ -43,11 +45,11 @@ - + - + diff --git a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,11 +51,13 @@ } public void addGraphDocument(GraphDocument document) { - for (FolderElement e : document.elements) { - e.setParent(this); - this.addElement(e); + if (document != this) { + for (FolderElement e : document.elements) { + e.setParent(this); + this.addElement(e); + } + document.clear(); } - document.clear(); getChangedEvent().fire(); } diff --git a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,7 +90,9 @@ public void addNode(int id) { InputNode node = graph.getNode(id); assert node != null; - assert !nodes.contains(node) : "duplicate : " + node; + // nodes.contains(node) is too expensive for large graphs so + // just make sure the Graph doesn't know it yet. + assert graph.getBlock(id) == null : "duplicate : " + node; graph.setBlock(node, this); nodes.add(node); } diff --git a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,7 +24,9 @@ package com.sun.hotspot.igv.data; import java.io.Serializable; +import java.lang.ref.WeakReference; import java.util.*; +import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -36,7 +38,7 @@ public class Properties implements Serializable, Iterable { public static final long serialVersionUID = 1L; - private String[] map = new String[4]; + protected String[] map = new String[4]; public Properties() { } @@ -102,6 +104,59 @@ System.arraycopy(p.map, 0, map, 0, p.map.length); } + protected Properties(String[] map) { + this.map = map; + } + + static class SharedProperties extends Properties { + int hashCode; + + SharedProperties(String[] map) { + super(map); + this.hashCode = Arrays.hashCode(map); + } + + @Override + protected void setPropertyInternal(String name, String value) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof SharedProperties)) { + return super.equals(other); + } + SharedProperties props2 = (SharedProperties) other; + return Arrays.equals(map, props2.map); + } + + @Override + public int hashCode() { + return hashCode; + } + } + + private static class PropertyCache { + static WeakHashMap> immutableCache = new WeakHashMap<>(); + + static synchronized SharedProperties intern(Properties properties) { + String[] map = properties.map; + SharedProperties key = new SharedProperties(map); + WeakReference entry = immutableCache.get(key); + if (entry != null) { + SharedProperties props = entry.get(); + if (props != null) { + return props; + } + } + immutableCache.put(key, new WeakReference<>(key)); + return key; + } + } + public static class Entity implements Provider { private Properties properties; @@ -118,6 +173,10 @@ public Properties getProperties() { return properties; } + + public void internProperties() { + properties = PropertyCache.intern(properties); + } } public interface PropertyMatcher { @@ -322,8 +381,8 @@ public void setProperty(String name, String value) { setPropertyInternal(name.intern(), value != null ? value.intern() : null); } - private void setPropertyInternal(String name, String value) { + protected void setPropertyInternal(String name, String value) { for (int i = 0; i < map.length; i += 2) { if (map[i] != null && map[i].equals(name)) { String p = map[i + 1]; diff --git a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.ReadableByteChannel; +import java.nio.charset.Charset; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -68,6 +69,8 @@ private static final String NO_BLOCK = "noBlock"; + private static final Charset utf8 = Charset.forName("UTF-8"); + private final GroupCallback callback; private final List constantPool; private final ByteBuffer buffer; @@ -275,28 +278,36 @@ hashStack = new LinkedList<>(); this.monitor = monitor; try { - this.digest = MessageDigest.getInstance("SHA-256"); + this.digest = MessageDigest.getInstance("SHA-1"); } catch (NoSuchAlgorithmException e) { } } private void fill() throws IOException { + // All the data between lastPosition and position has been + // used so add it to the digest. + int position = buffer.position(); + buffer.position(lastPosition); + byte[] remaining = new byte[position - buffer.position()]; + buffer.get(remaining); + digest.update(remaining); + assert position == buffer.position(); + buffer.compact(); if (channel.read(buffer) < 0) { throw new EOFException(); } buffer.flip(); + lastPosition = buffer.position(); } private void ensureAvailable(int i) throws IOException { + if (i > buffer.capacity()) { + throw new IllegalArgumentException(String.format("Can not request %d bytes: buffer capacity is %d", i, buffer.capacity())); + } while (buffer.remaining() < i) { fill(); } - buffer.mark(); - byte[] result = new byte[i]; - buffer.get(result); - digest.update(result); - buffer.reset(); } private int readByte() throws IOException { @@ -330,12 +341,7 @@ } private String readString() throws IOException { - int len = readInt(); - ensureAvailable(len * 2); - char[] chars = new char[len]; - buffer.asCharBuffer().get(chars); - buffer.position(buffer.position() + len * 2); - return new String(chars).intern(); + return new String(readBytes(), utf8).intern(); } private byte[] readBytes() throws IOException { @@ -343,10 +349,15 @@ if (len < 0) { return null; } - ensureAvailable(len); - byte[] data = new byte[len]; - buffer.get(data); - return data; + byte[] b = new byte[len]; + int bytesRead = 0; + while (bytesRead < b.length) { + int toRead = Math.min(b.length - bytesRead, buffer.capacity()); + ensureAvailable(toRead); + buffer.get(b, bytesRead, toRead); + bytesRead += toRead; + } + return b; } private String readIntsToString() throws IOException { @@ -643,6 +654,7 @@ int bci = readInt(); Group group = new Group(parent); group.getProperties().setProperty("name", name); + parseProperties(group.getProperties()); if (method != null) { InputMethod inMethod = new InputMethod(group, method.name, shortName, bci); inMethod.setBytecodes("TODO"); @@ -651,13 +663,25 @@ return group; } + int lastPosition = 0; + private InputGraph parseGraph() throws IOException { if (monitor != null) { monitor.updateProgress(); } String title = readPoolObject(String.class); digest.reset(); + lastPosition = buffer.position(); InputGraph graph = parseGraph(title); + + int position = buffer.position(); + buffer.position(lastPosition); + byte[] remaining = new byte[position - buffer.position()]; + buffer.get(remaining); + digest.update(remaining); + assert position == buffer.position(); + lastPosition = buffer.position(); + byte[] d = digest.digest(); byte[] hash = hashStack.peek(); if (hash != null && Arrays.equals(hash, d)) { @@ -669,11 +693,24 @@ return graph; } + private void parseProperties(Properties properties) throws IOException { + int propCount = readShort(); + for (int j = 0; j < propCount; j++) { + String key = readPoolObject(String.class); + Object value = readPropertyObject(); + properties.setProperty(key, value != null ? value.toString() : "null"); + } + } + private InputGraph parseGraph(String title) throws IOException { InputGraph graph = new InputGraph(title); + parseProperties(graph.getProperties()); parseNodes(graph); parseBlocks(graph); graph.ensureNodesInBlocks(); + for (InputNode node : graph.getNodes()) { + node.internProperties(); + } return graph; } @@ -822,9 +859,10 @@ } } + static final Pattern templatePattern = Pattern.compile("\\{(p|i)#([a-zA-Z0-9$_]+)(/(l|m|s))?\\}"); + private String createName(List edges, Map properties, String template) { - Pattern p = Pattern.compile("\\{(p|i)#([a-zA-Z0-9$_]+)(/(l|m|s))?\\}"); - Matcher m = p.matcher(template); + Matcher m = templatePattern.matcher(template); StringBuffer sb = new StringBuffer(); while (m.find()) { String name = m.group(2); diff --git a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/InputGraphProvider.java b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/InputGraphProvider.java --- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/InputGraphProvider.java +++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/InputGraphProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,4 +37,14 @@ InputGraph getGraph(); void setSelectedNodes(Set nodes); + + /** + * @return an iterator walking forward through the {@link InputGraph}s following the {@link #getGraph()} + */ + Iterable searchForward(); + + /** + * @return an iterator walking backward through the {@link InputGraph}s preceeding the {@link #getGraph()} + */ + Iterable searchBackward(); } diff --git a/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.xml b/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.xml --- a/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.xml +++ b/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.xml @@ -22,6 +22,14 @@ 1.0 + + com.sun.hotspot.igv.util + + + + 1.0 + + com.sun.hotspot.igv.graph diff --git a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Slot.java b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Slot.java --- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Slot.java +++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Slot.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import com.sun.hotspot.igv.data.Source; import com.sun.hotspot.igv.layout.Port; import com.sun.hotspot.igv.layout.Vertex; +import com.sun.hotspot.igv.util.StringUtils; import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; @@ -141,7 +142,7 @@ sb.append(text); for (InputNode n : getSource().getSourceNodes()) { - sb.append("Node (ID=" + n.getId() + "): " + n.getProperties().get("name")); + sb.append(StringUtils.escapeHTML("Node (ID=" + n.getId() + "): " + n.getProperties().get("name"))); sb.append("
"); } diff --git a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java --- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -445,5 +445,48 @@ void close() { filterChain.getChangedEvent().removeListener(filterChainChangedListener); sequenceFilterChain.getChangedEvent().removeListener(filterChainChangedListener); + } + + Iterable getGraphsForward() { + return new Iterable() { + + @Override + public Iterator iterator() { + return new Iterator() { + int index = getFirstPosition(); + + @Override + public boolean hasNext() { + return index + 1 < graphs.size(); + } + + @Override + public InputGraph next() { + return graphs.get(++index); + } + }; + } + }; + } + + Iterable getGraphsBackward() { + return new Iterable() { + @Override + public Iterator iterator() { + return new Iterator() { + int index = getFirstPosition(); + + @Override + public boolean hasNext() { + return index - 1 > 0; + } + + @Override + public InputGraph next() { + return graphs.get(--index); + } + }; + } + }; + } } -} diff --git a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorInputGraphProvider.java b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorInputGraphProvider.java --- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorInputGraphProvider.java +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorInputGraphProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,4 +50,14 @@ public void setSelectedNodes(Set nodes) { editor.setSelectedNodes(nodes); } + + @Override + public Iterable searchBackward() { + return editor.getDiagramModel().getGraphsBackward(); + } + + @Override + public Iterable searchForward() { + return editor.getDiagramModel().getGraphsForward(); + } } diff --git a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java --- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -289,7 +289,10 @@ quicksearch = (Component) quicksearch.getClass().getConstructor(KeyStroke.class).newInstance(new Object[]{null}); } catch (ReflectiveOperationException | IllegalArgumentException | SecurityException e) { } - quicksearch.setMinimumSize(quicksearch.getPreferredSize()); // necessary for GTK LAF + Dimension preferredSize = quicksearch.getPreferredSize(); + preferredSize = new Dimension((int) preferredSize.getWidth() * 2, (int) preferredSize.getHeight()); + quicksearch.setMinimumSize(preferredSize); // necessary for GTK LAF + quicksearch.setPreferredSize(preferredSize); toolBar.add(quicksearch); centerPanel = new JPanel(); diff --git a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/NodeQuickSearch.java b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/NodeQuickSearch.java --- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/NodeQuickSearch.java +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/NodeQuickSearch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ */ package com.sun.hotspot.igv.view; +import com.sun.hotspot.igv.data.InputGraph; import com.sun.hotspot.igv.data.InputNode; import com.sun.hotspot.igv.data.Properties; import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher; @@ -81,57 +82,67 @@ final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class); if (p != null && p.getGraph() != null) { - List matches = null; - try { - RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(name, value, Pattern.CASE_INSENSITIVE); - Properties.PropertySelector selector = new Properties.PropertySelector<>(p.getGraph().getNodes()); - - matches = selector.selectMultiple(matcher); - } catch (Exception e) { - final String msg = e.getMessage(); - response.addResult(new Runnable() { - @Override - public void run() { - Message desc = new NotifyDescriptor.Message("An exception occurred during the search, " - + "perhaps due to a malformed query string:\n" + msg, - NotifyDescriptor.WARNING_MESSAGE); - DialogDisplayer.getDefault().notify(desc); - } - }, - "(Error during search)" - ); + InputGraph matchGraph = p.getGraph(); + // Search the current graph + List matches = findMatches(name, value, p.getGraph(), response); + if (matches == null) { + // See if the it hits in a later graph + for (InputGraph graph : p.searchForward()) { + matches = findMatches(name, value, graph, response); + if (matches != null) { + matchGraph = graph; + break; + } + } + } + if (matches == null) { + // See if it hits in a earlier graph + for (InputGraph graph : p.searchBackward()) { + matches = findMatches(name, value, graph, response); + if (matches != null) { + matchGraph = graph; + break; + } + } } if (matches != null) { final Set set = new HashSet<>(matches); + final InputGraph theGraph = p.getGraph() != matchGraph ? matchGraph : null; response.addResult(new Runnable() { @Override - public void run() { - final EditorTopComponent comp = EditorTopComponent.getActive(); - if (comp != null) { - comp.setSelectedNodes(set); - comp.requestActive(); + public void run() { + final EditorTopComponent comp = EditorTopComponent.getActive(); + if (comp != null) { + if (theGraph != null) { + comp.getDiagramModel().selectGraph(theGraph); } + comp.setSelectedNodes(set); + comp.requestActive(); } - }, - "All " + matches.size() + " matching nodes (" + name + "=" + value + ")" + } + }, + "All " + matches.size() + " matching nodes (" + name + "=" + value + ")" + (theGraph != null ? " in " + theGraph.getName() : "") ); // Single matches for (final InputNode n : matches) { response.addResult(new Runnable() { @Override - public void run() { - final EditorTopComponent comp = EditorTopComponent.getActive(); - if (comp != null) { - final Set tmpSet = new HashSet<>(); - tmpSet.add(n); - comp.setSelectedNodes(tmpSet); - comp.requestActive(); + public void run() { + final EditorTopComponent comp = EditorTopComponent.getActive(); + if (comp != null) { + final Set tmpSet = new HashSet<>(); + tmpSet.add(n); + if (theGraph != null) { + comp.getDiagramModel().selectGraph(theGraph); } + comp.setSelectedNodes(tmpSet); + comp.requestActive(); } - }, - n.getProperties().get(name) + " (" + n.getId() + " " + n.getProperties().get("name") + ")" + } + }, + n.getProperties().get(name) + " (" + n.getId() + " " + n.getProperties().get("name") + ")" + (theGraph != null ? " in " + theGraph.getName() : "") ); } } @@ -139,4 +150,27 @@ System.out.println("no input graph provider!"); } } + + private List findMatches(String name, String value, InputGraph inputGraph, SearchResponse response) { + try { + RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(name, value, Pattern.CASE_INSENSITIVE); + Properties.PropertySelector selector = new Properties.PropertySelector<>(inputGraph.getNodes()); + List matches = selector.selectMultiple(matcher); + return matches.size() == 0 ? null : matches; + } catch (Exception e) { + final String msg = e.getMessage(); + response.addResult(new Runnable() { + @Override + public void run() { + Message desc = new NotifyDescriptor.Message("An exception occurred during the search, " + + "perhaps due to a malformed query string:\n" + msg, + NotifyDescriptor.WARNING_MESSAGE); + DialogDisplayer.getDefault().notify(desc); + } + }, + "(Error during search)" + ); + } + return null; + } } diff --git a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/layer.xml b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/layer.xml --- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/layer.xml +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/layer.xml @@ -61,14 +61,26 @@ + + + + + + + + + + + + diff --git a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java --- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java +++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ import com.sun.hotspot.igv.graph.Figure; import com.sun.hotspot.igv.graph.InputSlot; import com.sun.hotspot.igv.graph.OutputSlot; +import com.sun.hotspot.igv.util.StringUtils; import com.sun.hotspot.igv.view.DiagramScene; import java.awt.*; import java.awt.geom.Line2D; @@ -148,7 +149,7 @@ private String generateToolTipText(List conn) { StringBuilder sb = new StringBuilder(); for (Connection c : conn) { - sb.append(c.getToolTipText()); + sb.append(StringUtils.escapeHTML(c.getToolTipText())); sb.append("
"); } return sb.toString(); diff --git a/src/share/tools/IdealGraphVisualizer/nbproject/project.properties b/src/share/tools/IdealGraphVisualizer/nbproject/project.properties --- a/src/share/tools/IdealGraphVisualizer/nbproject/project.properties +++ b/src/share/tools/IdealGraphVisualizer/nbproject/project.properties @@ -48,5 +48,5 @@ # Disable assertions for RequestProcessor to prevent annoying messages in case # of multiple SceneAnimator update tasks in the default RequestProcessor. -run.args.extra = -J-server -J-da:org.openide.util.RequestProcessor -J-Xms2g -J-Xmx8g -J-Djava.lang.Integer.IntegerCache.high=20000 +run.args.extra = -J-server -J-da:org.openide.util.RequestProcessor -J-Xms2g -J-Xmx8g -J-Djava.lang.Integer.IntegerCache.high=200000 debug.args.extra = -J-server -J-da:org.openide.util.RequestProcessor