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.refcount.generational; 014 015import org.mmtk.plan.TraceLocal; 016import org.mmtk.plan.Trace; 017import org.mmtk.plan.refcount.RCHeader; 018import org.mmtk.policy.Space; 019import org.mmtk.utility.deque.ObjectReferenceDeque; 020import org.mmtk.vm.VM; 021 022import org.vmmagic.pragma.*; 023import org.vmmagic.unboxed.*; 024 025/** 026 * This class implements the thread-local core functionality for a transitive 027 * closure over the heap graph. 028 */ 029@Uninterruptible 030public final class GenRCFindRootSetTraceLocal extends TraceLocal { 031 032 private final ObjectReferenceDeque rootBuffer; 033 034 public GenRCFindRootSetTraceLocal(Trace trace, ObjectReferenceDeque rootBuffer) { 035 super(trace); 036 this.rootBuffer = rootBuffer; 037 } 038 039 /**************************************************************************** 040 * 041 * Externally visible Object processing and tracing 042 */ 043 044 /** 045 * Is the specified object reachable? 046 * 047 * @return <code>true</code> if the object is reachable. 048 */ 049 @Override 050 public boolean isLive(ObjectReference object) { 051 return GenRC.isRCObject(object) && RCHeader.isLiveRC(object) || 052 (!Space.isInSpace(GenRC.NURSERY, object) && super.isLive(object)); 053 } 054 055 /** 056 * When we trace a non-root object we do nothing. 057 */ 058 @Override 059 @Inline 060 public ObjectReference traceObject(ObjectReference object) { 061 return traceObject(object, false); 062 } 063 064 /** 065 * When we trace a root object we remember it. 066 */ 067 @Override 068 @Inline 069 public ObjectReference traceObject(ObjectReference object, boolean root) { 070 if (object.isNull()) return object; 071 072 if (Space.isInSpace(GenRC.NURSERY, object)) { 073 object = GenRC.nurserySpace.traceObject(this, object, GenRC.ALLOC_RC); 074 } else if (!GenRC.isRCObject(object)) { 075 return object; 076 } 077 078 if (root) { 079 rootBuffer.push(object); 080 } else { 081 RCHeader.incRC(object); 082 } 083 084 return object; 085 } 086 087 @Override 088 public boolean willNotMoveInCurrentCollection(ObjectReference object) { 089 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!object.isNull()); 090 return !(Space.isInSpace(GenRC.NURSERY, object)); 091 } 092}