/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
package org.mmtk.plan.gpu;
import org.mmtk.utility.Log;
import org.mmtk.vm.VM;
import org.vmmagic.pragma.*;
import org.vmmagic.unboxed.*;
/**
* This class implements <i>per-mutator thread</i> behavior
* and state for the <i>MS</i> plan, which implements a full-heap
* mark-sweep collector.<p>
*
* Specifically, this class defines <i>MS</i> mutator-time allocation
* and per-mutator thread collection semantics (flushing and restoring
* per-mutator allocator state).<p>
*
* @see GPU
* @see GPUCollector
* @see StopTheWorldMutator
* @see MutatorContext
*/
@Uninterruptible
public class GPU2Mutator extends GPUMutator {
//int callcount1 = 0;
//int callcount2 = 0;
// The -X:gc:noReferenceTypes=true option makes weak references and such
// into strong references (traced by GC), but write barriers are still
// not called for them
@Inline
@Override
public void javaLangReferenceUpdated(ObjectReference src, ObjectReference tgt) {
Address srcNode = src.toAddress().loadAddress(VM.objectModel.GC_HEADER_OFFSET());
//VM.assertions._assert(srcNode.loadObjectReference().toAddress().EQ(src.toAddress()));
// Assuming address of referent is reference object's first reference
srcNode.store(
tgt.isNull() ? Address.zero() : tgt.toAddress().loadAddress(VM.objectModel.GC_HEADER_OFFSET()),
Offset.fromIntZeroExtend(2 * BYTES_IN_ADDRESS));
//callcount1++;
}
@Inline
@Override
public void objectReferenceWrite(ObjectReference src, Address slot, ObjectReference tgt, Word metaDataA, Word metaDataB, int mode) {
VM.barriers.objectReferenceWrite(src, tgt, metaDataA, metaDataB, mode);
Address srcNode = src.toAddress().loadAddress(VM.objectModel.GC_HEADER_OFFSET());
if (!srcNode.isZero()) {
//VM.assertions._assert(srcNode.loadObjectReference().toAddress().EQ(src.toAddress()));
srcNode.store(
tgt.isNull() ? Address.zero() : tgt.toAddress().loadAddress(VM.objectModel.GC_HEADER_OFFSET()),
Offset.fromIntZeroExtend((2 + VM.gpu.getObjectRefIndex(src, slot)) * BYTES_IN_ADDRESS));
}
//callcount2++;
}
@Inline
@Override
public void collectionPhase(short phaseId, boolean primary) {
if (phaseId == GPU.PREPARE) {
/*Log.write("calls to GPU2Mutator.javaLangReferenceUpdated: ");
Log.writeln(callcount1);
Log.write("calls to GPU2Mutator.objectReferenceWrite: ");
Log.writeln(callcount2);
callcount1 = 0;
callcount2 = 0;*/
super.collectionPhase(phaseId, primary);
return;
}
}
}