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 org.mmtk.plan.TraceLocal; 016import org.mmtk.plan.Trace; 017import org.mmtk.utility.HeaderByte; 018import org.mmtk.utility.deque.*; 019 020import org.mmtk.vm.VM; 021 022import org.vmmagic.unboxed.*; 023import 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 030public 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 * 051 * @param specializedScan the id of the specialized scan 052 * @param trace the global trace class to use 053 * @param plan the state of the generational collector 054 */ 055 public GenMatureTraceLocal(int specializedScan, Trace trace, GenCollector plan) { 056 super(specializedScan, trace); 057 this.modbuf = plan.modbuf; 058 this.remset = plan.remset; 059 this.arrayRemset = plan.arrayRemset; 060 } 061 062 /** 063 * @param trace the global trace class to use 064 * @param plan the state of the generational collector 065 */ 066 public GenMatureTraceLocal(Trace trace, GenCollector plan) { 067 super(Gen.SCAN_MATURE, trace); 068 this.modbuf = plan.modbuf; 069 this.remset = plan.remset; 070 this.arrayRemset = plan.arrayRemset; 071 } 072 073 /**************************************************************************** 074 * 075 * Object processing and tracing 076 */ 077 078 /** 079 * {@inheritDoc} 080 */ 081 @Override 082 @Inline 083 public boolean isLive(ObjectReference object) { 084 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!object.isNull()); 085 if (Gen.inNursery(object)) { 086 return Gen.nurserySpace.isLive(object); 087 } 088 return super.isLive(object); 089 } 090 091 /** 092 * Return {@code true} if this object is guaranteed not to move during this 093 * collection (i.e. this object is definitely not an unforwarded 094 * object). 095 * 096 * @param object the object that might move 097 * @return {@code true} if this object is guaranteed not to move during this 098 * collection. 099 */ 100 @Override 101 public boolean willNotMoveInCurrentCollection(ObjectReference object) { 102 if (Gen.inNursery(object)) 103 return false; 104 else 105 return super.willNotMoveInCurrentCollection(object); 106 } 107 108 @Override 109 @Inline 110 public ObjectReference traceObject(ObjectReference object) { 111 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!object.isNull()); 112 if (Gen.inNursery(object)) 113 return Gen.nurserySpace.traceObject(this, object, Gen.ALLOC_MATURE_MAJORGC); 114 return super.traceObject(object); 115 } 116 117 /** 118 * Process any remembered set entries. 119 */ 120 @Override 121 protected void processRememberedSets() { 122 logMessage(5, "clearing modbuf"); 123 ObjectReference obj; 124 while (!(obj = modbuf.pop()).isNull()) { 125 HeaderByte.markAsUnlogged(obj); 126 } 127 logMessage(5, "clearing remset"); 128 while (!remset.isEmpty()) { 129 remset.pop(); 130 } 131 logMessage(5, "clearing array remset"); 132 while (!arrayRemset.isEmpty()) { 133 arrayRemset.pop1(); 134 arrayRemset.pop2(); 135 } 136 } 137 138}