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}