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 }