/* This file is part of jpcsp.
Jpcsp is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Jpcsp is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Jpcsp. If not, see <http://www.gnu.org/licenses/>.
*/
package jpcsp.Debugger;
import java.awt.Cursor;
import java.awt.Toolkit;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JFileChooser;
import jpcsp.Emulator;
import jpcsp.Memory;
import jpcsp.Allegrex.Common.Instruction;
import jpcsp.HLE.kernel.types.SceModule;
import jpcsp.util.Utilities;
import com.jidesoft.utils.SwingWorker;
import javax.swing.table.DefaultTableModel;
import jpcsp.WindowPropSaver;
/**
*
* @author George
*/
public class InstructionCounter extends javax.swing.JFrame implements PropertyChangeListener {
private static final long serialVersionUID = 1L;
private Task task;
private SceModule module;
/**
* Creates new form InstructionCounter
*/
public InstructionCounter() {
initComponents();
WindowPropSaver.loadWindowProperties(this);
}
public void setModule(SceModule module) {
this.module = module;
RefreshWindow();
}
public void RefreshWindow() {
if (module == null) {
return;
}
resetCounting();
areastatus.setText("");
if (module.text_addr == 0) {
textcheck.setEnabled(false);
textcheck.setSelected(false);
} else {
textcheck.setEnabled(true);
textcheck.setSelected(true);
areastatus.append("Found .text section at " + Integer.toHexString(module.text_addr) + " size " + module.text_size + "\n");
}
if (module.initsection[0] == 0) {
initcheck.setEnabled(false);
initcheck.setSelected(false);
} else {
initcheck.setEnabled(true);
initcheck.setSelected(true);
areastatus.append("Found .init section at " + Integer.toHexString(module.initsection[0]) + " size " + module.initsection[1] + "\n");
}
if (module.finisection[0] == 0) {
finicheck.setEnabled(false);
finicheck.setSelected(false);
} else {
finicheck.setEnabled(true);
finicheck.setSelected(true);
areastatus.append("Found .fini section at " + Integer.toHexString(module.finisection[0]) + " size " + module.finisection[1] + "\n");
}
if (module.stubtextsection[0] == 0) {
stubtextcheck.setEnabled(false);
stubtextcheck.setSelected(false);
} else {
stubtextcheck.setEnabled(true);
stubtextcheck.setSelected(true);
areastatus.append("Found .sceStub.text at " + Integer.toHexString(module.stubtextsection[0]) + " size " + module.stubtextsection[1]);
}
pack();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
textcheck = new javax.swing.JCheckBox();
initcheck = new javax.swing.JCheckBox();
finicheck = new javax.swing.JCheckBox();
lblCountWhat = new javax.swing.JLabel();
progressBar = new javax.swing.JProgressBar();
btnStart = new javax.swing.JButton();
jScrollPane1 = new javax.swing.JScrollPane();
areastatus = new javax.swing.JTextArea();
jScrollPane2 = new javax.swing.JScrollPane();
OpcodeTable = new javax.swing.JTable();
stubtextcheck = new javax.swing.JCheckBox();
btnSave = new javax.swing.JButton();
java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("jpcsp/languages/jpcsp"); // NOI18N
setTitle(bundle.getString("InstructionCounter.title")); // NOI18N
setResizable(false);
textcheck.setText(".text"); // NOI18N
initcheck.setText(".init"); // NOI18N
finicheck.setText(".fini"); // NOI18N
lblCountWhat.setText(bundle.getString("InstructionCounter.lblCountWhat.text")); // NOI18N
btnStart.setText(bundle.getString("InstructionCounter.btnStart.text")); // NOI18N
btnStart.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnStartActionPerformed(evt);
}
});
areastatus.setColumns(20);
areastatus.setFont(new java.awt.Font("Courier New", 0, 12)); // NOI18N
areastatus.setRows(4);
jScrollPane1.setViewportView(areastatus);
OpcodeTable.setAutoCreateRowSorter(true);
OpcodeTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"Opcode", "Category", "Count"
}
) {
Class[] types = new Class [] {
java.lang.String.class, java.lang.String.class, java.lang.Integer.class
};
boolean[] canEdit = new boolean [] {
false, false, false
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
OpcodeTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
jScrollPane2.setViewportView(OpcodeTable);
stubtextcheck.setText(".sceStub.text"); // NOI18N
btnSave.setText(bundle.getString("InstructionCounter.btnSave.text")); // NOI18N
btnSave.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnSaveActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(btnStart)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addComponent(jScrollPane1)
.addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(btnSave))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(lblCountWhat, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGroup(layout.createSequentialGroup()
.addComponent(textcheck)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(initcheck)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(finicheck))
.addComponent(stubtextcheck, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(finicheck)
.addComponent(initcheck)
.addComponent(textcheck)
.addComponent(lblCountWhat))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(stubtextcheck)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(progressBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnStart, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 59, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 402, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnSave)
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void btnStartActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnStartActionPerformed
btnStart.setEnabled(false);
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
//Instances of javax.swing.SwingWorker are not reusuable, so
//we create new instances as needed.
progressBar.setIndeterminate(true);
task = new Task();
task.addPropertyChangeListener(this);
task.execute();
}//GEN-LAST:event_btnStartActionPerformed
private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed
File file;
final JFileChooser fc = new JFileChooser();
fc.setDialogTitle(java.util.ResourceBundle.getBundle("jpcsp/languages/jpcsp").getString("InstructionCounter.strSaveInstructionDialog.text"));
fc.setCurrentDirectory(new java.io.File("."));
fc.setSelectedFile(new File("instructionoutput.txt"));
int returnvalue = fc.showSaveDialog(this);
if (returnvalue == JFileChooser.APPROVE_OPTION) {
file = fc.getSelectedFile();
} else {
return;
}
BufferedWriter bufferedWriter = null;
try {
// construct the BufferedWriter object
bufferedWriter = new BufferedWriter(new FileWriter(file));
// start writing to the output stream
for (int i = 0; i < OpcodeTable.getRowCount(); i++) {
bufferedWriter.write(OpcodeTable.getValueAt(i, 0) + "\t" + OpcodeTable.getValueAt(i, 1) + "\t" + OpcodeTable.getValueAt(i, 2));
bufferedWriter.newLine();
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
Utilities.close(bufferedWriter);
}
}//GEN-LAST:event_btnSaveActionPerformed
/**
* Invoked when task's progress property changes.
*/
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("progress")) {
int progress = (Integer) evt.getNewValue();
progressBar.setValue(progress);
}
}
public void findinitsections() {
for (int i = 0; i < module.initsection[1]; i += 4) {
int memread32 = Memory.getInstance().read32(module.initsection[0] + i);
jpcsp.Allegrex.Decoder.instruction(memread32).increaseCount();
}
}
public void findfinisections() {
for (int i = 0; i < module.finisection[1]; i += 4) {
int memread32 = Memory.getInstance().read32(module.finisection[0] + i);
jpcsp.Allegrex.Decoder.instruction(memread32).increaseCount();
}
}
public void findtextsections() {
for (int i = 0; i < module.text_size; i += 4) {
int memread32 = Memory.getInstance().read32(module.text_addr + i);
jpcsp.Allegrex.Decoder.instruction(memread32).increaseCount();
}
}
public void findstubtextsections() {
for (int i = 0; i < module.stubtextsection[1]; i += 4) {
int memread32 = Memory.getInstance().read32(module.stubtextsection[0] + i);
jpcsp.Allegrex.Decoder.instruction(memread32).increaseCount();
}
}
class Task extends SwingWorker<Void, Void> {
/*
* Main task. Executed in background thread.
*/
@Override
public Void doInBackground() {
setProgress(0);
resetCounting();
setProgress(20);
if (initcheck.isSelected()) {
findinitsections();
}
setProgress(40);
if (textcheck.isSelected()) {
findtextsections();
}
setProgress(60);
if (finicheck.isSelected()) {
findfinisections();
}
setProgress(80);
if (stubtextcheck.isSelected()) {
findstubtextsections();
}
setProgress(100);
return null;
}
/*
* Executed in event dispatching thread
*/
@Override
public void done() {
refreshCounter();
Toolkit.getDefaultToolkit().beep();
btnStart.setEnabled(true);
setCursor(null); // turn off the wait cursor
progressBar.setIndeterminate(false);
}
}
// Let's instanciate this private member so the two following methods
// can retrieve the right opcodes.
public static jpcsp.Allegrex.Instructions INSTRUCTIONS = new jpcsp.Allegrex.Instructions();
public void refreshCounter() {
java.util.TreeMap< String, Instruction> instructions = new java.util.TreeMap< String, Instruction>();
for (Instruction insn : jpcsp.Allegrex.Common.instructions()) {
if (insn != null) {
instructions.put(insn.name(), insn);
}
}
for (Instruction insn : instructions.values()) {
if (insn != null && insn.getCount() > 0) {
((DefaultTableModel) OpcodeTable.getModel()).addRow(new Object[]{
insn.name(),
insn.category(),
new Integer(insn.getCount())
});
}
}
}
public void resetCounting() {
for (Instruction insn : jpcsp.Allegrex.Common.instructions()) {
if (insn != null) {
insn.resetCount();
}
}
((DefaultTableModel) OpcodeTable.getModel()).setRowCount(0);
}
@Override
public void dispose() {
Emulator.getMainGUI().endWindowDialog();
super.dispose();
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JTable OpcodeTable;
private javax.swing.JTextArea areastatus;
private javax.swing.JButton btnSave;
private javax.swing.JButton btnStart;
private javax.swing.JCheckBox finicheck;
private javax.swing.JCheckBox initcheck;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JLabel lblCountWhat;
private javax.swing.JProgressBar progressBar;
private javax.swing.JCheckBox stubtextcheck;
private javax.swing.JCheckBox textcheck;
// End of variables declaration//GEN-END:variables
}