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.utility.gcspy.drivers;
014    
015    import org.mmtk.policy.Space;
016    
017    import org.mmtk.utility.gcspy.Color;
018    import org.mmtk.utility.gcspy.StreamConstants;
019    import org.mmtk.vm.VM;
020    import org.mmtk.vm.gcspy.ShortStream;
021    
022    import org.mmtk.utility.Log;
023    import org.mmtk.vm.gcspy.ServerInterpreter;
024    
025    import org.vmmagic.unboxed.*;
026    import org.vmmagic.pragma.*;
027    
028    /**
029     * GCspy driver for the MMTk generational immortal space.
030     * Additional Stream for remset references.
031     * This class extends ImmortalSpaceDriver, a simple driver for
032     * the contiguous MMTk ImmortalSpace.
033     */
034    @Uninterruptible public class GenImmortalSpaceDriver extends ImmortalSpaceDriver {
035    
036      private static final boolean DEBUG = false;
037    
038      /** The Stream for newly promoted objects */
039      protected ShortStream remsetStream;
040      /** Statistics for remset references */
041      protected int totalRemset = 0;
042    
043    
044      /**
045       * Create a new driver for a generational immortal space.
046       *
047       * @param server The GCspy ServerInterpreter
048       * @param spaceName The name of this GCspy space
049       * @param mmtkSpace The MMTk space
050       * @param blockSize The tile size
051       * @param mainSpace Is this the main space?
052       */
053      public GenImmortalSpaceDriver(
054                         ServerInterpreter server,
055                         String spaceName,
056                         Space mmtkSpace,
057                         int blockSize,
058                         boolean mainSpace) {
059    
060        super(server, spaceName, mmtkSpace, blockSize, mainSpace);
061    
062        // create additional stream
063        remsetStream = createRemsetStream();
064    
065        if (DEBUG) {
066          Log.write("GenImmortalSpaceDriver for "); Log.write(spaceName);
067          Log.write(", blocksize="); Log.write(blockSize);
068          Log.write(", start="); Log.write(mmtkSpace.getStart());
069          Log.write(", extent="); Log.write(mmtkSpace.getExtent());
070          Log.write(", maxTileNum="); Log.writeln(maxTileNum);
071        }
072    
073        resetData();
074      }
075    
076      /**
077       * Get the name of this driver type.
078       * @return The name, "MMTk GenImmortalSpaceDriver" for this driver.
079       */
080      @Override
081      protected String getDriverName() {
082        return "MMTk GenImmortalSpaceDriver";
083      }
084    
085      /**
086       * Helper methods to create the additional streams
087     */
088      @Interruptible
089      private ShortStream createRemsetStream() {
090        return VM.newGCspyShortStream(
091                         this,
092                         "Remembered set stream",
093                         (short)0,
094                         // Say, typical size = 4 * typical scalar size?
095                         (short)(maxObjectsPerBlock(blockSize)/8),
096                         (short)0,
097                         (short)0,
098                         "Remset references: ",
099                         " references",
100                         StreamConstants.PRESENTATION_PLUS,
101                         StreamConstants.PAINT_STYLE_ZERO,
102                         0,
103                         Color.Cyan,
104                         true);
105      }
106    
107      /**
108       * Setup summaries part of the <code>transmit</code> method.<p>
109       * Overrides method in superclass to handle additional Stream.
110      */
111      @Override
112      protected void setupSummaries() {
113        super.setupSummaries();
114        remsetStream.setSummary(totalRemset);
115      }
116    
117      /**
118       * Handle a remset address
119       *
120       * @param addr Remset Address
121       * @return {@code true} if the given Address is in this subspace.
122       */
123      public boolean handleRemsetAddress(Address addr) {
124        if(subspace.addressInRange(addr)) {
125          // increment tile
126          int index = subspace.getIndex(addr);
127          remsetStream.increment(index, (short)1);
128          // increment summary
129          totalRemset++;
130          return true;
131        } else {
132          return false;
133        }
134      }
135    
136      /**
137       * Reset the remset Stream
138       * The remset Stream has to be reset seperately because we do not
139       * gather data in the usual way using scan().
140       */
141      public void resetRemsetStream() {
142        remsetStream.resetData();
143        totalRemset = 0;
144      }
145    
146    }