1 /*
   2  * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.jfr.tool;
  27 
  28 import java.nio.file.Path;
  29 import java.util.regex.Matcher;
  30 import java.util.regex.Pattern;
  31 
  32 import jdk.jfr.Configuration;
  33 import jdk.jfr.Event;
  34 import jdk.jfr.Recording;
  35 import jdk.test.lib.JDKToolLauncher;
  36 import jdk.test.lib.Utils;
  37 import jdk.test.lib.process.OutputAnalyzer;
  38 import jdk.test.lib.process.ProcessTools;;
  39 
  40 final class ExecuteHelper {
  41 
  42     public static Object[] array;
  43 
  44     static class CustomEvent extends Event {
  45         int intValue;
  46         long longValue;
  47         double doubliValue;
  48         float floatValue;
  49         String stringValue;
  50         Short shortValue;
  51         boolean booleanValue;
  52         char charValue;
  53         double trickyDouble;
  54     }
  55 
  56     public static void emitCustomEvents() {
  57         // Custom events with potentially tricky values
  58         CustomEvent event1 = new CustomEvent();
  59         event1.trickyDouble = Double.NaN;
  60         event1.intValue = Integer.MIN_VALUE;
  61         event1.longValue = Long.MIN_VALUE;
  62         event1.doubliValue = Double.MIN_VALUE;
  63         event1.floatValue = Float.MIN_VALUE;
  64         StringBuilder sb = new StringBuilder();
  65         for (int i = 0; i < 512; i++) {
  66             sb.append((char) i);
  67         }
  68         sb.append("\u2324");
  69         event1.stringValue = sb.toString();
  70         event1.shortValue = Short.MIN_VALUE;
  71         event1.booleanValue = true;
  72         event1.booleanValue = false;
  73         event1.charValue = '\b';
  74         event1.commit();
  75 
  76         CustomEvent event2 = new CustomEvent();
  77         event2.trickyDouble = Double.NEGATIVE_INFINITY;
  78         event2.intValue = Integer.MAX_VALUE;
  79         event2.longValue = Long.MAX_VALUE;
  80         event2.doubliValue = Double.MAX_VALUE;
  81         event2.floatValue = Float.MAX_VALUE;
  82         event2.stringValue = null;
  83         event2.shortValue = Short.MAX_VALUE;
  84         event2.booleanValue = false;
  85         event2.charValue = 0;
  86         event2.commit();
  87     }
  88 
  89     public static Path createProfilingRecording() throws Exception {
  90         Path file = Utils.createTempFile("profiling-recording", ".jfr");
  91         // Create a recording with some data
  92         try (Recording r = new Recording(Configuration.getConfiguration("profile"))) {
  93             r.start();
  94 
  95             // Allocation event
  96             array = new Object[1000000];
  97             array = null;
  98 
  99             // Class loading event etc
 100             provokeClassLoading();
 101 
 102             // GC events
 103             System.gc();
 104 
 105             // ExecutionSample
 106             long t = System.currentTimeMillis();
 107             while (System.currentTimeMillis() - t < 50) {
 108                 // do nothing
 109             }
 110 
 111             // Other periodic events, i.e CPU load
 112             Thread.sleep(1000);
 113 
 114             r.stop();
 115             r.dump(file);
 116         }
 117 
 118         return file;
 119     }
 120 
 121     private static void provokeClassLoading() {
 122        // Matching a string with regexp
 123        // is expected to load some classes and generate some VM events
 124        Pattern p = Pattern.compile("a*b");
 125        Matcher m = p.matcher("aaaaab");
 126        m.matches();
 127     }
 128 
 129     public static OutputAnalyzer jfr(String... args) throws Throwable {
 130         JDKToolLauncher l = JDKToolLauncher.createUsingTestJDK("jfr");
 131         for (String arg : args) {
 132             l.addToolArg(arg);
 133         }
 134         return ProcessTools.executeCommand(l.getCommand());
 135     }
 136 }