/*
* 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.
*/
package com.sun.max.vm.layout;
import static com.sun.max.vm.VMConfiguration.*;
import com.sun.max.annotate.*;
import com.sun.max.unsafe.*;
import com.sun.max.vm.*;
import com.sun.max.vm.actor.holder.*;
import com.sun.max.vm.reference.*;
import com.sun.max.vm.type.*;
/**
* Static convenience methods for access to object layout information in the
* context of the current {@linkplain VMConfiguration VM configuration}.
*/
public final class Layout {
private Layout() {
}
/**
* Returns the layout scheme being used in the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @return the layout scheme in use
*/
@FOLD
public static LayoutScheme layoutScheme() {
return vmConfig().layoutScheme();
}
/**
* Returns the general layout scheme being used in the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @return the general layout scheme in use
*/
@FOLD
public static GeneralLayout generalLayout() {
return layoutScheme().generalLayout;
}
/**
* A descriptor for a word-sized slot in an object's header. All that the descriptor
* encapsulates is the name of a slot in a header. The offset of the
* slots is determined by the configured layout.
*/
public static class HeaderField {
/**
* The header word from which the hub of an object can be found.
*/
public static final HeaderField HUB = new HeaderField("HUB", "Reference to layout description (\"Hub\") for the object, based on its type");
/**
* The header word in which the monitor and hash code details of an object are encoded.
*/
public static final HeaderField MISC = new HeaderField("MISC", "Encoded monitor and hash code details for the object");
/**
* The header word in which the length of an array object is encoded.
*/
public static final HeaderField LENGTH = new HeaderField("LENGTH", "The number of elements in the array");
/**
* The name of this header field.
*/
public final String name;
/**
* A short, human-readable description of the field and the role it plays, suitable for inspection.
*/
public final String description;
public HeaderField(String name, String description) {
this.name = name;
this.description = description;
}
@Override
public String toString() {
return name;
}
}
public enum Category {
TUPLE, ARRAY, HYBRID;
}
/**
* Access to <strong>tuple object</strong> layout information in the
* context of the current {@linkplain VMConfiguration VM configuration}.
*/
@FOLD
public static TupleLayout tupleLayout() {
return layoutScheme().tupleLayout;
}
/**
* Access to <strong>hybrid object</strong> layout information in the
* context of the current {@linkplain VMConfiguration VM configuration}.
*/
@FOLD
public static HybridLayout hybridLayout() {
return layoutScheme().hybridLayout;
}
/**
* Access to <strong>array object</strong> layout information in the
* context of the current {@linkplain VMConfiguration VM configuration}.
*/
@FOLD
public static ArrayLayout arrayLayout() {
return layoutScheme().arrayLayout;
}
/**
* Computes the <strong>origin</strong> of an object, using layout information in
* the context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param cell starting location of an object in memory
* @return the location of the object's origin
*/
@INLINE
public static Pointer cellToOrigin(Pointer cell) {
return generalLayout().cellToOrigin(cell);
}
/**
* Computes the <strong>origin</strong> of a tuple object, using layout information in
* the context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param cell starting location of a tuple object in memory
* @return the location of the object's origin
*/
@INLINE
public static Pointer tupleCellToOrigin(Pointer cell) {
return tupleLayout().cellToOrigin(cell);
}
/**
* Computes the <strong>origin</strong> of a hybrid object, using layout information in
* the context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param cell starting location of a hybrid object in memory
* @return the location of the object's origin
*/
@INLINE
public static Pointer hybridCellToOrigin(Pointer cell) {
return hybridLayout().cellToOrigin(cell);
}
/**
* Computes the <strong>origin</strong> of an array object, using layout information in
* the context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param cell starting location of an array object in memory
* @return the location of the object's origin
*/
@INLINE
public static Pointer arrayCellToOrigin(Pointer cell) {
return arrayLayout().cellToOrigin(cell);
}
/**
* Computes the starting location of an object in VM memory, using layout information in
* the context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param origin location of the object's origin
* @return starting location of the object in memory
*/
@INLINE
public static Pointer originToCell(Pointer origin) {
return generalLayout().originToCell(origin);
}
/**
* Computes the starting location of a tuple object in VM memory, using layout information in
* the context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param origin location of the tuple object's origin
* @return starting location of the object in memory
*/
@INLINE
public static Pointer tupleOriginToCell(Pointer origin) {
return tupleLayout().originToCell(origin);
}
/**
* Computes the starting location of a hybrid object in VM memory, using layout information in
* the context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param origin location of the hybrid object's origin
* @return starting location of the object in memory
*/
@INLINE
public static Pointer hybridOriginToCell(Pointer origin) {
return hybridLayout().originToCell(origin);
}
/**
* Computes the starting location of an array object in VM memory, using layout information in
* the context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param origin location of the array object's origin
* @return starting location of the object in memory
*/
@INLINE
public static Pointer arrayOriginToCell(Pointer origin) {
return arrayLayout().originToCell(origin);
}
@FOLD
private static ReferenceScheme referenceScheme() {
return vmConfig().referenceScheme();
}
/**
* Determines whether an object is an array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param reference an object
* @return true iff the object is an array
*/
@ACCESSOR(Reference.class)
@INLINE
public static boolean isArray(Reference reference) {
return generalLayout().isArray(reference);
}
/**
* Gets the size an object, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param reference an object
* @return the size of the object
*/
@ACCESSOR(Reference.class)
@INLINE
public static Size size(Reference reference) {
return generalLayout().size(reference);
}
/**
* Gets the size an object, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param origin location of an object
* @return the size of the object
*/
@ACCESSOR(Pointer.class)
@INLINE
public static Size size(Pointer origin) {
return generalLayout().size(origin);
}
/**
* Reads the hub reference word in an object, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param reference an object
* @return the value of the object's hub reference
*/
@ACCESSOR(Reference.class)
@INLINE
public static Reference readHubReference(Reference reference) {
return generalLayout().readHubReference(reference);
}
/**
* Reads the hub reference word in an object, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param origin location of an object
* @return the value of the object's hub reference
*/
@ACCESSOR(Pointer.class)
@INLINE
public static Reference readHubReference(Pointer origin) {
return generalLayout().readHubReference(origin);
}
/**
* Reads the hub reference word in an object, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param reference an object
* @return the value of the object's hub reference as a word
*/
@ACCESSOR(Reference.class)
@INLINE
public static Word readHubReferenceAsWord(Reference reference) {
return generalLayout().readHubReferenceAsWord(reference);
}
/**
* Reads the hub reference word in an object, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param origin location of an object
* @return the value of the object's hub reference as a word
*/
@ACCESSOR(Pointer.class)
@INLINE
public static Word readHubReferenceAsWord(Pointer origin) {
return generalLayout().readHubReferenceAsWord(origin);
}
/**
* Writes the hub reference word in an object, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param reference an object
* @param hubReference the new value of the object's hub reference
*/
@ACCESSOR(Reference.class)
@INLINE
public static void writeHubReference(Reference reference, Reference hubReference) {
generalLayout().writeHubReference(reference, hubReference);
}
/**
* Writes the hub reference word in an object, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param origin location of an object
* @param hubReference the new value of the object's hub reference
*/
@ACCESSOR(Pointer.class)
@INLINE
public static void writeHubReference(Pointer origin, Reference hubReference) {
generalLayout().writeHubReference(origin, hubReference);
}
/**
* Reads the "misc" word from an object, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param reference an object
* @return the object's "misc" value
*/
@ACCESSOR(Reference.class)
@INLINE
public static Word readMisc(Reference reference) {
return generalLayout().readMisc(reference);
}
/**
* Writes the "misc" word in an object, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param reference an object
* @param value the new "misc" value
*/
@ACCESSOR(Reference.class)
@INLINE
public static void writeMisc(Reference reference, Word value) {
generalLayout().writeMisc(reference, value);
}
/**
* Writes the "misc" word in an object, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param origin location of an object
* @param value the new "misc" value
*/
@ACCESSOR(Pointer.class)
@INLINE
public static void writeMisc(Pointer origin, Word value) {
generalLayout().writeMisc(origin, value);
}
@ACCESSOR(Reference.class)
@INLINE
public static Word compareAndSwapMisc(Reference reference, Word expectedValue, Word newValue) {
return generalLayout().compareAndSwapMisc(reference, expectedValue, newValue);
}
/**
* Reads the length word from an array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param reference an array object
* @return array length
*/
@ACCESSOR(Reference.class)
@INLINE
public static int readArrayLength(Reference reference) {
return arrayLayout().readLength(reference);
}
/**
* Reads the length word from an array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param pointer location of an array object
* @return array length
*/
@ACCESSOR(Pointer.class)
@INLINE
public static int readArrayLength(Pointer pointer) {
return arrayLayout().readLength(pointer);
}
/**
* Writes the length word in an array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param origin location of an array object
* @param length the new value of the array's length word
*/
@ACCESSOR(Pointer.class)
@INLINE
public static void writeArrayLength(Pointer origin, int length) {
arrayLayout().writeLength(origin, length);
}
/**
* @see ArrayLayout#getArraySize(Kind, int)
*/
@INLINE
public static Size getArraySize(Kind kind, int length) {
return arrayLayout().getArraySize(kind, length);
}
@ACCESSOR(Pointer.class)
@INLINE
public static Reference readForwardRef(Pointer origin) {
return generalLayout().readForwardRef(origin);
}
@ACCESSOR(Pointer.class)
@INLINE
public static void writeForwardRef(Pointer origin, Reference forwardRef) {
generalLayout().writeForwardRef(origin, forwardRef);
}
/**
* Access to <strong>byte array object</strong> layout information in the
* context of the current {@linkplain VMConfiguration VM configuration}.
*/
@FOLD
public static ArrayLayout byteArrayLayout() {
return layoutScheme().byteArrayLayout;
}
/**
* Reads an element from a byte array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a byte array
* @param index the element to read
* @return the value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static byte getByte(Reference array, int index) {
return byteArrayLayout().getByte(array, index);
}
/**
* Writes into an element in a byte array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a byte array
* @param index the element into which to write
* @param value the new value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static void setByte(Reference array, int index, byte value) {
byteArrayLayout().setByte(array, index, value);
}
/**
* Access to <strong>boolean array object</strong> layout information in the
* context of the current {@linkplain VMConfiguration VM configuration}.
*/
@FOLD
public static ArrayLayout booleanArrayLayout() {
return layoutScheme().booleanArrayLayout;
}
/**
* Reads an element from a boolean array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a boolean array
* @param index the element to read
* @return the value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static boolean getBoolean(Reference array, int index) {
return booleanArrayLayout().getBoolean(array, index);
}
/**
* Writes into an element in a boolean array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a boolean array
* @param index the element into which to write
* @param value the new value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static void setBoolean(Reference array, int index, boolean value) {
booleanArrayLayout().setBoolean(array, index, value);
}
/**
* Access to <strong>short array object</strong> layout information in the
* context of the current {@linkplain VMConfiguration VM configuration}.
*/
@FOLD
public static ArrayLayout shortArrayLayout() {
return layoutScheme().shortArrayLayout;
}
/**
* Reads an element from a short array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a short array
* @param index the element to read
* @return the value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static short getShort(Reference array, int index) {
return shortArrayLayout().getShort(array, index);
}
/**
* Writes into an element in a short array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a short array
* @param index the element into which to write
* @param value the new value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static void setShort(Reference array, int index, short value) {
shortArrayLayout().setShort(array, index, value);
}
/**
* Access to <strong>char array object</strong> layout information in the
* context of the current {@linkplain VMConfiguration VM configuration}.
*/
@FOLD
public static ArrayLayout charArrayLayout() {
return layoutScheme().charArrayLayout;
}
/**
* Reads an element from a char array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a char array
* @param index the element to read
* @return the value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static char getChar(Reference array, int index) {
return charArrayLayout().getChar(array, index);
}
/**
* Writes into an element in a char array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a char array
* @param index the element into which to write
* @param value the new value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static void setChar(Reference array, int index, char value) {
charArrayLayout().setChar(array, index, value);
}
/**
* Access to <strong>int array object</strong> layout information in the
* context of the current {@linkplain VMConfiguration VM configuration}.
*/
@FOLD
public static ArrayLayout intArrayLayout() {
return layoutScheme().intArrayLayout;
}
/**
* Reads an element from a int array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a int array
* @param index the element to read
* @return the value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static int getInt(Reference array, int index) {
return intArrayLayout().getInt(array, index);
}
/**
* Writes into an element in a int array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a int array
* @param index the element into which to write
* @param value the new value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static void setInt(Reference array, int index, int value) {
intArrayLayout().setInt(array, index, value);
}
/**
* Access to <strong>float array object</strong> layout information in the
* context of the current {@linkplain VMConfiguration VM configuration}.
*/
@FOLD
public static ArrayLayout floatArrayLayout() {
return layoutScheme().floatArrayLayout;
}
/**
* Reads an element from a float array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a float array
* @param index the element to read
* @return the value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static float getFloat(Reference array, int index) {
return floatArrayLayout().getFloat(array, index);
}
/**
* Writes into an element in a float array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a float array
* @param index the element into which to write
* @param value the new value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static void setFloat(Reference array, int index, float value) {
floatArrayLayout().setFloat(array, index, value);
}
/**
* Access to <strong>long array object</strong> layout information in the
* context of the current {@linkplain VMConfiguration VM configuration}.
*/
@FOLD
public static ArrayLayout longArrayLayout() {
return layoutScheme().longArrayLayout;
}
/**
* Reads an element from a long array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a long array
* @param index the element to read
* @return the value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static long getLong(Reference array, int index) {
return longArrayLayout().getLong(array, index);
}
/**
* Writes into an element in a long array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a long array
* @param index the element into which to write
* @param value the new value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static void setLong(Reference array, int index, long value) {
longArrayLayout().setLong(array, index, value);
}
/**
* Access to <strong>double array object</strong> layout information in the
* context of the current {@linkplain VMConfiguration VM configuration}.
*/
@FOLD
public static ArrayLayout doubleArrayLayout() {
return layoutScheme().doubleArrayLayout;
}
/**
* Reads an element from a double array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a double array
* @param index the element to read
* @return the value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static double getDouble(Reference array, int index) {
return doubleArrayLayout().getDouble(array, index);
}
/**
* Writes into an element in a double array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a double array
* @param index the element into which to write
* @param value the new value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static void setDouble(Reference array, int index, double value) {
doubleArrayLayout().setDouble(array, index, value);
}
/**
* Access to <strong>word array object</strong> layout information in the
* context of the current {@linkplain VMConfiguration VM configuration}.
*/
@FOLD
public static ArrayLayout wordArrayLayout() {
return layoutScheme().wordArrayLayout;
}
/**
* Reads an element from a word array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a word array
* @param index the element to read
* @return the value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static Word getWord(Reference array, int index) {
return wordArrayLayout().getWord(array, index);
}
/**
* Writes into an element in a word array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a word array
* @param index the element into which to write
* @param value the new value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static void setWord(Reference array, int index, Word value) {
wordArrayLayout().setWord(array, index, value);
}
/**
* Access to <strong>reference array object</strong> layout information in the
* context of the current {@linkplain VMConfiguration VM configuration}.
*/
@FOLD
public static ArrayLayout referenceArrayLayout() {
return layoutScheme().referenceArrayLayout;
}
/**
* Reads an element from a reference array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a reference array
* @param index the element to read
* @return the value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static Reference getReference(Reference array, int index) {
return referenceArrayLayout().getReference(array, index);
}
/**
* Reads an element from a reference array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array location of a reference array
* @param index the element to read
* @return the value of the indexed element
*/
@ACCESSOR(Pointer.class)
@INLINE
public static Reference getReference(Pointer array, int index) {
return referenceArrayLayout().getReference(array, index);
}
/**
* Writes into an element in a reference array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array a reference array
* @param index the element into which to write
* @param value the new value of the indexed element
*/
@ACCESSOR(Reference.class)
@INLINE
public static void setReference(Reference array, int index, Reference value) {
referenceArrayLayout().setReference(array, index, value);
}
/**
* Writes into an element in a reference array, using layout information from the
* context of the current {@linkplain VMConfiguration VM configuration}.
*
* @param array location of a reference array
* @param index the element into which to write
* @param value the new value of the indexed element
*/
@ACCESSOR(Pointer.class)
@INLINE
public static void setReference(Pointer array, int index, Reference value) {
referenceArrayLayout().setReference(array, index, value);
}
/**
* Word index to a cell's hub from its origin.
*/
@FOLD
public static int hubIndex() {
return generalLayout().getOffsetFromOrigin(HeaderField.HUB).toInt() >> Word.widthValue().log2numberOfBytes;
}
/**
* Word index to the first element of a reference array from its origin.
*/
@FOLD
static public int firstElementIndex() {
return referenceArrayLayout().getElementOffsetInCell(0).toInt() >> Kind.REFERENCE.width.log2numberOfBytes;
}
@INLINE
static public Hub getHub(Pointer origin) {
return UnsafeCast.asHub(origin.getReference(Layout.hubIndex()));
}
}