use of org.jikesrvm.objectmodel.TIB in project JikesRVM by JikesRVM.
the class ObjectModel method copy.
@Override
@Inline
public ObjectReference copy(ObjectReference from, int allocator) {
TIB tib = org.jikesrvm.objectmodel.ObjectModel.getTIB(from);
RVMType type = Magic.objectAsType(tib.getType());
if (type.isClassType())
return copyScalar(from, tib, type.asClass(), allocator);
else
return copyArray(from, tib, type.asArray(), allocator);
}
use of org.jikesrvm.objectmodel.TIB in project JikesRVM by JikesRVM.
the class RVMArray method resolve.
/**
* Resolve an array.
* Also forces the resolution of the element type.
*/
@Override
public void resolve() {
synchronized (this) {
if (isResolved())
return;
if (VM.VerifyAssertions)
VM._assert(state == CLASS_LOADED);
}
// Resolving the element type requires a lock on the RVMType object that
// represents the element type. It does *not* require the lock of this object.
// It is thus safe to release the lock on this object while the element type is
// being resolved. This helps to to prevent deadlocks when compiling with multiple
// threads.
elementType.resolve();
synchronized (this) {
if (isResolved())
return;
// Using the type information block for java.lang.Object as a template,
// build a type information block for this new array type by copying the
// virtual method fields and substituting an appropriate type field.
//
TIB javaLangObjectTIB = RVMType.JavaLangObjectType.getTypeInformationBlock();
int alignCode = elementType.isReferenceType() ? HandInlinedScanning.referenceArray() : HandInlinedScanning.primitiveArray();
TIB allocatedTib = MemoryManager.newTIB(javaLangObjectTIB.numVirtualMethods(), alignCode);
superclassIds = DynamicTypeCheck.buildSuperclassIds(this);
doesImplement = DynamicTypeCheck.buildDoesImplement(this);
publishResolved(allocatedTib, superclassIds, doesImplement);
MemoryManager.notifyClassResolved(this);
}
}
use of org.jikesrvm.objectmodel.TIB in project JikesRVM by JikesRVM.
the class RVMArray method instantiate.
/**
* Instantiate an array.
* Main result is to copy the virtual methods from JavaLangObject's TIB.
*/
@Override
public synchronized void instantiate() {
if (isInstantiated())
return;
if (VM.VerifyAssertions)
VM._assert(state == CLASS_RESOLVED);
if (VM.TraceClassLoading && VM.runningVM) {
VM.sysWriteln("RVMArray: instantiate " + this);
}
// Initialize TIB slots for virtual methods (copy from superclass == Object)
RVMType objectType = RVMType.JavaLangObjectType;
if (VM.VerifyAssertions)
VM._assert(objectType.isInstantiated());
TIB javaLangObjectTIB = objectType.getTypeInformationBlock();
for (int i = 0; i < javaLangObjectTIB.numVirtualMethods(); i++) {
typeInformationBlock.setVirtualMethod(i, javaLangObjectTIB.getVirtualMethod(i));
}
SpecializedMethodManager.notifyTypeInstantiated(this);
// arrays have no "initialize" phase
state = CLASS_INITIALIZED;
}
use of org.jikesrvm.objectmodel.TIB in project JikesRVM by JikesRVM.
the class RVMClass method resolve.
/**
* {@inheritDoc} Space in the JTOC is allocated for static fields,
* static methods and constructors. Moreover, this method generates size
* and offset information for members of this class.<p>
*
* Side effects: superclasses and superinterfaces are resolved.
*/
@Override
public synchronized void resolve() {
if (isResolved())
return;
if (VM.TraceClassLoading && VM.runningVM)
VM.sysWriteln("RVMClass: (begin) resolve " + this);
if (VM.VerifyAssertions)
VM._assert(state == CLASS_LOADED);
//
if (superClass != null) {
superClass.resolve();
}
for (RVMClass declaredInterface : declaredInterfaces) {
declaredInterface.resolve();
}
if (isInterface()) {
if (VM.VerifyAssertions)
VM._assert(superClass == null);
depth = 1;
thinLockOffset = Offset.max();
} else if (superClass == null) {
if (VM.VerifyAssertions)
VM._assert(isJavaLangObjectType());
instanceSize = ObjectModel.computeScalarHeaderSize(this);
alignment = BYTES_IN_ADDRESS;
thinLockOffset = ObjectModel.defaultThinLockOffset();
depth = 0;
} else {
depth = superClass.depth + 1;
thinLockOffset = superClass.thinLockOffset;
instanceSize = superClass.instanceSize;
fieldLayoutContext = superClass.fieldLayoutContext;
alignment = superClass.alignment;
}
if (this == RVMType.JavaLangClassType) {
ObjectModel.allocateThinLock(this);
}
if (superClass != null && superClass.isNonMoving() && !isNonMoving()) {
VM.sysWriteln("WARNING: movable " + this + " extends non-moving " + superClass);
}
if (VM.verboseClassLoading)
VM.sysWriteln("[Preparing " + this + "]");
// build field and method lists for this class
//
{
FieldVector staticFields = new FieldVector();
FieldVector instanceFields = new FieldVector();
MethodVector staticMethods = new MethodVector();
MethodVector constructorMethods = new MethodVector();
MethodVector virtualMethods = new MethodVector();
//
if (superClass != null) {
for (RVMField field : superClass.getInstanceFields()) {
instanceFields.addElement(field);
}
for (RVMMethod method : superClass.getVirtualMethods()) {
virtualMethods.addElement(method);
}
}
//
for (RVMField field : getDeclaredFields()) {
if (field.isStatic()) {
staticFields.addElement(field);
} else {
instanceFields.addElement(field);
}
}
//
for (RVMMethod method : getDeclaredMethods()) {
if (VM.VerifyUnint) {
if (method.isSynchronized() && method.isUninterruptible()) {
if (VM.ParanoidVerifyUnint || !method.hasLogicallyUninterruptibleAnnotation()) {
VM.sysWriteln("WARNING: " + method + " cannot be both uninterruptible and synchronized");
}
}
}
if (method.isObjectInitializer()) {
Callbacks.notifyMethodOverride(method, null);
constructorMethods.addElement(method);
} else if (method.isStatic()) {
if (!method.isClassInitializer()) {
Callbacks.notifyMethodOverride(method, null);
staticMethods.addElement(method);
}
} else {
if (method.isSynchronized()) {
ObjectModel.allocateThinLock(this);
}
// method could override something in superclass - check for it
//
int superclassMethodIndex = -1;
for (int j = 0, m = virtualMethods.size(); j < m; ++j) {
RVMMethod alreadyDefinedMethod = virtualMethods.elementAt(j);
if (alreadyDefinedMethod.getName() == method.getName() && alreadyDefinedMethod.getDescriptor() == method.getDescriptor()) {
// method already defined in superclass
superclassMethodIndex = j;
break;
}
}
if (superclassMethodIndex == -1) {
Callbacks.notifyMethodOverride(method, null);
// append
virtualMethods.addElement(method);
} else {
RVMMethod superc = virtualMethods.elementAt(superclassMethodIndex);
if (VM.VerifyUnint) {
if (!superc.isInterruptible() && method.isInterruptible()) {
VM.sysWriteln("WARNING: interruptible " + method + " overrides uninterruptible " + superc);
}
}
Callbacks.notifyMethodOverride(method, superc);
// override
virtualMethods.setElementAt(method, superclassMethodIndex);
}
}
}
// method is declared. If one is not, then create an abstract method to fill the void.
if (!isInterface() && isAbstract()) {
for (RVMClass I : declaredInterfaces) {
RVMMethod[] iMeths = I.getVirtualMethods();
outer: for (RVMMethod iMeth : iMeths) {
Atom iName = iMeth.getName();
Atom iDesc = iMeth.getDescriptor();
for (int k = 0; k < virtualMethods.size(); k++) {
RVMMethod vMeth = virtualMethods.elementAt(k);
if (vMeth.getName() == iName && vMeth.getDescriptor() == iDesc)
continue outer;
}
MemberReference mRef = MemberReference.findOrCreate(typeRef, iName, iDesc);
virtualMethods.addElement(new AbstractMethod(getTypeRef(), mRef, (short) (ACC_ABSTRACT | ACC_PUBLIC), iMeth.getExceptionTypes(), null, null, null, null));
}
}
}
// If this is an interface, inherit methods from its superinterfaces
if (isInterface()) {
for (RVMClass declaredInterface : declaredInterfaces) {
RVMMethod[] meths = declaredInterface.getVirtualMethods();
for (RVMMethod meth : meths) {
virtualMethods.addUniqueElement(meth);
}
}
}
this.staticFields = staticFields.finish();
this.instanceFields = instanceFields.finish();
this.staticMethods = staticMethods.finish();
this.constructorMethods = constructorMethods.finish();
this.virtualMethods = virtualMethods.finish();
}
//
for (RVMField field : staticFields) {
if (field.isReferenceType()) {
field.setOffset(Statics.allocateReferenceSlot(true));
} else if (field.getSize() <= BYTES_IN_INT) {
field.setOffset(Statics.allocateNumericSlot(BYTES_IN_INT, true));
} else {
field.setOffset(Statics.allocateNumericSlot(BYTES_IN_LONG, true));
}
// seems to be a good time.
if (field.isFinal()) {
setFinalStaticJTOCEntry(field, field.getOffset());
}
}
// lay out instance fields
//
ObjectModel.layoutInstanceFields(this);
// count reference fields
int referenceFieldCount = 0;
for (RVMField field : instanceFields) {
if (field.isTraced()) {
referenceFieldCount += 1;
}
}
//
if (typeRef.isRuntimeTable()) {
referenceOffsets = MemoryManager.newNonMovingIntArray(0);
} else {
referenceOffsets = MemoryManager.newNonMovingIntArray(referenceFieldCount);
int j = 0;
for (RVMField field : instanceFields) {
if (field.isTraced()) {
referenceOffsets[j++] = field.getOffset().toInt();
}
}
}
//
for (RVMMethod method : constructorMethods) {
method.setOffset(Statics.allocateReferenceSlot(true));
}
//
for (RVMMethod method : staticMethods) {
if (method.isClassInitializer()) {
// should never be used.
method.setOffset(Offset.fromIntZeroExtend(0xebad0ff5));
} else {
method.setOffset(Statics.allocateReferenceSlot(true));
}
}
if (!isInterface()) {
// (to be filled in by instantiate)
for (int i = 0, n = virtualMethods.length; i < n; ++i) {
RVMMethod method = virtualMethods[i];
method.setOffset(TIB.getVirtualMethodOffset(i));
}
}
// RCGC: Determine if class is inherently acyclic
// must initially be false for recursive types
acyclic = false;
boolean foundCyclic = false;
for (RVMField instanceField : instanceFields) {
TypeReference ft = instanceField.getType();
if (!ft.isResolved() || !ft.peekType().isAcyclicReference()) {
foundCyclic = true;
break;
}
}
if (!foundCyclic) {
acyclic = true;
}
// allocate "type information block"
TIB allocatedTib;
if (isInterface()) {
allocatedTib = MemoryManager.newTIB(0, AlignmentEncoding.ALIGN_CODE_NONE);
} else if (isAnnotationDeclared(TypeReference.ReferenceFieldsVary)) {
allocatedTib = MemoryManager.newTIB(virtualMethods.length, HandInlinedScanning.fallback());
} else {
allocatedTib = MemoryManager.newTIB(virtualMethods.length, HandInlinedScanning.scalar(referenceOffsets));
}
superclassIds = DynamicTypeCheck.buildSuperclassIds(this);
doesImplement = DynamicTypeCheck.buildDoesImplement(this);
// can't move this beyond "finalize" code block as findVirtualMethod
// assumes state >= RESOLVED, no allocation occurs until
// state >= CLASS_INITIALIZING
publishResolved(allocatedTib, superclassIds, doesImplement);
// TODO: Make this into a more general listener interface
if (VM.BuildForOptCompiler && VM.writingBootImage) {
classLoadListener.classInitialized(this, true);
}
Callbacks.notifyClassResolved(this);
MemoryManager.notifyClassResolved(this);
//
if (!isInterface()) {
final RVMMethod method = findVirtualMethod(RVMClassLoader.StandardObjectFinalizerMethodName, RVMClassLoader.StandardObjectFinalizerMethodDescriptor);
if (!method.getDeclaringClass().isJavaLangObjectType()) {
hasFinalizer = true;
}
}
if (VM.TraceClassLoading && VM.runningVM)
VM.sysWriteln("RVMClass: (end) resolve " + this);
}
use of org.jikesrvm.objectmodel.TIB in project JikesRVM by JikesRVM.
the class RVMType method updateArrayMethods.
/**
* Updates the TIB for all array types with the newly (re)compiled method.
*
* @param m the method that was recompiled. Must be a virtual method
* declared by {@code java.lang.Object}.
*/
static synchronized void updateArrayMethods(RVMMethod m) {
if (VM.VerifyAssertions)
VM._assert(m.getDeclaringClass().isJavaLangObjectType());
if (VM.VerifyAssertions)
VM._assert(!m.isStatic());
// Start at slot 1 since nextId is initialized to 1
for (int i = 1; i <= numTypes(); i++) {
RVMType type = RVMType.getType(i);
if (type.isArrayType() && type.isResolved()) {
TIB arrayTIB = type.getTypeInformationBlock();
TIB objectTIB = RVMType.JavaLangObjectType.getTypeInformationBlock();
Offset virtualMethodOffset = m.getOffset();
CodeArray virtualMethod = objectTIB.getVirtualMethod(virtualMethodOffset);
arrayTIB.setVirtualMethod(virtualMethodOffset, virtualMethod);
}
}
}
Aggregations