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;
014    
015    import org.mmtk.plan.TraceLocal;
016    import org.mmtk.plan.Trace;
017    import org.mmtk.utility.HeaderByte;
018    import org.mmtk.utility.deque.*;
019    import org.mmtk.vm.VM;
020    
021    import org.vmmagic.pragma.*;
022    import org.vmmagic.unboxed.*;
023    
024    /**
025     * This class implements the core functionality for a transitive
026     * closure over the heap graph.
027     */
028    @Uninterruptible
029    public final class GenNurseryTraceLocal extends TraceLocal {
030    
031      /****************************************************************************
032       *
033       * Instance fields.
034       */
035    
036      /**
037       *
038       */
039      private final ObjectReferenceDeque modbuf;
040      private final AddressDeque remset;
041      private final AddressPairDeque arrayRemset;
042    
043      /**
044       * Constructor
045       */
046      public GenNurseryTraceLocal(Trace trace, GenCollector plan) {
047        super(Gen.SCAN_NURSERY, trace);
048        this.modbuf = plan.modbuf;
049        this.remset = plan.remset;
050        this.arrayRemset = plan.arrayRemset;
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 (Gen.inNursery(object)) {
065          return Gen.nurserySpace.isLive(object);
066        }
067        if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(super.isLive(object));
068        return true;
069      }
070    
071      @Override
072      @Inline
073      public ObjectReference traceObject(ObjectReference object) {
074        if (Gen.inNursery(object)) {
075          return Gen.nurserySpace.traceObject(this, object, Gen.ALLOC_MATURE_MINORGC);
076        }
077        return object;
078      }
079    
080      /**
081       * Process any remembered set entries.
082       */
083      @Override
084      @Inline
085      protected void processRememberedSets() {
086        logMessage(5, "processing modbuf");
087        ObjectReference obj;
088        while (!(obj = modbuf.pop()).isNull()) {
089          if (VM.DEBUG) VM.debugging.modbufEntry(obj);
090          HeaderByte.markAsUnlogged(obj);
091          scanObject(obj);
092        }
093        logMessage(5, "processing remset");
094        while (!remset.isEmpty()) {
095          Address loc = remset.pop();
096          if (VM.DEBUG) VM.debugging.remsetEntry(loc);
097          processRootEdge(loc, false);
098        }
099        logMessage(5, "processing array remset");
100        arrayRemset.flushLocal();
101        while (!arrayRemset.isEmpty()) {
102          Address start = arrayRemset.pop1();
103          Address guard = arrayRemset.pop2();
104          if (VM.DEBUG) VM.debugging.arrayRemsetEntry(start,guard);
105          while (start.LT(guard)) {
106            processRootEdge(start, false);
107            start = start.plus(BYTES_IN_ADDRESS);
108          }
109        }
110      }
111    
112      /**
113       * Will the object move from now on during the collection.
114       *
115       * @param object The object to query.
116       * @return {@code true} if the object is guaranteed not to move.
117       */
118      @Override
119      public boolean willNotMoveInCurrentCollection(ObjectReference object) {
120        if (object.isNull()) return false;
121        return !Gen.inNursery(object);
122      }
123    
124    }