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 implments 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      private final ObjectReferenceDeque modbuf;
037      private final AddressDeque remset;
038      private final AddressPairDeque arrayRemset;
039    
040      /****************************************************************************
041       *
042       * Initialization
043       */
044    
045      /**
046       * Constructor
047       */
048      public GenMatureTraceLocal(int specializedScan, Trace trace, GenCollector plan) {
049        super(specializedScan, trace);
050        this.modbuf = plan.modbuf;
051        this.remset = plan.remset;
052        this.arrayRemset = plan.arrayRemset;
053      }
054    
055      /**
056       * Constructor
057       */
058      public GenMatureTraceLocal(Trace trace, GenCollector plan) {
059        super(Gen.SCAN_MATURE, trace);
060        this.modbuf = plan.modbuf;
061        this.remset = plan.remset;
062        this.arrayRemset = plan.arrayRemset;
063      }
064    
065      /****************************************************************************
066       *
067       * Object processing and tracing
068       */
069    
070      /**
071       * Is the specified object live?
072       *
073       * @param object The object.
074       * @return True if the object is live.
075       */
076      @Inline
077      public boolean isLive(ObjectReference object) {
078        if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!object.isNull());
079        if (Gen.inNursery(object)) {
080          return Gen.nurserySpace.isLive(object);
081        }
082        return super.isLive(object);
083      }
084    
085      /**
086       * Return true if this object is guaranteed not to move during this
087       * collection (i.e. this object is defintely not an unforwarded
088       * object).
089       *
090       * @param object
091       * @return True if this object is guaranteed not to move during this
092       *         collection.
093       */
094      public boolean willNotMoveInCurrentCollection(ObjectReference object) {
095        if (Gen.inNursery(object))
096          return false;
097        else
098          return super.willNotMoveInCurrentCollection(object);
099      }
100    
101      /**
102       * This method is the core method during the trace of the object graph.
103       * The role of this method is to:
104       *
105       * 1. Ensure the traced object is not collected.
106       * 2. If this is the first visit to the object enqueue it to be scanned.
107       * 3. Return the forwarded reference to the object.
108       *
109       * @param object The object to be traced.
110       * @return The new reference to the same object instance.
111       */
112      @Inline
113      public ObjectReference traceObject(ObjectReference object) {
114        if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!object.isNull());
115        if (Gen.inNursery(object))
116          return Gen.nurserySpace.traceObject(this, object, Gen.ALLOC_MATURE_MAJORGC);
117        return super.traceObject(object);
118      }
119    
120      /**
121       * Process any remembered set entries.
122       */
123      protected void processRememberedSets() {
124        logMessage(5, "clearing modbuf");
125        ObjectReference obj;
126        while (!(obj = modbuf.pop()).isNull()) {
127          HeaderByte.markAsUnlogged(obj);
128        }
129        logMessage(5, "clearing remset");
130        while (!remset.isEmpty()) {
131          remset.pop();
132        }
133        logMessage(5, "clearing array remset");
134        while (!arrayRemset.isEmpty()) {
135          arrayRemset.pop1();
136          arrayRemset.pop2();
137        }
138      }
139    
140    }