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.markcompact;
014
015 import org.mmtk.plan.TraceLocal;
016 import org.mmtk.plan.Trace;
017 import org.mmtk.policy.MarkCompactSpace;
018 import org.mmtk.policy.Space;
019 import org.mmtk.vm.VM;
020
021 import org.vmmagic.pragma.*;
022 import org.vmmagic.unboxed.*;
023
024 /**
025 * This class implments the thread-local functionality for a transitive
026 * closure over a mark-compact space during the initial marking phase.
027 */
028 @Uninterruptible
029 public final class MCMarkTraceLocal extends TraceLocal {
030 /**
031 * Constructor
032 */
033 public MCMarkTraceLocal(Trace trace) {
034 super(MC.SCAN_MARK, trace);
035 }
036
037 /****************************************************************************
038 *
039 * Externally visible Object processing and tracing
040 */
041
042 /**
043 * Is the specified object live?
044 *
045 * @param object The object.
046 * @return True if the object is live.
047 */
048 public boolean isLive(ObjectReference object) {
049 if (object.isNull()) return false;
050 if (Space.isInSpace(MC.MARK_COMPACT, object)) {
051 return MC.mcSpace.isLive(object);
052 }
053 return super.isLive(object);
054 }
055
056 /**
057 * This method is the core method during the trace of the object graph.
058 * The role of this method is to:
059 *
060 * 1. Ensure the traced object is not collected.
061 * 2. If this is the first visit to the object enqueue it to be scanned.
062 * 3. Return the forwarded reference to the object.
063 *
064 * In this instance, we refer objects in the mark-sweep space to the
065 * msSpace for tracing, and defer to the superclass for all others.
066 *
067 * @param object The object to be traced.
068 * @return The new reference to the same object instance.
069 */
070 @Inline
071 public ObjectReference traceObject(ObjectReference object) {
072 if (object.isNull()) return object;
073 if (Space.isInSpace(MC.MARK_COMPACT, object))
074 return MC.mcSpace.traceMarkObject(this, object);
075 return super.traceObject(object);
076 }
077
078 /**
079 * Ensure that this object will not move for the rest of the GC.
080 *
081 * @param object The object that must not move
082 * @return The new object, guaranteed stable for the rest of the GC.
083 */
084 @Inline
085 public ObjectReference precopyObject(ObjectReference object) {
086 if (Space.isInSpace(MC.MARK_COMPACT, object)) {
087 if (MarkCompactSpace.testAndMark(object)) {
088 // TODO: If precopy returns many different objects, this will cause a leak.
089 // Currently, Jikes RVM does not require many objects to be precopied.
090 ObjectReference newObject = VM.objectModel.copy(object, MC.ALLOC_IMMORTAL);
091 MarkCompactSpace.setForwardingPointer(object, newObject);
092 processNode(newObject);
093 return newObject;
094 }
095 // Somebody else got to it first
096 while (MarkCompactSpace.getForwardingPointer(object).isNull());
097 return MarkCompactSpace.getForwardingPointer(object);
098 }
099 return super.precopyObject(object);
100 }
101
102 /**
103 * Will this object move from this point on, during the current trace ?
104 *
105 * @param object The object to query.
106 * @return True if the object will not move.
107 */
108 public boolean willNotMoveInCurrentCollection(ObjectReference object) {
109 // All objects in the MC space may move
110 return !Space.isInSpace(MC.MARK_COMPACT, object);
111 }
112
113 }