1/* 2 * Copyright (c) 2004, 2010, 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.io.*; 28import java.awt.*; 29import java.awt.event.*; 30import javax.swing.*; 31import javax.swing.event.*; 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.*; 38import sun.jvm.hotspot.code.*; 39import sun.jvm.hotspot.ui.classbrowser.*; 40 41/** Finds a given (Address) value in the code cache. Only intended for use 42 in a debugging system. */ 43 44public class FindInCodeCachePanel extends SAPanel { 45 private Visitor iterator; 46 private long usedSize; 47 private long iterated; 48 private Address value; 49 private ProgressBarPanel progressBar; 50 private HistoryComboBox addressField; 51 private JButton findButton; 52 private SAEditorPane contentEditor; 53 54 class Visitor implements CodeCacheVisitor { 55 Address base; 56 StringBuffer result; 57 boolean searching; 58 59 public void prologue(Address start, Address end) { 60 searching = true; 61 base = start; 62 usedSize = end.minus(start); 63 iterated = 0; 64 result = new StringBuffer(); 65 clearResultWindow(); 66 } 67 68 public void visit(CodeBlob blob) { 69 Address begin = blob.headerBegin(); 70 Address end = begin.addOffsetTo(blob.getSize()); 71 long addressSize = VM.getVM().getAddressSize(); 72 73 boolean found = false; 74 while (!found && begin.lessThan(end)) { 75 Address val = begin.getAddressAt(0); 76 if (AddressOps.equal(val, value)) { 77 reportResult(result, blob); 78 found = true; 79 } 80 begin = begin.addOffsetTo(addressSize); 81 } 82 iterated = end.minus(base);; 83 updateProgressBar(null); 84 } 85 86 public void epilogue() { 87 } 88 89 public void cleanup() { 90 iterated = 0; 91 updateProgressBar(result); 92 searching = false; 93 result = null; 94 } 95 96 private void search() { 97 // Parse text 98 Address val = null; 99 try { 100 val = VM.getVM().getDebugger().parseAddress(addressField.getText()); 101 } catch (Exception ex) { 102 contentEditor.setText("<b>Error parsing address</b>"); 103 return; 104 } 105 106 // make sure we don't start up multiple search threads in parallel 107 synchronized (iterator) { 108 if (searching && value.equals(val)) { 109 return; 110 } 111 112 value = val; 113 contentEditor.setText(""); 114 findButton.setEnabled(false); 115 116 System.out.println("Searching " + value); 117 java.lang.Thread t = new java.lang.Thread(new Runnable() { 118 public void run() { 119 synchronized (iterator) { 120 try { 121 VM.getVM().getCodeCache().iterate(iterator); 122 } finally { 123 iterator.cleanup(); 124 } 125 } 126 } 127 }); 128 t.start(); 129 } 130 } 131 } 132 133 134 public FindInCodeCachePanel() { 135 super(); 136 137 setLayout(new BorderLayout()); 138 139 JPanel topPanel = new JPanel(); 140 topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS)); 141 142 JPanel panel = new JPanel(); 143 panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS)); 144 panel.add(new JLabel("Address to search for:")); 145 146 addressField = new HistoryComboBox(); 147 panel.add(addressField); 148 149 iterator = new Visitor(); 150 151 findButton = new JButton("Find"); 152 ActionListener listener = new ActionListener() { 153 public void actionPerformed(ActionEvent e) { 154 iterator.search(); 155 } 156 }; 157 panel.add(findButton); 158 findButton.addActionListener(listener); 159 addressField.addActionListener(listener); 160 topPanel.add(panel); 161 162 progressBar = new ProgressBarPanel(ProgressBarPanel.HORIZONTAL, "Search progress:"); 163 topPanel.add(progressBar); 164 165 add(topPanel, BorderLayout.NORTH); 166 167 contentEditor = new SAEditorPane(); 168 169 HyperlinkListener hyperListener = new HyperlinkListener() { 170 public void hyperlinkUpdate(HyperlinkEvent e) { 171 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { 172 String description = e.getDescription(); 173 int index = description.indexOf(':'); 174 if (index != -1) { 175 String item = description.substring(0, index); 176 if (item.equals("blob")) { 177 Address blob = VM.getVM().getDebugger().parseAddress(description.substring(index + 1)); 178 showCodeViewer(blob); 179 } 180 } 181 } 182 } 183 }; 184 185 contentEditor.addHyperlinkListener(hyperListener); 186 187 JScrollPane scroller = new JScrollPane(contentEditor); 188 add(scroller, BorderLayout.CENTER); 189 } 190 191 private void reportResult(StringBuffer result, CodeBlob blob) { 192 result.append("<a href='blob:"); 193 result.append(blob.contentBegin().toString()); 194 result.append("'>"); 195 result.append(blob.getName()); 196 result.append("@"); 197 result.append(blob.contentBegin()); 198 result.append("</a><br>"); 199 } 200 201 private void clearResultWindow() { 202 SwingUtilities.invokeLater(new Runnable() { 203 public void run() { 204 contentEditor.setText(""); 205 } 206 }); 207 } 208 209 private void updateProgressBar(final StringBuffer result) { 210 SwingUtilities.invokeLater(new Runnable() { 211 public void run() { 212 progressBar.setValue((double) iterated / (double) usedSize); 213 if (result != null) { 214 String s = "<html> <head> </head> <body>\n" + result + " </body> </html>"; 215 contentEditor.setText(s); 216 findButton.setEnabled(true); 217 } 218 } 219 }); 220 } 221} 222