8154483: update IGV with improvements from Graal

Reviewed-by: kvn
This commit is contained in:
Tom Rodriguez 2016-04-29 12:56:27 -07:00
parent 528bf589fd
commit f1eeebc17e
19 changed files with 423 additions and 159 deletions

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,11 +25,13 @@ package com.sun.hotspot.igv.coordinator;
import com.sun.hotspot.igv.coordinator.actions.RemoveCookie; import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
import com.sun.hotspot.igv.data.*; import com.sun.hotspot.igv.data.*;
import com.sun.hotspot.igv.util.PropertiesSheet;
import java.awt.Image; import java.awt.Image;
import java.util.List; import java.util.List;
import org.openide.nodes.AbstractNode; import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children; import org.openide.nodes.Children;
import org.openide.nodes.Node; import org.openide.nodes.Node;
import org.openide.nodes.Sheet;
import org.openide.util.ImageUtilities; import org.openide.util.ImageUtilities;
import org.openide.util.lookup.AbstractLookup; import org.openide.util.lookup.AbstractLookup;
import org.openide.util.lookup.InstanceContent; import org.openide.util.lookup.InstanceContent;
@ -74,6 +76,16 @@ public class FolderNode extends AbstractNode {
} }
} }
@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 @Override
public Image getIcon(int i) { public Image getIcon(int i) {
return ImageUtilities.loadImage("com/sun/hotspot/igv/coordinator/images/folder.png"); return ImageUtilities.loadImage("com/sun/hotspot/igv/coordinator/images/folder.png");

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -124,6 +124,8 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
public void clear() { public void clear() {
document.clear(); document.clear();
root = new FolderNode(document);
manager.setRootContext(root);
} }
@Override @Override

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -31,31 +31,47 @@ import com.sun.hotspot.igv.data.serialization.GraphParser;
import com.sun.hotspot.igv.data.serialization.ParseMonitor; import com.sun.hotspot.igv.data.serialization.ParseMonitor;
import com.sun.hotspot.igv.data.serialization.Parser; import com.sun.hotspot.igv.data.serialization.Parser;
import com.sun.hotspot.igv.settings.Settings; import com.sun.hotspot.igv.settings.Settings;
import java.awt.event.InputEvent; import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.nio.file.StandardOpenOption; 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.JFileChooser;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter; import javax.swing.filechooser.FileFilter;
import org.netbeans.api.progress.ProgressHandle; import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.api.progress.ProgressHandleFactory; import org.netbeans.api.progress.ProgressHandleFactory;
import org.openide.util.Exceptions; 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.HelpCtx;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor; import org.openide.util.actions.SystemAction;
import org.openide.util.actions.CallableSystemAction;
/** /**
* *
* @author Thomas Wuerthinger * @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; private static final int WORKUNITS = 10000;
public static FileFilter getFileFilter() { public static FileFilter getFileFilter() {
@ -74,74 +90,77 @@ public final class ImportAction extends CallableSystemAction {
} }
@Override @Override
public void performAction() { public void actionPerformed(ActionEvent e) {
JFileChooser fc = new JFileChooser(); JFileChooser fc = new JFileChooser();
fc.setFileFilter(ImportAction.getFileFilter()); fc.setFileFilter(ImportAction.getFileFilter());
fc.setCurrentDirectory(new File(Settings.get().get(Settings.DIRECTORY, Settings.DIRECTORY_DEFAULT))); fc.setCurrentDirectory(new File(Settings.get().get(Settings.DIRECTORY, Settings.DIRECTORY_DEFAULT)));
fc.setMultiSelectionEnabled(true);
if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile(); for (final File file : fc.getSelectedFiles()) {
File dir = file;
File dir = file; if (!dir.isDirectory()) {
if (!dir.isDirectory()) { dir = dir.getParentFile();
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) {
}
}
@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 Settings.get().put(Settings.DIRECTORY, dir.getAbsolutePath());
public void run() { try {
try { final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.READ);
final GraphDocument document = parser.parse(); final ProgressHandle handle = ProgressHandleFactory.createHandle("Opening file " + file.getName());
if (document != null) { handle.start(WORKUNITS);
SwingUtilities.invokeLater(new Runnable(){ final long startTime = System.currentTimeMillis();
@Override final long start = channel.size();
public void run() { ParseMonitor monitor = new ParseMonitor() {
component.requestActive(); @Override
component.getDocument().addGraphDocument(document); public void updateProgress() {
} try {
}); int prog = (int) (WORKUNITS * (double) channel.position() / (double) start);
handle.progress(prog);
} catch (IOException ex) {
}
} }
} catch (IOException ex) { @Override
Exceptions.printStackTrace(ex); public void setState(String state) {
} updateProgress();
handle.finish(); 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() {
} catch (FileNotFoundException ex) { @Override
Exceptions.printStackTrace(ex); public void run() {
} catch (IOException ex) { try {
Exceptions.printStackTrace(ex); 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);
}
} }
} }
} }
@ -151,11 +170,6 @@ public final class ImportAction extends CallableSystemAction {
return NbBundle.getMessage(ImportAction.class, "CTL_ImportAction"); 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 @Override
protected String iconResource() { protected String iconResource() {
return "com/sun/hotspot/igv/coordinator/images/import.png"; return "com/sun/hotspot/igv/coordinator/images/import.png";
@ -165,9 +179,4 @@ public final class ImportAction extends CallableSystemAction {
public HelpCtx getHelpCtx() { public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP; return HelpCtx.DEFAULT_HELP;
} }
@Override
protected boolean asynchronous() {
return false;
}
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,14 +29,30 @@ import java.awt.event.InputEvent;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import javax.swing.Action; import javax.swing.Action;
import javax.swing.KeyStroke; 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.HelpCtx;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.openide.util.actions.CallableSystemAction; import org.openide.util.actions.CallableSystemAction;
/** /**
* *
* @author Thomas Wuerthinger * @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 { public final class SaveAllAction extends CallableSystemAction {
@Override @Override

View File

@ -18,6 +18,8 @@
<folder name="Menu"> <folder name="Menu">
<folder name="File"> <folder name="File">
<file name="Export_hidden"/>
<file name="Import_hidden"/>
<file name="Separator2.instance_hidden"/> <file name="Separator2.instance_hidden"/>
<file name="Separator3.instance_hidden"/> <file name="Separator3.instance_hidden"/>
<file name="SeparatorOpen.instance_hidden"/> <file name="SeparatorOpen.instance_hidden"/>
@ -43,11 +45,11 @@
</file> </file>
<file name="com-sun-hotspot-igv-coordinator-actions-RemoveAction.shadow"> <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAction.shadow">
<attr name="originalFile" stringvalue="Actions/Edit/com-sun-hotspot-igv-coordinator-actions-RemoveAction.instance"/> <attr name="originalFile" stringvalue="Actions/Edit/com-sun-hotspot-igv-coordinator-actions-RemoveAction.instance"/>
<attr name="position" intvalue="400" /> <attr name="position" intvalue="400"/>
</file> </file>
<file name="com-sun-hotspot-igv-coordinator-actions-RemoveAllAction.shadow"> <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAllAction.shadow">
<attr name="originalFile" stringvalue="Actions/Edit/com-sun-hotspot-igv-coordinator-actions-RemoveAllAction.instance"/> <attr name="originalFile" stringvalue="Actions/Edit/com-sun-hotspot-igv-coordinator-actions-RemoveAllAction.instance"/>
<attr name="position" intvalue="500" /> <attr name="position" intvalue="500"/>
</file> </file>
<!-- Hidden menu entries from other modules --> <!-- Hidden menu entries from other modules -->

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -51,11 +51,13 @@ public class GraphDocument extends Properties.Entity implements ChangedEventProv
} }
public void addGraphDocument(GraphDocument document) { public void addGraphDocument(GraphDocument document) {
for (FolderElement e : document.elements) { if (document != this) {
e.setParent(this); for (FolderElement e : document.elements) {
this.addElement(e); e.setParent(this);
this.addElement(e);
}
document.clear();
} }
document.clear();
getChangedEvent().fire(); getChangedEvent().fire();
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -90,7 +90,9 @@ public class InputBlock {
public void addNode(int id) { public void addNode(int id) {
InputNode node = graph.getNode(id); InputNode node = graph.getNode(id);
assert node != null; 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); graph.setBlock(node, this);
nodes.add(node); nodes.add(node);
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -24,7 +24,9 @@
package com.sun.hotspot.igv.data; package com.sun.hotspot.igv.data;
import java.io.Serializable; import java.io.Serializable;
import java.lang.ref.WeakReference;
import java.util.*; import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException; import java.util.regex.PatternSyntaxException;
@ -36,7 +38,7 @@ import java.util.regex.PatternSyntaxException;
public class Properties implements Serializable, Iterable<Property> { public class Properties implements Serializable, Iterable<Property> {
public static final long serialVersionUID = 1L; public static final long serialVersionUID = 1L;
private String[] map = new String[4]; protected String[] map = new String[4];
public Properties() { public Properties() {
} }
@ -102,6 +104,59 @@ public class Properties implements Serializable, Iterable<Property> {
System.arraycopy(p.map, 0, map, 0, p.map.length); 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<SharedProperties, WeakReference<SharedProperties>> immutableCache = new WeakHashMap<>();
static synchronized SharedProperties intern(Properties properties) {
String[] map = properties.map;
SharedProperties key = new SharedProperties(map);
WeakReference<SharedProperties> 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 { public static class Entity implements Provider {
private Properties properties; private Properties properties;
@ -118,6 +173,10 @@ public class Properties implements Serializable, Iterable<Property> {
public Properties getProperties() { public Properties getProperties() {
return properties; return properties;
} }
public void internProperties() {
properties = PropertyCache.intern(properties);
}
} }
public interface PropertyMatcher { public interface PropertyMatcher {
@ -322,8 +381,8 @@ public class Properties implements Serializable, Iterable<Property> {
public void setProperty(String name, String value) { public void setProperty(String name, String value) {
setPropertyInternal(name.intern(), value != null ? value.intern() : null); 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) { for (int i = 0; i < map.length; i += 2) {
if (map[i] != null && map[i].equals(name)) { if (map[i] != null && map[i].equals(name)) {
String p = map[i + 1]; String p = map[i + 1];

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -31,6 +31,7 @@ import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.nio.charset.Charset;
import java.util.*; import java.util.*;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -68,6 +69,8 @@ public class BinaryParser implements GraphParser {
private static final String NO_BLOCK = "noBlock"; private static final String NO_BLOCK = "noBlock";
private static final Charset utf8 = Charset.forName("UTF-8");
private final GroupCallback callback; private final GroupCallback callback;
private final List<Object> constantPool; private final List<Object> constantPool;
private final ByteBuffer buffer; private final ByteBuffer buffer;
@ -275,28 +278,36 @@ public class BinaryParser implements GraphParser {
hashStack = new LinkedList<>(); hashStack = new LinkedList<>();
this.monitor = monitor; this.monitor = monitor;
try { try {
this.digest = MessageDigest.getInstance("SHA-256"); this.digest = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
} }
} }
private void fill() throws IOException { 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(); buffer.compact();
if (channel.read(buffer) < 0) { if (channel.read(buffer) < 0) {
throw new EOFException(); throw new EOFException();
} }
buffer.flip(); buffer.flip();
lastPosition = buffer.position();
} }
private void ensureAvailable(int i) throws IOException { 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) { while (buffer.remaining() < i) {
fill(); fill();
} }
buffer.mark();
byte[] result = new byte[i];
buffer.get(result);
digest.update(result);
buffer.reset();
} }
private int readByte() throws IOException { private int readByte() throws IOException {
@ -330,12 +341,7 @@ public class BinaryParser implements GraphParser {
} }
private String readString() throws IOException { private String readString() throws IOException {
int len = readInt(); return new String(readBytes(), utf8).intern();
ensureAvailable(len * 2);
char[] chars = new char[len];
buffer.asCharBuffer().get(chars);
buffer.position(buffer.position() + len * 2);
return new String(chars).intern();
} }
private byte[] readBytes() throws IOException { private byte[] readBytes() throws IOException {
@ -343,10 +349,15 @@ public class BinaryParser implements GraphParser {
if (len < 0) { if (len < 0) {
return null; return null;
} }
ensureAvailable(len); byte[] b = new byte[len];
byte[] data = new byte[len]; int bytesRead = 0;
buffer.get(data); while (bytesRead < b.length) {
return data; 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 { private String readIntsToString() throws IOException {
@ -643,6 +654,7 @@ public class BinaryParser implements GraphParser {
int bci = readInt(); int bci = readInt();
Group group = new Group(parent); Group group = new Group(parent);
group.getProperties().setProperty("name", name); group.getProperties().setProperty("name", name);
parseProperties(group.getProperties());
if (method != null) { if (method != null) {
InputMethod inMethod = new InputMethod(group, method.name, shortName, bci); InputMethod inMethod = new InputMethod(group, method.name, shortName, bci);
inMethod.setBytecodes("TODO"); inMethod.setBytecodes("TODO");
@ -651,13 +663,25 @@ public class BinaryParser implements GraphParser {
return group; return group;
} }
int lastPosition = 0;
private InputGraph parseGraph() throws IOException { private InputGraph parseGraph() throws IOException {
if (monitor != null) { if (monitor != null) {
monitor.updateProgress(); monitor.updateProgress();
} }
String title = readPoolObject(String.class); String title = readPoolObject(String.class);
digest.reset(); digest.reset();
lastPosition = buffer.position();
InputGraph graph = parseGraph(title); 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[] d = digest.digest();
byte[] hash = hashStack.peek(); byte[] hash = hashStack.peek();
if (hash != null && Arrays.equals(hash, d)) { if (hash != null && Arrays.equals(hash, d)) {
@ -669,11 +693,24 @@ public class BinaryParser implements GraphParser {
return graph; 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 { private InputGraph parseGraph(String title) throws IOException {
InputGraph graph = new InputGraph(title); InputGraph graph = new InputGraph(title);
parseProperties(graph.getProperties());
parseNodes(graph); parseNodes(graph);
parseBlocks(graph); parseBlocks(graph);
graph.ensureNodesInBlocks(); graph.ensureNodesInBlocks();
for (InputNode node : graph.getNodes()) {
node.internProperties();
}
return graph; return graph;
} }
@ -822,9 +859,10 @@ public class BinaryParser implements GraphParser {
} }
} }
static final Pattern templatePattern = Pattern.compile("\\{(p|i)#([a-zA-Z0-9$_]+)(/(l|m|s))?\\}");
private String createName(List<Edge> edges, Map<String, Object> properties, String template) { private String createName(List<Edge> edges, Map<String, Object> properties, String template) {
Pattern p = Pattern.compile("\\{(p|i)#([a-zA-Z0-9$_]+)(/(l|m|s))?\\}"); Matcher m = templatePattern.matcher(template);
Matcher m = p.matcher(template);
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
while (m.find()) { while (m.find()) {
String name = m.group(2); String name = m.group(2);

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -37,4 +37,14 @@ public interface InputGraphProvider {
InputGraph getGraph(); InputGraph getGraph();
void setSelectedNodes(Set<InputNode> nodes); void setSelectedNodes(Set<InputNode> nodes);
/**
* @return an iterator walking forward through the {@link InputGraph}s following the {@link #getGraph()}
*/
Iterable<InputGraph> searchForward();
/**
* @return an iterator walking backward through the {@link InputGraph}s preceeding the {@link #getGraph()}
*/
Iterable<InputGraph> searchBackward();
} }

View File

@ -22,6 +22,14 @@
<specification-version>1.0</specification-version> <specification-version>1.0</specification-version>
</run-dependency> </run-dependency>
</dependency> </dependency>
<dependency>
<code-name-base>com.sun.hotspot.igv.util</code-name-base>
<build-prerequisite/>
<compile-dependency/>
<run-dependency>
<specification-version>1.0</specification-version>
</run-dependency>
</dependency>
</module-dependencies> </module-dependencies>
<public-packages> <public-packages>
<package>com.sun.hotspot.igv.graph</package> <package>com.sun.hotspot.igv.graph</package>

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -28,6 +28,7 @@ import com.sun.hotspot.igv.data.Properties;
import com.sun.hotspot.igv.data.Source; import com.sun.hotspot.igv.data.Source;
import com.sun.hotspot.igv.layout.Port; import com.sun.hotspot.igv.layout.Port;
import com.sun.hotspot.igv.layout.Vertex; import com.sun.hotspot.igv.layout.Vertex;
import com.sun.hotspot.igv.util.StringUtils;
import java.awt.Color; import java.awt.Color;
import java.awt.Font; import java.awt.Font;
import java.awt.FontMetrics; import java.awt.FontMetrics;
@ -141,7 +142,7 @@ public abstract class Slot implements Port, Source.Provider, Properties.Provider
sb.append(text); sb.append(text);
for (InputNode n : getSource().getSourceNodes()) { 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("<br>"); sb.append("<br>");
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -445,5 +445,48 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
void close() { void close() {
filterChain.getChangedEvent().removeListener(filterChainChangedListener); filterChain.getChangedEvent().removeListener(filterChainChangedListener);
sequenceFilterChain.getChangedEvent().removeListener(filterChainChangedListener); sequenceFilterChain.getChangedEvent().removeListener(filterChainChangedListener);
} }
Iterable<InputGraph> getGraphsForward() {
return new Iterable<InputGraph>() {
@Override
public Iterator<InputGraph> iterator() {
return new Iterator<InputGraph>() {
int index = getFirstPosition();
@Override
public boolean hasNext() {
return index + 1 < graphs.size();
}
@Override
public InputGraph next() {
return graphs.get(++index);
}
};
}
};
}
Iterable<InputGraph> getGraphsBackward() {
return new Iterable<InputGraph>() {
@Override
public Iterator<InputGraph> iterator() {
return new Iterator<InputGraph>() {
int index = getFirstPosition();
@Override
public boolean hasNext() {
return index - 1 > 0;
}
@Override
public InputGraph next() {
return graphs.get(--index);
}
};
}
};
}
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -50,4 +50,14 @@ public class EditorInputGraphProvider implements InputGraphProvider {
public void setSelectedNodes(Set<InputNode> nodes) { public void setSelectedNodes(Set<InputNode> nodes) {
editor.setSelectedNodes(nodes); editor.setSelectedNodes(nodes);
} }
@Override
public Iterable<InputGraph> searchBackward() {
return editor.getDiagramModel().getGraphsBackward();
}
@Override
public Iterable<InputGraph> searchForward() {
return editor.getDiagramModel().getGraphsForward();
}
} }

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -289,7 +289,10 @@ public final class EditorTopComponent extends TopComponent implements PropertyCh
quicksearch = (Component) quicksearch.getClass().getConstructor(KeyStroke.class).newInstance(new Object[]{null}); quicksearch = (Component) quicksearch.getClass().getConstructor(KeyStroke.class).newInstance(new Object[]{null});
} catch (ReflectiveOperationException | IllegalArgumentException | SecurityException e) { } 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); toolBar.add(quicksearch);
centerPanel = new JPanel(); centerPanel = new JPanel();

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,6 +23,7 @@
*/ */
package com.sun.hotspot.igv.view; 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.InputNode;
import com.sun.hotspot.igv.data.Properties; import com.sun.hotspot.igv.data.Properties;
import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher; import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
@ -81,57 +82,67 @@ public class NodeQuickSearch implements SearchProvider {
final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class); final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);
if (p != null && p.getGraph() != null) { if (p != null && p.getGraph() != null) {
List<InputNode> matches = null; InputGraph matchGraph = p.getGraph();
try { // Search the current graph
RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(name, value, Pattern.CASE_INSENSITIVE); List<InputNode> matches = findMatches(name, value, p.getGraph(), response);
Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<>(p.getGraph().getNodes()); if (matches == null) {
// See if the it hits in a later graph
matches = selector.selectMultiple(matcher); for (InputGraph graph : p.searchForward()) {
} catch (Exception e) { matches = findMatches(name, value, graph, response);
final String msg = e.getMessage(); if (matches != null) {
response.addResult(new Runnable() { matchGraph = graph;
@Override break;
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); if (matches == null) {
DialogDisplayer.getDefault().notify(desc); // See if it hits in a earlier graph
} for (InputGraph graph : p.searchBackward()) {
}, matches = findMatches(name, value, graph, response);
"(Error during search)" if (matches != null) {
); matchGraph = graph;
break;
}
}
} }
if (matches != null) { if (matches != null) {
final Set<InputNode> set = new HashSet<>(matches); final Set<InputNode> set = new HashSet<>(matches);
final InputGraph theGraph = p.getGraph() != matchGraph ? matchGraph : null;
response.addResult(new Runnable() { response.addResult(new Runnable() {
@Override @Override
public void run() { public void run() {
final EditorTopComponent comp = EditorTopComponent.getActive(); final EditorTopComponent comp = EditorTopComponent.getActive();
if (comp != null) { if (comp != null) {
comp.setSelectedNodes(set); if (theGraph != null) {
comp.requestActive(); 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 // Single matches
for (final InputNode n : matches) { for (final InputNode n : matches) {
response.addResult(new Runnable() { response.addResult(new Runnable() {
@Override @Override
public void run() { public void run() {
final EditorTopComponent comp = EditorTopComponent.getActive(); final EditorTopComponent comp = EditorTopComponent.getActive();
if (comp != null) { if (comp != null) {
final Set<InputNode> tmpSet = new HashSet<>(); final Set<InputNode> tmpSet = new HashSet<>();
tmpSet.add(n); tmpSet.add(n);
comp.setSelectedNodes(tmpSet); if (theGraph != null) {
comp.requestActive(); 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 @@ public class NodeQuickSearch implements SearchProvider {
System.out.println("no input graph provider!"); System.out.println("no input graph provider!");
} }
} }
private List<InputNode> findMatches(String name, String value, InputGraph inputGraph, SearchResponse response) {
try {
RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(name, value, Pattern.CASE_INSENSITIVE);
Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<>(inputGraph.getNodes());
List<InputNode> 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;
}
} }

View File

@ -61,14 +61,26 @@
<attr name="position" intvalue="710"/> <attr name="position" intvalue="710"/>
</file> </file>
</folder> </folder>
<folder name="Window">
<file name="Tools_hidden"/>
<file name="Web_hidden"/>
<file name="org-netbeans-modules-tasks-ui-DashboardTopComponent.shadow_hidden"/>
</folder>
</folder> </folder>
<folder name="QuickSearch"> <folder name="QuickSearch">
<file name="Actions_hidden"/>
<file name="GoToOption_hidden"/>
<file name="GoToSymbol_hidden"/>
<file name="GoToType_hidden"/>
<file name="Help_hidden"/>
<file name="Hudson_hidden"/>
<folder name="Nodes"> <folder name="Nodes">
<attr name="command" stringvalue="n"/> <attr name="command" stringvalue="n"/>
<attr name="position" intvalue="0"/> <attr name="position" intvalue="0"/>
<file name="com-sun-hotspot-igv-view-NodeQuickSearch.instance"/> <file name="com-sun-hotspot-igv-view-NodeQuickSearch.instance"/>
</folder> </folder>
<file name="Projects_hidden"/>
</folder> </folder>
<folder name="QuickSearchShadow"> <folder name="QuickSearchShadow">

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,6 +27,7 @@ import com.sun.hotspot.igv.graph.Connection;
import com.sun.hotspot.igv.graph.Figure; import com.sun.hotspot.igv.graph.Figure;
import com.sun.hotspot.igv.graph.InputSlot; import com.sun.hotspot.igv.graph.InputSlot;
import com.sun.hotspot.igv.graph.OutputSlot; import com.sun.hotspot.igv.graph.OutputSlot;
import com.sun.hotspot.igv.util.StringUtils;
import com.sun.hotspot.igv.view.DiagramScene; import com.sun.hotspot.igv.view.DiagramScene;
import java.awt.*; import java.awt.*;
import java.awt.geom.Line2D; import java.awt.geom.Line2D;
@ -148,7 +149,7 @@ public class LineWidget extends Widget implements PopupMenuProvider {
private String generateToolTipText(List<Connection> conn) { private String generateToolTipText(List<Connection> conn) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (Connection c : conn) { for (Connection c : conn) {
sb.append(c.getToolTipText()); sb.append(StringUtils.escapeHTML(c.getToolTipText()));
sb.append("<br>"); sb.append("<br>");
} }
return sb.toString(); return sb.toString();

View File

@ -48,5 +48,5 @@ project.com.sun.hotspot.igv.util=Util
# Disable assertions for RequestProcessor to prevent annoying messages in case # Disable assertions for RequestProcessor to prevent annoying messages in case
# of multiple SceneAnimator update tasks in the default RequestProcessor. # 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 debug.args.extra = -J-server -J-da:org.openide.util.RequestProcessor