Search in sources :

Example 21 with TIB

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);
}
Also used : RVMType(org.jikesrvm.classloader.RVMType) TIB(org.jikesrvm.objectmodel.TIB) Inline(org.vmmagic.pragma.Inline)

Example 22 with TIB

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);
    }
}
Also used : TIB(org.jikesrvm.objectmodel.TIB) Entrypoint(org.vmmagic.pragma.Entrypoint)

Example 23 with TIB

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;
}
Also used : TIB(org.jikesrvm.objectmodel.TIB) Entrypoint(org.vmmagic.pragma.Entrypoint)

Example 24 with TIB

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);
}
Also used : TIB(org.jikesrvm.objectmodel.TIB) Entrypoint(org.vmmagic.pragma.Entrypoint)

Example 25 with TIB

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);
        }
    }
}
Also used : CodeArray(org.jikesrvm.compilers.common.CodeArray) TIB(org.jikesrvm.objectmodel.TIB) Entrypoint(org.vmmagic.pragma.Entrypoint) Offset(org.vmmagic.unboxed.Offset)

Aggregations

TIB (org.jikesrvm.objectmodel.TIB)36 Entrypoint (org.vmmagic.pragma.Entrypoint)16 RVMArray (org.jikesrvm.classloader.RVMArray)14 RVMType (org.jikesrvm.classloader.RVMType)13 NoInline (org.vmmagic.pragma.NoInline)9 Interruptible (org.vmmagic.pragma.Interruptible)8 Address (org.vmmagic.unboxed.Address)7 Test (org.junit.Test)5 CodeArray (org.jikesrvm.compilers.common.CodeArray)4 ITable (org.jikesrvm.objectmodel.ITable)4 RVMClass (org.jikesrvm.classloader.RVMClass)3 RVMMethod (org.jikesrvm.classloader.RVMMethod)3 Offset (org.vmmagic.unboxed.Offset)3 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)2 IMT (org.jikesrvm.objectmodel.IMT)2 ITableArray (org.jikesrvm.objectmodel.ITableArray)2 Inline (org.vmmagic.pragma.Inline)2 BufferedOutputStream (java.io.BufferedOutputStream)1 FileOutputStream (java.io.FileOutputStream)1 PrintStream (java.io.PrintStream)1