Save This Page
Home » openjdk-7 » sun » misc » [javadoc | source]
    1   /*
    2    * Copyright (c) 2002, 2006, 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   package sun.misc;
   26   
   27   import java.nio.ByteBuffer;
   28   import java.security.Permission;
   29   import java.security.PrivilegedAction;
   30   import java.io.IOException;
   31   import java.io.UnsupportedEncodingException;
   32   
   33   /**
   34    * The Perf class provides the ability to attach to an instrumentation
   35    * buffer maintained by a Java virtual machine. The instrumentation
   36    * buffer may be for the Java virtual machine running the methods of
   37    * this class or it may be for another Java virtual machine on the
   38    * same system.
   39    * <p>
   40    * In addition, this class provides methods to create instrumentation
   41    * objects in the instrumentation buffer for the Java virtual machine
   42    * that is running these methods. It also contains methods for acquiring
   43    * the value of a platform specific high resolution clock for time
   44    * stamp and interval measurement purposes.
   45    *
   46    * @author   Brian Doherty
   47    * @since    1.4.2
   48    * @see      #getPerf
   49    * @see      sun.misc.Perf$GetPerfAction
   50    * @see      java.nio.ByteBuffer
   51    */
   52   public final class Perf {
   53   
   54       private static Perf instance;
   55   
   56       private static final int PERF_MODE_RO = 0;
   57       private static final int PERF_MODE_RW = 1;
   58   
   59       private Perf() { }    // prevent instantiation
   60   
   61       /**
   62        * The GetPerfAction class is a convenience class for acquiring access
   63        * to the singleton Perf instance using the
   64        * <code>AccessController.doPrivileged()</code> method.
   65        * <p>
   66        * An instance of this class can be used as the argument to
   67        * <code>AccessController.doPrivileged(PrivilegedAction)</code>.
   68        * <p> Here is a suggested idiom for use of this class:
   69        *
   70        * <blockquote><pre>
   71        * class MyTrustedClass {
   72        *   private static final Perf perf =
   73        *       AccessController.doPrivileged(new Perf.GetPerfAction<Perf>());
   74        *   ...
   75        * }
   76        * </pre></blockquote>
   77        * <p>
   78        * In the presence of a security manager, the <code>MyTrustedClass</code>
   79        * class in the above example will need to be granted the
   80        * <em>"sun.misc.Perf.getPerf"</em> <code>RuntimePermission</code>
   81        * permission in order to successfully acquire the singleton Perf instance.
   82        * <p>
   83        * Please note that the <em>"sun.misc.Perf.getPerf"</em> permission
   84        * is not a JDK specified permission.
   85        *
   86        * @see  java.security.AccessController#doPrivileged(PrivilegedAction)
   87        * @see  java.lang.RuntimePermission
   88        */
   89       public static class GetPerfAction implements PrivilegedAction<Perf>
   90       {
   91           /**
   92            * Run the <code>Perf.getPerf()</code> method in a privileged context.
   93            *
   94            * @see #getPerf
   95            */
   96           public Perf run() {
   97               return getPerf();
   98           }
   99       }
  100   
  101       /**
  102        * Return a reference to the singleton Perf instance.
  103        * <p>
  104        * The getPerf() method returns the singleton instance of the Perf
  105        * class. The returned object provides the caller with the capability
  106        * for accessing the instrumentation buffer for this or another local
  107        * Java virtual machine.
  108        * <p>
  109        * If a security manager is installed, its <code>checkPermission</code>
  110        * method is called with a <code>RuntimePermission</code> with a target
  111        * of <em>"sun.misc.Perf.getPerf"</em>. A security exception will result
  112        * if the caller has not been granted this permission.
  113        * <p>
  114        * Access to the returned <code>Perf</code> object should be protected
  115        * by its caller and not passed on to untrusted code. This object can
  116        * be used to attach to the instrumentation buffer provided by this Java
  117        * virtual machine or for those of other Java virtual machines running
  118        * on the same system. The instrumentation buffer may contain senstitive
  119        * information. API's built on top of this interface may want to provide
  120        * finer grained access control to the contents of individual
  121        * instrumentation objects contained within the buffer.
  122        * <p>
  123        * Please note that the <em>"sun.misc.Perf.getPerf"</em> permission
  124        * is not a JDK specified permission.
  125        *
  126        * @return       A reference to the singleton Perf instance.
  127        * @throws AccessControlException  if a security manager exists and
  128        *               its <code>checkPermission</code> method doesn't allow
  129        *               access to the <em>"sun.misc.Perf.getPerf"</em> target.
  130        * @see  java.lang.RuntimePermission
  131        * @see  #attach
  132        */
  133       public static Perf getPerf()
  134       {
  135           SecurityManager security = System.getSecurityManager();
  136           if (security != null) {
  137               Permission perm = new RuntimePermission("sun.misc.Perf.getPerf");
  138               security.checkPermission(perm);
  139           }
  140   
  141           return instance;
  142       }
  143   
  144       /**
  145        * Attach to the instrumentation buffer for the specified Java virtual
  146        * machine.
  147        * <p>
  148        * This method will attach to the instrumentation buffer for the
  149        * specified virtual machine. It returns a <code>ByteBuffer</code> object
  150        * that is initialized to access the instrumentation buffer for the
  151        * indicated Java virtual machine. The <code>lvmid</code> parameter is
  152        * a integer value that uniquely identifies the target local Java virtual
  153        * machine. It is typically, but not necessarily, the process id of
  154        * the target Java virtual machine.
  155        * <p>
  156        * If the <code>lvmid</code> identifies a Java virtual machine different
  157        * from the one running this method, then the coherency characteristics
  158        * of the buffer are implementation dependent. Implementations that do
  159        * not support named, coherent, shared memory may return a
  160        * <code>ByteBuffer</code> object that contains only a snap shot of the
  161        * data in the instrumentation buffer. Implementations that support named,
  162        * coherent, shared memory, may return a <code>ByteBuffer</code> object
  163        * that will be changing dynamically over time as the target Java virtual
  164        * machine updates its mapping of this buffer.
  165        * <p>
  166        * If the <code>lvmid</code> is 0 or equal to the actual <code>lvmid</code>
  167        * for the Java virtual machine running this method, then the returned
  168        * <code>ByteBuffer</code> object will always be coherent and dynamically
  169        * changing.
  170        * <p>
  171        * The attach mode specifies the access permissions requested for the
  172        * instrumentation buffer of the target virtual machine. The permitted
  173        * access permissions are:
  174        * <p>
  175        * <bl>
  176        * <li>"r"  - Read only access. This Java virtual machine has only
  177        * read access to the instrumentation buffer for the target Java
  178        * virtual machine.
  179        * <li>"rw"  - Read/Write access. This Java virtual machine has read and
  180        * write access to the instrumentation buffer for the target Java virtual
  181        * machine. This mode is currently not supported and is reserved for
  182        * future enhancements.
  183        * </bl>
  184        *
  185        * @param   lvmid            an integer that uniquely identifies the
  186        *                           target local Java virtual machine.
  187        * @param   mode             a string indicating the attach mode.
  188        * @return  ByteBuffer       a direct allocated byte buffer
  189        * @throws  IllegalArgumentException  The lvmid or mode was invalid.
  190        * @throws  IOException      An I/O error occurred while trying to acquire
  191        *                           the instrumentation buffer.
  192        * @throws  OutOfMemoryError The instrumentation buffer could not be mapped
  193        *                           into the virtual machine's address space.
  194        * @see     java.nio.ByteBuffer
  195        */
  196       public ByteBuffer attach(int lvmid, String mode)
  197              throws IllegalArgumentException, IOException
  198       {
  199           if (mode.compareTo("r") == 0) {
  200               return attachImpl(null, lvmid, PERF_MODE_RO);
  201           }
  202           else if (mode.compareTo("rw") == 0) {
  203               return attachImpl(null, lvmid, PERF_MODE_RW);
  204           }
  205           else {
  206               throw new IllegalArgumentException("unknown mode");
  207           }
  208       }
  209   
  210       /**
  211        * Attach to the instrumentation buffer for the specified Java virtual
  212        * machine owned by the given user.
  213        * <p>
  214        * This method behaves just as the <code>attach(int lvmid, String mode)
  215        * </code> method, except that it only searches for Java virtual machines
  216        * owned by the specified user.
  217        *
  218        * @param   user             A <code>String</code> object containing the
  219        *                           name of the user that owns the target Java
  220        *                           virtual machine.
  221        * @param   lvmid            an integer that uniquely identifies the
  222        *                           target local Java virtual machine.
  223        * @param   mode             a string indicating the attach mode.
  224        * @return  ByteBuffer       a direct allocated byte buffer
  225        * @throws  IllegalArgumentException  The lvmid or mode was invalid.
  226        * @throws  IOException      An I/O error occurred while trying to acquire
  227        *                           the instrumentation buffer.
  228        * @throws  OutOfMemoryError The instrumentation buffer could not be mapped
  229        *                           into the virtual machine's address space.
  230        * @see     java.nio.ByteBuffer
  231        */
  232       public ByteBuffer attach(String user, int lvmid, String mode)
  233              throws IllegalArgumentException, IOException
  234       {
  235           if (mode.compareTo("r") == 0) {
  236               return attachImpl(user, lvmid, PERF_MODE_RO);
  237           }
  238           else if (mode.compareTo("rw") == 0) {
  239               return attachImpl(user, lvmid, PERF_MODE_RW);
  240           }
  241           else {
  242               throw new IllegalArgumentException("unknown mode");
  243           }
  244       }
  245   
  246       /**
  247        * Call the implementation specific attach method.
  248        * <p>
  249        * This method calls into the Java virtual machine to perform the platform
  250        * specific attach method. Buffers returned from this method are
  251        * internally managed as <code>PhantomRefereces</code> to provide for
  252        * guaranteed, secure release of the native resources.
  253        *
  254        * @param   user             A <code>String</code> object containing the
  255        *                           name of the user that owns the target Java
  256        *                           virtual machine.
  257        * @param   lvmid            an integer that uniquely identifies the
  258        *                           target local Java virtual machine.
  259        * @param   mode             a string indicating the attach mode.
  260        * @return  ByteBuffer       a direct allocated byte buffer
  261        * @throws  IllegalArgumentException  The lvmid or mode was invalid.
  262        * @throws  IOException      An I/O error occurred while trying to acquire
  263        *                           the instrumentation buffer.
  264        * @throws  OutOfMemoryError The instrumentation buffer could not be mapped
  265        *                           into the virtual machine's address space.
  266        */
  267       private ByteBuffer attachImpl(String user, int lvmid, int mode)
  268               throws IllegalArgumentException, IOException
  269       {
  270           final ByteBuffer b = attach(user, lvmid, mode);
  271   
  272           if (lvmid == 0) {
  273               // The native instrumentation buffer for this Java virtual
  274               // machine is never unmapped.
  275               return b;
  276           }
  277           else {
  278               // This is an instrumentation buffer for another Java virtual
  279               // machine with native resources that need to be managed. We
  280               // create a duplicate of the native ByteBuffer and manage it
  281               // with a Cleaner object (PhantomReference). When the duplicate
  282               // becomes only phantomly reachable, the native resources will
  283               // be released.
  284   
  285               final ByteBuffer dup = b.duplicate();
  286               Cleaner.create(dup, new Runnable() {
  287                       public void run() {
  288                           try {
  289                               instance.detach(b);
  290                           }
  291                           catch (Throwable th) {
  292                               // avoid crashing the reference handler thread,
  293                               // but provide for some diagnosability
  294                               assert false : th.toString();
  295                           }
  296                       }
  297                   });
  298               return dup;
  299           }
  300       }
  301   
  302       /**
  303        * Native method to perform the implementation specific attach mechanism.
  304        * <p>
  305        * The implementation of this method may return distinct or identical
  306        * <code>ByteBuffer</code> objects for two distinct calls requesting
  307        * attachment to the same Java virtual machine.
  308        * <p>
  309        * For the Sun HotSpot JVM, two distinct calls to attach to the same
  310        * target Java virtual machine will result in two distinct ByteBuffer
  311        * objects returned by this method. This may change in a future release.
  312        *
  313        * @param   user             A <code>String</code> object containing the
  314        *                           name of the user that owns the target Java
  315        *                           virtual machine.
  316        * @param   lvmid            an integer that uniquely identifies the
  317        *                           target local Java virtual machine.
  318        * @param   mode             a string indicating the attach mode.
  319        * @return  ByteBuffer       a direct allocated byte buffer
  320        * @throws  IllegalArgumentException  The lvmid or mode was invalid.
  321        * @throws  IOException      An I/O error occurred while trying to acquire
  322        *                           the instrumentation buffer.
  323        * @throws  OutOfMemoryError The instrumentation buffer could not be mapped
  324        *                           into the virtual machine's address space.
  325        */
  326       private native ByteBuffer attach(String user, int lvmid, int mode)
  327                      throws IllegalArgumentException, IOException;
  328   
  329       /**
  330        * Native method to perform the implementation specific detach mechanism.
  331        * <p>
  332        * If this method is passed a <code>ByteBuffer</code> object that is
  333        * not created by the <code>attach</code> method, then the results of
  334        * this method are undefined, with unpredictable and potentially damaging
  335        * effects to the Java virtual machine. To prevent accidental or malicious
  336        * use of this method, all native ByteBuffer created by the <code>
  337        * attach</code> method are managed internally as PhantomReferences
  338        * and resources are freed by the system.
  339        * <p>
  340        * If this method is passed a <code>ByteBuffer</code> object created
  341        * by the <code>attach</code> method with a lvmid for the Java virtual
  342        * machine running this method (lvmid=0, for example), then the detach
  343        * request is silently ignored.
  344        *
  345        * @param ByteBuffer  A direct allocated byte buffer created by the
  346        *                    <code>attach</code> method.
  347        * @see   java.nio.ByteBuffer
  348        * @see   #attach
  349        */
  350       private native void detach(ByteBuffer bb);
  351   
  352       /**
  353        * Create a <code>long</code> scalar entry in the instrumentation buffer
  354        * with the given variability characteristic, units, and initial value.
  355        * <p>
  356        * Access to the instrument is provided through the returned <code>
  357        * ByteBuffer</code> object. Typically, this object should be wrapped
  358        * with <code>LongBuffer</code> view object.
  359        *
  360        * @param   variability the variability characteristic for this entry.
  361        * @param   units       the units for this entry.
  362        * @param   name        the name of this entry.
  363        * @param   value       the initial value for this entry.
  364        * @return  ByteBuffer  a direct allocated ByteBuffer object that
  365        *                      allows write access to a native memory location
  366        *                      containing a <code>long</code> value.
  367        *
  368        * see sun.misc.perf.Variability
  369        * see sun.misc.perf.Units
  370        * @see java.nio.ByteBuffer
  371        */
  372       public native ByteBuffer createLong(String name, int variability,
  373                                           int units, long value);
  374   
  375       /**
  376        * Create a <code>String</code> entry in the instrumentation buffer with
  377        * the given variability characteristic, units, and initial value.
  378        * <p>
  379        * The maximum length of the <code>String</code> stored in this string
  380        * instrument is given in by <code>maxLength</code> parameter. Updates
  381        * to this instrument with <code>String</code> values with lengths greater
  382        * than <code>maxLength</code> will be truncated to <code>maxLength</code>.
  383        * The truncated value will be terminated by a null character.
  384        * <p>
  385        * The underlying implementation may further limit the length of the
  386        * value, but will continue to preserve the null terminator.
  387        * <p>
  388        * Access to the instrument is provided through the returned <code>
  389        * ByteBuffer</code> object.
  390        *
  391        * @param   variability the variability characteristic for this entry.
  392        * @param   units       the units for this entry.
  393        * @param   name        the name of this entry.
  394        * @param   value       the initial value for this entry.
  395        * @param   maxLength   the maximum string length for this string
  396        *                      instrument.
  397        * @return  ByteBuffer  a direct allocated ByteBuffer that allows
  398        *                      write access to a native memory location
  399        *                      containing a <code>long</code> value.
  400        *
  401        * see sun.misc.perf.Variability
  402        * see sun.misc.perf.Units
  403        * @see java.nio.ByteBuffer
  404        */
  405       public ByteBuffer createString(String name, int variability,
  406                                      int units, String value, int maxLength)
  407       {
  408           byte[] v = getBytes(value);
  409           byte[] v1 = new byte[v.length+1];
  410           System.arraycopy(v, 0, v1, 0, v.length);
  411           v1[v.length] = '\0';
  412           return createByteArray(name, variability, units, v1, Math.max(v1.length, maxLength));
  413       }
  414   
  415       /**
  416        * Create a <code>String</code> entry in the instrumentation buffer with
  417        * the given variability characteristic, units, and initial value.
  418        * <p>
  419        * The maximum length of the <code>String</code> stored in this string
  420        * instrument is implied by the length of the <code>value</code> parameter.
  421        * Subsequent updates to the value of this instrument will be truncated
  422        * to this implied maximum length. The truncated value will be terminated
  423        * by a null character.
  424        * <p>
  425        * The underlying implementation may further limit the length of the
  426        * initial or subsequent value, but will continue to preserve the null
  427        * terminator.
  428        * <p>
  429        * Access to the instrument is provided through the returned <code>
  430        * ByteBuffer</code> object.
  431        *
  432        * @param   variability the variability characteristic for this entry.
  433        * @param   units       the units for this entry.
  434        * @param   name        the name of this entry.
  435        * @param   value       the initial value for this entry.
  436        * @return  ByteBuffer  a direct allocated ByteBuffer that allows
  437        *                      write access to a native memory location
  438        *                      containing a <code>long</code> value.
  439        *
  440        * see sun.misc.perf.Variability
  441        * see sun.misc.perf.Units
  442        * @see java.nio.ByteBuffer
  443        */
  444       public ByteBuffer createString(String name, int variability,
  445                                      int units, String value)
  446       {
  447           byte[] v = getBytes(value);
  448           byte[] v1 = new byte[v.length+1];
  449           System.arraycopy(v, 0, v1, 0, v.length);
  450           v1[v.length] = '\0';
  451           return createByteArray(name, variability, units, v1, v1.length);
  452       }
  453   
  454       /**
  455        * Create a <code>byte</code> vector entry in the instrumentation buffer
  456        * with the given variability characteristic, units, and initial value.
  457        * <p>
  458        * The <code>maxLength</code> parameter limits the size of the byte
  459        * array instrument such that the initial or subsequent updates beyond
  460        * this length are silently ignored. No special handling of truncated
  461        * updates is provided.
  462        * <p>
  463        * The underlying implementation may further limit the length of the
  464        * length of the initial or subsequent value.
  465        * <p>
  466        * Access to the instrument is provided through the returned <code>
  467        * ByteBuffer</code> object.
  468        *
  469        * @param   variability the variability characteristic for this entry.
  470        * @param   units       the units for this entry.
  471        * @param   name        the name of this entry.
  472        * @param   value       the initial value for this entry.
  473        * @param   maxLength   the maximum length of this byte array.
  474        * @return  ByteBuffer  a direct allocated byte buffer that allows
  475        *                      write access to a native memory location
  476        *                      containing a <code>long</code> value.
  477        *
  478        * see sun.misc.perf.Variability
  479        * see sun.misc.perf.Units
  480        * @see java.nio.ByteBuffer
  481        */
  482       public native ByteBuffer createByteArray(String name, int variability,
  483                                                int units, byte[] value,
  484                                                int maxLength);
  485   
  486   
  487       /**
  488        * convert string to an array of UTF-8 bytes
  489        */
  490       private static byte[] getBytes(String s)
  491       {
  492           byte[] bytes = null;
  493   
  494           try {
  495               bytes = s.getBytes("UTF-8");
  496           }
  497           catch (UnsupportedEncodingException e) {
  498               // ignore, UTF-8 encoding is always known
  499           }
  500   
  501           return bytes;
  502       }
  503   
  504       /**
  505        * Return the value of the High Resolution Counter.
  506        *
  507        * The High Resolution Counter returns the number of ticks since
  508        * since the start of the Java virtual machine. The resolution of
  509        * the counter is machine dependent and can be determined from the
  510        * value return by the {@link #highResFrequency} method.
  511        *
  512        * @return  the number of ticks of machine dependent resolution since
  513        *          the start of the Java virtual machine.
  514        *
  515        * @see #highResFrequency
  516        * @see java.lang.System#currentTimeMillis()
  517        */
  518       public native long highResCounter();
  519   
  520       /**
  521        * Returns the frequency of the High Resolution Counter, in ticks per
  522        * second.
  523        *
  524        * This value can be used to convert the value of the High Resolution
  525        * Counter, as returned from a call to the {@link #highResCounter} method,
  526        * into the number of seconds since the start of the Java virtual machine.
  527        *
  528        * @return  the frequency of the High Resolution Counter.
  529        * @see #highResCounter
  530        */
  531       public native long highResFrequency();
  532   
  533       private static native void registerNatives();
  534   
  535       static {
  536           registerNatives();
  537           instance = new Perf();
  538       }
  539   }

Save This Page
Home » openjdk-7 » sun » misc » [javadoc | source]