BaseExperimentBuilder.java

Go to the documentation of this file.
00001 package edu.rice.cs.hpc.data.experiment.xml;
00002 
00003 
00004 import java.io.File;
00005 import java.util.ArrayList;
00006 import java.util.EmptyStackException;
00007 import java.util.HashMap;
00008 import java.util.List;
00009 import java.util.Stack;
00010 
00011 import edu.rice.cs.hpc.data.experiment.BaseExperiment;
00012 import edu.rice.cs.hpc.data.experiment.ExperimentConfiguration;
00013 import edu.rice.cs.hpc.data.experiment.extdata.TraceAttribute;
00014 import edu.rice.cs.hpc.data.experiment.scope.AlienScope;
00015 import edu.rice.cs.hpc.data.experiment.scope.CallSiteScope;
00016 import edu.rice.cs.hpc.data.experiment.scope.CallSiteScopeType;
00017 import edu.rice.cs.hpc.data.experiment.scope.FileScope;
00018 import edu.rice.cs.hpc.data.experiment.scope.LineScope;
00019 import edu.rice.cs.hpc.data.experiment.scope.LoadModuleScope;
00020 import edu.rice.cs.hpc.data.experiment.scope.LoopScope;
00021 import edu.rice.cs.hpc.data.experiment.scope.ProcedureScope;
00022 import edu.rice.cs.hpc.data.experiment.scope.RootScope;
00023 import edu.rice.cs.hpc.data.experiment.scope.RootScopeType;
00024 import edu.rice.cs.hpc.data.experiment.scope.Scope;
00025 import edu.rice.cs.hpc.data.experiment.scope.StatementRangeScope;
00026 import edu.rice.cs.hpc.data.experiment.source.FileSystemSourceFile;
00027 import edu.rice.cs.hpc.data.experiment.source.SourceFile;
00028 import edu.rice.cs.hpc.data.experiment.xml.Token2.TokenXML;
00029 import edu.rice.cs.hpc.data.util.Dialogs;
00030 import edu.rice.cs.hpc.data.util.IUserData;
00031 
00032 
00033 /****
00034  * 
00035  * Base class to build experiment class without metrics associated
00036  * The base class is ideal for using CCT only like hpctraceviewer
00037  * 
00038  * @see ExperimentBuilder2 for building experiment with metrics
00039  */
00040 public class BaseExperimentBuilder extends Builder {
00041 
00042     
00043     protected final static String LINE_ATTRIBUTE        = "l";
00044     protected final static String NAME_ATTRIBUTE        = "n";
00045     protected final static String FILENAME_ATTRIBUTE    = "f";
00046     protected final static String VALUE_ATTRIBUTE       = "v";
00047     protected final static String ID_ATTRIBUTE          = "i";
00048     
00049     private final static String PROCEDURE_UNKNOWN = "unknown procedure";
00050 
00052     protected String defaultName;
00053 
00055     protected ExperimentConfiguration configuration;
00056 
00057     protected Scope rootScope;
00058     protected Scope viewRootScope[];
00059 
00061     protected BaseExperiment experiment;
00062 
00064     protected Stack<Scope> scopeStack;
00065 
00067     protected Stack<SourceFile> srcFileStack;
00068 
00069     private boolean csviewer;
00070     
00071     final private IUserData<String, String> userData;
00072 
00073     protected Token2.TokenXML previousToken = TokenXML.T_INVALID_ELEMENT_NAME;
00074     protected Token2.TokenXML elemInfoState = TokenXML.T_INVALID_ELEMENT_NAME;
00075 
00076     //--------------------------------------------------------------------------------------
00077     private HashMap<Integer, String> hashProcedureTable;
00078     private HashMap<Integer, LoadModuleScope> hashLoadModuleTable;
00079     private HashMap <Integer, SourceFile> hashSourceFileTable;
00080     private HashMap<Integer, Scope> hashCallSiteTable;
00081 
00082 
00083     private int current_cs_id = Integer.MAX_VALUE - 1;
00084 
00085     //=============================================================
00086     
00087     /*************************************************************************
00088      *  Creates a ExperimentBuilder.
00089      *
00090      *  Parsed objects are added to the experiment as soon as possible, but
00091      *  all the parsed objects of a given kind must be added at once. The
00092      *  builder keeps parsed objects on lists until a whole set can be added
00093      *  to the experiment.
00094      *  <p>
00095      *  Because of the way <code>Metric</code>s are implemented, the metric
00096      *  objects must be added to the experiment before any scope objects are
00097      *  constructed. Scopes need to know how many metrics the experiment has,
00098      *  and find out by asking the experiment.
00099      *
00100      *  @param experiment: experiment class
00101      *  @param defaultName: the default name of the experiment
00102      *
00103      ************************************************************************/
00104     public BaseExperimentBuilder(BaseExperiment experiment, String defaultName, IUserData<String, String> userData) {
00105         super();
00106         this.csviewer = false;
00107         viewRootScope = new RootScope[3];
00108         
00109         hashProcedureTable = new HashMap<Integer, String>();
00110         hashLoadModuleTable = new HashMap<Integer, LoadModuleScope>();
00111         new HashMap<Integer, Scope>();
00112         hashSourceFileTable = new HashMap<Integer, SourceFile>();
00113         hashCallSiteTable = new HashMap<Integer, Scope>();
00114 
00115         // parse action data structures
00116         this.scopeStack = new Stack<Scope>();
00117         this.srcFileStack = new Stack<SourceFile>();
00118         this.srcFileStack.push(null); // mimic old behavior
00119 
00120         // creation arguments
00121         this.experiment = experiment;
00122         this.defaultName = defaultName;
00123         
00124         this.userData = userData;
00125     }
00126     
00127     
00128     protected boolean isCallingContextTree() {
00129         return this.csviewer;
00130     }
00131     
00132     private SourceFile getSourceFile(String fileIdString)
00133     {
00134         SourceFile sourceFile = null;
00135         try {
00136             Integer objFileKey = Integer.parseInt(fileIdString);
00137              sourceFile=hashSourceFileTable.get(objFileKey.intValue());
00138         } catch (NumberFormatException e) {
00139             e.printStackTrace();
00140         }
00141         return sourceFile;
00142     }   
00143 
00144 
00145     /*************************************************************************
00146      *  Takes notice of the beginning of an element.
00147      * @throws OldXMLFormatException 
00148      ************************************************************************/
00149 
00150     public void beginElement(String element, String[] attributes, String[] values) 
00151     {
00152         TokenXML current = Token2.map(element);
00153 
00154         switch(current)
00155         {
00156         case T_HPCTOOLKIT_EXPERIMENT:
00157             this.do_HPCTOOLKIT(attributes, values);
00158             break;
00159         case T_HEADER:
00160             this.do_Header(attributes,values);  
00161             break;
00162         case T_INFO:
00163             this.do_Info();
00164             break;
00165 
00166         case T_SEC_CALLPATH_PROFILE:
00167             // we need to retrieve the profile name and the ID
00168             this.csviewer = true;
00169             this.do_TITLE(attributes, values);
00170             break;
00171 
00172         case T_SEC_FLAT_PROFILE:
00173             this.csviewer = false;
00174             this.do_TITLE(attributes, values);
00175             break;
00176 
00177             // PGM elements
00178         case T_SEC_FLAT_PROFILE_DATA:
00179         case T_CALLPATH_PROFILE_DATA:   // semi old format. some data has this kind of tag
00180         case T_SEC_CALLPATH_PROFILE_DATA:
00181             this.begin_SecData(attributes, values); break;
00182 
00183             // load module dictionary
00184         case T_LOAD_MODULE:
00185             this.do_LoadModule(attributes, values);
00186             break;
00187             // file dictionary
00188         case T_FILE:
00189             this.do_File(attributes, values); break;
00190             
00191             // flat profiles
00192         case T_LM:
00193             this.begin_LM (attributes, values); break;
00194         case T_F:
00195             this.begin_F  (attributes, values); break;
00196         case T_P:
00197             
00198         case T_PR:
00199         case T_PF:
00200             this.begin_PF  (attributes, values);    break;
00201         case T_A:
00202             this.begin_A  (attributes, values); break;
00203         case T_L:
00204             this.begin_L  (attributes, values); break;
00205         case T_S:
00206             this.begin_S  (attributes, values); break;
00207 
00208             // callstack elements
00209         case T_C:
00210             this.begin_CALLSITE(attributes,values); 
00211             break;
00212             
00213         case T_PROCEDURE:
00214             this.do_Procedure(attributes, values); break;
00215 
00216 
00217             // trace database
00218         case T_TRACE_DB_TABLE:
00219             this.begin_TraceDBTable(attributes, values);
00220             break;
00221             
00222         case T_TRACE_DB:
00223             this.do_TraceDB(attributes, values); break;
00224 
00225         // ---------------------
00226         // XML v. 3.0
00227         // ---------------------
00228         case T_SUMMARY_DB_FILE:
00229             
00230             
00231         case T_TRACE_DB_FILE:
00232         case T_PLOT_DB_FILE:
00233             break;
00234             // ---------------------
00235             // old token from old XML
00236             // ---------------------
00237         case T_CSPROFILE:
00238         case T_HPCVIEWER:
00239             throw new java.lang.RuntimeException(new OldXMLFormatException());
00240             // unknown elements
00241             
00242         // ---------------------
00243         // Tokens to be ignored 
00244         // ---------------------
00245             
00246         case T_PROCEDURE_TABLE:
00247         case T_FILE_TABLE:
00248         case T_LOAD_MODULE_TABLE:
00249         case T_SEC_HEADER:
00250             break;
00251         
00252         default:
00253             break;
00254         } 
00255         saveTokenContext(current);
00256     }
00257 
00258 
00259     /****
00260      * all children requires to register the current context
00261      * 
00262      * @param current
00263      */
00264     protected void saveTokenContext(TokenXML current) 
00265     {
00266         // laks: preserve the state of the current token for the next parsing state
00267         this.previousToken = current;
00268     }
00269     
00270     /*************************************************************************
00271      *  Takes notice of the ending of an element.
00272      ************************************************************************/
00273     public void endElement(String element)
00274     {
00275         TokenXML current = Token2.map(element);
00276         switch(current)
00277         {
00278         case T_SEC_FLAT_PROFILE:
00279         case T_SEC_CALLPATH_PROFILE:
00280             break;
00281 
00282         // Data elements
00283         case T_CALLPATH_PROFILE_DATA:   // @deprecated: semi old format. some data has this kind of tag
00284         case T_SEC_FLAT_PROFILE_DATA:
00285         case T_SEC_CALLPATH_PROFILE_DATA:
00286             this.end_PGM();
00287             break;
00288         case T_LM:
00289             this.end_LM();
00290             break;
00291             
00292         case T_P:
00293         case T_PR:
00294         case T_PF:
00295             this.end_PF();
00296             break;
00297         case T_A:
00298             this.end_A();
00299             break;
00300         case T_L:
00301             this.end_L();
00302             break;
00303         case T_S:
00304             this.end_S();
00305             break;
00306         case T_C:       
00307             this.end_CALLSITE();
00308             break;
00309         case T_F:
00310             this.end_F();
00311             break;
00312             
00313         case T_TRACE_DB_TABLE:
00314             this.end_TraceDBTable();
00315             break;
00316             
00317 
00318             // ignored elements
00319             // trace database
00320         case T_TRACE_DB:
00321         case T_METRIC_RAW:
00322         case T_M:
00323         case T_HPCTOOLKIT_EXPERIMENT:
00324         case T_NAME_VALUE:
00325         case T_HEADER:
00326         case T_INFO:
00327         case T_METRIC_FORMULA:
00328         case T_SEC_HEADER:
00329         case T_METRIC:
00330         case T_PROCEDURE_TABLE:
00331         case T_PROCEDURE:
00332         case T_FILE_TABLE:
00333         case T_FILE:
00334         case T_LOAD_MODULE_TABLE:
00335         case T_LOAD_MODULE:
00336             break;
00337         } 
00338     }
00339 
00340 
00341 //  ------------------------------- BUILDING        ---------------------------//
00342 
00343     /*************************************************************************
00344      * Process a HPCToolkitExperiment
00345      *************************************************************************/
00346     private void do_HPCTOOLKIT(String[] attributes, String[] values) {
00347         String version = null;
00348         for (int i=0; i<attributes.length; i++) {
00349             if (attributes[i].charAt(0) == 'v') {
00350                 //version of the database
00351                 version = values[i];
00352             }
00353         }
00354         this.experiment.setVersion(version);
00355     }
00356 
00357 
00358     /*************************************************************************
00359      *      Processes a TARGET element as TITLE.
00360      ************************************************************************/
00361 
00362     private void do_Header(String[] attributes, String[] values)
00363     {
00364         this.configuration.setName(ExperimentConfiguration.NAME_EXPERIMENT, values[0]);
00365     }
00366 
00367     private void do_Info() {
00368         this.elemInfoState = this.previousToken;
00369     }
00370 
00371     /*************************************************************************
00372      *  Processes a TITLE element.
00373      ************************************************************************/
00374 
00375     private void do_TITLE(String[] attributes, String[] values)
00376     {
00377         // <!ATTLIST SecCallPathProfile
00378         //        i CDATA #REQUIRED
00379         //        n CDATA #REQUIRED>
00380         this.Assert(attributes.length == 2);
00381         String sTitle = "";
00382         if(values.length == 2) {
00383             sTitle = values[1];
00384         }
00385         this.configuration.setName(ExperimentConfiguration.NAME_EXPERIMENT, sTitle);
00386     }
00387 
00388     /************************************************************************
00389      * <!ELEMENT LoadModule (Info?)>
00390     <!ATTLIST LoadModule
00391               i CDATA #REQUIRED
00392               n CDATA #REQUIRED>
00393      * Example:
00394      *   <LoadModule i="43497" n="/lib64/libc-2.7.so"/>
00395      * @param attributes
00396      * @param values
00397      ************************************************************************/
00398     private void do_LoadModule(String[] attributes, String[] values) {
00399         if(values.length < 2)
00400             return;
00401         
00402         // We assume that the 1st attribute is always the ID and the 2nd attribute is the value
00403         String sValue = values[1];
00404         String sID = values[0];
00405         try {
00406             Integer objID = new Integer(sID);
00407             LoadModuleScope lmScope = new LoadModuleScope(this.experiment, sValue, null, objID.intValue());
00408             this.hashLoadModuleTable.put(objID, lmScope);
00409         } catch (java.lang.NumberFormatException e) {
00410             System.err.println("Incorrect load module ID: "+sID);
00411         } catch (java.lang.NullPointerException e) {
00412             System.err.println("load module table is empty. Key: "+sID+" value: "+sValue);
00413         }
00414     }
00415 
00416 
00417 
00418     /*************************************************************************
00419      *      Processes a FILE.
00420      *          <!ELEMENT File (Info?)>
00421     <!ATTLIST File
00422               i CDATA #REQUIRED
00423               n CDATA #REQUIRED>
00424      ************************************************************************/
00425     private void do_File(String[] attributes, String[] values) {
00426         if(values.length < 2)
00427             return;
00428         String sID = values[0];     
00429         try {
00430             final Integer objFileID = Integer.parseInt(sID);
00431             // just in case if there is a duplicate key in the dictionary, we need to make a test
00432             final SourceFile sourceFile = this.getOrCreateSourceFile(values[1], objFileID.intValue());
00433             
00434             this.hashSourceFileTable.put(objFileID, sourceFile);
00435             
00436         } catch (Exception e) {
00437             
00438         }
00439     }
00440 
00441     
00442     /*************************************************************************
00443      *  Begins processing an LM (load module) element.
00444      *  <!ATTLIST LM
00445                 i CDATA #IMPLIED
00446                 n CDATA #REQUIRED
00447                 v CDATA #IMPLIED>
00448      ************************************************************************/
00449     private void begin_LM(String[] attributes, String[] values)
00450     {
00451         // LM n="load module name"
00452         String name = getAttributeByName(NAME_ATTRIBUTE, attributes, values);
00453         String sIndex = getAttributeByName(ID_ATTRIBUTE, attributes, values);
00454         
00455         try {
00456             Integer objIndex = Integer.parseInt(sIndex);
00457             SourceFile sourceFile = this.getOrCreateSourceFile(name, objIndex.intValue());
00458             Scope lmScope = new LoadModuleScope(this.experiment, name, sourceFile, objIndex.intValue());
00459             // make a new load module scope object
00460             this.beginScope(lmScope);
00461         } catch (Exception e) {
00462             e.printStackTrace();
00463         }
00464     }
00465     
00466     /*************************************************************************
00467      *  Begins processing an F (file) element.
00468      *      <!ATTLIST F
00469                 i CDATA #IMPLIED
00470                 n CDATA #REQUIRED>
00471      ************************************************************************/
00472     private void begin_F(String[] attributes, String[] values)
00473 
00474     {
00475         // F n="filename"
00476         String inode = getAttributeByName(ID_ATTRIBUTE, attributes, values);
00477         try {
00478             Integer objFileKey = Integer.parseInt(inode);
00479             // make a new file scope object
00480             SourceFile sourceFile  = this.getOrCreateSourceFile(getAttributeByName(NAME_ATTRIBUTE, attributes, values), 
00481                     objFileKey.intValue());
00482 
00483             this.srcFileStack.push(sourceFile);
00484             Scope fileScope = new FileScope(this.experiment, sourceFile, objFileKey.intValue());
00485 
00486             this.beginScope(fileScope);
00487 
00488         } catch (NumberFormatException e) {
00489             e.printStackTrace();
00490         }
00491 
00492     }
00493 
00494 
00495     /*************************************************************************
00496      *  Begins processing a PF (procedure frame) element.
00497      *       <!ATTLIST Pr
00498                 i  CDATA #IMPLIED
00499                 s  CDATA #IMPLIED
00500                 n  CDATA #REQUIRED
00501                 lm CDATA #IMPLIED
00502                 f  CDATA #IMPLIED
00503                 l  CDATA #IMPLIED
00504                 a  (1|0) "0"
00505                 v  CDATA #IMPLIED>
00506      ************************************************************************/
00507     private void begin_PF(String[] attributes, String[] values)
00508     {
00509             boolean istext = true; 
00510             boolean isalien = false; 
00511             boolean new_cct_format = false;
00512             int cct_id = 0, flat_id = 0;
00513             int firstLn = 0, lastLn = 0;
00514             SourceFile srcFile = null; // file location of this procedure
00515             
00516             LoadModuleScope objLoadModule = null;
00517             String sProcName = PROCEDURE_UNKNOWN;
00518 
00519             for(int i=0; i<attributes.length; i++) {
00520                 if (attributes[i].equals("s")) { 
00521                     // new database format: s is the flat ID of the procedure
00522                     sProcName = this.getProcedureName(values[i]);
00523                     flat_id = Integer.parseInt(values[i]);
00524                     if (!new_cct_format)
00525                         // old format: cct ID = flat ID
00526                         cct_id = flat_id;
00527                     
00528                 } else if (attributes[i].equals(ID_ATTRIBUTE)) {
00529                     // id of the proc frame. needs to cross ref
00530                     cct_id = Integer.parseInt(values[i]); 
00531                     new_cct_format = true;
00532                     
00533                 } else if(attributes[i].equals(FILENAME_ATTRIBUTE)) {
00534                     // file
00535                     istext = true;
00536                     try {
00537                         Integer indexFile = Integer.parseInt(values[i]);
00538                         srcFile = this.hashSourceFileTable.get(indexFile);
00539                     } catch (java.lang.NumberFormatException e) {
00540                         // in this case, either the value of "f" is invalid or it is the name of the file
00541                         // In some old format the attribute f contains the file not in the dictionary. So 
00542                         //  we need to create it from here
00543                         if (this.srcFileStack.size()==1) {
00544                             // the first stack is null, so let start from number 1
00545                             srcFile = this.getOrCreateSourceFile(values[i], this.srcFileStack.size()+1);
00546                         }
00547                     }
00548                     
00549                 } else if(attributes[i].equals("lm")) { 
00550                     // load module
00551                     try {
00552                         // let see if the value of ln is an ID or a simple load module name
00553                         Integer indexFile = Integer.parseInt(values[i]);
00554                         // look at the dictionary for the name of the load module
00555                         objLoadModule = this.hashLoadModuleTable.get(indexFile);
00556                         if (objLoadModule == null) {
00557                             objLoadModule = new LoadModuleScope(this.experiment, values[i], null, indexFile.intValue());
00558                             this.hashLoadModuleTable.put(indexFile, objLoadModule);
00559                         }
00560                     } catch (java.lang.NumberFormatException e) {
00561                         // this error means that the lm is not based on dictionary
00562                         objLoadModule = new LoadModuleScope(this.experiment, values[i], null, values[i].hashCode());
00563                     }
00564                 } else if (attributes[i].equals("p") ) {
00565                     // obsolete format: p is the name of the procedure
00566                     sProcName = values[i];
00567                     
00568                 } else if(attributes[i].equals(NAME_ATTRIBUTE)) {
00569                     // new database format: n is the flat ID of the procedure
00570                     sProcName = this.getProcedureName(values[i]);
00571                     
00572                 } else if(attributes[i].equals(LINE_ATTRIBUTE)) {
00573                     // line number (or range)
00574                     StatementRange objRange = new StatementRange(values[i]);
00575                     firstLn = objRange.getFirstLine();
00576                     lastLn = objRange.getLastLine();
00577                     
00578                 } else if(attributes[i].equals("a")) { 
00579                     // alien
00580                     isalien = values[i].equals("1");
00581                     
00582                 } else if(attributes[i].equals(VALUE_ATTRIBUTE)) {
00583                 }
00584             }
00585             
00586             if (isalien) {
00587                 flat_id = Integer.MAX_VALUE ^ flat_id;
00588 
00589                 if (sProcName.isEmpty()) {
00590                     // this is a line scope
00591                     Scope scope;
00592                     if (firstLn == lastLn)
00593                         scope = new LineScope(this.experiment, srcFile, firstLn-1, cct_id, flat_id);
00594                     else
00595                         scope = new StatementRangeScope(this.experiment, srcFile, 
00596                                 firstLn-1, lastLn-1, cct_id, flat_id);
00597                     scope.setCpid(0);
00598                     scopeStack.push(scope);
00599 
00600                     srcFile.setIsText(istext);
00601                     this.srcFileStack.add(srcFile);
00602                     return;
00603                 } else {
00604                     // this is a procedure scope uses the handling below
00605                 }
00606             }
00607 
00608             // FLAT PROFILE: we retrieve the source file from the previous tag
00609             if(srcFile == null) {
00610                     srcFile = this.srcFileStack.peek();
00611             } 
00612              
00613             srcFile.setIsText(istext);
00614             this.srcFileStack.add(srcFile);
00615 
00616             ProcedureScope procScope  = new ProcedureScope(this.experiment, objLoadModule, srcFile, 
00617                     firstLn-1, lastLn-1, 
00618                     sProcName, isalien, cct_id, flat_id, userData);
00619 
00620             if ( (this.scopeStack.size()>1) && ( this.scopeStack.peek() instanceof LineScope)  ) {
00621 
00622                 LineScope ls = (LineScope)this.scopeStack.pop();
00623                 
00624                 //-----------------------------------------------------------------------------------------
00625                 // In some database (especially the old ones), they have the same ID for different call sites
00626                 // In order to keep compatibility, we need to generate our own ID hoping it doesn't interfere
00627                 // with the ID generated by the new hpcprof :-(
00628                 //-----------------------------------------------------------------------------------------
00629                 int callsiteID = this.getCallSiteID(ls, procScope);  
00630                 CallSiteScope csn = new CallSiteScope(ls, procScope, 
00631                         CallSiteScopeType.CALL_TO_PROCEDURE, cct_id, callsiteID);
00632 
00633                 // beginScope pushes csn onto the node stack and connects it with its parent
00634                 // this is done while the ls is off the stack so the parent of csn is ls's parent. 
00635                 // afterward, we rearrange the top of stack to tuck ls back underneath csn in case it is 
00636                 // needed for a subsequent procedure frame that is a sibling of csn in the tree.
00637                 this.beginScope(csn);
00638                 CallSiteScope csn2 = (CallSiteScope) this.scopeStack.pop();
00639                 this.scopeStack.push(ls);
00640                 this.scopeStack.push(csn2);
00641 
00642             } else {
00643                 this.beginScope(procScope);
00644             }
00645     }
00646 
00647     /*************************************************************************
00648      * Retrieve the ID of a call site.
00649      * Instead of using hpcprof's flat index, we reconstruct our own ID 
00650      *  (not sure if this is hpcprof's bug or not). hpcprof's flat index is not
00651      *  suitable if the same function is from the same file from different load modules
00652      *  In this case, hpcprof's flat index will be the same (which is incorrect) 
00653      *  
00654      * In normal case, the ID is the hashcode of its call site (line scope). 
00655      * But, in case of there are multiple calls in one line statement, we need
00656      * to generate different ID for each call sites.
00657      * 
00658      * @param ls
00659      * @param cs
00660      * @return
00661      *************************************************************************/
00662     private int getCallSiteID ( LineScope ls, ProcedureScope cs ) {
00663         LoadModuleScope module = cs.getLoadModule();
00664         // add flat index if there are two calls in the same line
00665         String sName = ls.getName() + "/" + cs.getName() + "/" + ls.getFlatIndex();
00666         // in case of the same file and the same procedure with different module name
00667         // this should fix where we have ~unknown-file~ and ~unknown-procedure~ in 
00668         // different modules
00669         if (module != null) {
00670             sName = module.getModuleName()+ "/" + sName;
00671         }
00672         
00673         int scope_id = sName.hashCode();
00674         Scope s_old = this.hashCallSiteTable.get( Integer.valueOf(scope_id) );
00675         if (s_old != null) {
00676             if (s_old.getName().equals(cs.getName())) {
00677                 // the same line, the same ID, the same calls
00678             } else {
00679                 // the same line, different calls. We need to create a new ID
00680                 scope_id = this.current_cs_id;
00681                 this.hashCallSiteTable.put(Integer.valueOf(scope_id), cs);
00682                 this.current_cs_id--;
00683             }
00684         } else {
00685             this.hashCallSiteTable.put(Integer.valueOf(scope_id), cs);
00686         }
00687         return scope_id;
00688     }
00689     
00690 
00691     
00692     /*************************************************************************
00693      *  Begins processing a A (alien) element.
00694       <!ELEMENT A (A|L|S|C|M)*>      <!ATTLIST A
00695                 i CDATA #IMPLIED
00696                 f CDATA #IMPLIED
00697                 n CDATA #IMPLIED
00698                 l CDATA #IMPLIED
00699                 v CDATA #IMPLIED>
00700      ************************************************************************/
00701 
00702     private void begin_A(String[] attributes, String[] values)
00703     {
00704         String sIndex = null;
00705         String filenm = null;
00706         String procnm = null;
00707         String sLine = null;
00708         
00709         // make a new alien scope object
00710         for (int i=0; i<attributes.length; i++) {
00711             if (attributes[i].equals(ID_ATTRIBUTE)) {
00712                 sIndex = values[i];
00713             } else if (attributes[i].equals(FILENAME_ATTRIBUTE)) {
00714                 filenm = values[i];
00715             } else if (attributes[i].equals(NAME_ATTRIBUTE)) {
00716                 procnm = values[i];
00717             } else if (attributes[i].equals(LINE_ATTRIBUTE)) {
00718                 sLine = values[i];
00719             }
00720         }
00721         
00722         try {
00723             Integer objIndex = Integer.parseInt(sIndex);
00724 
00725             int firstLn, lastLn;
00726             StatementRange objRange = new StatementRange(sLine);
00727             firstLn = objRange.getFirstLine();
00728             lastLn = objRange.getLastLine();
00729 
00730             SourceFile sourceFile = this.getOrCreateSourceFile(filenm, objIndex.intValue());
00731             this.srcFileStack.push(sourceFile);
00732 
00733             Scope alienScope = new AlienScope(this.experiment, sourceFile, filenm, procnm, firstLn-1, lastLn-1, objIndex.intValue());
00734 
00735             this.beginScope(alienScope);
00736 
00737         } catch (NumberFormatException e) {
00738             e.printStackTrace();
00739         }
00740         
00741     }
00742 
00743     
00744     /*************************************************************************
00745      * 
00746      * @param attributes
00747      * @param values
00748      * <!ATTLIST Procedure
00749               i CDATA #REQUIRED
00750               n CDATA #REQUIRED>
00751      *************************************************************************/
00752     private void do_Procedure(String[] attributes, String[] values) {
00753         if(values.length < 2)
00754             return;
00755         String sID = values[0];
00756         String sData = values[1];
00757 
00758         try {
00759             Integer objID = Integer.parseInt(sID);
00760             this.hashProcedureTable.put(objID, sData);
00761         } catch (java.lang.NumberFormatException e) {
00762             e.printStackTrace();
00763         }
00764     }
00765     
00766     
00767 
00768 
00769     /*************************************************************************
00770      *  Begins processing an L (loop) element.
00771      *  <!ELEMENT L (A|L|S|C|M)*>
00772       <!ATTLIST L
00773                 i CDATA #IMPLIED
00774                 s CDATA #IMPLIED
00775                 l CDATA #IMPLIED
00776                 v CDATA #IMPLIED>
00777      ************************************************************************/
00778 
00779     private void begin_L(String[] attributes, String[] values)
00780     {
00781         int cct_id = 0, flat_id = 0;
00782         int firstLn = 0;
00783         int lastLn = 0;
00784         SourceFile sourceFile = null;
00785         
00786         for(int i=0; i<attributes.length; i++) {
00787             if(attributes[i].equals("s")) {
00788                 flat_id = Integer.parseInt(values[i]);
00789                 if (cct_id == 0)
00790                     cct_id = flat_id;
00791                 
00792             } else if(attributes[i].equals(LINE_ATTRIBUTE)) {
00793                 String sLine = values[i];
00794                 StatementRange objRange = new StatementRange( sLine );
00795                 firstLn = objRange.getFirstLine();
00796                 lastLn = objRange.getLastLine();
00797             } else if (attributes[i].equals(FILENAME_ATTRIBUTE)) {
00798                 String fileIdString = values[i];
00799                 getSourceFile(fileIdString);
00800             } else if(attributes[i].equals(ID_ATTRIBUTE)) {
00801                 cct_id = Integer.parseInt(values[i]);
00802             } 
00803         }
00804         
00805         if (sourceFile == null) {   
00806             sourceFile = this.srcFileStack.peek();
00807             if (this.csviewer) {
00808                 // Use the source file of the Procedure Frame
00809                 // NOTE: the current scope (i.e. the parent of this
00810                 // nascent loop scope) should be either a procedure frame
00811                 // or a loop that recursively obtained its file from the
00812                 // procedure frame.
00813                 Scope frameScope = this.getCurrentScope();
00814                 //while ( !(frameScope instanceof ProcedureScope) ) {
00815                 //  frameScope = frameScope.getParentScope();
00816                 //}
00817                 sourceFile = frameScope.getSourceFile();
00818             }
00819         }
00820         Scope loopScope = new LoopScope(this.experiment, sourceFile, firstLn-1, lastLn-1, cct_id, flat_id);
00821 
00822         this.beginScope(loopScope);
00823     }
00824 
00825     /*************************************************************************
00826      *  Finishes processing an L (loop) element.
00827      ************************************************************************/
00828 
00829     private void end_L()
00830     {
00831         this.endScope();
00832     }
00833 
00834     /*************************************************************************
00835      *  Begins processing an LN (line) element.
00836      * <!ATTLIST S
00837                 i CDATA #IMPLIED
00838                 s CDATA #IMPLIED
00839                 l CDATA #IMPLIED
00840                 v CDATA #IMPLIED>
00841      ************************************************************************/
00842     private void begin_S(String[] attributes, String[] values)
00843     {
00844         begin_S_internal( attributes,  values, false);
00845     }
00846     
00847     private void begin_S_internal(String[] attributes, String[] values, boolean isCallSite)
00848     {
00849         int cct_id = 0, flat_id = 0;
00850         // make a new statement-range scope object
00851         int firstLn = 0;
00852         int lastLn  = 0;
00853         int cpid = 0;
00854 
00855         for(int i=0; i<attributes.length; i++) {
00856             if(attributes[i].equals(LINE_ATTRIBUTE)) {
00857                 firstLn = Integer.parseInt(values[i]);
00858                 lastLn = firstLn;
00859                 
00860             } else if(attributes[i].equals("s"))  {
00861                 flat_id = Integer.parseInt(values[i]);
00862                 if (cct_id == 0)
00863                     cct_id = flat_id;
00864                 
00865             } else if(attributes[i].equals(ID_ATTRIBUTE))  {
00866                 cct_id = Integer.parseInt(values[i]);
00867 
00868             } else if(attributes[i].equals("it")) { //the cpid
00869                 cpid = Integer.parseInt(values[i]);
00870             }
00871 
00872         }
00873 
00874         SourceFile srcFile = this.srcFileStack.peek();
00875 
00876 
00877         Scope scope;
00878         if( firstLn == lastLn )
00879             scope = new LineScope(this.experiment, srcFile, firstLn-1, cct_id, flat_id);
00880         else
00881             scope = new StatementRangeScope(this.experiment, srcFile, 
00882                     firstLn-1, lastLn-1, cct_id, flat_id);
00883 
00884         scope.setCpid(cpid);
00885         if (isCallSite) {
00886             scopeStack.push(scope);
00887         } else {
00888             this.beginScope(scope);
00889         }
00890     }
00891 
00892     /*************************************************************************
00893      *  Finishes processing an S (line) element.
00894      ************************************************************************/
00895 
00896     private void end_S()
00897     {
00898         this.endScope(); 
00899     }
00900 
00901 
00902     /*************************************************************************
00903      * Begin a new CALLSITE
00904      * <!ATTLIST C
00905                 i CDATA #IMPLIED
00906                 s CDATA #IMPLIED
00907                 l CDATA #IMPLIED
00908                 v CDATA #IMPLIED>
00909      ************************************************************************/
00910     private void begin_CALLSITE(String[] attributes, String[] values) {  
00911         this.begin_S_internal(attributes, values, true); // orig: true  
00912     }
00913 
00914 
00915 
00916     /*************************************************************************
00917      *  end a callsite.
00918      ************************************************************************/
00919     private void end_CALLSITE() 
00920     {
00921         end_S();
00922     }
00923 
00924 
00925     private void end_PGM()
00926     {
00927         this.endScope();
00928     }
00929 
00930 
00931     
00932 
00933 
00934     /*************************************************************************
00935      *  Finishes processing an LM (load module) element.
00936      ************************************************************************/
00937     private void end_LM()
00938     {
00939         this.endScope();
00940     }
00941 
00942 
00943 
00944     /*************************************************************************
00945      *  Finishes processing an F (file) element.
00946      ************************************************************************/
00947     private void end_F()
00948     {
00949         this.endScope();
00950         this.srcFileStack.pop();
00951         this.Assert(srcFileStack.peek() == null); // mimic old behavior
00952     }
00953 
00954 
00955     
00956     
00957     /*************************************************************************
00958      *  Finishes processing a P (procedure) element.
00959      ************************************************************************/
00960 
00961     private void end_PF()
00962     {
00963         this.srcFileStack.pop();
00964         this.endScope();
00965     }
00966 
00967 
00968 
00969 
00970     /*************************************************************************
00971      *  Finishes processing a A (alien) element.
00972      ************************************************************************/
00973 
00974     private void end_A()
00975     {
00976         this.srcFileStack.pop();
00977         this.endScope();
00978     }
00979 
00980     
00981     
00982     //--------------------------------------------------------------------------------
00983     // trace database
00984     //--------------------------------------------------------------------------------
00985     private void begin_TraceDBTable(String[] attributes, String[] values) 
00986     {
00987     }
00988 
00989     
00990     private void end_TraceDBTable() 
00991     {
00992     }
00993 
00994     
00995     
00996     /*******
00997      * handling trace db
00998      * @param attributes
00999      * @param values
01000      */
01001     private void do_TraceDB(String[] attributes, String[] values)
01002     {
01003         TraceAttribute attribute = new TraceAttribute();
01004         // tallent: Note that the DTD currently only permits one instance of <TraceDB>
01005         for (int i=0; i<attributes.length; i++) {
01006             
01007             if (attributes[i].charAt(0) == 'i') {
01008             } else if (attributes[i].equals("db-glob")) {
01009                 attribute.dbGlob = values[i];
01010                 
01011             } else if (attributes[i].equals("db-min-time")) {
01012                 attribute.dbTimeMin = Long.parseLong(values[i]);
01013                 
01014             } else if (attributes[i].equals("db-max-time")) {
01015                 attribute.dbTimeMax = Long.parseLong(values[i]);
01016 
01017             } else if (attributes[i].equals("db-header-sz")) {
01018                 attribute.dbHeaderSize = Integer.parseInt(values[i]);
01019             }
01020         }
01021         this.experiment.setTraceAttribute(attribute);
01022     }
01023 
01024 
01025 
01026     //===============================================
01027     // Utilities that may be used by children of the class
01028     //===============================================
01029     
01030     /*************************************************************************
01031      *  Begins processing a profile data (program) element.
01032      ************************************************************************/
01033     protected void begin_SecData(String[] attributes, String[] values) 
01034     {
01035         // make the root scope
01036         this.rootScope = new RootScope(this.experiment, "Invisible Outer Root Scope", RootScopeType.Invisible);
01037         this.scopeStack.push(this.rootScope);   // don't use 'beginScope'
01038 
01039         final String title;
01040         final RootScopeType rootType;
01041         
01042         if (this.csviewer) {
01043             title = "Calling Context View";
01044             rootType = RootScopeType.CallingContextTree;
01045         } else {
01046             title = "Flat View";
01047             rootType = RootScopeType.Flat;
01048         }
01049         this.viewRootScope[0]  = new RootScope(this.experiment, title, rootType);
01050         beginScope(this.viewRootScope[0]);
01051     }
01052 
01053 
01054     /************************************************************************* 
01055      * treat XML attributes like a named property list; this is an alternative to a brittle
01056      * position-based approach for recognizing attributes
01057      *************************************************************************/
01058     protected String getAttributeByName(String name, String[] attributes, String[] values)
01059     {
01060         for (int i = 0; i < attributes.length; i++) if (name == attributes[i]) return values[i];
01061         return null;
01062     }
01063 
01064 
01065 //  ------------------------------------------------------------------- //
01066 //  SCOPE TREE BUILDING                                                 //
01067 //  ------------------------------------------------------------------- //
01068     
01069     /*************************************************************************
01070      *  Adds a newly parsed scope to the scope tree.
01071      ************************************************************************/
01072     private void beginScope(Scope scope)
01073     {
01074         // add to the tree
01075         Scope top = getCurrentScope();
01076         top.addSubscope(scope);
01077         scope.setParentScope(top);
01078         
01079         // push the new scope to the stack
01080         scopeStack.push(scope);
01081     }
01082 
01083     
01084     /*************************************************************************
01085      *  Ends a newly parsed scope.
01086      ************************************************************************/
01087     protected void endScope()
01088     {
01089         try {
01090             this.scopeStack.pop();
01091         } catch (java.util.EmptyStackException e) {
01092             System.out.println("End of stack:"+this.parser.getLineNumber());
01093         }
01094     }
01095 
01096     /*************************************************************************
01097      *  Returns the current scope.
01098      ************************************************************************/
01099     protected Scope getCurrentScope()
01100     {
01101         return this.scopeStack.peek();
01102     }
01103 
01104     /*************************************************************************
01105      *   Get the File for a callsite    
01106      *   Using Hashtable to store the "FileSystemSourceFile" object 
01107      *   for the callsite's file attribute.
01108      ************************************************************************/
01109     protected SourceFile getOrCreateSourceFile(String fileLine, int keyFile)
01110     {
01111         SourceFile sourceFile=hashSourceFileTable.get(keyFile);
01112         if (sourceFile == null) {
01113             File filename = new File(fileLine);
01114             sourceFile = new FileSystemSourceFile(experiment, filename, keyFile);
01115             this.hashSourceFileTable.put(Integer.valueOf(keyFile), sourceFile);
01116         }  
01117 
01118         return sourceFile;
01119     }
01120 
01121     
01122 
01123     /*************************************************************************
01124      *  Initializes the build process.
01125      ************************************************************************/
01126 
01127     public void begin()
01128     {
01129         this.configuration = new ExperimentConfiguration();
01130     }
01131 
01132 
01133     /*************************************************************************
01134      *  Takes notice of content characters within an element.
01135      *
01136      *  None of the elements in an hpcviewer experiment XML file have content
01137      *  characters, so this method should never be called.
01138      *
01139      ************************************************************************/
01140     public void content(String s)
01141     {
01142         Dialogs.notCalled("ExperimentBuilder.content");
01143     }
01144 
01145 
01146 
01147     /*************************************************************************
01148      *  Finalizes the build process.
01149      ************************************************************************/
01150 
01151     public void end()
01152     {
01153         // bugs no 224: https://outreach.scidac.gov/tracker/index.php?func=detail&aid=224&group_id=22&atid=169
01154         try {
01155             // pop out root scope
01156             this.scopeStack.pop();
01157         } catch (EmptyStackException e) {
01158             System.err.println("ExperimentBuilder: no root scope !");
01159         }
01160         
01161         // check that input was properly nested
01162         if (!this.scopeStack.empty()) {
01163             Scope topScope = this.scopeStack.peek();
01164             System.out.println("Stack is not empty; remaining top scope = " + topScope.getName());
01165             this.error();
01166         }
01167 
01168         // copy parse results into configuration
01169         this.experiment.setConfiguration(this.configuration);
01170 
01171         this.experiment.setRootScope(this.rootScope);
01172         
01173         // supply defaults for missing info
01174         if( this.configuration.getName(ExperimentConfiguration.NAME_EXPERIMENT) == null )
01175             this.configuration.setName(ExperimentConfiguration.NAME_EXPERIMENT, this.defaultName);
01176         
01177         if( this.configuration.getSearchPathCount() == 0 )
01178         {
01179             List<File> paths = new ArrayList<File>();
01180             paths.add(new File(""));
01181             paths.add(new File("src"));
01182             paths.add(new File("compile"));
01183             this.configuration.setSearchPaths(paths);
01184         }
01185 
01186     }
01187 
01188     
01189 
01190     
01191     //--------------------------------------------------------------------------------
01192     // Utilities
01193     //--------------------------------------------------------------------------------
01194 
01195     
01196     private String getProcedureName(String sProcIndex) {
01197         String sProcName = PROCEDURE_UNKNOWN;
01198         boolean hashtableExist = (this.hashProcedureTable.size()>0);
01199         if(hashtableExist) {
01200             try {
01201                 Integer objProcID = Integer.parseInt(sProcIndex); 
01202                 // get the real name of the procedure from the dictionary
01203                 String sProc = this.hashProcedureTable.get(objProcID);
01204                 if(sProc != null) {
01205                     sProcName = sProc;
01206                 }
01207             } catch (java.lang.NumberFormatException e) {
01208                 System.err.println("Warning: Procedure index doesn't exist: " + sProcIndex);
01209             }
01210         } else {
01211             // the database of procedure doesn't exist. This can be a flat view.
01212             sProcName = sProcIndex;
01213         }
01214         return sProcName;
01215     }
01216     
01217     
01218     
01219     /*************************************************************************
01220      * Class to treat a string of line or range of lines into two lines: first line and last line 
01221      * @author laksonoadhianto
01222      *
01223      ************************************************************************/
01224     private class StatementRange {
01225         private int firstLn;
01226         private int lastLn;
01227         
01228         public StatementRange(String sLine) {
01229             // find the range separator
01230             int iSeparator = sLine.indexOf('-');
01231             if(iSeparator > 0) {
01232                 // separator exist, it should be a range
01233                 this.firstLn = Integer.parseInt( sLine.substring(0,iSeparator) );
01234                 this.lastLn = Integer.parseInt( sLine.substring(iSeparator+1) );
01235             } else {
01236                 // no separator: no range
01237                 this.firstLn = Integer.parseInt(sLine);
01238                 this.lastLn = this.firstLn;
01239             }
01240         }
01241         
01242         public int getFirstLine( ) { return this.firstLn; }
01243         public int getLastLine( ) { return this.lastLn; }
01244     }
01245 
01246 }

Generated on 5 May 2015 for HPCVIEWER by  doxygen 1.6.1