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 static org.mmtk.utility.Constants.BYTES_IN_ADDRESS; 016 017import org.mmtk.plan.TraceLocal; 018import org.mmtk.plan.Trace; 019import org.mmtk.utility.HeaderByte; 020import org.mmtk.utility.deque.*; 021import org.mmtk.vm.VM; 022 023import org.vmmagic.pragma.*; 024import org.vmmagic.unboxed.*; 025 026/** 027 * This class implements the core functionality for a transitive 028 * closure over the heap graph. 029 */ 030@Uninterruptible 031public final class GenNurseryTraceLocal extends TraceLocal { 032 033 /**************************************************************************** 034 * 035 * Instance fields. 036 */ 037 038 /** 039 * 040 */ 041 private final ObjectReferenceDeque modbuf; 042 private final AddressDeque remset; 043 private final AddressPairDeque arrayRemset; 044 045 /** 046 * @param trace the global trace class to use 047 * @param plan the state of the generational collector 048 */ 049 public GenNurseryTraceLocal(Trace trace, GenCollector plan) { 050 super(Gen.SCAN_NURSERY, trace); 051 this.modbuf = plan.modbuf; 052 this.remset = plan.remset; 053 this.arrayRemset = plan.arrayRemset; 054 } 055 056 /**************************************************************************** 057 * 058 * Externally visible Object processing and tracing 059 */ 060 061 /** 062 * {@inheritDoc} 063 */ 064 @Override 065 public boolean isLive(ObjectReference object) { 066 if (object.isNull()) return false; 067 if (Gen.inNursery(object)) { 068 return Gen.nurserySpace.isLive(object); 069 } 070 /* During a nursery trace, all objects not in the nursery are considered alive */ 071 return true; 072 } 073 074 @Override 075 @Inline 076 public ObjectReference traceObject(ObjectReference object) { 077 if (Gen.inNursery(object)) { 078 return Gen.nurserySpace.traceObject(this, object, Gen.ALLOC_MATURE_MINORGC); 079 } 080 return object; 081 } 082 083 /** 084 * Process any remembered set entries. 085 */ 086 @Override 087 @Inline 088 protected void processRememberedSets() { 089 logMessage(5, "processing modbuf"); 090 ObjectReference obj; 091 while (!(obj = modbuf.pop()).isNull()) { 092 if (VM.DEBUG) VM.debugging.modbufEntry(obj); 093 HeaderByte.markAsUnlogged(obj); 094 scanObject(obj); 095 } 096 logMessage(5, "processing remset"); 097 while (!remset.isEmpty()) { 098 Address loc = remset.pop(); 099 if (VM.DEBUG) VM.debugging.remsetEntry(loc); 100 processRootEdge(loc, false); 101 } 102 logMessage(5, "processing array remset"); 103 arrayRemset.flushLocal(); 104 while (!arrayRemset.isEmpty()) { 105 Address start = arrayRemset.pop1(); 106 Address guard = arrayRemset.pop2(); 107 if (VM.DEBUG) VM.debugging.arrayRemsetEntry(start,guard); 108 while (start.LT(guard)) { 109 processRootEdge(start, false); 110 start = start.plus(BYTES_IN_ADDRESS); 111 } 112 } 113 } 114 115 /** 116 * Will the object move from now on during the collection. 117 * 118 * @param object The object to query. 119 * @return {@code true} if the object is guaranteed not to move. 120 */ 121 @Override 122 public boolean willNotMoveInCurrentCollection(ObjectReference object) { 123 if (object.isNull()) return false; 124 return !Gen.inNursery(object); 125 } 126 127}