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