sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/UndecidedPool.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.instr/src/com/nokia/carbide/cpp/pi/instr/UndecidedPool.java Thu Feb 11 15:32:31 2010 +0200
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description:
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.instr;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.nokia.carbide.cpp.internal.pi.model.Binary;
+
+
+public class UndecidedPool
+{
+ private Hashtable undecidedLocations;
+ private Vector unprocessed;
+ private AdvancedMemoryMap amm;
+ private Vector unDecided;
+
+ public UndecidedPool(AdvancedMemoryMap amm)
+ {
+ this.amm = amm;
+ // keys will be the binary names, and values wile be
+ // their corresponding UndecidedLocation objects
+ this.undecidedLocations = new Hashtable();
+
+ this.unprocessed = new Vector();
+ this.unDecided = new Vector();
+ }
+
+ public Vector getUnprocessed()
+ {
+ return this.unprocessed;
+ }
+
+ public void clearUnprocessed()
+ {
+ this.unprocessed = new Vector();
+ }
+
+ public Vector getUndecided()
+ {
+ return this.unDecided;
+ }
+
+ public void insertSample(IttSample sample,int decisionBoundary)
+ {
+ if (!this.unDecided.contains(sample))
+ this.unDecided.add(sample);
+
+ BinaryReaderResult brr = this.amm.getBinaryReader().findSequence(sample);
+ for (int i=0;i<brr.possibleBinaries.length;i++)
+ {
+ Binary possibleBinary = brr.possibleBinaries[i];
+ UndecidedLocation ul =
+ (UndecidedLocation)undecidedLocations.get(possibleBinary.binaryName);
+
+ if (ul != null)
+ {
+ ul.addSample(sample,possibleBinary.startAddress);
+ }
+ else
+ {
+ ul = new UndecidedLocation(possibleBinary);
+ ul.addSample(sample,possibleBinary.startAddress);
+ this.undecidedLocations.put(possibleBinary.binaryName,ul);
+ }
+
+ // the value of decisionBoundary has to be reduced in the future
+ // when no binaries can be resolved with the current value
+ if (ul.getDecidedAddress(decisionBoundary) != -1)
+ {
+ // location of the binary has been resolved
+
+ // refresh the samples that belong to the decision
+ ul.refreshDecidedAndUndecidedSamples();
+
+ // add all the samples that didn't fit to this binary, to
+ // the pool of unprocessed samples
+ Vector undecided = ul.getUndecidedSamples();
+ // add only those samples that are not present in the undecided
+ // vector already
+ Enumeration unEnum = undecided.elements();
+ while(unEnum.hasMoreElements())
+ {
+ IttSample us = (IttSample)unEnum.nextElement();
+ if (!this.unprocessed.contains(us)) this.unprocessed.add(us);
+ }
+
+ // then, pass the decision to the decidedPool
+ Vector decided = ul.getDecidedSamples();
+ this.amm.getDecidedPool().insertDecidedBinary(possibleBinary,decided);
+
+ // then, remove the decided samples from all other possible binaries
+ Enumeration renum = decided.elements();
+ while(renum.hasMoreElements())
+ {
+ IttSample sampleToRemove = (IttSample)renum.nextElement();
+ this.removeSampleFromAllPossibleLocations(sampleToRemove);
+ }
+ }
+ }
+ }
+
+ private void removeSampleFromAllPossibleLocations(IttSample sample)
+ {
+ Enumeration renum = this.undecidedLocations.keys();
+ Vector removeList = new Vector();
+
+ this.unDecided.remove(sample);
+
+ while(renum.hasMoreElements())
+ {
+ String name = (String)renum.nextElement();
+
+ UndecidedLocation ul = (UndecidedLocation)this.undecidedLocations.get(name);
+ ul.removeSample(sample);
+
+ if (ul.samplesForLocations.size() == 0) removeList.add(name);
+ }
+
+ if (removeList.size() > 0)
+ {
+ Enumeration enumer = removeList.elements();
+ while(enumer.hasMoreElements())
+ {
+ this.undecidedLocations.remove(enumer.nextElement());
+ }
+ }
+
+ if (this.unprocessed.contains(sample))
+ {
+ this.unprocessed.remove(sample);
+ }
+ }
+
+ private static class UndecidedLocation
+ {
+ private Hashtable samplesForLocations;
+
+ private Binary binary;
+
+ private int processedMostHits = 0;
+ private Long addressWithMostHits = null;
+ private Vector samplesWithMostHits = null;
+
+ private boolean processedUndecided = false;
+ private Vector undecidedSamples = null;
+ private Vector decidedSamples = null;
+
+ public UndecidedLocation(Binary binary)
+ {
+ // key will be the address, and the value will be a
+ // vector with all samples that support that location
+ this.samplesForLocations = new Hashtable();
+ this.binary = binary;
+ }
+
+ public Binary getBinary()
+ {
+ return this.binary;
+ }
+
+ public void addSample(IttSample sample,long startAddress)
+ {
+ // clear the flags so that the values will be recalculated if needed
+ this.processedMostHits = 0;
+ this.processedUndecided = false;
+
+ Object o = this.samplesForLocations.get(new Long(startAddress));
+
+ if (o != null)
+ {
+ // this location has already a vector associated with it
+ Vector sampleVec = (Vector)o;
+
+ Enumeration sampleEnum = sampleVec.elements();
+ boolean isAlready = false;
+
+ while(sampleEnum.hasMoreElements())
+ {
+ IttSample testSample = (IttSample)sampleEnum.nextElement();
+ if (testSample.programCounter == sample.programCounter &&
+ testSample.checksum == sample.checksum)
+ {
+ isAlready = true;
+ break;
+ }
+ }
+ // add the sample only if it is
+ // different from the other samples
+ if (isAlready == false)
+ {
+ //System.out.println("Added unique sample "+sample.programCounter+" to "+this.binary.binaryName);
+ sampleVec.add(sample);
+ }
+ else
+ {
+ //System.out.println("Discarded "+sample.programCounter+" to "+this.binary.binaryName);
+ }
+
+ }
+ else
+ {
+ //System.out.println("Added unique sample "+sample.programCounter+" to "+this.binary.binaryName);
+ Vector sampleVec = new Vector();
+ sampleVec.add(sample);
+ samplesForLocations.put(new Long(startAddress),sampleVec);
+ }
+ }
+
+ public void removeSample(IttSample sample)
+ {
+ // clear the flags so that the values will be recalculated if needed
+ this.processedMostHits = 0;
+ this.processedUndecided = false;
+
+ // remove this sample from all vectors, remove the vectors if they
+ // become empty
+ Enumeration enumer = this.samplesForLocations.keys();
+ Vector removeList = new Vector();
+
+ while(enumer.hasMoreElements())
+ {
+ Long address = (Long)enumer.nextElement();
+ Vector v = (Vector)this.samplesForLocations.get(address);
+
+ if (v.contains(sample))
+ {
+ v.remove(sample);
+ // do not remove the vector yet because
+ // it would mess the hashtable iteration
+ if (v.size() == 0) removeList.add(address);
+ }
+ }
+
+ // finally, remove the vectors that
+ // were emptied after removing the last sample
+ if (removeList.size() > 0)
+ {
+ Enumeration renum = removeList.elements();
+ while(renum.hasMoreElements())
+ {
+ this.samplesForLocations.remove(renum.nextElement());
+ }
+ }
+
+ }
+
+ public long getDecidedAddress(int minSampleAmount)
+ {
+ if (minSampleAmount <= 0) return -1;
+
+ if (this.processedMostHits == minSampleAmount)
+ {
+ // the function has been run with this value
+ return this.addressWithMostHits.longValue();
+ }
+
+ Enumeration addresses = samplesForLocations.keys();
+
+ int amountOfMaxValues = 0;
+
+ while(addresses.hasMoreElements())
+ {
+ Long address = (Long)addresses.nextElement();
+ Vector samples = (Vector)samplesForLocations.get(address);
+ if (samples.size() >= minSampleAmount)
+ {
+ // there are at least minSampleAmount different samples
+ // that support this binary being in this place
+ if (samplesWithMostHits != null)
+ {
+ // there is already a value, check do we exceed it
+ if (samples.size() > samplesWithMostHits.size())
+ {
+ samplesWithMostHits = samples;
+ addressWithMostHits = address;
+ amountOfMaxValues = 1;
+ }
+ else if (samples.size() == samplesWithMostHits.size())
+ {
+ amountOfMaxValues++;
+ }
+ }
+ else
+ {
+ // there is no max value yet
+ samplesWithMostHits = samples;
+ addressWithMostHits = address;
+ amountOfMaxValues = 1;
+ }
+ }
+ }
+
+ // this function does not need to be run again
+ // if the values do not change
+ this.processedMostHits = minSampleAmount;
+
+ // there are two or more max values
+ // or no max values at all
+ if (amountOfMaxValues != 1) return -1;
+ else return addressWithMostHits.longValue();
+ }
+
+ public void refreshDecidedAndUndecidedSamples()
+ {
+ if (this.processedUndecided == true) return;
+
+ this.undecidedSamples = new Vector();
+ this.decidedSamples = new Vector();
+
+ Enumeration enumer = this.samplesForLocations.elements();
+ while(enumer.hasMoreElements())
+ {
+ Vector v = (Vector)enumer.nextElement();
+
+ if (!v.equals(this.samplesWithMostHits))
+ {
+ // count all samples but the one with
+ undecidedSamples.addAll(v);
+ }
+ else
+ {
+ // add the decided samples
+ this.decidedSamples.addAll(v);
+ }
+ }
+
+ this.processedUndecided = true;
+ }
+
+ public Vector getDecidedSamples()
+ {
+ // there is no value according to which the decision
+ // could base on
+ if (this.processedMostHits == 0) return new Vector();
+
+ this.refreshDecidedAndUndecidedSamples();
+
+ return this.decidedSamples;
+ }
+
+ public Vector getUndecidedSamples()
+ {
+ // there is no value according to which the decision
+ // could base on
+ if (this.processedMostHits == 0) return new Vector();
+
+ this.refreshDecidedAndUndecidedSamples();
+
+ return this.undecidedSamples;
+ }
+ }
+
+}