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