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.organizers;
014    
015    import org.jikesrvm.VM;
016    import org.jikesrvm.adaptive.controller.Controller;
017    import org.jikesrvm.adaptive.database.methodsamples.MethodCountData;
018    import org.jikesrvm.adaptive.measurements.RuntimeMeasurements;
019    import org.jikesrvm.adaptive.measurements.listeners.MethodListener;
020    import org.jikesrvm.adaptive.util.AOSLogging;
021    import org.jikesrvm.scheduler.RVMThread;
022    import org.vmmagic.pragma.NonMoving;
023    
024    /**
025     * An organizer for method listener information that
026     * simply accumulates the samples into a private
027     * MethodCountData instance.
028     *
029     * This organizer is used to simply gather aggregate sample data and
030     * report it.
031     */
032    @NonMoving
033    public final class AccumulatingMethodSampleOrganizer extends Organizer {
034    
035      private MethodCountData data;
036    
037      public AccumulatingMethodSampleOrganizer() {
038        makeDaemon(true);
039      }
040    
041      /**
042       * Initialization: set up data structures and sampling objects.
043       */
044      @Override
045      public void initialize() {
046        data = new MethodCountData();
047        new AsyncReporter().start();
048        int numSamples = Controller.options.METHOD_SAMPLE_SIZE * RVMThread.numProcessors;
049        if (Controller.options.mlCBS()) {
050          numSamples *= VM.CBSMethodSamplesPerTick;
051        }
052        MethodListener methodListener = new MethodListener(numSamples);
053        listener = methodListener;
054        listener.setOrganizer(this);
055        if (Controller.options.mlTimer()) {
056          RuntimeMeasurements.installTimerMethodListener(methodListener);
057        } else if (Controller.options.mlCBS()) {
058          RuntimeMeasurements.installCBSMethodListener(methodListener);
059        } else {
060          if (VM.VerifyAssertions) VM._assert(false, "Unexpected value of method_listener_trigger");
061        }
062      }
063    
064      /**
065       * Method that is called when the sampling threshold is reached
066       */
067      void thresholdReached() {
068        AOSLogging.logger.organizerThresholdReached();
069        int numSamples = ((MethodListener) listener).getNumSamples();
070        int[] samples = ((MethodListener) listener).getSamples();
071        data.update(samples, numSamples);
072      }
073    
074      public void report() {
075        VM.sysWrite("\nMethod sampler report");
076        if (data != null) data.report();
077      }
078      @NonMoving
079      class AsyncReporter extends RVMThread {
080        public AsyncReporter() {
081          super("Async Profile Reporter");
082          makeDaemon(true);
083        }
084        public void run() {
085          for (;;) {
086            RVMThread.doProfileReport.waitAndCloseWithHandshake();
087            report();
088          }
089        }
090      }
091    }
092