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    }