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