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 }