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.generational.immix;
014    
015    import static org.mmtk.policy.immix.ImmixConstants.MARK_LINE_AT_SCAN_TIME;
016    
017    import org.mmtk.plan.generational.GenCollector;
018    import org.mmtk.plan.generational.GenMatureTraceLocal;
019    import org.mmtk.plan.Trace;
020    import org.mmtk.policy.Space;
021    
022    import org.vmmagic.unboxed.*;
023    import org.vmmagic.pragma.*;
024    
025    /**
026     * This class implements the core functionality for a transitive
027     * closure over the heap graph, specifically in a generational immix
028     * collector.
029     */
030    @Uninterruptible
031    public final class GenImmixMatureTraceLocal extends GenMatureTraceLocal{
032    
033      /**
034       * Constructor
035       */
036      public GenImmixMatureTraceLocal(Trace global, GenCollector plan) {
037        super(GenImmix.SCAN_IMMIX, global, plan);
038      }
039    
040      /**
041       * This method is the core method during the trace of the object graph.
042       * The role of this method is to:
043       *
044       * 1. Ensure the traced object is not collected.
045       * 2. If this is the first visit to the object enqueue it to be scanned.
046       * 3. Return the forwarded reference to the object.
047       *
048       * @param object The object to be traced.
049       * @return The new reference to the same object instance.
050       */
051      @Inline
052      public ObjectReference traceObject(ObjectReference object) {
053        if (object.isNull()) return object;
054    
055        if (Space.isInSpace(GenImmix.IMMIX, object)) {
056          return GenImmix.immixSpace.fastTraceObject(this, object);
057        }
058        return super.traceObject(object);
059      }
060    
061      /**
062       * Is the specified object live?
063       *
064       * @param object The object.
065       * @return True if the object is live.
066       */
067      public boolean isLive(ObjectReference object) {
068        if (object.isNull()) return false;
069        if (Space.isInSpace(GenImmix.IMMIX, object)) {
070          return GenImmix.immixSpace.isLive(object);
071        }
072        return super.isLive(object);
073      }
074    
075      /**
076       * Return true if this object is guaranteed not to move during this
077       * collection (i.e. this object is defintely not an unforwarded
078       * object).
079       *
080       * @param object
081       * @return True if this object is guaranteed not to move during this
082       *         collection.
083       */
084      @Override
085      public boolean willNotMoveInCurrentCollection(ObjectReference object) {
086        if (Space.isInSpace(GenImmix.IMMIX, object)) {
087          return true;
088        }
089        return super.willNotMoveInCurrentCollection(object);
090      }
091    
092      /**
093       * Collectors that move objects <b>must</b> override this method.
094       * It performs the deferred scanning of objects which are forwarded
095       * during bootstrap of each copying collection.  Because of the
096       * complexities of the collection bootstrap (such objects are
097       * generally themselves gc-critical), the forwarding and scanning of
098       * the objects must be dislocated.  It is an error for a non-moving
099       * collector to call this method.
100       *
101       * @param object The forwarded object to be scanned
102       */
103      @Inline
104      @Override
105      protected void scanObject(ObjectReference object) {
106        super.scanObject(object);
107        if (MARK_LINE_AT_SCAN_TIME && Space.isInSpace(GenImmix.IMMIX, object))
108          GenImmix.immixSpace.markLines(object);
109      }
110    }