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 }