Search in sources :

Example 6 with NoInline

use of org.vmmagic.pragma.NoInline in project JikesRVM by JikesRVM.

the class JNIHelpers method invokeWithDotDotVarArg.

/**
 * Common code shared by the JNI functions Call<type>Method
 * (virtual method invocation)
 * @param obj the object instance
 * @param methodID the method ID
 * @param expectReturnType the return type for checking purpose
 * @param skip4Args  true if the calling JNI Function takes 4 args before the vararg
 *                   false if the calling JNI Function takes 3 args before the vararg
 * @return an object that may be the return object or a wrapper for the primitive return value
 * @throws Exception if the return type doesn't match the expected return type
 */
@NoInline
@NoOptCompile
public static // expect a certain stack frame structure
Object invokeWithDotDotVarArg(Object obj, int methodID, TypeReference expectReturnType, boolean skip4Args) throws Exception {
    MethodReference mr = MemberReference.getMethodRef(methodID);
    Address varargAddress = getVarArgAddress(skip4Args);
    Object[] argObjectArray = packageParameterFromVarArg(mr, varargAddress);
    return callMethod(obj, mr, argObjectArray, expectReturnType, skip4Args);
}
Also used : Address(org.vmmagic.unboxed.Address) MethodReference(org.jikesrvm.classloader.MethodReference) NoInline(org.vmmagic.pragma.NoInline) NoOptCompile(org.vmmagic.pragma.NoOptCompile)

Example 7 with NoInline

use of org.vmmagic.pragma.NoInline in project JikesRVM by JikesRVM.

the class JNIHelpers method invokeWithDotDotVarArg.

/**
 * Common code shared by the JNI functions CallStatic<type>Method
 * (static method invocation)
 * @param methodID the method ID
 * @param expectReturnType the return type of the method to be invoked
 * @return an object that may be the return object or a wrapper for the primitive return value
 */
@NoInline
public static Object invokeWithDotDotVarArg(int methodID, TypeReference expectReturnType) throws Exception {
    MethodReference mr = MemberReference.getMethodRef(methodID);
    if (VM.BuildForPower64ELF_ABI) {
        Address varargAddress = pushVarArgToSpillArea(methodID, false);
        Object[] argObjectArray = packageParameterFromVarArg(mr, varargAddress);
        return callMethod(null, mr, argObjectArray, expectReturnType, true);
    } else {
        if (VM.VerifyAssertions)
            VM._assert(VM.BuildForSVR4ABI);
        Address glueFP = Magic.getCallerFramePointer(Magic.getCallerFramePointer(Magic.getCallerFramePointer(Magic.getFramePointer())));
        Object[] argObjectArray = packageParameterFromDotArgSVR4(mr, glueFP, false);
        return callMethod(null, mr, argObjectArray, expectReturnType, true);
    }
}
Also used : Address(org.vmmagic.unboxed.Address) MethodReference(org.jikesrvm.classloader.MethodReference) NoInline(org.vmmagic.pragma.NoInline)

Example 8 with NoInline

use of org.vmmagic.pragma.NoInline in project JikesRVM by JikesRVM.

the class JNIHelpers method pushVarArgToSpillArea.

/**
 * This method supports var args passed from C.<p>
 *
 * TODO update for AIX removal
 *
 * In the AIX C convention, the caller keeps the first 8 words in registers and
 * the rest in the spill area in the caller frame.  The callee will push the values
 * in registers out to the spill area of the caller frame and use the beginning
 * address of this spill area as the var arg address.<p>
 *
 * For the JNI functions that takes var args, their prolog code will save the
 * var arg in the glue frame because the values in the register may be lost by
 * subsequent calls.<p>
 *
 * This method copies the var arg values that were saved earlier in glue frame into
 * the spill area of the original caller, thereby doing the work that the callee
 * normally performs in the AIX C convention..<p>
 *
 * NOTE:  this method assumes that it is immediately above the
 * invokeWithDotDotVarArg frame, the JNI frame, the glue frame and
 * the C caller frame in the respective order.
 * Therefore, this method will not work if called from anywhere else
 * <pre>
 *
 *   |  fp  | <- JNIEnvironment.pushVarArgToSpillArea
 *   | mid  |
 *   | xxx  |
 *   |      |
 *   |      |
 *   |------|
 *   |  fp  | <- JNIEnvironment.invokeWithDotDotVarArg frame
 *   | mid  |
 *   | xxx  |
 *   |      |
 *   |      |
 *   |      |
 *   |------|
 *   |  fp  | <- JNI method frame
 *   | mid  |
 *   | xxx  |
 *   |      |
 *   |      |
 *   |      |
 *   |------|
 *   |  fp  | <- glue frame
 *   | mid  |
 *   + xxx  +
 *   | r3   |   volatile save area
 *   | r4   |
 *   | r5   |
 *   | r6   |   vararg GPR[6-10]save area   <- VARARG_AREA_OFFSET
 *   | r7   |
 *   | r8   |
 *   | r9   |
 *   | r10  |
 *   | fpr1 |   vararg FPR[1-3] save area (also used as volatile FPR[1-6] save area)
 *   | fpr2 |
 *   | fpr3 |
 *   | fpr4 |
 *   | fpr5 |
 *   + fpr6 +
 *   | r13  |   nonvolatile GPR[13-31] save area
 *   | ...  |
 *   + r31  +
 *   | fpr14|   nonvolatile FPR[14-31] save area
 *   | ...  |
 *   | fpr31|
 *   |topjav|   offset to preceding Java to C glue frame
 *   |------|
 *   | fp   | <- Native C caller frame
 *   | cr   |
 *   | lr   |
 *   | resv |
 *   | resv |
 *   + toc  +
 *   |   0  |    spill area initially not filled
 *   |   1  |    to be filled by this method
 *   |   2  |
 *   |   3  |
 *   |   4  |
 *   |   5  |
 *   |   6  |
 *   |   7  |
 *   |   8  |    spill area already filled by caller
 *   |   9  |
 *   |      |
 *   |      |
 *   |      |
 * </pre>
 *
 * @param methodID a MemberReference id
 * @param skip4Args if true, the calling JNI function has 4 args before the vararg
 *                  if false, the calling JNI function has 3 args before the vararg
 * @return the starting address of the vararg in the caller stack frame
 */
@NoInline
private static Address pushVarArgToSpillArea(int methodID, boolean skip4Args) throws Exception {
    if (!(VM.BuildForPower64ELF_ABI || VM.BuildForSVR4ABI)) {
        if (VM.VerifyAssertions)
            VM._assert(VM.NOT_REACHED);
        return Address.zero();
    }
    int glueFrameSize = JNI_GLUE_FRAME_SIZE;
    // get the FP for this stack frame and traverse 3 frames to get to the glue frame
    Address gluefp = // *.ppc.JNIHelpers.invoke*
    Magic.getFramePointer().plus(StackFrameLayout.getStackFramePointerOffset()).loadAddress();
    // architecture.JNIHelpers.invoke*
    gluefp = gluefp.plus(StackFrameLayout.getStackFramePointerOffset()).loadAddress();
    // JNIFunctions
    gluefp = gluefp.plus(StackFrameLayout.getStackFramePointerOffset()).loadAddress();
    // glue frame
    gluefp = gluefp.plus(StackFrameLayout.getStackFramePointerOffset()).loadAddress();
    // compute the offset into the area where the vararg GPR[6-10] and FPR[1-3] are saved
    // skipping the args which are not part of the arguments for the target method
    // For Call<type>Method functions and NewObject, skip 3 args
    // For CallNonvirtual<type>Method functions, skip 4 args
    Offset varargGPROffset = Offset.fromIntSignExtend(VARARG_AREA_OFFSET + (skip4Args ? BYTES_IN_ADDRESS : 0));
    Offset varargFPROffset = varargGPROffset.plus(5 * BYTES_IN_ADDRESS);
    // compute the offset into the spill area of the native caller frame,
    // skipping the args which are not part of the arguments for the target method
    // For Call<type>Method functions, skip 3 args
    // For CallNonvirtual<type>Method functions, skip 4 args
    Offset spillAreaLimit = Offset.fromIntSignExtend(glueFrameSize + NATIVE_FRAME_HEADER_SIZE + 8 * BYTES_IN_ADDRESS);
    Offset spillAreaOffset = Offset.fromIntSignExtend(glueFrameSize + NATIVE_FRAME_HEADER_SIZE + (skip4Args ? 4 * BYTES_IN_ADDRESS : 3 * BYTES_IN_ADDRESS));
    // address to return pointing to the var arg list
    Address varargAddress = gluefp.plus(spillAreaOffset);
    // VM.sysWrite("pushVarArgToSpillArea:  var arg at " +
    // Services.intAsHexString(varargAddress) + "\n");
    RVMMethod targetMethod = MemberReference.getMethodRef(methodID).resolve();
    TypeReference[] argTypes = targetMethod.getParameterTypes();
    int argCount = argTypes.length;
    for (int i = 0; i < argCount && spillAreaOffset.sLT(spillAreaLimit); i++) {
        Word hiword, loword;
        if (argTypes[i].isFloatingPointType()) {
            // move 2 words from the vararg FPR save area into the spill area of the caller
            hiword = gluefp.loadWord(varargFPROffset);
            varargFPROffset = varargFPROffset.plus(BYTES_IN_ADDRESS);
            if (VM.BuildFor32Addr) {
                loword = gluefp.loadWord(varargFPROffset);
                varargFPROffset = varargFPROffset.plus(BYTES_IN_ADDRESS);
            }
            gluefp.store(hiword, spillAreaOffset);
            spillAreaOffset = spillAreaOffset.plus(BYTES_IN_ADDRESS);
            if (VM.BuildFor32Addr) {
                gluefp.store(loword, spillAreaOffset);
                spillAreaOffset = spillAreaOffset.plus(BYTES_IN_ADDRESS);
            }
        } else if (argTypes[i].isLongType()) {
            // move 2 words from the vararg GPR save area into the spill area of the caller
            hiword = gluefp.loadWord(varargGPROffset);
            varargGPROffset = varargGPROffset.plus(BYTES_IN_ADDRESS);
            gluefp.store(hiword, spillAreaOffset);
            spillAreaOffset = spillAreaOffset.plus(BYTES_IN_ADDRESS);
            // this covers the case when the long value straddles the spill boundary
            if (VM.BuildFor32Addr && spillAreaOffset.sLT(spillAreaLimit)) {
                loword = gluefp.loadWord(varargGPROffset);
                varargGPROffset = varargGPROffset.plus(BYTES_IN_ADDRESS);
                gluefp.store(loword, spillAreaOffset);
                spillAreaOffset = spillAreaOffset.plus(BYTES_IN_ADDRESS);
            }
        } else {
            hiword = gluefp.loadWord(varargGPROffset);
            varargGPROffset = varargGPROffset.plus(BYTES_IN_ADDRESS);
            gluefp.store(hiword, spillAreaOffset);
            spillAreaOffset = spillAreaOffset.plus(BYTES_IN_ADDRESS);
        }
    }
    // return the address of the beginning of the vararg to use in invoking the target method
    return varargAddress;
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) Word(org.vmmagic.unboxed.Word) Address(org.vmmagic.unboxed.Address) TypeReference(org.jikesrvm.classloader.TypeReference) Offset(org.vmmagic.unboxed.Offset) NoInline(org.vmmagic.pragma.NoInline)

Example 9 with NoInline

use of org.vmmagic.pragma.NoInline in project JikesRVM by JikesRVM.

the class MemoryManager method newRuntimeTable.

/**
 * Allocates a new runtime table (at runtime).
 *
 * @param size The size of the table
 * @param type the type for the table
 * @return the newly allocated table
 */
@NoInline
@Interruptible
public static Object newRuntimeTable(int size, RVMType type) {
    if (VM.VerifyAssertions)
        VM._assert(VM.runningVM);
    TIB realTib = type.getTypeInformationBlock();
    RVMArray fakeType = RVMType.WordArrayType;
    TIB fakeTib = fakeType.getTypeInformationBlock();
    int headerSize = ObjectModel.computeArrayHeaderSize(fakeType);
    int align = ObjectModel.getAlignment(fakeType);
    int offset = ObjectModel.getOffsetForAlignment(fakeType, false);
    int width = fakeType.getLogElementSize();
    /* Allocate a word array */
    Object array = allocateArray(size, width, headerSize, fakeTib, type.getMMAllocator(), align, offset, Plan.DEFAULT_SITE);
    /* Now we replace the TIB */
    ObjectModel.setTIB(array, realTib);
    return array;
}
Also used : RVMArray(org.jikesrvm.classloader.RVMArray) TIB(org.jikesrvm.objectmodel.TIB) Entrypoint(org.vmmagic.pragma.Entrypoint) Interruptible(org.vmmagic.pragma.Interruptible) NoInline(org.vmmagic.pragma.NoInline)

Example 10 with NoInline

use of org.vmmagic.pragma.NoInline in project JikesRVM by JikesRVM.

the class TIB method isInternalLazyCompilationTrampoline.

/**
 * @param virtualMethodIndex the index of the virtual method
 * @return whether a virtual method is the internal lazy compilation trampoline
 */
@NoInline
public boolean isInternalLazyCompilationTrampoline(int virtualMethodIndex) {
    int index = TIB_FIRST_VIRTUAL_METHOD_INDEX + virtualMethodIndex;
    Address tibAddress = Magic.objectAsAddress(this);
    Address callAddress = tibAddress.loadAddress(Offset.fromIntZeroExtend(index << LOG_BYTES_IN_ADDRESS));
    Address maxAddress = tibAddress.plus(Offset.fromIntZeroExtend(length() << LOG_BYTES_IN_ADDRESS));
    return callAddress.GE(tibAddress) && callAddress.LT(maxAddress);
}
Also used : Address(org.vmmagic.unboxed.Address) NoInline(org.vmmagic.pragma.NoInline)

Aggregations

NoInline (org.vmmagic.pragma.NoInline)46 Entrypoint (org.vmmagic.pragma.Entrypoint)23 Address (org.vmmagic.unboxed.Address)22 Unpreemptible (org.vmmagic.pragma.Unpreemptible)10 TIB (org.jikesrvm.objectmodel.TIB)9 Interruptible (org.vmmagic.pragma.Interruptible)9 RVMArray (org.jikesrvm.classloader.RVMArray)8 Word (org.vmmagic.unboxed.Word)6 NoOptCompile (org.vmmagic.pragma.NoOptCompile)5 Offset (org.vmmagic.unboxed.Offset)5 MethodReference (org.jikesrvm.classloader.MethodReference)4 CodeArray (org.jikesrvm.compilers.common.CodeArray)4 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)4 AbstractRegisters (org.jikesrvm.architecture.AbstractRegisters)3 RVMMethod (org.jikesrvm.classloader.RVMMethod)3 BaselineCompiledMethod (org.jikesrvm.compilers.baseline.BaselineCompiledMethod)3 OptCompiledMethod (org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod)3 BaselineSaveLSRegisters (org.vmmagic.pragma.BaselineSaveLSRegisters)3 RVMType (org.jikesrvm.classloader.RVMType)2 RVMThread (org.jikesrvm.scheduler.RVMThread)2