/* * 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.jikesrvm.classloader; import org.jikesrvm.Constants; import org.jikesrvm.VM; import org.jikesrvm.objectmodel.TIB; import org.vmmagic.pragma.NonMoving; import org.vmmagic.pragma.Pure; import org.vmmagic.pragma.Uninterruptible; import org.vmmagic.unboxed.Offset; /** * Description of a java "primitive" type (int, float, etc.) * * <p> This description is not read from a ".class" file, but rather * is manufactured by the vm before execution begins. * * <p> Note that instances of primitives are not objects: * <ul> * <li> they are never heap allocated in the virtual machine * <li> they have no virtual methods * <li> they appear only in the virtual machine's stack, in its registers, * or in fields/elements of class/array instances. * </ul> * * @see RVMType * @see RVMClass * @see RVMArray * @see UnboxedType */ @NonMoving public final class Primitive extends RVMType implements Constants, ClassLoaderConstants { /** * The pretty (external) name for this primitive. * For example, for a long the name is 'long' * and the descriptor is 'J' */ private final Atom name; /** * How many slots in the Java Expression Stack does it take * to hold a value of this primitive type? */ private final int stackWords; /** * How many bytes in memory does it take to hold a value of this * primitive type? */ private final int memoryBytes; /** * Name - something like "int". */ @Override @Pure public String toString() { return name.toString(); } /** * Constructor * @param tr The canonical type reference for this primitive * @param classForType The java.lang.Class representation * @param name The name for this primitive * @param stackWords The stack slots used by this primitive * @param memoryBytes The bytes in memory used by this primitive */ private Primitive(TypeReference tr, Class<?> classForType, Atom name, int stackWords, int memoryBytes) { super(tr, // type reference classForType, // j.l.Class representation -1, // dimensionality null // runtime visible annotations ); this.name = name; this.stackWords = stackWords; this.memoryBytes = memoryBytes; this.depth = 0; } /** * Create an instance of a {@link Primitive} * @param tr The canonical type reference for this primitive */ static Primitive createPrimitive(TypeReference tr) { Atom name; int stackWords; int memoryBytes; Class<?> classForType; switch (tr.getName().parseForTypeCode()) { case VoidTypeCode: stackWords = 0; memoryBytes = 0; name = Atom.findOrCreateAsciiAtom("void"); classForType = Void.TYPE; break; case BooleanTypeCode: stackWords = 1; memoryBytes = BYTES_IN_BOOLEAN; name = Atom.findOrCreateAsciiAtom("boolean"); classForType = Boolean.TYPE; break; case ByteTypeCode: stackWords = 1; memoryBytes = BYTES_IN_BYTE; name = Atom.findOrCreateAsciiAtom("byte"); classForType = Byte.TYPE; break; case CharTypeCode: stackWords = 1; memoryBytes = BYTES_IN_CHAR; name = Atom.findOrCreateAsciiAtom("char"); classForType = Character.TYPE; break; case ShortTypeCode: stackWords = 1; memoryBytes = BYTES_IN_SHORT; name = Atom.findOrCreateAsciiAtom("short"); classForType = Short.TYPE; break; case IntTypeCode: stackWords = 1; memoryBytes = BYTES_IN_INT; name = Atom.findOrCreateAsciiAtom("int"); classForType = Integer.TYPE; break; case LongTypeCode: stackWords = 2; memoryBytes = BYTES_IN_LONG; name = Atom.findOrCreateAsciiAtom("long"); classForType = Long.TYPE; break; case FloatTypeCode: stackWords = 1; memoryBytes = BYTES_IN_FLOAT; name = Atom.findOrCreateAsciiAtom("float"); classForType = Float.TYPE; break; case DoubleTypeCode: stackWords = 2; memoryBytes = BYTES_IN_DOUBLE; name = Atom.findOrCreateAsciiAtom("double"); classForType = Double.TYPE; break; default: throw new Error("Unknown primitive "+tr.getName().classFileNameFromDescriptor()); } return new Primitive(tr, classForType, name, stackWords, memoryBytes); } /** * get number of superclasses to Object * @return 0 */ @Override @Pure @Uninterruptible public int getTypeDepth() { return 0; } /** * Reference Count GC: Is a reference of this type contained in * another object inherently acyclic (without cycles) ? * @return true */ @Override @Pure @Uninterruptible public boolean isAcyclicReference() { return true; } /** * Number of [ in descriptor for arrays; -1 for primitives; 0 for * classes * @return -1; */ @Override @Pure @Uninterruptible public int getDimensionality() { return -1; } /** * Resolution status. * @return true */ @Override @Uninterruptible public boolean isResolved() { return true; } /** * Instantiation status. * @return true */ @Override @Pure @Uninterruptible public boolean isInstantiated() { return true; } /** * Initialization status. * @return true */ @Override @Pure @Uninterruptible public boolean isInitialized() { return true; } /** * Only intended to be used by the BootImageWriter */ @Override public void markAsBootImageClass() {} /** * Is this class part of the virtual machine's boot image? */ @Override @Pure @Uninterruptible public boolean isInBootImage() { return true; } /** * Get the offset in instances of this type assigned to the thin * lock word. Offset.max() if instances of this type do not have thin lock * words. * @return Offset.max(); */ @Override @Pure @Uninterruptible public Offset getThinLockOffset() { if (VM.VerifyAssertions) VM._assert(NOT_REACHED); return Offset.max(); } /** * Whether or not this is an instance of RVMClass? * @return false */ @Override @Pure @Uninterruptible public boolean isClassType() { return false; } /** * Whether or not this is an instance of RVMArray? * @return false */ @Override @Pure @Uninterruptible public boolean isArrayType() { return false; } /** * Whether or not this is a primitive type * @return true */ @Override @Pure @Uninterruptible public boolean isPrimitiveType() { return true; } /** * @return whether or not this is a reference (ie non-primitive) type. */ @Override @Pure @Uninterruptible public boolean isReferenceType() { return false; } /** * @return whether or not this is an unboxed type */ @Override @Pure @Uninterruptible public boolean isUnboxedType() { return false; } /** * Stack space requirement in words. */ @Override @Pure @Uninterruptible public int getStackWords() { return stackWords; } /** * Space required in memory in bytes. */ @Override @Pure @Uninterruptible public int getMemoryBytes() { return memoryBytes; } /** * Cause resolution to take place. */ @Override @Pure public void resolve() {} @Override public void allBootImageTypesResolved() { } /** * Cause instantiation to take place. */ @Override @Pure public void instantiate() {} /** * Cause initialization to take place. */ @Override @Pure public void initialize() {} /** * Does this type override java.lang.Object.finalize()? */ @Override @Pure @Uninterruptible public boolean hasFinalizer() { return false; } /* * Primitives are not first class objects - * but the implementation of reflection is cleaner if * we pretend that they are and provide dummy implementations of * the following methods */ /** * Static fields of this class/array type. * @return zero length array */ @Override @Pure public RVMField[] getStaticFields() { return emptyVMField; } /** * Non-static fields of this class/array type * (composed with supertypes, if any). * @return zero length array */ @Override @Pure public RVMField[] getInstanceFields() { return emptyVMField; } /** * Statically dispatched methods of this class/array type. * @return zero length array */ @Override @Pure public RVMMethod[] getStaticMethods() { return emptyVMMethod; } /** * Virtually dispatched methods of this class/array type * (composed with supertypes, if any). * @return zero length array */ @Override @Pure public RVMMethod[] getVirtualMethods() { return emptyVMMethod; } /** * Runtime type information for this class/array type. */ @Override @Uninterruptible public TIB getTypeInformationBlock() { if (VM.VerifyAssertions) VM._assert(NOT_REACHED); return null; } }