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    
020    import org.mmtk.vm.VM;
021    
022    import org.vmmagic.unboxed.*;
023    import org.vmmagic.pragma.*;
024    
025    /**
026     * This abstract class implements the core functionality for a transitive
027     * closure over the heap graph.
028     */
029    @Uninterruptible
030    public abstract class GenMatureTraceLocal extends TraceLocal {
031    
032      /****************************************************************************
033       *
034       * Instance fields.
035       */
036    
037      /**
038       *
039       */
040      private final ObjectReferenceDeque modbuf;
041      private final AddressDeque remset;
042      private final AddressPairDeque arrayRemset;
043    
044      /****************************************************************************
045       *
046       * Initialization
047       */
048    
049      /**
050       * Constructor
051       */
052      public GenMatureTraceLocal(int specializedScan, Trace trace, GenCollector plan) {
053        super(specializedScan, trace);
054        this.modbuf = plan.modbuf;
055        this.remset = plan.remset;
056        this.arrayRemset = plan.arrayRemset;
057      }
058    
059      /**
060       * Constructor
061       */
062      public GenMatureTraceLocal(Trace trace, GenCollector plan) {
063        super(Gen.SCAN_MATURE, trace);
064        this.modbuf = plan.modbuf;
065        this.remset = plan.remset;
066        this.arrayRemset = plan.arrayRemset;
067      }
068    
069      /****************************************************************************
070       *
071       * Object processing and tracing
072       */
073    
074      /**
075       * {@inheritDoc}
076       */
077      @Override
078      @Inline
079      public boolean isLive(ObjectReference object) {
080        if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!object.isNull());
081        if (Gen.inNursery(object)) {
082          return Gen.nurserySpace.isLive(object);
083        }
084        return super.isLive(object);
085      }
086    
087      /**
088       * Return {@code true} if this object is guaranteed not to move during this
089       * collection (i.e. this object is definitely not an unforwarded
090       * object).
091       *
092       * @param object
093       * @return {@code true} if this object is guaranteed not to move during this
094       *         collection.
095       */
096      @Override
097      public boolean willNotMoveInCurrentCollection(ObjectReference object) {
098        if (Gen.inNursery(object))
099          return false;
100        else
101          return super.willNotMoveInCurrentCollection(object);
102      }
103    
104      @Override
105      @Inline
106      public ObjectReference traceObject(ObjectReference object) {
107        if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!object.isNull());
108        if (Gen.inNursery(object))
109          return Gen.nurserySpace.traceObject(this, object, Gen.ALLOC_MATURE_MAJORGC);
110        return super.traceObject(object);
111      }
112    
113      /**
114       * Process any remembered set entries.
115       */
116      @Override
117      protected void processRememberedSets() {
118        logMessage(5, "clearing modbuf");
119        ObjectReference obj;
120        while (!(obj = modbuf.pop()).isNull()) {
121          HeaderByte.markAsUnlogged(obj);
122        }
123        logMessage(5, "clearing remset");
124        while (!remset.isEmpty()) {
125          remset.pop();
126        }
127        logMessage(5, "clearing array remset");
128        while (!arrayRemset.isEmpty()) {
129          arrayRemset.pop1();
130          arrayRemset.pop2();
131        }
132      }
133    
134    }