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.mmtk.vm.gcspy;
014    
015    import org.mmtk.utility.Log;
016    import org.mmtk.utility.gcspy.Color;
017    import org.mmtk.utility.gcspy.StreamConstants;
018    import org.mmtk.utility.gcspy.drivers.AbstractDriver;
019    import org.mmtk.vm.VM;
020    import org.vmmagic.pragma.*;
021    import org.vmmagic.unboxed.Address;
022    
023    /**
024     *
025     * Abstract class for a GCspy Stream.
026     * Implementing classes will mostly forward calls
027     * to the gcspy C library
028     */
029    
030    @Uninterruptible public abstract class Stream {
031    
032      /****************************************************************************
033      *
034      * Instance variables
035      */
036    
037      /**
038       * The address of the C stream, gcspy_gc_stream_t *stream, used in all calls
039       * to the C library
040       */
041      protected Address stream;
042    
043      /** The owning GCspy space */
044      protected ServerSpace serverSpace;
045    
046      /** The stream's ID */
047      protected int streamId;
048    
049      /**
050       * A summary has 1 or 2 values depending on presentation style
051       * (PERCENT* styles require 2 values).
052       */
053      protected int summaryLen;
054    
055      /** The first summary value */
056      protected int summary0;
057    
058      /** The second summary value (if any) */
059      protected int summary1;
060    
061      /** The minimum value for tiles */
062      private int min;
063    
064      /** The maximum value for tiles */
065      private int max;
066    
067      /** use summaries? */
068      protected boolean summaryEnabled;
069    
070      /** the presentation style */
071      protected int presentation;
072    
073      protected static final boolean DEBUG = false;
074    
075      /**
076       * Construct a new GCspy stream.
077       *
078       * @param driver The AbstractDriver that owns this Stream
079       * @param dataType The stream's data type, one of BYTE_TYPE, SHORT_TYPE or INT_TYPE
080       * @param name The name of the stream (e.g. "Used space")
081       * @param minValue The minimum value for any item in this stream. Values less than
082       *                 this will be represented as "minValue-"
083       * @param maxValue The maximum value for any item in this stream. Values greater than
084       *                 this will be represented as "maxValue+"
085       * @param zeroValue The zero value for this stream
086       * @param defaultValue The default value for this stream
087       * @param stringPre A string to prefix values (e.g. "Used: ")
088       * @param stringPost A string to suffix values (e.g. " bytes.")
089       * @param presentation How a stream value is to be presented.
090       * @param paintStyle How the value is to be painted.
091       * @param indexMaxStream The index for the maximum stream if the presentation is *_VAR.
092       * @param colour The default colour for tiles of this stream
093       * @param summary Is a summary enabled?
094       */
095      protected Stream(
096          AbstractDriver driver,
097          int dataType,
098          String name,
099          int minValue,
100          int maxValue,
101          int zeroValue,
102          int defaultValue,
103          String stringPre,
104          String stringPost,
105          int presentation,
106          int paintStyle,
107          int indexMaxStream,
108          Color colour,
109          boolean summary) {
110    
111        serverSpace = driver.getServerSpace();
112        summaryEnabled = summary;
113        this.presentation = presentation;
114        if (summary)
115          setupSummary(presentation);
116        min = minValue;
117        max = maxValue;
118    
119        driver.addStream(this);
120        if (DEBUG) {
121          Log.write("Adding stream ");
122          Log.write(name);
123          Log.writeln(" id=", streamId);
124        }
125      }
126    
127    
128      /**
129       * Set the stream address and id (called by AbstractDriver.addStream).
130       * @param id the id
131       * @param str the address of the gcspy C gcspy_gc_stream_t *stream
132       */
133      public void setStream(int id, Address str) {
134        streamId = id;
135        stream = str;
136      }
137    
138      /**
139       * Return the minimum value expected for this stream.
140       * @return the minimum value
141       */
142      public int getMinValue() { return min; }
143    
144      /**
145       * Return the maximum value expected for this stream.
146       * @return the maximum value
147       */
148      public int getMaxValue() { return max; }
149    
150      /**
151       * Setup the summary array.
152       * @param presentation the presentation style
153       */
154      @Interruptible
155      private void setupSummary(int presentation) {
156        switch (presentation) {
157          case StreamConstants.PRESENTATION_PLAIN:
158          case StreamConstants.PRESENTATION_PLUS:
159          case StreamConstants.PRESENTATION_MAX_VAR:
160          case StreamConstants.PRESENTATION_ENUM:
161            summaryLen = 1;
162            break;
163          case StreamConstants.PRESENTATION_PERCENT:
164          case StreamConstants.PRESENTATION_PERCENT_VAR:
165            summaryLen = 2;
166            break;
167          default:
168            VM.assertions._assert(false);
169        }
170      }
171    
172      /**
173       * Set the summary value for presentation styles with just one value
174       * @param value0 the value
175       */
176      public void setSummary(int value0) {
177        if (VM.VERIFY_ASSERTIONS)
178          VM.assertions._assert(presentation != StreamConstants.PRESENTATION_PERCENT &&
179                                presentation != StreamConstants.PRESENTATION_PERCENT_VAR);
180        summary0 = value0;
181      }
182    
183      /**
184       * Set the summary values for presentation styles with two values (i.e.
185       * PRESENTATION_PERCENT and PRESENTATION_PERCENT_VAR).
186       * @param value0 the numerator value
187       * @param value1 the denominator value
188       */
189      public void setSummary(int value0, int value1) {
190        if (VM.VERIFY_ASSERTIONS)
191          VM.assertions._assert(presentation == StreamConstants.PRESENTATION_PERCENT ||
192                                presentation == StreamConstants.PRESENTATION_PERCENT_VAR);
193        summary0 = value0;
194        summary1 = value1;
195      }
196    
197      /**
198       * Send the data for this stream.
199       * @param event the event.
200       * @param numTiles the number of tiles to send (which may be less than maxTileNum)
201    
202       */
203      public abstract void send(int event, int numTiles);
204    
205      /**
206       * Send the summary data for this stream.
207       */
208      public void sendSummary() {
209        if (summaryEnabled) {
210          serverSpace.summary(streamId, summaryLen);
211          serverSpace.summaryValue(summary0);
212          if (summaryLen == 2)
213            serverSpace.summaryValue(summary1);
214          serverSpace.summaryEnd();
215        }
216      }
217    
218    }
219    
220