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