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.concurrent; 014 015 import org.mmtk.plan.*; 016 017 import org.mmtk.vm.VM; 018 019 import org.vmmagic.pragma.*; 020 import org.vmmagic.unboxed.*; 021 022 /** 023 * This class implements <i>per-mutator thread</i> behavior 024 * and state for a simple whole-heap concurrent collector. 025 * 026 * @see Concurrent 027 * @see ConcurrentCollector 028 * @see StopTheWorldMutator 029 * @see MutatorContext 030 */ 031 @Uninterruptible 032 public abstract class ConcurrentMutator extends SimpleMutator { 033 034 /**************************************************************************** 035 * Instance fields 036 */ 037 038 /** 039 * 040 */ 041 public static boolean newMutatorBarrierActive = false; 042 protected volatile boolean barrierActive = false; 043 044 protected ConcurrentMutator() { 045 barrierActive = newMutatorBarrierActive; 046 } 047 048 /**************************************************************************** 049 * 050 * Collection 051 */ 052 053 /** 054 * Perform a per-mutator collection phase. 055 */ 056 @Override 057 @Inline 058 public void collectionPhase(short phaseId, boolean primary) { 059 if (phaseId == Concurrent.SET_BARRIER_ACTIVE) { 060 barrierActive = true; 061 return; 062 } 063 064 if (phaseId == Concurrent.CLEAR_BARRIER_ACTIVE) { 065 barrierActive = false; 066 return; 067 } 068 069 if (phaseId == Concurrent.FLUSH_MUTATOR) { 070 flush(); 071 return; 072 } 073 074 super.collectionPhase(phaseId, primary); 075 } 076 077 /**************************************************************************** 078 * 079 * Write and read barriers. 080 */ 081 082 /** 083 * {@inheritDoc}<p> 084 * 085 * <b>In this case we employ a Yuasa style snapshot barrier.</b> 086 * 087 */ 088 @Inline 089 @Override 090 public void objectReferenceWrite(ObjectReference src, Address slot, ObjectReference tgt, Word metaDataA, Word metaDataB, int mode) { 091 if (barrierActive) checkAndEnqueueReference(slot.loadObjectReference()); 092 VM.barriers.objectReferenceWrite(src, tgt, metaDataA, metaDataB, mode); 093 } 094 095 @Inline 096 @Override 097 public boolean objectReferenceTryCompareAndSwap(ObjectReference src, Address slot, ObjectReference old, 098 ObjectReference tgt, Word metaDataA, Word metaDataB, int mode) { 099 boolean result = VM.barriers.objectReferenceTryCompareAndSwap(src, old, tgt, metaDataA, metaDataB, mode); 100 if (barrierActive) checkAndEnqueueReference(old); 101 return result; 102 } 103 104 /** 105 * {@inheritDoc} 106 * 107 * @param src The source of the values to be copied 108 * @param srcOffset The offset of the first source address, in 109 * bytes, relative to <code>src</code> (in principle, this could be 110 * negative). 111 * @param dst The mutated object, i.e. the destination of the copy. 112 * @param dstOffset The offset of the first destination address, in 113 * bytes relative to <code>tgt</code> (in principle, this could be 114 * negative). 115 * @param bytes The size of the region being copied, in bytes. 116 */ 117 @Inline 118 @Override 119 public boolean objectReferenceBulkCopy(ObjectReference src, Offset srcOffset, ObjectReference dst, Offset dstOffset, int bytes) { 120 Address cursor = dst.toAddress().plus(dstOffset); 121 Address limit = cursor.plus(bytes); 122 while (cursor.LT(limit)) { 123 ObjectReference ref = cursor.loadObjectReference(); 124 if (barrierActive) checkAndEnqueueReference(ref); 125 cursor = cursor.plus(BYTES_IN_ADDRESS); 126 } 127 return false; 128 } 129 130 @Inline 131 @Override 132 public ObjectReference javaLangReferenceReadBarrier(ObjectReference ref) { 133 if (barrierActive) checkAndEnqueueReference(ref); 134 return ref; 135 } 136 137 /** 138 * Process a reference that may require being enqueued as part of a concurrent 139 * collection. 140 * 141 * @param ref The reference to check. 142 */ 143 protected abstract void checkAndEnqueueReference(ObjectReference ref); 144 }