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