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.utility.gcspy.drivers;
014
015import static org.mmtk.utility.gcspy.StreamConstants.PAINT_STYLE_ZERO;
016import static org.mmtk.utility.gcspy.StreamConstants.PRESENTATION_PLUS;
017
018import org.mmtk.policy.Space;
019import org.mmtk.utility.Log;
020import org.mmtk.utility.gcspy.Color;
021import org.mmtk.vm.VM;
022import org.mmtk.vm.gcspy.ServerInterpreter;
023import org.mmtk.vm.gcspy.ShortStream;
024import org.vmmagic.pragma.Interruptible;
025import org.vmmagic.pragma.Uninterruptible;
026import org.vmmagic.unboxed.Address;
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
089
090  @Interruptible
091  private ShortStream createRemsetStream() {
092    return VM.newGCspyShortStream(
093                     this,
094                     "Remembered set stream",
095                     (short)0,
096                     // Say, typical size = 4 * typical scalar size?
097                     (short)(maxObjectsPerBlock(blockSize) / 8),
098                     (short)0,
099                     (short)0,
100                     "Remset references: ",
101                     " references",
102                     PRESENTATION_PLUS,
103                     PAINT_STYLE_ZERO,
104                     0,
105                     Color.Cyan,
106                     true);
107  }
108
109  /**
110   * Setup summaries part of the <code>transmit</code> method.<p>
111   * Overrides method in superclass to handle additional Stream.
112  */
113  @Override
114  protected void setupSummaries() {
115    super.setupSummaries();
116    remsetStream.setSummary(totalRemset);
117  }
118
119  /**
120   * Handle a remset address
121   *
122   * @param addr Remset Address
123   * @return {@code true} if the given Address is in this subspace.
124   */
125  public boolean handleRemsetAddress(Address addr) {
126    if (subspace.addressInRange(addr)) {
127      // increment tile
128      int index = subspace.getIndex(addr);
129      remsetStream.increment(index, (short)1);
130      // increment summary
131      totalRemset++;
132      return true;
133    } else {
134      return false;
135    }
136  }
137
138  /**
139   * Reset the remset Stream
140   * The remset Stream has to be reset seperately because we do not
141   * gather data in the usual way using scan().
142   */
143  public void resetRemsetStream() {
144    remsetStream.resetData();
145    totalRemset = 0;
146  }
147
148}