Search in sources :

Example 56 with Entrypoint

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

the class Barriers method byteArrayRead.

/**
 * Barrier for loads of bytes from fields of arrays (i.e. baload).
 *
 * @param ref the array containing the reference.
 * @param index the index into the array were the reference resides.
 * @return the value read from the array
 */
@Inline
@Entrypoint
public static byte byteArrayRead(byte[] ref, int index) {
    if (NEEDS_BYTE_GC_READ_BARRIER) {
        ObjectReference array = ObjectReference.fromObject(ref);
        Offset offset = Offset.fromIntZeroExtend(index);
        return Selected.Mutator.get().byteRead(array, array.toAddress().plus(offset), offset.toWord(), Word.zero(), ARRAY_ELEMENT);
    } else if (VM.VerifyAssertions)
        VM._assert(VM.NOT_REACHED);
    return 0;
}
Also used : ObjectReference(org.vmmagic.unboxed.ObjectReference) Offset(org.vmmagic.unboxed.Offset) Entrypoint(org.vmmagic.pragma.Entrypoint) Inline(org.vmmagic.pragma.Inline)

Example 57 with Entrypoint

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

the class Barriers method booleanArrayRead.

/**
 * Barrier for loads of booleans from fields of arrays (i.e. aload).
 *
 * @param ref the array containing the reference.
 * @param index the index into the array were the reference resides.
 * @return the value read from the array
 */
@Inline
@Entrypoint
public static boolean booleanArrayRead(boolean[] ref, int index) {
    if (NEEDS_BOOLEAN_GC_READ_BARRIER) {
        ObjectReference array = ObjectReference.fromObject(ref);
        Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_BOOLEAN);
        return Selected.Mutator.get().booleanRead(array, array.toAddress().plus(offset), offset.toWord(), Word.zero(), ARRAY_ELEMENT);
    } else if (VM.VerifyAssertions)
        VM._assert(VM.NOT_REACHED);
    return false;
}
Also used : ObjectReference(org.vmmagic.unboxed.ObjectReference) Offset(org.vmmagic.unboxed.Offset) Entrypoint(org.vmmagic.pragma.Entrypoint) Inline(org.vmmagic.pragma.Inline)

Example 58 with Entrypoint

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

the class Barriers method charArrayWrite.

/**
 * Barrier for writes of chars into arrays (i.e. castore).
 *
 * @param ref the array which is the subject of the astore
 * @param index the index into the array where the new reference
 * resides.  The index is the "natural" index into the array, for
 * example a[index].
 * @param value the value to be stored.
 */
@Inline
@Entrypoint
public static void charArrayWrite(char[] ref, int index, char value) {
    if (NEEDS_CHAR_GC_WRITE_BARRIER) {
        ObjectReference array = ObjectReference.fromObject(ref);
        Offset offset = Offset.fromIntZeroExtend(index << LOG_BYTES_IN_CHAR);
        Selected.Mutator.get().charWrite(array, array.toAddress().plus(offset), value, offset.toWord(), Word.zero(), ARRAY_ELEMENT);
    } else if (VM.VerifyAssertions)
        VM._assert(VM.NOT_REACHED);
}
Also used : ObjectReference(org.vmmagic.unboxed.ObjectReference) Offset(org.vmmagic.unboxed.Offset) Entrypoint(org.vmmagic.pragma.Entrypoint) Inline(org.vmmagic.pragma.Inline)

Example 59 with Entrypoint

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

the class Barriers method intFieldWrite.

/**
 * Barrier for writes of ints into fields of instances (i.e. putfield).
 *
 * @param ref the object which is the subject of the putfield
 * @param value the new value for the field
 * @param offset the offset of the field to be modified
 * @param locationMetadata an int that encodes the source location being modified
 */
@Inline
@Entrypoint
public static void intFieldWrite(Object ref, int value, Offset offset, int locationMetadata) {
    if (NEEDS_INT_GC_WRITE_BARRIER) {
        ObjectReference src = ObjectReference.fromObject(ref);
        Selected.Mutator.get().intWrite(src, src.toAddress().plus(offset), value, offset.toWord(), Word.fromIntZeroExtend(locationMetadata), INSTANCE_FIELD);
    } else if (VM.VerifyAssertions)
        VM._assert(VM.NOT_REACHED);
}
Also used : ObjectReference(org.vmmagic.unboxed.ObjectReference) Entrypoint(org.vmmagic.pragma.Entrypoint) Inline(org.vmmagic.pragma.Inline)

Example 60 with Entrypoint

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

the class OutOfLineMachineCode method generateReflectiveMethodInvokerInstructions.

/**
 * Machine code for reflective method invocation.
 * <pre>
 * VM compiled with NUM_PARAMETERS_GPRS == 0
 *   Registers taken at runtime:
 *     none
 *   Stack taken at runtime:
 *     hi-mem
 *         address of method entrypoint to be called
 *         address of gpr registers to be loaded
 *         address of fpr registers to be loaded
 *         address of parameters area in calling frame
 *         return address
 *     low-mem
 *
 * VM compiled with NUM_PARAMETERS_GPRS == 1
 *   T0 == address of method entrypoint to be called
 *   Stack taken at runtime:
 *     hi-mem
 *         space ???
 *         address of gpr registers to be loaded
 *         address of fpr registers to be loaded
 *         address of parameters area in calling frame
 *         return address
 *     low-mem
 *
 * VM compiled with NUM_PARAMETERS_GPRS == 2
 *   T0 == address of method entrypoint to be called
 *   T1 == address of gpr registers to be loaded
 *   Stack taken at runtime:
 *     hi-mem
 *         space ???
 *         space ???
 *         address of fpr registers to be loaded
 *         address of parameters area in calling frame
 *         return address
 *     low-mem
 *
 * Registers returned at runtime:
 *   standard return value conventions used
 *
 * Side effects at runtime:
 *   artificial stackframe created and destroyed
 *   volatile, and scratch registers destroyed
 * </pre>
 *
 * @return instructions for the reflective method invoker
 */
private static CodeArray generateReflectiveMethodInvokerInstructions() {
    Assembler asm = new Assembler(100);
    int gprs;
    Offset fpOffset = ArchEntrypoints.framePointerField.getOffset();
    GPR T = T0;
    gprs = NUM_PARAMETER_GPRS;
    // we have exactly 5 paramaters, offset 0 from SP is the return address the
    // parameters are at offsets 5 to 1
    Offset offset = Offset.fromIntZeroExtend(5 << LG_WORDSIZE);
    // logically equivalent to ParamaterRegisterUnload in the compiler
    if (gprs > 0) {
        gprs--;
        if (VM.BuildFor32Addr) {
            asm.emitMOV_RegDisp_Reg(SP, offset, T);
        } else {
            asm.emitMOV_RegDisp_Reg_Quad(SP, offset, T);
        }
        T = T1;
        offset = offset.minus(WORDSIZE);
    }
    if (gprs > 0) {
        if (VM.BuildFor32Addr) {
            asm.emitMOV_RegDisp_Reg(SP, offset, T);
        } else {
            asm.emitMOV_RegDisp_Reg_Quad(SP, offset, T);
        }
    }
    /* available registers S0, T0, T1 */
    /* push a new frame */
    // link this frame with next
    asm.emitPUSH_RegDisp(TR, fpOffset);
    if (VM.BuildFor32Addr) {
        // establish base of new frame
        asm.emitMOV_RegDisp_Reg(THREAD_REGISTER, fpOffset, SP);
        asm.emitPUSH_Imm(INVISIBLE_METHOD_ID);
        asm.emitADD_Reg_Imm(SP, STACKFRAME_BODY_OFFSET.toInt());
    } else {
        // establish base of new frame
        asm.emitMOV_RegDisp_Reg_Quad(THREAD_REGISTER, fpOffset, SP);
        asm.emitPUSH_Imm(INVISIBLE_METHOD_ID);
        asm.emitADD_Reg_Imm_Quad(SP, STACKFRAME_BODY_OFFSET.toInt());
    }
    /* write parameters on stack
     * move data from memory addressed by Paramaters array, the fourth
     * parameter to this, into the stack.
     * SP target address
     * S0 source address
     * T1 length
     * T0 scratch
     */
    if (VM.BuildFor32Addr) {
        asm.emitMOV_Reg_RegDisp(S0, THREAD_REGISTER, fpOffset);
        // S0 <- Parameters
        asm.emitMOV_Reg_RegDisp(S0, S0, PARAMS_FP_OFFSET);
        // T1 <- Parameters.length()
        asm.emitMOV_Reg_RegDisp(T1, S0, ObjectModel.getArrayLengthOffset());
        // length == 0 ?
        asm.emitCMP_Reg_Imm(T1, 0);
    } else {
        asm.emitMOV_Reg_RegDisp_Quad(S0, THREAD_REGISTER, fpOffset);
        // S0 <- Parameters
        asm.emitMOV_Reg_RegDisp_Quad(S0, S0, PARAMS_FP_OFFSET);
        if (ARRAY_LENGTH_BYTES == 4) {
            // T1 <- Parameters.length()
            asm.emitMOV_Reg_RegDisp(T1, S0, ObjectModel.getArrayLengthOffset());
            // length == 0 ?
            asm.emitCMP_Reg_Imm(T1, 0);
        } else {
            // T1 <- Parameters.length()
            asm.emitMOV_Reg_RegDisp_Quad(T1, S0, ObjectModel.getArrayLengthOffset());
            // length == 0 ?
            asm.emitCMP_Reg_Imm_Quad(T1, 0);
        }
    }
    int parameterLoopLabel = asm.getMachineCodeIndex();
    // done? --> branch to end
    ForwardReference fr1 = asm.forwardJcc(EQ);
    if (VM.BuildFor32Addr) {
        // T0 <- Paramaters[i]
        asm.emitMOV_Reg_RegInd(T0, S0);
    } else {
        // T0 <- Paramaters[i]
        asm.emitMOV_Reg_RegInd_Quad(T0, S0);
    }
    // mem[j++] <- Parameters[i]
    asm.emitPUSH_Reg(T0);
    if (VM.BuildFor32Addr) {
        // i++
        asm.emitADD_Reg_Imm(S0, WORDSIZE);
    } else {
        // i++
        asm.emitADD_Reg_Imm_Quad(S0, WORDSIZE);
    }
    if (ARRAY_LENGTH_BYTES == 4) {
        // length--
        asm.emitADD_Reg_Imm(T1, -1);
    } else {
        // length--
        asm.emitADD_Reg_Imm_Quad(T1, -1);
    }
    asm.emitJMP_Imm(parameterLoopLabel);
    // end of the loop
    fr1.resolve(asm);
    if (SSE2_FULL) {
        /* write fprs onto fprs registers */
        if (VM.BuildFor32Addr) {
            asm.emitMOV_Reg_RegDisp(S0, THREAD_REGISTER, fpOffset);
            // T0 <- FPRs
            asm.emitMOV_Reg_RegDisp(T0, S0, FPRS_FP_OFFSET);
            // T1 <- FPRs.length()
            asm.emitMOV_Reg_RegDisp(T1, T0, ObjectModel.getArrayLengthOffset());
            // S0 <- FPRmeta
            asm.emitMOV_Reg_RegDisp(S0, S0, FPRMETA_FP_OFFSET);
        } else {
            asm.emitMOV_Reg_RegDisp_Quad(S0, THREAD_REGISTER, fpOffset);
            // T0 <- FPRs
            asm.emitMOV_Reg_RegDisp_Quad(T0, S0, FPRS_FP_OFFSET);
            if (ARRAY_LENGTH_BYTES == 4) {
                // T1 <- FPRs.length()
                asm.emitMOV_Reg_RegDisp(T1, T0, ObjectModel.getArrayLengthOffset());
            } else {
                // T1 <- FPRs.length()
                asm.emitMOV_Reg_RegDisp_Quad(T1, T0, ObjectModel.getArrayLengthOffset());
            }
            // S0 <- FPRmeta
            asm.emitMOV_Reg_RegDisp_Quad(S0, S0, FPRMETA_FP_OFFSET);
        }
        if (VM.VerifyAssertions)
            VM._assert(NUM_PARAMETER_FPRS <= 4);
        ForwardReference fr_next;
        // length == 0 ?
        asm.emitCMP_Reg_Imm(T1, 0);
        ForwardReference fpr_r1 = asm.forwardJcc(EQ);
        asm.emitMOVSD_Reg_RegInd(XMM0, T0);
        asm.emitCMP_RegInd_Imm_Byte(S0, 0);
        fr_next = asm.forwardJcc(NE);
        asm.emitCVTSD2SS_Reg_Reg(XMM0, XMM0);
        fr_next.resolve(asm);
        // length == 0 ?
        asm.emitSUB_Reg_Imm(T1, 1);
        ForwardReference fpr_r2 = asm.forwardJcc(EQ);
        asm.emitMOVSD_Reg_RegDisp(XMM1, T0, Offset.fromIntZeroExtend(BYTES_IN_DOUBLE));
        asm.emitCMP_RegDisp_Imm_Byte(S0, Offset.fromIntZeroExtend(1), 0);
        fr_next = asm.forwardJcc(NE);
        asm.emitCVTSD2SS_Reg_Reg(XMM1, XMM1);
        fr_next.resolve(asm);
        // length == 0 ?
        asm.emitSUB_Reg_Imm(T1, 1);
        ForwardReference fpr_r3 = asm.forwardJcc(EQ);
        asm.emitMOVSD_Reg_RegDisp(XMM2, T0, Offset.fromIntZeroExtend(BYTES_IN_DOUBLE * 2));
        asm.emitCMP_RegDisp_Imm_Byte(S0, Offset.fromIntZeroExtend(2), 0);
        fr_next = asm.forwardJcc(NE);
        asm.emitCVTSD2SS_Reg_Reg(XMM2, XMM2);
        fr_next.resolve(asm);
        // length == 0 ?
        asm.emitSUB_Reg_Imm(T1, 1);
        ForwardReference fpr_r4 = asm.forwardJcc(EQ);
        asm.emitMOVSD_Reg_RegDisp(XMM3, T0, Offset.fromIntZeroExtend(BYTES_IN_DOUBLE * 3));
        asm.emitCMP_RegDisp_Imm_Byte(S0, Offset.fromIntZeroExtend(3), 0);
        fr_next = asm.forwardJcc(NE);
        asm.emitCVTSD2SS_Reg_Reg(XMM3, XMM3);
        fr_next.resolve(asm);
        fpr_r1.resolve(asm);
        fpr_r2.resolve(asm);
        fpr_r3.resolve(asm);
        fpr_r4.resolve(asm);
    } else {
        if (VM.VerifyAssertions)
            VM._assert(VM.BuildFor32Addr);
        /* write fprs onto fprs registers */
        if (VM.BuildFor32Addr) {
            asm.emitMOV_Reg_RegDisp(S0, THREAD_REGISTER, fpOffset);
        } else {
            asm.emitMOV_Reg_RegDisp_Quad(S0, THREAD_REGISTER, fpOffset);
        }
        // S0 <- FPRs
        asm.emitMOV_Reg_RegDisp(S0, S0, FPRS_FP_OFFSET);
        // T1 <- FPRs.length()
        asm.emitMOV_Reg_RegDisp(T1, S0, ObjectModel.getArrayLengthOffset());
        // length in bytes
        asm.emitSHL_Reg_Imm(T1, LG_WORDSIZE + 1);
        // S0 <- last FPR + 8
        asm.emitADD_Reg_Reg(S0, T1);
        // length == 0 ?
        asm.emitCMP_Reg_Imm(T1, 0);
        int fprsLoopLabel = asm.getMachineCodeIndex();
        // done? --> branch to end
        ForwardReference fr2 = asm.forwardJcc(EQ);
        // i--
        asm.emitSUB_Reg_Imm(S0, 2 * WORDSIZE);
        // frp[fpr_sp++] <-FPRs[i]
        asm.emitFLD_Reg_RegInd_Quad(FP0, S0);
        // length--
        asm.emitSUB_Reg_Imm(T1, 2 * WORDSIZE);
        asm.emitJMP_Imm(fprsLoopLabel);
        // end of the loop
        fr2.resolve(asm);
    }
    /* write gprs: S0 = Base address of GPRs[], T1 = GPRs.length */
    if (VM.BuildFor32Addr) {
        asm.emitMOV_Reg_RegDisp(S0, THREAD_REGISTER, fpOffset);
        // S0 <- GPRs
        asm.emitMOV_Reg_RegDisp(S0, S0, GPRS_FP_OFFSET);
        // T1 <- GPRs.length()
        asm.emitMOV_Reg_RegDisp(T1, S0, ObjectModel.getArrayLengthOffset());
        // length == 0 ?
        asm.emitCMP_Reg_Imm(T1, 0);
    } else {
        asm.emitMOV_Reg_RegDisp_Quad(S0, THREAD_REGISTER, fpOffset);
        // S0 <- GPRs
        asm.emitMOV_Reg_RegDisp_Quad(S0, S0, GPRS_FP_OFFSET);
        if (ARRAY_LENGTH_BYTES == 4) {
            // T1 <- GPRs.length()
            asm.emitMOV_Reg_RegDisp(T1, S0, ObjectModel.getArrayLengthOffset());
            // length == 0 ?
            asm.emitCMP_Reg_Imm(T1, 0);
        } else {
            // T1 <- GPRs.length()
            asm.emitMOV_Reg_RegDisp_Quad(T1, S0, ObjectModel.getArrayLengthOffset());
            // length == 0 ?
            asm.emitCMP_Reg_Imm_Quad(T1, 0);
        }
    }
    // result 0 --> branch to end
    ForwardReference fr3 = asm.forwardJcc(EQ);
    if (VM.BuildFor32Addr) {
        // T0 <- GPRs[0]
        asm.emitMOV_Reg_RegInd(T0, S0);
        // S0 += WORDSIZE
        asm.emitADD_Reg_Imm(S0, WORDSIZE);
        // T1--
        asm.emitADD_Reg_Imm(T1, -1);
    } else {
        // T0 <- GPRs[0]
        asm.emitMOV_Reg_RegInd_Quad(T0, S0);
        // S0 += WORDSIZE
        asm.emitADD_Reg_Imm_Quad(S0, WORDSIZE);
        // T1--
        asm.emitADD_Reg_Imm_Quad(T1, -1);
    }
    // result 0 --> branch to end
    ForwardReference fr4 = asm.forwardJcc(EQ);
    if (VM.BuildFor32Addr) {
        // T1 <- GPRs[1]
        asm.emitMOV_Reg_RegInd(T1, S0);
    } else {
        // T1 <- GPRs[1]
        asm.emitMOV_Reg_RegInd_Quad(T1, S0);
    }
    fr3.resolve(asm);
    fr4.resolve(asm);
    /* branch to method.  On a good day we might even be back */
    if (VM.BuildFor32Addr) {
        asm.emitMOV_Reg_RegDisp(S0, THREAD_REGISTER, fpOffset);
        // S0 <- code
        asm.emitMOV_Reg_RegDisp(S0, S0, CODE_FP_OFFSET);
    } else {
        asm.emitMOV_Reg_RegDisp_Quad(S0, THREAD_REGISTER, fpOffset);
        // S0 <- code
        asm.emitMOV_Reg_RegDisp_Quad(S0, S0, CODE_FP_OFFSET);
    }
    // go there
    asm.emitCALL_Reg(S0);
    // add back in the initial SP to FP delta to get SP to be a framepointer again!
    if (VM.BuildFor32Addr) {
        asm.emitADD_Reg_Imm(SP, -STACKFRAME_BODY_OFFSET.toInt() + WORDSIZE);
    } else {
        asm.emitADD_Reg_Imm_Quad(SP, -STACKFRAME_BODY_OFFSET.toInt() + WORDSIZE);
    }
    asm.emitPOP_RegDisp(TR, fpOffset);
    // again, exactly 5 parameters
    asm.emitRET_Imm(5 << LG_WORDSIZE);
    return asm.getMachineCodes();
}
Also used : ForwardReference(org.jikesrvm.compilers.common.assembler.ForwardReference) GPR(org.jikesrvm.ia32.RegisterConstants.GPR) Assembler(org.jikesrvm.compilers.common.assembler.ia32.Assembler) Entrypoint(org.vmmagic.pragma.Entrypoint) Offset(org.vmmagic.unboxed.Offset)

Aggregations

Entrypoint (org.vmmagic.pragma.Entrypoint)69 Inline (org.vmmagic.pragma.Inline)35 ObjectReference (org.vmmagic.unboxed.ObjectReference)33 Offset (org.vmmagic.unboxed.Offset)22 Address (org.vmmagic.unboxed.Address)12 TypeReference (org.jikesrvm.classloader.TypeReference)7 NoInline (org.vmmagic.pragma.NoInline)7 RVMType (org.jikesrvm.classloader.RVMType)6 Unpreemptible (org.vmmagic.pragma.Unpreemptible)6 RVMMethod (org.jikesrvm.classloader.RVMMethod)5 RVMArray (org.jikesrvm.classloader.RVMArray)3 RVMClass (org.jikesrvm.classloader.RVMClass)3 RVMThread (org.jikesrvm.scheduler.RVMThread)3 BaselineSaveLSRegisters (org.vmmagic.pragma.BaselineSaveLSRegisters)3 NoOptCompile (org.vmmagic.pragma.NoOptCompile)3 AbstractRegisters (org.jikesrvm.architecture.AbstractRegisters)2 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)2 ForwardReference (org.jikesrvm.compilers.common.assembler.ForwardReference)2 ITable (org.jikesrvm.objectmodel.ITable)2 TIB (org.jikesrvm.objectmodel.TIB)2