001    /*
002     *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003     *
004     *  This file is licensed to You under the Eclipse Public License (EPL);
005     *  You may not use this file except in compliance with the License. You
006     *  may obtain a copy of the License at
007     *
008     *      http://www.opensource.org/licenses/eclipse-1.0.php
009     *
010     *  See the COPYRIGHT.txt file distributed with this work for information
011     *  regarding copyright ownership.
012     */
013    package org.jikesrvm.mm.mmtk;
014    
015    import org.mmtk.utility.Constants;
016    import org.mmtk.utility.statistics.PerfEvent;
017    import org.jikesrvm.runtime.Time;
018    import static org.jikesrvm.runtime.SysCall.sysCall;
019    
020    import org.jikesrvm.mm.mminterface.MemoryManager;
021    
022    import org.vmmagic.pragma.*;
023    
024    @Uninterruptible
025    public final class Statistics extends org.mmtk.vm.Statistics implements Constants {
026      /**
027       * Returns the number of collections that have occurred.
028       *
029       * @return The number of collections that have occurred.
030       */
031      @Uninterruptible
032      public int getCollectionCount() {
033        return MemoryManager.getCollectionCount();
034      }
035    
036      /**
037       * Read nanoTime (high resolution, monotonically increasing clock).
038       * Has same semantics as java.lang.System.nanoTime().
039       */
040      public long nanoTime() {
041        return Time.nanoTime();
042      }
043    
044      /**
045       * Read a cycle counter (high resolution, non-monotonic clock).
046       * This method should be used with care as the cycle counters (especially on IA32 SMP machines)
047       * are not a reliably time source.
048       */
049      public long cycles() {
050        return Time.cycles();
051      }
052    
053      /**
054       * Convert nanoseconds to milliseconds
055       */
056      public double nanosToMillis(long c) {
057        return ((double)c)/1e6;
058      }
059    
060      /**
061       * Convert nanoseconds to seconds
062       */
063      public double nanosToSecs(long c) {
064        return ((double)c)/1e9;
065      }
066    
067      /**
068       * Convert milliseconds to nanoseconds
069       */
070      public long millisToNanos(double t) {
071        return (long)(t * 1e6);
072      }
073    
074      /**
075       * Convert seconds to nanoseconds
076       */
077      public long secsToNanos(double t) {
078        return (long)(t * 1e9);
079      }
080    
081      private PerfEvent[] perfEvents;
082    
083      /**
084       * Initialize performance events
085       */
086      @Interruptible
087      public void perfEventInit(String events) {
088        if (events.length() == 0) {
089          // no initialization needed
090          return;
091        }
092        // initialize perf event
093        String[] perfEventNames = events.split(",");
094        int n = perfEventNames.length;
095        sysCall.sysPerfEventInit(n);
096        perfEvents = new PerfEvent[n];
097        for (int i = 0; i < n; i++) {
098          sysCall.sysPerfEventCreate(i, perfEventNames[i].getBytes());
099          perfEvents[i] = new PerfEvent(i, perfEventNames[i]);
100        }
101        sysCall.sysPerfEventEnable();
102      }
103    
104      /**
105       * Read a performance event
106       */
107      public void perfEventRead(int id, long[] values) {
108        sysCall.sysPerfEventRead(id, values);
109      }
110    }
111