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