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.semispace.gctrace; 014 015import static org.mmtk.utility.Constants.*; 016 017import org.mmtk.plan.semispace.SSMutator; 018import org.mmtk.plan.*; 019import org.mmtk.utility.TraceGenerator; 020import org.mmtk.vm.VM; 021 022import org.vmmagic.unboxed.*; 023import org.vmmagic.pragma.*; 024 025/** 026 * This class implements <i>per-mutator thread</i> behavior and state for the 027 * <i>GCTrace</i> plan, which implements a GC tracing algorithm.<p> 028 * 029 * Specifically, this class defines <i>SS</i> mutator-time allocation, write 030 * barriers, and per-mutator collection semantics.<p> 031 * 032 * See {@link GCTrace} for an overview of the GC trace algorithm. 033 * 034 * @see SSMutator 035 * @see GCTrace 036 * @see GCTraceCollector 037 * @see org.mmtk.plan.StopTheWorldMutator 038 * @see org.mmtk.plan.MutatorContext 039 */ 040@Uninterruptible public class GCTraceMutator extends SSMutator { 041 042 /**************************************************************************** 043 * 044 * Mutator-time allocation 045 */ 046 047 /** 048 * {@inheritDoc} 049 */ 050 @Override 051 @Inline 052 public final void postAlloc(ObjectReference object, ObjectReference typeRef, 053 int bytes, int allocator) { 054 /* Make the trace generator aware of the new object. */ 055 TraceGenerator.addTraceObject(object, allocator); 056 057 super.postAlloc(object, typeRef, bytes, allocator); 058 059 /* Now have the trace process aware of the new allocation. */ 060 GCTrace.traceInducedGC = TraceGenerator.MERLIN_ANALYSIS; 061 TraceGenerator.traceAlloc(allocator == GCTrace.ALLOC_IMMORTAL, object, typeRef, bytes); 062 GCTrace.traceInducedGC = false; 063 } 064 065 066 /**************************************************************************** 067 * 068 * Write barrier. 069 */ 070 071 /** 072 * {@inheritDoc}<p> 073 * 074 * In this case, we remember the address of the source of the 075 * pointer if the new reference points into the nursery from 076 * non-nursery space. 077 */ 078 @Override 079 @Inline 080 public final void objectReferenceWrite(ObjectReference src, Address slot, 081 ObjectReference tgt, Word metaDataA, 082 Word metaDataB, int mode) { 083 TraceGenerator.processPointerUpdate(mode == INSTANCE_FIELD, 084 src, slot, tgt); 085 VM.barriers.objectReferenceWrite(src, tgt, metaDataA, metaDataB, mode); 086 } 087 088 @Override 089 @Inline 090 public boolean objectReferenceTryCompareAndSwap(ObjectReference src, Address slot, 091 ObjectReference old, ObjectReference tgt, Word metaDataA, 092 Word metaDataB, int mode) { 093 boolean result = VM.barriers.objectReferenceTryCompareAndSwap(src, old, tgt, metaDataA, metaDataB, mode); 094 if (result) { 095 TraceGenerator.processPointerUpdate(mode == INSTANCE_FIELD, src, slot, tgt); 096 } 097 return result; 098 } 099 100 /** 101 * {@inheritDoc}<p> 102 * 103 * @param src The source of the values to be copied 104 * @param srcOffset The offset of the first source address, in 105 * bytes, relative to <code>src</code> (in principle, this could be 106 * negative). 107 * @param dst The mutated object, i.e. the destination of the copy. 108 * @param dstOffset The offset of the first destination address, in 109 * bytes relative to <code>tgt</code> (in principle, this could be 110 * negative). 111 * @param bytes The size of the region being copied, in bytes. 112 * @return True if the update was performed by the barrier, false if 113 * left to the caller (always false in this case). 114 */ 115 @Override 116 public boolean objectReferenceBulkCopy(ObjectReference src, Offset srcOffset, 117 ObjectReference dst, Offset dstOffset, int bytes) { 118 /* These names seem backwards, but are defined to be compatable with the 119 * previous writeBarrier method. */ 120 Address slot = dst.toAddress().plus(dstOffset); 121 Address tgtLoc = src.toAddress().plus(srcOffset); 122 for (int i = 0; i < bytes; i += BYTES_IN_ADDRESS) { 123 ObjectReference tgt = tgtLoc.loadObjectReference(); 124 TraceGenerator.processPointerUpdate(false, dst, slot, tgt); 125 slot = slot.plus(BYTES_IN_ADDRESS); 126 tgtLoc = tgtLoc.plus(BYTES_IN_ADDRESS); 127 } 128 return false; 129 } 130 131 /**************************************************************************** 132 * 133 * Collection 134 */ 135 136 /** 137 * {@inheritDoc} 138 */ 139 @Override 140 public void collectionPhase(short phaseId, boolean primary) { 141 if (!GCTrace.traceInducedGC || 142 (phaseId != StopTheWorld.PREPARE) && 143 (phaseId != StopTheWorld.RELEASE)) { 144 // Delegate up. 145 super.collectionPhase(phaseId, primary); 146 } 147 } 148}