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.plan.semispace;
014
015 import org.mmtk.plan.TraceLocal;
016 import org.mmtk.plan.Trace;
017 import org.mmtk.policy.Space;
018
019 import org.vmmagic.pragma.*;
020 import org.vmmagic.unboxed.*;
021
022 /**
023 * This class implments the core functionality for a transitive
024 * closure over the heap graph.
025 */
026 @Uninterruptible
027 public class SSTraceLocal extends TraceLocal {
028 /**
029 * Constructor
030 */
031 public SSTraceLocal(Trace trace, boolean specialized) {
032 super(specialized ? SS.SCAN_SS : -1, trace);
033 }
034
035 /**
036 * Constructor
037 */
038 public SSTraceLocal(Trace trace) {
039 this(trace, true);
040 }
041
042 /****************************************************************************
043 *
044 * Externally visible Object processing and tracing
045 */
046
047 /**
048 * Return true if <code>obj</code> is a live object.
049 *
050 * @param object The object in question
051 * @return True if <code>obj</code> is a live object.
052 */
053 public boolean isLive(ObjectReference object) {
054 if (object.isNull()) return false;
055 if (Space.isInSpace(SS.SS0, object))
056 return SS.hi ? SS.copySpace0.isLive(object) : true;
057 if (Space.isInSpace(SS.SS1, object))
058 return SS.hi ? true : SS.copySpace1.isLive(object);
059 return super.isLive(object);
060 }
061
062
063 /**
064 * This method is the core method during the trace of the object graph.
065 * The role of this method is to:
066 *
067 * 1. Ensure the traced object is not collected.
068 * 2. If this is the first visit to the object enqueue it to be scanned.
069 * 3. Return the forwarded reference to the object.
070 *
071 * @param object The object to be traced.
072 * @return The new reference to the same object instance.
073 */
074 @Inline
075 public ObjectReference traceObject(ObjectReference object) {
076 if (object.isNull()) return object;
077 if (Space.isInSpace(SS.SS0, object))
078 return SS.copySpace0.traceObject(this, object, SS.ALLOC_SS);
079 if (Space.isInSpace(SS.SS1, object))
080 return SS.copySpace1.traceObject(this, object, SS.ALLOC_SS);
081 return super.traceObject(object);
082 }
083
084 /**
085 * Ensure that this object will not move for the rest of the GC.
086 *
087 * @param object The object that must not move
088 * @return The new object, guaranteed stable for the rest of the GC.
089 */
090 @Inline
091 public ObjectReference precopyObject(ObjectReference object) {
092 if (object.isNull()) return object;
093 if (Space.isInSpace(SS.SS0, object))
094 return SS.copySpace0.traceObject(this, object, SS.ALLOC_SS);
095 if (Space.isInSpace(SS.SS1, object))
096 return SS.copySpace1.traceObject(this, object, SS.ALLOC_SS);
097 return object;
098 }
099
100 /**
101 * Will this object move from this point on, during the current trace ?
102 *
103 * @param object The object to query.
104 * @return True if the object will not move.
105 */
106 public boolean willNotMoveInCurrentCollection(ObjectReference object) {
107 return (SS.hi && !Space.isInSpace(SS.SS0, object)) ||
108 (!SS.hi && !Space.isInSpace(SS.SS1, object));
109 }
110 }