Search in sources :

Example 11 with CodeArray

use of org.jikesrvm.compilers.common.CodeArray in project JikesRVM by JikesRVM.

the class BootImageWriter method copyToBootImage.

/**
 * Copy an object (and, recursively, any of its fields or elements that
 * are references) from host jdk address space into image.
 *
 * @param jdkObject object to be copied
 * @param allocOnly if allocOnly is true, the TIB and other reference fields are not recursively copied
 * @param overwriteAddress if !overwriteAddress.isMax(), then copy object to given address
 * @param parentObject
 * @param untraced Do not report any fields of this object as references
 * @param alignCode Alignment-encoded value (TIB allocation only)
 * @return offset of copied object within image, in bytes
 *         (OBJECT_NOT_PRESENT --> object not copied:
 *            it's not part of bootimage)
 */
private static Address copyToBootImage(Object jdkObject, boolean allocOnly, Address overwriteAddress, Object parentObject, boolean untraced, int alignCode) throws IllegalAccessException {
    try {
        // Return object if it is already copied and not being overwritten
        BootImageMap.Entry mapEntry = BootImageMap.findOrCreateEntry(jdkObject);
        if ((!mapEntry.imageAddress.EQ(OBJECT_NOT_ALLOCATED)) && overwriteAddress.isMax()) {
            return mapEntry.imageAddress;
        }
        if (verbosity.isAtLeast(DETAILED))
            depth++;
        // fetch object's type information
        Class<?> jdkType = jdkObject.getClass();
        RVMType rvmType = getRvmType(jdkType);
        if (rvmType == null) {
            if (verbosity.isAtLeast(DETAILED))
                traverseObject(jdkObject);
            if (verbosity.isAtLeast(DETAILED))
                depth--;
            // object not part of bootimage
            return OBJECT_NOT_PRESENT;
        }
        // copy object to image
        if (jdkType.isArray()) {
            // allocate space in image prior to recursing
            int arrayCount = Array.getLength(jdkObject);
            RVMArray rvmArrayType = rvmType.asArray();
            boolean needsIdentityHash = mapEntry.requiresIdentityHashCode();
            int identityHashValue = mapEntry.getIdentityHashCode();
            Address arrayImageAddress = (overwriteAddress.isMax()) ? bootImage.allocateArray(rvmArrayType, arrayCount, needsIdentityHash, identityHashValue, alignCode) : overwriteAddress;
            mapEntry.imageAddress = arrayImageAddress;
            mapEntry.imageAddress = copyArrayToBootImage(arrayCount, arrayImageAddress, jdkObject, jdkType, rvmArrayType, allocOnly, overwriteAddress, parentObject, untraced);
            // already
            if (!allocOnly) {
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.push("", jdkObject.getClass().getName(), "tib");
                Address tibImageAddress = copyToBootImage(rvmType.getTypeInformationBlock(), allocOnly, Address.max(), jdkObject, false, AlignmentEncoding.ALIGN_CODE_NONE);
                if (verbosity.isAtLeast(DETAILED))
                    traceContext.pop();
                if (tibImageAddress.EQ(OBJECT_NOT_ALLOCATED)) {
                    fail("can't copy tib for " + jdkObject);
                }
                ObjectModel.setTIB(bootImage, mapEntry.imageAddress, tibImageAddress, rvmType);
            }
        } else if (jdkObject instanceof TIB) {
            Object backing = ((RuntimeTable<?>) jdkObject).getBacking();
            int alignCodeValue = ((TIB) jdkObject).getAlignData();
            if (verbosity.isAtLeast(DETAILED))
                say("Encoding value " + alignCodeValue + " into tib");
            /* Copy the backing array, and then replace its TIB */
            mapEntry.imageAddress = copyToBootImage(backing, allocOnly, overwriteAddress, jdkObject, rvmType.getTypeRef().isRuntimeTable(), alignCodeValue);
            if (verbosity.isAtLeast(DETAILED))
                say(String.format("TIB address = %x, encoded value = %d, requested = %d%n", mapEntry.imageAddress.toInt(), AlignmentEncoding.extractTibCode(mapEntry.imageAddress), alignCodeValue));
            if (!allocOnly) {
                copyTIBToBootImage(rvmType, jdkObject, mapEntry.imageAddress);
            }
        } else if (rvmType == RVMType.ObjectReferenceArrayType || rvmType.getTypeRef().isRuntimeTable()) {
            Object backing = ((RuntimeTable<?>) jdkObject).getBacking();
            /* Copy the backing array, and then replace its TIB */
            mapEntry.imageAddress = copyToBootImage(backing, allocOnly, overwriteAddress, jdkObject, rvmType.getTypeRef().isRuntimeTable(), AlignmentEncoding.ALIGN_CODE_NONE);
            if (!allocOnly) {
                copyTIBToBootImage(rvmType, jdkObject, mapEntry.imageAddress);
            }
        } else if (jdkObject instanceof RuntimeTable) {
            Object backing = ((RuntimeTable<?>) jdkObject).getBacking();
            mapEntry.imageAddress = copyMagicArrayToBootImage(backing, rvmType.asArray(), allocOnly, overwriteAddress, parentObject);
        } else if (rvmType == RVMType.CodeArrayType) {
            // Handle the code array that is represented as either byte or int arrays
            if (verbosity.isAtLeast(DETAILED))
                depth--;
            Object backing = ((CodeArray) jdkObject).getBacking();
            return copyMagicArrayToBootImage(backing, rvmType.asArray(), allocOnly, overwriteAddress, parentObject);
        } else if (rvmType.getTypeRef().isMagicType()) {
            say("Unhandled copying of magic type: " + rvmType.getDescriptor().toString() + " in object of type " + parentObject.getClass().toString());
            fail("incomplete boot image support");
        } else {
            // allocate space in image
            if (rvmType instanceof RVMArray)
                fail("This isn't a scalar " + rvmType);
            RVMClass rvmScalarType = rvmType.asClass();
            boolean needsIdentityHash = mapEntry.requiresIdentityHashCode();
            int identityHashValue = mapEntry.getIdentityHashCode();
            Address scalarImageAddress = (overwriteAddress.isMax()) ? bootImage.allocateScalar(rvmScalarType, needsIdentityHash, identityHashValue) : overwriteAddress;
            mapEntry.imageAddress = scalarImageAddress;
            mapEntry.imageAddress = copyClassToBootImage(scalarImageAddress, jdkObject, jdkType, rvmScalarType, allocOnly, overwriteAddress, parentObject, untraced);
            // already
            if (!allocOnly) {
                copyTIBToBootImage(rvmType, jdkObject, mapEntry.imageAddress);
            }
        }
        if (verbosity.isAtLeast(DETAILED))
            depth--;
        return mapEntry.imageAddress;
    } catch (Error e) {
        e = new Error(e.getMessage() + "\nwhile copying " + jdkObject + (jdkObject != null ? ":" + jdkObject.getClass() : "") + " from " + parentObject + (parentObject != null ? ":" + parentObject.getClass() : ""), e.getCause() != null ? e.getCause() : e);
        throw e;
    }
}
Also used : Address(org.vmmagic.unboxed.Address) RVMType(org.jikesrvm.classloader.RVMType) TIB(org.jikesrvm.objectmodel.TIB) RVMClass(org.jikesrvm.classloader.RVMClass) RuntimeTable(org.jikesrvm.objectmodel.RuntimeTable) CodeArray(org.jikesrvm.compilers.common.CodeArray) RVMArray(org.jikesrvm.classloader.RVMArray)

Example 12 with CodeArray

use of org.jikesrvm.compilers.common.CodeArray in project JikesRVM by JikesRVM.

the class PostThreadSwitch method postProcess.

/**
 * This method must not be inlined to keep the correctness
 * This method is called at the end of threadSwitch, the caller
 * is threadSwitchFrom&lt;...&gt;
 *
 * @param myThread the currently running thread
 */
@NoInline
public static void postProcess(RVMThread myThread) {
    /* We need to generate thread specific code and install new code.
    * We have to make sure that no GC happens from here and before
    * the new code get executed.
    */
    // add branch instruction from CTR.
    CodeArray bridge = myThread.bridgeInstructions;
    Address bridgeaddr = Magic.objectAsAddress(bridge);
    if (VM.TraceOnStackReplacement) {
        VM.sysWriteln("osr post processing");
    }
    Offset offset = myThread.tsFPOffset.plus(STACKFRAME_RETURN_ADDRESS_OFFSET);
    Magic.objectAsAddress(myThread.getStack()).store(bridgeaddr, offset);
    myThread.tsFPOffset = Offset.zero();
    myThread.isWaitingForOsr = false;
    myThread.bridgeInstructions = null;
// no GC should happen until the glue code gets executed.
}
Also used : CodeArray(org.jikesrvm.compilers.common.CodeArray) Address(org.vmmagic.unboxed.Address) Offset(org.vmmagic.unboxed.Offset) NoInline(org.vmmagic.pragma.NoInline)

Example 13 with CodeArray

use of org.jikesrvm.compilers.common.CodeArray in project JikesRVM by JikesRVM.

the class InterfaceMethodConflictResolver method createStub.

/**
 * Creates a conflict resolution stub for the set of interface method signatures {@code l}.
 * @param sigIds ids of elements in {@code l}
 * @param targets target methods of elements in {@code l}
 * @return code that implements the stub
 */
public static CodeArray createStub(int[] sigIds, RVMMethod[] targets) {
    // (1) Create an assembler.
    int numEntries = sigIds.length;
    // pretend each entry is a bytecode
    Assembler asm = new Assembler(numEntries);
    // (2) signatures must be in ascending order (to build binary search tree).
    if (VM.VerifyAssertions) {
        for (int i = 1; i < sigIds.length; i++) {
            VM._assert(sigIds[i - 1] < sigIds[i]);
        }
    }
    // (3) Assign synthetic bytecode numbers to each switch such that we'll generate them
    // in ascending order.  This lets us use the general forward branching mechanisms
    // of the Assembler.
    int[] bcIndices = new int[numEntries];
    assignBytecodeIndices(0, bcIndices, 0, numEntries - 1);
    // (4) Generate the stub.
    insertStubPrologue(asm);
    insertStubCase(asm, sigIds, targets, bcIndices, 0, numEntries - 1);
    CodeArray stub = asm.getMachineCodes();
    // (5) synchronize icache with generated machine code that was written through dcache
    if (VM.runningVM)
        Memory.sync(Magic.objectAsAddress(stub), stub.length() << LG_INSTRUCTION_WIDTH);
    return stub;
}
Also used : CodeArray(org.jikesrvm.compilers.common.CodeArray) Assembler(org.jikesrvm.compilers.common.assembler.ppc.Assembler)

Example 14 with CodeArray

use of org.jikesrvm.compilers.common.CodeArray in project JikesRVM by JikesRVM.

the class DynamicLinker method lazyMethodInvoker.

/**
 * Resolve, compile if necessary, and invoke a method.
 * <pre>
 *  Taken:    nothing (calling context is implicit)
 *  Returned: does not return (method dispatch table is updated and method is executed)
 * </pre>
 */
@Entrypoint
static void lazyMethodInvoker() {
    DynamicLink dl = DL_Helper.resolveDynamicInvocation();
    RVMMethod targMethod = DL_Helper.resolveMethodRef(dl);
    DL_Helper.compileMethod(dl, targMethod);
    CodeArray code = targMethod.getCurrentEntryCodeArray();
    // restore parameters and invoke
    Magic.dynamicBridgeTo(code);
    // does not return here
    if (VM.VerifyAssertions)
        VM._assert(NOT_REACHED);
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) CodeArray(org.jikesrvm.compilers.common.CodeArray) Entrypoint(org.vmmagic.pragma.Entrypoint)

Example 15 with CodeArray

use of org.jikesrvm.compilers.common.CodeArray 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

CodeArray (org.jikesrvm.compilers.common.CodeArray)18 Address (org.vmmagic.unboxed.Address)6 Offset (org.vmmagic.unboxed.Offset)6 RVMClass (org.jikesrvm.classloader.RVMClass)4 RVMMethod (org.jikesrvm.classloader.RVMMethod)4 TIB (org.jikesrvm.objectmodel.TIB)4 Entrypoint (org.vmmagic.pragma.Entrypoint)4 NoInline (org.vmmagic.pragma.NoInline)4 RVMType (org.jikesrvm.classloader.RVMType)3 TypeReference (org.jikesrvm.classloader.TypeReference)3 FileOutputStream (java.io.FileOutputStream)2 IOException (java.io.IOException)2 PrintStream (java.io.PrintStream)2 TreeSet (java.util.TreeSet)2 RVMArray (org.jikesrvm.classloader.RVMArray)2 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)2 Interruptible (org.vmmagic.pragma.Interruptible)2 BufferedOutputStream (java.io.BufferedOutputStream)1 BufferedWriter (java.io.BufferedWriter)1 OutputStreamWriter (java.io.OutputStreamWriter)1