/*
* Copyright (c) 2007, 2011, 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.
*/
package com.sun.max.vm.object;
import static com.sun.max.vm.MaxineVM.*;
import static com.sun.max.vm.intrinsics.MaxineIntrinsicIDs.*;
import java.lang.reflect.*;
import java.nio.*;
import com.sun.max.annotate.*;
import com.sun.max.unsafe.*;
import com.sun.max.vm.actor.holder.*;
import com.sun.max.vm.heap.*;
import com.sun.max.vm.jdk.*;
import com.sun.max.vm.layout.*;
import com.sun.max.vm.monitor.*;
import com.sun.max.vm.reference.*;
/**
* This class implements a facade for the {@link Layout Layout} class, which
* accepts only {@code Reference} objects.
*/
public final class ObjectAccess {
protected ObjectAccess() {
}
/**
* Checks whether the specified object is {@code zero} (i.e. is {@code null}).
*
* @param object the object to check
* @return {@code true} if the object reference is {@code zero}; {@code false} otherwise
*/
@INLINE
public static boolean isZero(Object object) {
return Reference.fromJava(object).isZero();
}
/**
* Checks whether the specified object is an array.
*
* @param object the object to check
* @return {@code true} if the object is an array; {@code false} otherwise
*/
public static boolean isArray(Object object) {
return Layout.isArray(Reference.fromJava(object));
}
/**
* Converts an object reference to a pointer to the object's <i>origin</i>.
*
* @param object the object
* @return a pointer to the specified object's origin
*/
@INLINE
public static Pointer toOrigin(Object object) {
return Reference.fromJava(object).toOrigin();
}
/**
* Reads the hub of an object reference.
*
* @param object the object for which to read the hub
* @return a reference to the hub of the object
*/
@INLINE
public static Hub readHub(Object object) {
if (isHosted()) {
if (object instanceof StaticTuple) {
final StaticTuple staticTuple = (StaticTuple) object;
return staticTuple.classActor().staticHub();
}
return ClassActor.fromJava(object.getClass()).dynamicHub();
}
return UnsafeCast.asHub(Reference.fromJava(object).readHubReference().toJava());
}
/**
* Reads the hub of an object and uses the hub to get the class actor for the specified object.
*
* @param object the object for which to read the hub
* @return a reference to the class actor, which represents the object's type
*/
@INLINE
public static ClassActor readClassActor(Object object) {
final Hub hub = UnsafeCast.asHub(Reference.fromJava(object).readHubReference().toJava());
return hub.classActor;
}
/**
* Reads the "misc" word from an object's header. The misc word encodes lock state, hash code, etc.
*
* @param object the object for which to read the misc word
* @return the misc word for the specified object
*/
@INLINE
public static Word readMisc(Object object) {
return Layout.readMisc(Reference.fromJava(object));
}
/**
* Write the "misc" word into an object's header.
*
* @param object the object for which to write the misc word
* @param value the new value for the misc word
*/
@INLINE
public static void writeMisc(Object object, Word value) {
Layout.writeMisc(Reference.fromJava(object), value);
}
/**
* Atomically compare and swap the misc word of an object header.
*
* @param object the object in whose header to compare and swap
* @param expectedValue the value to compare the misc word against
* @param newValue the new value to be written into the object header
* @return the old value of the misc word, if the comparison succeeds; the new value if it fails
*/
@INLINE
public static Word compareAndSwapMisc(Object object, Word expectedValue, Word newValue) {
return Layout.compareAndSwapMisc(Reference.fromJava(object), expectedValue, newValue);
}
/**
* Computes a new default hashcode for the specified object.
*
* @param object the object for which to calculate the hash code
* @return a new identity hashcode for the specified object
*/
public static int makeHashCode(Object object) {
return Monitor.makeHashCode(object);
}
/**
* Compute the cell size of an object using the appropriate layout.
*
* @param object the object for which to compute the size
* @return the size of the objects in bytes
*/
public static Size size(Object object) {
if (isHosted()) {
Hub hub = readHub(object);
if (object.getClass().isArray()) {
final ArrayLayout arrayLayout = (ArrayLayout) hub.specificLayout;
return arrayLayout.getArraySize(Array.getLength(object));
}
if (object instanceof Hybrid) {
final Hybrid hybrid = (Hybrid) object;
final HybridLayout hybridLayout = (HybridLayout) hub.specificLayout;
return hybridLayout.getArraySize(hybrid.length());
}
return hub.tupleSize;
}
return Layout.size(Reference.fromJava(object));
}
@INTRINSIC(UNSAFE_CAST)
private static native ObjectAccess asThis(Object buffer);
@ALIAS(declaringClassName = "java.nio.DirectByteBuffer", name = "<init>")
private native void init(long addr, int capacity);
/**
* Creates a new instance of the package private class java.nio.DirectByteBuffer.
*/
public static ByteBuffer createDirectByteBuffer(long address, int capacity) {
Object buffer = Heap.createTuple(JDK.java_nio_DirectByteBuffer.classActor().dynamicHub());
asThis(buffer).init(address, capacity);
ByteBuffer directBuffer = (ByteBuffer) buffer;
return directBuffer;
}
}