/*
* 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.harness.lang.runtime;
import org.mmtk.harness.lang.Trace;
import org.mmtk.harness.lang.Trace.Item;
import org.mmtk.harness.vm.ObjectModel;
import org.mmtk.plan.TraceLocal;
import org.mmtk.vm.ReferenceProcessor.Semantics;
import org.vmmagic.unboxed.ObjectReference;
/**
* Moral equivalent of java.lang.ref.Reference
*
* In the MMTk harness, Reference types aren't heap objects. This has the up side
* that we can debug problems with forwarding of referents more easily, but means
* that we don't exercise the method getForwardedReference, just getForwardedReferent.
*
* TODO make this more comprehensive.
*/
public abstract class ReferenceValue extends Value {
private static int nextId = 0x100001;
private final int id = nextId++;
private ObjectReference ref;
private final Semantics semantics;
private boolean cleared = false;
protected ReferenceValue(ObjectReference ref, Semantics semantics) {
this.ref = ref;
this.semantics = semantics;
}
public void clear() {
Trace.trace(Item.REFERENCES, "Clearing reference %s", this);
cleared = true;
}
/**
* @see org.mmtk.harness.lang.runtime.Value#getObjectValue()
*/
@Override
public ObjectReference getObjectValue() {
return cleared ? ObjectReference.nullReference() : ref;
}
/**
* @return The reference semantics
*/
public Semantics getSemantics() {
return semantics;
}
/**
* GC-time processing of the contained object.
*
* Corresponds to the core of the processReference method of the MMTk ReferenceProcessor
* for the WEAK reference type.
*
* @param trace The MMTk trace
*/
public void processReference(TraceLocal trace) {
if (cleared)
return;
ObjectReference newRef = trace.getForwardedReferent(ref);
if (Trace.isEnabled(Item.REFERENCES)) {
Trace.trace(Item.REFERENCES, "Forwarded reference %x: %s reference (%s -> %s)",
id, semantics, ObjectModel.getString(ref), ObjectModel.getString(newRef));
}
ref = newRef;
}
/**
* Deferred GC-time processing of the contained object, used in collectors
* like MarkCompact which determine liveness separately from copying.
*
* Corresponds to the core of the forward method of the MMTk ReferenceProcessor
* for the WEAK reference type.
*
* @param trace The MMTk trace
*/
public void forwardReference(TraceLocal trace) {
if (cleared)
return;
/*
* Currently, do exactly the same thing for process as for forward.
*
* TODO - perhaps make this different, only really relevant when we have different semantics
* for the different types of references.
*/
Trace.trace(Item.REFERENCES, "Forwarding reference %x: %s reference %s",
System.identityHashCode(this), semantics,
ObjectModel.getString(ref));
processReference(trace);
}
/**
* @see org.mmtk.harness.lang.runtime.Value#equals(java.lang.Object)
*/
@Override
public boolean equals(Object o) {
return this == o;
}
@Override
public int hashCode() {
return System.identityHashCode(this);
}
@Override
public String toString() {
return String.format("%x: %s reference (-> %s)", id, semantics, ObjectModel.getString(ref));
}
}