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.adaptive.measurements.instrumentation;
014    
015    import org.jikesrvm.adaptive.database.AOSDatabase;
016    import org.jikesrvm.adaptive.measurements.RuntimeMeasurements;
017    import org.jikesrvm.adaptive.util.AOSOptions;
018    import org.jikesrvm.compilers.opt.InstrumentedEventCounterManager;
019    
020    /**
021     * This class is used to provide general functionality useful to
022     * instrumenting methods.
023     */
024    public final class Instrumentation {
025    
026      /**
027       * A pointer to a InstrumentedEventCounterManager, (See
028       * InstrumentedEventCounterManager.java for the idea behind a
029       * counter manager) There can be multiple managers in use at the
030       * same time (for example, one per method)., but for now we just use
031       * one for everything.
032       **/
033      public static InstrumentedEventCounterManager eventCounterManager;
034    
035      /**
036       * Called at boot time
037       **/
038      public static void boot(AOSOptions options) {
039    
040        // If the system may perform any instrumentation that uses managed
041        // event counters, initialize a counter manager here.
042        if (options
043            .INSERT_INSTRUCTION_COUNTERS ||
044                                         options
045                                             .INSERT_METHOD_COUNTERS_OPT ||
046                                                                         options
047                                                                             .INSERT_YIELDPOINT_COUNTERS ||
048                                                                                                         options
049                                                                                                             .INSERT_DEBUGGING_COUNTERS) {
050          eventCounterManager = new CounterArrayManager();
051        }
052    
053        // If inserting method counters, initialize the counter space for
054        // the invocation counters, using the eventCounterManager from above.
055        if (options.INSERT_METHOD_COUNTERS_OPT) {
056          AOSDatabase.methodInvocationCounterData = new MethodInvocationCounterData(eventCounterManager);
057    
058          // Method Counters have only one array of counters for the whole
059          // program, so initialize it here. Make it automatically double
060          // in size when needed.
061          AOSDatabase.methodInvocationCounterData.
062              automaticallyGrowCounters(true);
063    
064          // Report at end
065          RuntimeMeasurements.
066              registerReportableObject(AOSDatabase.methodInvocationCounterData);
067        }
068    
069        /**
070         * If collecting yieldpoint counts, initialize the
071         * data here.
072         **/
073        if (options.INSERT_YIELDPOINT_COUNTERS) {
074          // Create it here, because we need only one array of numbers,
075          // not one per method.
076          AOSDatabase.yieldpointCounterData = new YieldpointCounterData(eventCounterManager);
077    
078          // We want to report everything at the end.
079          RuntimeMeasurements.
080              registerReportableObject(AOSDatabase.yieldpointCounterData);
081    
082        }
083    
084        /**
085         * If collecting instruction counts, initialize the
086         * data here.
087         **/
088        if (options.INSERT_INSTRUCTION_COUNTERS) {
089          AOSDatabase.instructionCounterData = new StringEventCounterData(eventCounterManager, "Instruction Counter");
090          AOSDatabase.instructionCounterData.automaticallyGrowCounters(true);
091    
092          // We want to report everything at the end.
093          RuntimeMeasurements.
094              registerReportableObject(AOSDatabase.instructionCounterData);
095        }
096    
097        /**
098         * If collecting instruction counts, initialize the
099         * data here.
100         **/
101        if (options.INSERT_DEBUGGING_COUNTERS) {
102          AOSDatabase.debuggingCounterData = new StringEventCounterData(eventCounterManager, "Debugging Counters");
103          AOSDatabase.debuggingCounterData.automaticallyGrowCounters(true);
104    
105          // We want to report everything at the end.
106          RuntimeMeasurements.
107              registerReportableObject(AOSDatabase.debuggingCounterData);
108        }
109    
110      }
111    
112      /**
113       * Calling this routine causes all future compilations not to insert
114       * instrumentation, regardless of what the options say.  Used during
115       * system shutdown.  Note, this method will not stop instrumentation
116       * in currently compiled methods from executing.
117       */
118      static void disableInstrumentation() {
119        instrumentationEnabled = false;
120      }
121    
122      /**
123       * Enable instrumentations, so that future compilations will not
124       * perform any instrumentation.
125       */
126      static void enableInstrumentation() {
127        instrumentationEnabled = true;
128      }
129    
130      /**
131       * Is it currently O.K. to compile a method and insert instrumentation?
132       */
133      public static boolean instrumentationEnabled() {
134        return instrumentationEnabled;
135      }
136    
137      private static boolean instrumentationEnabled = true;
138    }