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 */
013package org.mmtk.plan.generational;
014
015import org.mmtk.plan.TraceLocal;
016import org.mmtk.plan.Trace;
017import org.mmtk.utility.HeaderByte;
018import org.mmtk.utility.deque.*;
019
020import org.mmtk.vm.VM;
021
022import org.vmmagic.unboxed.*;
023import 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
030public 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   *
051   * @param specializedScan the id of the specialized scan
052   * @param trace the global trace class to use
053   * @param plan the state of the generational collector
054   */
055  public GenMatureTraceLocal(int specializedScan, Trace trace, GenCollector plan) {
056    super(specializedScan, trace);
057    this.modbuf = plan.modbuf;
058    this.remset = plan.remset;
059    this.arrayRemset = plan.arrayRemset;
060  }
061
062  /**
063   * @param trace the global trace class to use
064   * @param plan the state of the generational collector
065   */
066  public GenMatureTraceLocal(Trace trace, GenCollector plan) {
067    super(Gen.SCAN_MATURE, trace);
068    this.modbuf = plan.modbuf;
069    this.remset = plan.remset;
070    this.arrayRemset = plan.arrayRemset;
071  }
072
073  /****************************************************************************
074   *
075   * Object processing and tracing
076   */
077
078  /**
079   * {@inheritDoc}
080   */
081  @Override
082  @Inline
083  public boolean isLive(ObjectReference object) {
084    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!object.isNull());
085    if (Gen.inNursery(object)) {
086      return Gen.nurserySpace.isLive(object);
087    }
088    return super.isLive(object);
089  }
090
091  /**
092   * Return {@code true} if this object is guaranteed not to move during this
093   * collection (i.e. this object is definitely not an unforwarded
094   * object).
095   *
096   * @param object the object that might move
097   * @return {@code true} if this object is guaranteed not to move during this
098   *         collection.
099   */
100  @Override
101  public boolean willNotMoveInCurrentCollection(ObjectReference object) {
102    if (Gen.inNursery(object))
103      return false;
104    else
105      return super.willNotMoveInCurrentCollection(object);
106  }
107
108  @Override
109  @Inline
110  public ObjectReference traceObject(ObjectReference object) {
111    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!object.isNull());
112    if (Gen.inNursery(object))
113      return Gen.nurserySpace.traceObject(this, object, Gen.ALLOC_MATURE_MAJORGC);
114    return super.traceObject(object);
115  }
116
117  /**
118   * Process any remembered set entries.
119   */
120  @Override
121  protected void processRememberedSets() {
122    logMessage(5, "clearing modbuf");
123    ObjectReference obj;
124    while (!(obj = modbuf.pop()).isNull()) {
125      HeaderByte.markAsUnlogged(obj);
126    }
127    logMessage(5, "clearing remset");
128    while (!remset.isEmpty()) {
129      remset.pop();
130    }
131    logMessage(5, "clearing array remset");
132    while (!arrayRemset.isEmpty()) {
133      arrayRemset.pop1();
134      arrayRemset.pop2();
135    }
136  }
137
138}