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