Profiling.java
     1: //========================================================================================
     2: //  Profiling.java
     3: //    en:Profiling -- It measures the elapsed time of methods.
     4: //    ja:プロファイリング -- メソッドの所要時間を計ります。
     5: //  Copyright (C) 2003-2017 Makoto Kamada
     6: //
     7: //  This file is part of the XEiJ (X68000 Emulator in Java).
     8: //  You can use, modify and redistribute the XEiJ if the conditions are met.
     9: //  Read the XEiJ License for more details.
    10: //  http://stdkmd.com/xeij/
    11: //========================================================================================
    12: 
    13: //----------------------------------------------------------------------------------------
    14: //  メソッドの所要時間を計る
    15: //  メソッドの先頭
    16: //    if (Profiling.PFF_ON) {
    17: //      Profiling.pffStart[Profiling.PRF.<name-of-method>.ordinal ()] = System.nanoTime ();
    18: //    }
    19: //  メソッドの末尾
    20: //    if (Profiling.PFF_ON) {
    21: //      Profiling.pffTotal[Profiling.PRF.<name-of-method>.ordinal ()] += System.nanoTime () - Profiling.pffStart[Profiling.PRF.<name-of-method>.ordinal ()];
    22: //      Profiling.pffCount[Profiling.PRF.<name-of-method>.ordinal ()]++;
    23: //    }
    24: //  returnやthrowで抜けてしまうと計れないことに注意
    25: //----------------------------------------------------------------------------------------
    26: 
    27: package xeij;
    28: 
    29: import java.awt.*;  //BasicStroke,BorderLayout,BoxLayout,Color,Component,Container,Cursor,Desktop,Dimension,Font,Frame,Graphics,Graphics2D,GraphicsDevice,GraphicsEnvironment,GridLayout,Image,Insets,Paint,Point,Rectangle,RenderingHints,Robot,Shape,Stroke,TexturePaint,Toolkit
    30: import java.awt.event.*;  //ActionEvent,ActionListener,ComponentAdapter,ComponentEvent,ComponentListener,FocusAdapter,FocusEvent,FocusListener,InputEvent,KeyAdapter,KeyEvent,KeyListener,MouseAdapter,MouseEvent,MouseListener,MouseMotionAdapter,MouseWheelEvent,WindowAdapter,WindowEvent,WindowListener,WindowStateListener
    31: import java.lang.*;  //Boolean,Character,Class,Comparable,Double,Exception,Float,IllegalArgumentException,Integer,Long,Math,Number,Object,Runnable,SecurityException,String,StringBuilder,System
    32: import java.util.*;  //ArrayList,Arrays,Calendar,GregorianCalendar,HashMap,Map,Map.Entry,Timer,TimerTask,TreeMap
    33: import javax.swing.*;  //AbstractSpinnerModel,Box,ButtonGroup,DefaultListModel,ImageIcon,JApplet,JButton,JCheckBox,JCheckBoxMenuItem,JDialog,JFileChooser,JFrame,JLabel,JList,JMenu,JMenuBar,JMenuItem,JPanel,JRadioButton,JScrollPane,JSpinner,JTextArea,JTextField,JTextPane,JViewport,ScrollPaneConstants,SpinnerListModel,SpinnerNumberModel,SwingConstants,SwingUtilities,UIManager,UIDefaults,UnsupportedLookAndFeelException
    34: 
    35: public class Profiling {
    36: 
    37:   public static final boolean PFF_ON = false;  //true=メソッドの所要時間を計る
    38: 
    39:   public static enum PRF {
    40: 
    41:     //MMU
    42:     mmuTranslate,
    43: 
    44:     //IRP
    45:     irpOriByte,
    46:     irpOriWord,
    47:     irpOriLong,
    48:     irpCmp2Chk2Byte,
    49:     irpAndiByte,
    50:     irpAndiWord,
    51:     irpAndiLong,
    52:     irpCmp2Chk2Word,
    53:     irpSubiByte,
    54:     irpSubiWord,
    55:     irpSubiLong,
    56:     irpCmp2Chk2Long,
    57:     irpAddiByte,
    58:     irpAddiWord,
    59:     irpAddiLong,
    60:     irpCallm,
    61:     irpBtstImm,
    62:     irpBchgImm,
    63:     irpBclrImm,
    64:     irpBsetImm,
    65:     irpEoriByte,
    66:     irpEoriWord,
    67:     irpEoriLong,
    68:     irpCasByte,
    69:     irpCmpiByte,
    70:     irpCmpiWord,
    71:     irpCmpiLong,
    72:     irpCasWord,
    73:     irpMovesByte,
    74:     irpMovesWord,
    75:     irpMovesLong,
    76:     irpCasLong,
    77:     irpBtstReg,
    78:     irpBchgReg,
    79:     irpBclrReg,
    80:     irpBsetReg,
    81:     irpMoveToDRByte,
    82:     irpMoveToMMByte,
    83:     irpMoveToMPByte,
    84:     irpMoveToMNByte,
    85:     irpMoveToMWByte,
    86:     irpMoveToMXByte,
    87:     irpMoveToZWByte,
    88:     irpMoveToZLByte,
    89:     irpMoveToDRLong,
    90:     irpMoveaLong,
    91:     irpMoveToMMLong,
    92:     irpMoveToMPLong,
    93:     irpMoveToMNLong,
    94:     irpMoveToMWLong,
    95:     irpMoveToMXLong,
    96:     irpMoveToZWLong,
    97:     irpMoveToZLLong,
    98:     irpMoveToDRWord,
    99:     irpMoveaWord,
   100:     irpMoveToMMWord,
   101:     irpMoveToMPWord,
   102:     irpMoveToMNWord,
   103:     irpMoveToMWWord,
   104:     irpMoveToMXWord,
   105:     irpMoveToZWWord,
   106:     irpMoveToZLWord,
   107:     irpNegxByte,
   108:     irpNegxWord,
   109:     irpNegxLong,
   110:     irpMoveFromSR,
   111:     irpClrByte,
   112:     irpClrWord,
   113:     irpClrLong,
   114:     irpMoveFromCCR,
   115:     irpNegByte,
   116:     irpNegWord,
   117:     irpNegLong,
   118:     irpMoveToCCR,
   119:     irpNotByte,
   120:     irpNotWord,
   121:     irpNotLong,
   122:     irpMoveToSR,
   123:     irpNbcd,
   124:     irpPea,
   125:     irpMovemToMemWord,
   126:     irpMovemToMemLong,
   127:     irpTstByte,
   128:     irpTstWord,
   129:     irpTstLong,
   130:     irpTas,
   131:     irpMuluMulsLong,
   132:     irpDivuDivsLong,
   133:     irpMovemToRegWord,
   134:     irpMovemToRegLong,
   135:     irpEmx,
   136:     irpTrap,
   137:     irpTrap15,
   138:     irpLinkWord,
   139:     irpUnlk,
   140:     irpMoveToUsp,
   141:     irpMoveFromUsp,
   142:     irpReset,
   143:     irpNop,
   144:     irpStop,
   145:     irpRte,
   146:     irpRtd,
   147:     irpRts,
   148:     irpTrapv,
   149:     irpRtr,
   150:     irpMovecFromControl,
   151:     irpMovecToControl,
   152:     irpMisc,
   153:     irpJsr,
   154:     irpJmp,
   155:     irpChkLong,
   156:     irpChkWord,
   157:     irpLea,
   158:     irpAddqByte,
   159:     irpAddqWord,
   160:     irpAddqLong,
   161:     irpSubqByte,
   162:     irpSubqWord,
   163:     irpSubqLong,
   164:     irpSt,
   165:     irpSf,
   166:     irpScc,
   167:     irpShi,
   168:     irpSls,
   169:     irpShs,
   170:     irpSlo,
   171:     irpSne,
   172:     irpSeq,
   173:     irpSvc,
   174:     irpSvs,
   175:     irpSpl,
   176:     irpSmi,
   177:     irpSge,
   178:     irpSlt,
   179:     irpSgt,
   180:     irpSle,
   181:     irpBrasw,
   182:     irpBras,
   183:     irpBrasl,
   184:     irpBsrsw,
   185:     irpBsrs,
   186:     irpBsrsl,
   187:     irpBccsw,
   188:     irpBccs,
   189:     irpBccsl,
   190:     irpBhisw,
   191:     irpBhis,
   192:     irpBhisl,
   193:     irpBlssw,
   194:     irpBlss,
   195:     irpBlssl,
   196:     irpBhssw,
   197:     irpBhss,
   198:     irpBhssl,
   199:     irpBlosw,
   200:     irpBlos,
   201:     irpBlosl,
   202:     irpBnesw,
   203:     irpBnes,
   204:     irpBnesl,
   205:     irpBeqsw,
   206:     irpBeqs,
   207:     irpBeqsl,
   208:     irpBvcsw,
   209:     irpBvcs,
   210:     irpBvcsl,
   211:     irpBvssw,
   212:     irpBvss,
   213:     irpBvssl,
   214:     irpBplsw,
   215:     irpBpls,
   216:     irpBplsl,
   217:     irpBmisw,
   218:     irpBmis,
   219:     irpBmisl,
   220:     irpBgesw,
   221:     irpBges,
   222:     irpBgesl,
   223:     irpBltsw,
   224:     irpBlts,
   225:     irpBltsl,
   226:     irpBgtsw,
   227:     irpBgts,
   228:     irpBgtsl,
   229:     irpBlesw,
   230:     irpBles,
   231:     irpBlesl,
   232:     irpMoveq,
   233:     irpMvsByte,
   234:     irpMvsWord,
   235:     irpMvzByte,
   236:     irpMvzWord,
   237:     irpOrToRegByte,
   238:     irpOrToRegWord,
   239:     irpOrToRegLong,
   240:     irpDivuWord,
   241:     irpOrToMemByte,
   242:     irpOrToMemWord,
   243:     irpOrToMemLong,
   244:     irpDivsWord,
   245:     irpSubToRegByte,
   246:     irpSubToRegWord,
   247:     irpSubToRegLong,
   248:     irpSubaWord,
   249:     irpSubToMemByte,
   250:     irpSubToMemWord,
   251:     irpSubToMemLong,
   252:     irpSubaLong,
   253:     irpAline,
   254:     irpCmpByte,
   255:     irpCmpWord,
   256:     irpCmpLong,
   257:     irpCmpaWord,
   258:     irpEorByte,
   259:     irpEorWord,
   260:     irpEorLong,
   261:     irpCmpaLong,
   262:     irpAndToRegByte,
   263:     irpAndToRegWord,
   264:     irpAndToRegLong,
   265:     irpMuluWord,
   266:     irpAndToMemByte,
   267:     irpAndToMemWord,
   268:     irpAndToMemLong,
   269:     irpMulsWord,
   270:     irpAddToRegByte,
   271:     irpAddToRegWord,
   272:     irpAddToRegLong,
   273:     irpAddaWord,
   274:     irpAddToMemByte,
   275:     irpAddToMemWord,
   276:     irpAddToMemLong,
   277:     irpAddaLong,
   278:     irpXxrToRegByte,
   279:     irpXxrToRegWord,
   280:     irpXxrToRegLong,
   281:     irpAsrToMem,
   282:     irpLsrToMem,
   283:     irpRoxrToMem,
   284:     irpRorToMem,
   285:     irpXxlToRegByte,
   286:     irpXxlToRegWord,
   287:     irpXxlToRegLong,
   288:     irpAslToMem,
   289:     irpLslToMem,
   290:     irpRoxlToMem,
   291:     irpRolToMem,
   292:     irpBftst,
   293:     irpBfextu,
   294:     irpBfchg,
   295:     irpBfexts,
   296:     irpBfclr,
   297:     irpBfffo,
   298:     irpBfset,
   299:     irpBfins,
   300:     irpPgen,
   301:     irpPscc,
   302:     irpPbccWord,
   303:     irpPbccLong,
   304:     irpPsave,
   305:     irpPrestore,
   306:     irpFgen,
   307:     irpFscc,
   308:     irpFbccWord,
   309:     irpFbccLong,
   310:     irpFsave,
   311:     irpFrestore,
   312:     irpCinvCpushNC,
   313:     irpCinvCpushDC,
   314:     irpCinvCpushIC,
   315:     irpCinvCpushBC,
   316:     irpPflush,
   317:     irpPlpaw,
   318:     irpPlpar,
   319:     irpMove16,
   320:     irpLpstop,
   321:     irpFpack,
   322:     irpFline,
   323:     irpIllegal,
   324:     irpSetPC,
   325:     irpSetSR,
   326:     irpInterrupt,
   327:     irpException,
   328: 
   329:     //CRT
   330:     CRTTicker__START__,
   331:     InitialStage,
   332:     NormalStart,
   333:     NormalDrawIdleFront,
   334:     NormalDrawIdleSync,
   335:     NormalDrawIdleBackDisp,
   336:     NormalDrawDispFront,
   337:     NormalDrawDispSync,
   338:     NormalDrawDispBack,
   339:     NormalDrawDispDisp,
   340:     NormalOmitIdleFront,
   341:     NormalOmitIdleSync,
   342:     NormalOmitIdleBackDisp,
   343:     NormalOmitDispFront,
   344:     NormalOmitDispSync,
   345:     NormalOmitDispBackDisp,
   346:     DuplicationStart,
   347:     DuplicationDrawIdleFront,
   348:     DuplicationDrawIdleSync,
   349:     DuplicationDrawIdleBackDisp,
   350:     DuplicationDrawDispEvenFront,
   351:     DuplicationDrawDispOddFront,
   352:     DuplicationDrawDispEvenSync,
   353:     DuplicationDrawDispOddSync,
   354:     DuplicationDrawDispEvenBack,
   355:     DuplicationDrawDispOddBack,
   356:     DuplicationDrawDispEvenDisp,
   357:     DuplicationDrawDispOddDisp,
   358:     DuplicationOmitIdleFront,
   359:     DuplicationOmitIdleSync,
   360:     DuplicationOmitIdleBackDisp,
   361:     DuplicationOmitDispEvenFront,
   362:     DuplicationOmitDispOddFront,
   363:     DuplicationOmitDispEvenSync,
   364:     DuplicationOmitDispOddSync,
   365:     DuplicationOmitDispEvenBackDisp,
   366:     DuplicationOmitDispOddBackDisp,
   367:     InterlaceStart,
   368:     InterlaceDrawIdleFront,
   369:     InterlaceDrawIdleSync,
   370:     InterlaceDrawIdleBackDisp,
   371:     InterlaceDrawDispFront,
   372:     InterlaceDrawDispSync,
   373:     InterlaceDrawDispBack,
   374:     InterlaceDrawDispDisp,
   375:     InterlaceOmitIdleFront,
   376:     InterlaceOmitIdleSync,
   377:     InterlaceOmitIdleBackDisp,
   378:     InterlaceOmitDispFront,
   379:     InterlaceOmitDispSync,
   380:     InterlaceOmitDispBackDisp,
   381:     SlitStart,
   382:     SlitDrawIdleFront,
   383:     SlitDrawIdleSync,
   384:     SlitDrawIdleBackDisp,
   385:     SlitDrawDispFront,
   386:     SlitDrawDispSync,
   387:     SlitDrawDispBack,
   388:     SlitDrawDispDisp,
   389:     SlitOmitIdleFront,
   390:     SlitOmitIdleSync,
   391:     SlitOmitIdleBackDisp,
   392:     SlitOmitDispFront,
   393:     SlitOmitDispSync,
   394:     SlitOmitDispBackDisp,
   395:     CRTTicker__END__,
   396: 
   397:     //DMA
   398:     dmaTransfer,
   399: 
   400:     //MFP
   401:     mfpTick,
   402: 
   403:     //SND
   404:     sndTick,
   405: 
   406:     //OPM
   407:     opmUpdate,
   408: 
   409:     //PCM
   410:     pcmWriteBuffer,
   411:     pcmFillBuffer,
   412: 
   413:     PRF__END__,
   414: 
   415:     CRTTicker,
   416: 
   417:   };  //enum PRF
   418: 
   419:   public static final int PFF_STAGE_STANDBY = 0;
   420:   public static final int PFF_STAGE_START   = 1;
   421:   public static final int PFF_STAGE_RUNNING = 2;
   422:   public static final int PFF_STAGE_STOP    = 3;
   423: 
   424:   public static PRF[] pffValues;
   425:   public static int pffLength;
   426:   public static String[] pffNames;
   427:   public static long[] pffStart;
   428:   public static long[] pffTotal;
   429:   public static long[] pffCount;
   430:   public static JCheckBoxMenuItem pffCheckBoxMenuItem;
   431:   public static int pffStage;
   432:   public static JFrame pffFrame;
   433:   public static ScrollTextArea pffBoard;
   434:   public static JTextArea pffTextArea;
   435: 
   436:   public static void pffInit () {
   437:     pffValues = PRF.values ();
   438:     pffLength = pffValues.length;
   439:     pffNames = new String[pffLength];
   440:     for (PRF n : pffValues) {
   441:       pffNames[n.ordinal ()] = n.toString ();
   442:     }
   443:     pffStart = new long[pffLength];
   444:     pffTotal = new long[pffLength];
   445:     pffCount = new long[pffLength];
   446:     pffCheckBoxMenuItem =
   447:       Multilingual.mlnText (
   448:         ComponentFactory.createCheckBoxMenuItem (
   449:           false, "Profiling",
   450:           new ActionListener () {
   451:             @Override public void actionPerformed (ActionEvent ae) {
   452:               if (pffCheckBoxMenuItem.isSelected ()) {
   453:                 if (pffStage == PFF_STAGE_STANDBY) {
   454:                   pffStage = PFF_STAGE_START;
   455:                 }
   456:               } else {
   457:                 if (pffStage == PFF_STAGE_RUNNING) {
   458:                   pffStage = PFF_STAGE_STOP;
   459:                 }
   460:               }
   461:             }
   462:           }),
   463:         "ja", "プロファイリング");
   464:     pffStage = PFF_STAGE_STANDBY;
   465:   }  //pffInit
   466: 
   467:   //pffClear ()
   468:   //  メソッドの所要時間を消去
   469:   public static void pffClear () {
   470:     Arrays.fill (pffStart, 0L);
   471:     Arrays.fill (pffTotal, 0L);
   472:     Arrays.fill (pffCount, 0L);
   473:     pffStage = PFF_STAGE_RUNNING;
   474:   }  //pffClear()
   475: 
   476:   //pffReport ()
   477:   //  メソッドの所要時間を報告
   478:   public static void pffReport () {
   479:     long[] ttl = Arrays.copyOf (pffTotal, pffLength);  //ソート中に値が変わると気持ち悪いのでコピーしてからソートする
   480:     long[] cnt = Arrays.copyOf (pffCount, pffLength);
   481:     {
   482:       int k = PRF.CRTTicker.ordinal ();
   483:       ttl[k] = 0L;
   484:       cnt[k] = 0L;
   485:       for (int i = PRF.CRTTicker__START__.ordinal () + 1, l = PRF.CRTTicker__END__.ordinal (); i < l; i++) {
   486:         ttl[k] += ttl[i];
   487:         cnt[k] += cnt[i];
   488:       }
   489:     }
   490:     int[] a = new int[pffLength];
   491:     for (int i = 0; i < pffLength; i++) {
   492:       long x = ttl[i];
   493:       int l = 0;
   494:       int r = i;
   495:       while (l < r) {
   496:         int m = (l + r) >> 1;
   497:         if (ttl[a[m]] >= x) {
   498:           l = m + 1;
   499:         } else {
   500:           r = m;
   501:         }
   502:       }
   503:       r = i;
   504:       while (l < r) {
   505:         a[r] = a[r - 1];
   506:         r--;
   507:       }
   508:       a[l] = i;
   509:     }
   510:     StringBuilder sb = new StringBuilder ();
   511:     sb.append ("rank      time       ratio     count       average                    method\n");
   512:     sb.append ("----  ------------  -------  ---------  -------------  ------------------------------------\n");
   513:     long total = 0L;
   514:     for (int i = 0, l = PRF.PRF__END__.ordinal (); i < l; i++) {
   515:       total += ttl[i];
   516:     }
   517:     for (int i = 0; i < pffLength; i++) {
   518:       int j = a[i];
   519:       long k = ttl[j];
   520:       if (k == 0L) {
   521:         break;
   522:       }
   523:       //!!! 計測範囲の包含関係を考慮していないので占有率の表示が正しくない
   524:       sb.append (String.format ("%4d  %10.3fms  %6.3f%%  %9d  %11.3fns  %s\n",
   525:                                 i + 1,
   526:                                 (double) k / 1000000.0,
   527:                                 100.0 * (double) k / (double) total,
   528:                                 cnt[j],
   529:                                 (double) k / (double) cnt[j],
   530:                                 pffNames[j]));
   531:     }
   532:     if (pffFrame == null) {
   533:       pffBoard = ComponentFactory.setPreferredSize (
   534:         ComponentFactory.setFont (new ScrollTextArea (), new Font ("Monospaced", Font.PLAIN, 12)),
   535:         600, 400);
   536:       pffBoard.setMargin (new Insets (2, 4, 2, 4));
   537:       pffBoard.setHighlightCursorOn (true);
   538:       pffTextArea = pffBoard.getTextArea ();
   539:       pffTextArea.setEditable (false);
   540:       pffFrame = Multilingual.mlnTitle (
   541:         ComponentFactory.createRestorableSubFrame (
   542:           Settings.SGS_PFF_FRAME_KEY,
   543:           "Profiling",
   544:           null,
   545:           pffBoard
   546:         ),
   547:         "ja", "プロファイリング");
   548:     }
   549:     pffTextArea.setText (sb.toString ());
   550:     pffTextArea.setCaretPosition (0);
   551:     pffFrame.setVisible (true);
   552:     pffStage = PFF_STAGE_STANDBY;
   553:   }  //pffReport()
   554: 
   555: }  //class Profiling
   556: 
   557: 
   558: