Search in sources :

Example 1 with Word

use of org.vmmagic.unboxed.Word in project JikesRVM by JikesRVM.

the class BootImageWriter method check.

private static void check(Word value, String msg) {
    // yes, max
    Word low = ObjectModel.maximumObjectRef(Address.zero()).toWord();
    // we shouldn't have that many objects
    Word high = Word.fromIntZeroExtend(0x10000000);
    if (value.GT(low) && value.LT(high) && !value.EQ(Word.fromIntZeroExtend(32767)) && (value.LT(Word.fromIntZeroExtend(4088)) || value.GT(Word.fromIntZeroExtend(4096)))) {
        say("Warning: Suspicious Address value of ", Services.addressAsHexString(value.toAddress()), " written for " + msg);
    }
}
Also used : Word(org.vmmagic.unboxed.Word)

Example 2 with Word

use of org.vmmagic.unboxed.Word in project JikesRVM by JikesRVM.

the class BootImageWriter method getWordValue.

private static Word getWordValue(Object addr, String msg, boolean warn) {
    if (addr == null)
        return Word.zero();
    Word value = Word.zero();
    if (addr instanceof Address) {
        value = ((Address) addr).toWord();
    } else if (addr instanceof ObjectReference) {
        value = ((ObjectReference) addr).toAddress().toWord();
    } else if (addr instanceof Word) {
        value = (Word) addr;
    } else if (addr instanceof Extent) {
        value = ((Extent) addr).toWord();
    } else if (addr instanceof Offset) {
        value = ((Offset) addr).toWord();
    } else {
        say("Unhandled supposed address value: " + addr);
        say(msg);
        fail("incomplete boot image support");
    }
    if (warn)
        check(value, msg);
    return value;
}
Also used : Word(org.vmmagic.unboxed.Word) Address(org.vmmagic.unboxed.Address) ObjectReference(org.vmmagic.unboxed.ObjectReference) Extent(org.vmmagic.unboxed.Extent) Offset(org.vmmagic.unboxed.Offset)

Example 3 with Word

use of org.vmmagic.unboxed.Word 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 4 with Word

use of org.vmmagic.unboxed.Word in project JikesRVM by JikesRVM.

the class JNIGenericHelpers method packageParametersFromJValuePtr.

/**
 * Repackage the arguments passed as an array of jvalue into an array of Object,
 * used by the JNI functions CallStatic&lt;type&gt;MethodA
 * @param targetMethod the target {@link MethodReference}
 * @param argAddress an address into the C space for the array of jvalue unions
 * @return an Object array holding the arguments wrapped at Objects
 */
protected static Object[] packageParametersFromJValuePtr(MethodReference targetMethod, Address argAddress) {
    TypeReference[] argTypes = targetMethod.getParameterTypes();
    int argCount = argTypes.length;
    Object[] argObjectArray = new Object[argCount];
    // get the JNIEnvironment for this thread in case we need to dereference any object arg
    JNIEnvironment env = RVMThread.getCurrentThread().getJNIEnv();
    Address addr = argAddress;
    for (int i = 0; i < argCount; i++, addr = addr.plus(BYTES_IN_LONG)) {
        // convert and wrap the argument according to the expected type
        if (argTypes[i].isReferenceType()) {
            // Avoid endianness issues by loading the whole slot
            Word wholeSlot = addr.loadWord();
            // for object, the arg is a JREF index, dereference to get the real object
            int JREFindex = wholeSlot.toInt();
            argObjectArray[i] = env.getJNIRef(JREFindex);
        } else if (argTypes[i].isIntType()) {
            argObjectArray[i] = addr.loadInt();
        } else if (argTypes[i].isLongType()) {
            argObjectArray[i] = addr.loadLong();
        } else if (argTypes[i].isBooleanType()) {
            // the 0/1 bit is stored in the high byte
            argObjectArray[i] = addr.loadByte() != 0;
        } else if (argTypes[i].isByteType()) {
            // the target byte is stored in the high byte
            argObjectArray[i] = addr.loadByte();
        } else if (argTypes[i].isCharType()) {
            // char is stored in the high 2 bytes
            argObjectArray[i] = addr.loadChar();
        } else if (argTypes[i].isShortType()) {
            // short is stored in the high 2 bytes
            argObjectArray[i] = addr.loadShort();
        } else if (argTypes[i].isFloatType()) {
            argObjectArray[i] = addr.loadFloat();
        } else {
            if (VM.VerifyAssertions)
                VM._assert(argTypes[i].isDoubleType());
            argObjectArray[i] = addr.loadDouble();
        }
    }
    return argObjectArray;
}
Also used : Word(org.vmmagic.unboxed.Word) Address(org.vmmagic.unboxed.Address) TypeReference(org.jikesrvm.classloader.TypeReference)

Example 5 with Word

use of org.vmmagic.unboxed.Word in project JikesRVM by JikesRVM.

the class JavaHeader method moveObject.

/**
 * Copies an object to the given raw storage address.
 *
 * @param toObj the target object. If this is non-{@code null}, the target
 *  address must be {@code Address.zero()}.
 * @param toAddress the target address. If this is not {@code Address.zero()},
 *  the target object must be {@code null}.
 * @param fromObj the object to copy from
 * @param numBytes the number of bytes to copy
 * @return the reference of the object's copy
 */
@Inline
public static Object moveObject(Address toAddress, Object fromObj, Object toObj, int numBytes) {
    if (VM.VerifyAssertions)
        VM._assert(toAddress.isZero() || toObj == null);
    // Default values
    int copyBytes = numBytes;
    int objRefOffset = OBJECT_REF_OFFSET;
    Word statusWord = Word.zero();
    Word hashState = HASH_STATE_UNHASHED;
    if (ADDRESS_BASED_HASHING) {
        // Read the hash state (used below)
        statusWord = Magic.getWordAtOffset(fromObj, STATUS_OFFSET);
        hashState = statusWord.and(HASH_STATE_MASK);
        if (hashState.EQ(HASH_STATE_HASHED)) {
            // We do not copy the hashcode, but we do allocate it
            copyBytes -= HASHCODE_BYTES;
            if (!DYNAMIC_HASH_OFFSET) {
                // The hashcode is the first word, so we copy to object one word higher
                if (toObj == null) {
                    toAddress = toAddress.plus(HASHCODE_BYTES);
                }
            }
        } else if (!DYNAMIC_HASH_OFFSET && hashState.EQ(HASH_STATE_HASHED_AND_MOVED)) {
            // Simple operation (no hash state change), but one word larger header
            objRefOffset += HASHCODE_BYTES;
        }
    }
    if (toObj != null) {
        toAddress = Magic.objectAsAddress(toObj).minus(objRefOffset);
    }
    // Low memory word of source object
    Address fromAddress = Magic.objectAsAddress(fromObj).minus(objRefOffset);
    // Do the copy
    Memory.aligned32Copy(toAddress, fromAddress, copyBytes);
    if (toObj == null) {
        toObj = Magic.addressAsObject(toAddress.plus(objRefOffset));
    } else {
        if (VM.VerifyAssertions)
            VM._assert(toObj == Magic.addressAsObject(toAddress.plus(objRefOffset)));
    }
    // Do we need to copy the hash code?
    if (hashState.EQ(HASH_STATE_HASHED)) {
        int hashCode = Magic.objectAsAddress(fromObj).toWord().rshl(LOG_BYTES_IN_ADDRESS).toInt();
        if (DYNAMIC_HASH_OFFSET) {
            Magic.setIntAtOffset(toObj, Offset.fromIntSignExtend(numBytes - OBJECT_REF_OFFSET - HASHCODE_BYTES), hashCode);
        } else {
            Magic.setIntAtOffset(toObj, HASHCODE_OFFSET, (hashCode << 1) | ALIGNMENT_MASK);
        }
        Magic.setWordAtOffset(toObj, STATUS_OFFSET, statusWord.or(HASH_STATE_HASHED_AND_MOVED));
        if (ObjectModel.HASH_STATS)
            ObjectModel.hashTransition2++;
    }
    return toObj;
}
Also used : Word(org.vmmagic.unboxed.Word) Address(org.vmmagic.unboxed.Address) Inline(org.vmmagic.pragma.Inline) NoInline(org.vmmagic.pragma.NoInline)

Aggregations

Word (org.vmmagic.unboxed.Word)62 Inline (org.vmmagic.pragma.Inline)15 Address (org.vmmagic.unboxed.Address)14 NoInline (org.vmmagic.pragma.NoInline)11 Offset (org.vmmagic.unboxed.Offset)10 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)8 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)8 CodeConstantOperand (org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand)8 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)8 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)8 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)8 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)8 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)8 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)8 ObjectConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand)8 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)8 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)8 TIBConstantOperand (org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand)8 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)8 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)8