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