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 }