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.plan.TransitiveClosure; 016 import org.mmtk.policy.Space; 017 import org.mmtk.utility.Log; 018 import org.mmtk.vm.gcspy.ServerInterpreter; 019 import org.mmtk.vm.VM; 020 021 import org.vmmagic.unboxed.*; 022 import org.vmmagic.pragma.*; 023 024 /** 025 * GCspy driver for the contiguous MMTk ImmortalSpace. 026 * Adds features for the Immortal space. 027 * <p> 028 * 029 * This class extends LinearSpaceDriver, a simple driver for contiguous MMTk spaces 030 * such as CopySpace and ImmortalSpace. 031 */ 032 @Uninterruptible public class ImmortalSpaceDriver extends LinearSpaceDriver { 033 034 private static final boolean DEBUG = false; 035 036 // Instance variables 037 private AbstractDriver[] registeredDrivers; 038 private ImmortalSpaceDriver.Closure closure; 039 040 /** 041 * Create a new driver for an immortal Contiguous MMTk space. 042 * 043 * @param server The GCspy ServerInterpreter 044 * @param spaceName The name of this GCspy space 045 * @param mmtkSpace The MMTk space 046 * @param blockSize The tile size 047 * @param mainSpace Is this the main space? 048 */ 049 public ImmortalSpaceDriver( 050 ServerInterpreter server, 051 String spaceName, 052 Space mmtkSpace, 053 int blockSize, 054 boolean mainSpace) { 055 056 super(server, spaceName, mmtkSpace, blockSize, mainSpace); 057 058 if (DEBUG) { 059 Log.write("ImmortalSpaceDriver for "); Log.write(spaceName); 060 Log.write(", blocksize="); Log.write(blockSize); 061 Log.write(", start="); Log.write(mmtkSpace.getStart()); 062 Log.write(", extent="); Log.write(mmtkSpace.getExtent()); 063 Log.write(", maxTileNum="); Log.writeln(maxTileNum); 064 } 065 066 // initially no registered drivers for reference notification 067 registeredDrivers = new AbstractDriver[0]; 068 069 closure = new ImmortalSpaceDriver.Closure(); 070 } 071 072 /** 073 * Get the name of this driver type. 074 * @return The name, "MMTk ImmortalSpaceDriver" for this driver. 075 */ 076 @Override 077 protected String getDriverName() { 078 return "MMTk ImmortalSpaceDriver"; 079 } 080 081 /** 082 * Update the tile statistics. <br> 083 * This method overrides <code> scan </code> iin its superclass to 084 * add immortal space features. 085 * 086 * @param object The current object 087 * @param total Whether to accumulate the values 088 */ 089 @Override 090 public void scan(ObjectReference object, boolean total) { 091 Address addr = object.toAddress(); 092 093 if (subspace.addressInRange(addr)) { 094 VM.scanning.scanObject(closure, object); 095 super.scan(object, total); 096 } 097 } 098 099 /** 100 * Register a set of AbstractDriver instances to be notified about direct references. 101 * 102 * @param drivers The array of driver objects. 103 */ 104 public void registerDriversForReferenceNotification(AbstractDriver[] drivers) { 105 this.registeredDrivers = drivers; 106 } 107 108 /** 109 * Used to visit the edges in the immortal object. 110 */ 111 @Uninterruptible 112 private class Closure extends TransitiveClosure { 113 /** 114 * Process an edge. 115 */ 116 @Override 117 public void processEdge(ObjectReference source, Address slot) { 118 // Address in Range, locate references 119 Address target = slot.loadAddress(); 120 // notify registered drivers 121 for (int j = 0; j < registeredDrivers.length; j++) { 122 registeredDrivers[j].handleReferenceFromImmortalSpace(target); 123 } 124 } 125 } 126 }