/*
* 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 an Unboxed Magic type.
*
* Currently, unboxed types are restricted to be values that can fit in a single machines word.
*
* @see RVMType
* @see RVMClass
* @see RVMArray
* @see Primitive
*/
@NonMoving
public final class UnboxedType extends RVMType implements Constants, ClassLoaderConstants {
/**
* The pretty (external) name for this Unboxed type.
*/
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 UnboxedType(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 UnboxedType}
* @param tr The canonical type reference for this primitive
*/
static UnboxedType createUnboxedType(TypeReference tr) {
Atom name;
int stackWords = 1;
int memoryBytes;
Class<?> classForType;
name = tr.getName();
if (tr == TypeReference.Address ||
tr == TypeReference.Word ||
tr == TypeReference.Offset ||
tr == TypeReference.Extent) {
memoryBytes = BYTES_IN_ADDRESS;
} else if (tr == TypeReference.Code) {
memoryBytes = VM.BuildForIA32 ? BYTES_IN_BYTE : BYTES_IN_INT;
} else {
throw new Error("Unknown unboxed type " + tr.getName());
}
try {
classForType = Class.forName(name.classNameFromDescriptor());
} catch (Exception e) {
throw new Error("Error getting java.lang.Class wrapper for type " + name.classNameFromDescriptor());
}
return new UnboxedType(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 false;
}
/**
* @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 true;
}
/**
* 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;
}
}