1/* 2 * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25package sun.jvm.hotspot.ui; 26 27import java.util.*; 28import java.io.*; 29import java.awt.*; 30import java.awt.event.*; 31import javax.swing.*; 32import javax.swing.text.*; 33 34import sun.jvm.hotspot.debugger.*; 35import sun.jvm.hotspot.oops.*; 36import sun.jvm.hotspot.runtime.*; 37import sun.jvm.hotspot.utilities.*; 38 39/** Finds a given (Address) value in the heap. Only intended for use 40 in a debugging system. */ 41 42public class FindInHeapPanel extends JPanel { 43 private RawHeapVisitor iterator; 44 private long addressSize; 45 private long usedSize; 46 private long iterated; 47 private Address value; 48 private ProgressBarPanel progressBar; 49 private HistoryComboBox addressField; 50 private JButton findButton; 51 private JTextArea textArea; 52 private ArrayList updates; 53 private double lastFrac; 54 55 static final double minUpdateFraction = 0.05; 56 57 public FindInHeapPanel() { 58 super(); 59 60 setLayout(new BorderLayout()); 61 62 JPanel topPanel = new JPanel(); 63 topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS)); 64 65 JPanel panel = new JPanel(); 66 panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); 67 panel.add(new JLabel("Address to search for:")); 68 69 addressField = new HistoryComboBox(); 70 panel.add(addressField); 71 72 addressSize = VM.getVM().getAddressSize(); 73 74 iterator = new RawHeapVisitor() { 75 boolean error = false; 76 77 public void prologue(long used) { 78 usedSize = used; 79 iterated = 0; 80 lastFrac = 0; 81 error = false; 82 updates = new ArrayList(); 83 } 84 85 public void visitAddress(Address addr) { 86 if (error) return; 87 88 Address val = addr.getAddressAt(0); 89 if (AddressOps.equal(val, value)) { 90 error = reportResult(addr); 91 } 92 iterated += addressSize; 93 updateProgressBar(); 94 } 95 public void visitCompOopAddress(Address addr) { 96 if (error) return; 97 98 Address val = addr.getCompOopAddressAt(0); 99 if (AddressOps.equal(val, value)) { 100 error = reportResult(addr); 101 } 102 iterated += addressSize; 103 updateProgressBar(); 104 105 } 106 public void epilogue() { 107 iterated = 0; 108 updateProgressBar(); 109 findButton.setEnabled(true); 110 } 111 }; 112 113 findButton = new JButton("Find"); 114 ActionListener listener = new ActionListener() { 115 public void actionPerformed(ActionEvent e) { 116 clearResultWindow(); 117 // Parse text 118 try { 119 Address val = VM.getVM().getDebugger().parseAddress(addressField.getText()); 120 value = val; 121 122 findButton.setEnabled(false); 123 124 java.lang.Thread t = new java.lang.Thread(new Runnable() { 125 public void run() { 126 try { 127 VM.getVM().getObjectHeap().iterateRaw(iterator); 128 } finally { 129 SwingUtilities.invokeLater(new Runnable() { 130 public void run() { 131 findButton.setEnabled(true); 132 } 133 }); 134 } 135 } 136 }); 137 t.start(); 138 } catch (Exception ex) { 139 textArea.setText("Error parsing address"); 140 } 141 } 142 }; 143 panel.add(findButton); 144 findButton.addActionListener(listener); 145 addressField.addActionListener(listener); 146 topPanel.add(panel); 147 148 progressBar = new ProgressBarPanel(ProgressBarPanel.HORIZONTAL, "Search progress:"); 149 topPanel.add(progressBar); 150 151 add(topPanel, BorderLayout.NORTH); 152 153 textArea = new JTextArea(); 154 JScrollPane scroller = new JScrollPane(textArea); 155 add(scroller, BorderLayout.CENTER); 156 } 157 158 private boolean pendingUpdate = false; 159 160 private boolean reportResult(final Address addr) { 161 synchronized (this) { 162 try { 163 updates.add("found at " + addr + "\n"); 164 if (!pendingUpdate) { 165 pendingUpdate = true; 166 SwingUtilities.invokeLater(new Runnable() { 167 public void run() { 168 updateResultWindow(); 169 } 170 }); 171 } 172 } catch (Throwable t) { 173 t.printStackTrace(); 174 return true; 175 } 176 } 177 178 return false; 179 } 180 181 private void clearResultWindow() { 182 SwingUtilities.invokeLater(new Runnable() { 183 public void run() { 184 185 Document d = textArea.getDocument(); 186 try { 187 d.remove(0, d.getLength()); 188 } catch (BadLocationException e) { 189 } 190 } 191 }); 192 } 193 194 private synchronized void updateResultWindow() { 195 if (updates.size() > 0) { 196 Iterator i = updates.iterator(); 197 while (i.hasNext()) { 198 textArea.append((String)i.next()); 199 } 200 updates = new ArrayList();; 201 } 202 pendingUpdate = false; 203 } 204 205 private void invokeInDispatchThread(Runnable runnable) { 206 if (EventQueue.isDispatchThread()) { 207 runnable.run(); 208 } else { 209 SwingUtilities.invokeLater(runnable); 210 } 211 } 212 213 private void updateProgressBar() { 214 final double frac = (double) iterated / (double) usedSize; 215 if (frac == 0.0 || (frac - lastFrac > minUpdateFraction)) { 216 lastFrac = frac; 217 if (iterated > usedSize) { 218 System.out.println("iterated " + iterated + " usedSize " + usedSize); 219 } 220 SwingUtilities.invokeLater(new Runnable() { 221 public void run() { 222 progressBar.setValue(frac); 223 } 224 }); 225 } 226 } 227} 228