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 }