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.mmtk.vm.gcspy;
014
015import static org.mmtk.utility.gcspy.StreamConstants.SHORT_TYPE;
016
017import org.mmtk.utility.Log;
018import org.mmtk.utility.gcspy.Color;
019import org.mmtk.utility.gcspy.GCspy;
020import org.mmtk.utility.gcspy.drivers.AbstractDriver;
021import org.mmtk.vm.VM;
022import org.vmmagic.pragma.Uninterruptible;
023
024/**
025 * Set up a GCspy Stream with data type SHORT_TYPE.
026 */
027@Uninterruptible public abstract class ShortStream extends Stream {
028
029  /****************************************************************************
030   *
031   * Instance variables
032   */
033
034  /**
035   *
036   */
037  private final short[] data;         // The stream data
038  private final short defaultValue;   // The default value for the data items
039
040  /****************************************************************************
041   *
042   * Initialization
043   */
044
045  /**
046   * Construct a new GCspy stream of SHORT_TYPE
047   * @param driver          The driver that owns this Stream
048   * @param name           The name of the stream (e.g. "Used space")
049   * @param minValue       The minimum value for any item in this stream.
050   *                       Values less than this will be represented as "minValue-"
051   * @param maxValue       The maximum value for any item in this stream.
052   *                       Values greater than this will be represented as "maxValue+"
053   * @param zeroValue      The zero value for this stream
054   * @param defaultValue   The default value for this stream
055   * @param stringPre      A string to prefix values (e.g. "Used: ")
056   * @param stringPost     A string to suffix values (e.g. " bytes.")
057   * @param presentation   How a stream value is to be presented.
058   * @param paintStyle     How the value is to be painted.
059   * @param indexMaxStream The index of the maximum stream if the presentation is *_VAR.
060   * @param colour         The default colour for tiles of this stream
061   * @param summary        Is a summary enabled?
062   */
063  public ShortStream(
064         AbstractDriver driver,
065         String name,
066         short minValue,
067         short maxValue,
068         short zeroValue,
069         short defaultValue,
070         String stringPre,
071         String stringPost,
072         int presentation,
073         int paintStyle,
074         int indexMaxStream,
075         Color colour,
076         boolean summary) {
077
078    super(driver, SHORT_TYPE, name,
079          minValue, maxValue, zeroValue, defaultValue,
080          stringPre, stringPost, presentation, paintStyle,
081          indexMaxStream, colour, summary);
082
083    data = (short[])GCspy.util.createDataArray(new short[0], driver.getMaxTileNum());
084    this.defaultValue = defaultValue;
085  }
086
087  /**
088   * Reset all data in this stream to default values.
089   */
090  public void resetData() {
091    for (int i = 0; i < data.length; i++)
092      data[i] = defaultValue;
093  }
094
095
096  /**
097   * Distribute a value across a sequence of tiles. This handles the case
098   * when when an object spans two or more tiles and its value is to be
099   * attributed to each tile proportionally.
100   *
101   * @param start the index of the starting tile
102   * @param remainder the value left in the starting tile
103   * @param blockSize the size of each tile
104   * @param value the value to distribute
105   */
106  public void distribute(int start, short remainder, int blockSize, short value) {
107    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(remainder <= blockSize);
108    if (value <= remainder) {  // fits in this tile
109      data[start] += value;
110      //checkspace(start, value, "scanObject fits in first tile");
111    } else {
112      data[start] += remainder;
113      //checkspace(start, remainder, "scanObject remainder put in first tile");
114      value -= remainder;
115      start++;
116      while (value >= blockSize) {
117        data[start] += blockSize;
118        //checkspace(start, blockSize, "scanObject subsequent tile");
119        value -= blockSize;
120        start++;
121      }
122      data[start] += value;
123      //checkspace(start, value, "scanObject last tile");
124    }
125  }
126
127  /**
128   * Increment the value of a tile.
129   * @param index the index
130   * @param value the increment
131   */
132  public void increment(int index, short value) {
133    data[index] += value;
134  }
135
136  @Override
137  public void send(int event, int numTiles) {
138    if (DEBUG) {
139      Log.write("sending "); Log.write(numTiles); Log.writeln(" int values");
140    }
141    serverSpace.stream(streamId, numTiles);
142    for (int index = 0; index < numTiles; index++)
143      serverSpace.streamShortValue(data[index]);
144    serverSpace.streamEnd();
145
146    // send the summary
147    sendSummary();
148  }
149}
150