/*
* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*VCSID=e74ecb84-ca6a-4129-a3b6-b9f3408cec81*/
package com.sun.max.tele.value;
import com.sun.max.lang.*;
import com.sun.max.tele.*;
import com.sun.max.tele.object.*;
import com.sun.max.tele.reference.*;
import com.sun.max.tele.util.*;
import com.sun.max.unsafe.*;
import com.sun.max.vm.actor.holder.*;
import com.sun.max.vm.reference.*;
import com.sun.max.vm.value.*;
/**
* Boxed representations of object references (and null).
* We cannot use {@link ObjectReferenceValue},
* because it wraps an Object, not a reference for bootstrapping reasons.
* Instead we need to wrap a Reference here,
* since there is no related Object in our address space.
*
* NOTE: (mlvdv) Although the name of this class suggests that it is
* part of the {@link TeleObject} class hierarchy that is used to
* model the state of heap objects in the VM, it is in fact
* not part of that hierarchy. This represents the clash of two
* models for doing things that have not yet been resolved.
* The function of a {@link TeleReferenceValue} is very much
* like that of a {@link TeleObject}.
*
* @see Reference
*/
public final class TeleReferenceValue extends ReferenceValue {
private static TeleReferenceValue zero = null;
private final TeleVM vm;
public final RemoteReference reference;
public static TeleReferenceValue from(TeleVM vm, Reference reference) {
return new TeleReferenceValue(vm, reference);
}
public static TeleReferenceValue zero(TeleVM vm) {
if (zero == null) {
zero = new TeleReferenceValue(vm, Reference.zero());
}
return zero;
}
private TeleReferenceValue(TeleVM vm, Reference reference) {
this.vm = vm;
this.reference = (RemoteReference) reference;
}
@Override
public boolean isZero() {
return reference.isZero();
}
@Override
public boolean isAllOnes() {
return reference.isAllOnes();
}
@Override
public boolean equals(Object other) {
if (this == other) {
// common case of reference equality
return true;
}
if (!(other instanceof TeleReferenceValue)) {
return false;
}
final TeleReferenceValue teleReferenceValue = (TeleReferenceValue) other;
return reference.equals(teleReferenceValue.reference);
}
@Override
protected int compareSameKind(ReferenceValue other) {
// TODO: It seems impossible to find a way to deterministically order the identities of two objects.
// So, Value should not implement Comparable!
throw TeleError.unexpected("trying to compare reference values");
}
@Override
public int hashCode() {
return reference.hashCode();
}
@Override
public String toString() {
if (reference.isZero()) {
return "null";
}
return reference.toString();
}
@Override
public Object asBoxedJavaValue() {
if (reference.isLocal()) {
return reference.toJava();
}
throw new UnsupportedOperationException();
}
@Override
public Object unboxObject() {
if (reference.isLocal()) {
return reference.toJava();
}
throw new UnsupportedOperationException();
}
@Override
public RemoteReference asReference() {
return reference;
}
@Override
public Object asObject() {
if (reference.isLocal()) {
return reference.toJava();
}
throw new UnsupportedOperationException();
}
@Override
public Word toWord() {
return vm.referenceManager().toOrigin(reference);
}
@Override
public WordWidth signedEffectiveWidth() {
return Word.widthValue();
}
@Override
public WordWidth unsignedEffectiveWidth() {
return Word.widthValue();
}
@Override
public byte[] toBytes(DataModel dataModel) {
return dataModel.toBytes(reference.toOrigin());
}
@Override
public ClassActor getClassActor() {
if (reference.isLocal()) {
return ClassActor.fromJava(reference.toJava().getClass());
}
return vm.classes().makeClassActorForTypeOf(reference);
}
}