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.stickyimmix;
014
015 import static org.mmtk.policy.immix.ImmixConstants.MARK_LINE_AT_SCAN_TIME;
016 import static org.mmtk.policy.immix.ImmixConstants.PREFER_COPY_ON_NURSERY_GC;
017
018 import org.mmtk.plan.TraceLocal;
019 import org.mmtk.plan.Trace;
020 import org.mmtk.policy.Space;
021 import org.mmtk.utility.HeaderByte;
022 import org.mmtk.utility.deque.ObjectReferenceDeque;
023 import org.mmtk.vm.VM;
024
025 import org.vmmagic.pragma.*;
026 import org.vmmagic.unboxed.*;
027
028 /**
029 * This class implements the thread-local functionality for a transitive
030 * closure over a sticky-immix space.
031 */
032 @Uninterruptible
033 public final class StickyImmixNurseryTraceLocal extends TraceLocal {
034
035 /****************************************************************************
036 *
037 * Instance fields.
038 */
039
040 /**
041 *
042 */
043 private final ObjectReferenceDeque modBuffer;
044
045 /**
046 * Constructor
047 */
048 public StickyImmixNurseryTraceLocal(Trace trace, ObjectReferenceDeque modBuffer) {
049 super(StickyImmix.SCAN_NURSERY, trace);
050 this.modBuffer = modBuffer;
051 }
052
053 /****************************************************************************
054 *
055 * Externally visible Object processing and tracing
056 */
057
058 /**
059 * {@inheritDoc}
060 */
061 @Override
062 public boolean isLive(ObjectReference object) {
063 if (object.isNull()) return false;
064 if (Space.isInSpace(StickyImmix.IMMIX, object))
065 return PREFER_COPY_ON_NURSERY_GC ? StickyImmix.immixSpace.copyNurseryIsLive(object) : StickyImmix.immixSpace.fastIsLive(object);
066 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(super.isLive(object));
067 return true;
068 }
069
070 @Override
071 @Inline
072 public ObjectReference traceObject(ObjectReference object) {
073 if (object.isNull()) return object;
074 if (Space.isInSpace(StickyImmix.IMMIX, object))
075 return StickyImmix.immixSpace.nurseryTraceObject(this, object, StickyImmix.ALLOC_DEFAULT);
076 else
077 return object;
078 }
079
080 /**
081 * Return {@code true} if this object is guaranteed not to move during this
082 * collection (i.e. this object is definitely not an unforwarded
083 * object).
084 *
085 * @param object
086 * @return {@code true} if this object is guaranteed not to move during this
087 * collection.
088 */
089 @Override
090 public boolean willNotMoveInCurrentCollection(ObjectReference object) {
091 if (Space.isInSpace(StickyImmix.IMMIX, object)) {
092 if (!PREFER_COPY_ON_NURSERY_GC)
093 return true;
094 else
095 return StickyImmix.immixSpace.willNotMoveThisNurseryGC(object);
096 }
097 return super.willNotMoveInCurrentCollection(object);
098 }
099
100 @Inline
101 @Override
102 protected void scanObject(ObjectReference object) {
103 super.scanObject(object);
104 if (MARK_LINE_AT_SCAN_TIME && Space.isInSpace(StickyImmix.IMMIX, object))
105 StickyImmix.immixSpace.markLines(object);
106 }
107
108 /**
109 * Process any remembered set entries. This means enumerating the
110 * mod buffer and for each entry, marking the object as unlogged
111 * and enqueing it for scanning.
112 */
113 @Override
114 protected void processRememberedSets() {
115 logMessage(2, "processing modBuffer");
116 while (!modBuffer.isEmpty()) {
117 ObjectReference src = modBuffer.pop();
118 HeaderByte.markAsUnlogged(src);
119 processNode(src);
120 }
121 }
122 }