Search in sources :

Example 61 with TypeReference

use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method defineStackAndLocalLocations.

private void defineStackAndLocalLocations() {
    short nextFixedLocalRegister = FIRST_FIXED_LOCAL_REGISTER.value();
    short nextFloatLocalRegister = FIRST_FLOAT_LOCAL_REGISTER.value();
    // define local registers
    int nparam = method.getParameterWords();
    TypeReference[] types = method.getParameterTypes();
    int localIndex = 0;
    if (!method.isStatic()) {
        if (VM.VerifyAssertions)
            VM._assert(localTypes[0] == ADDRESS_TYPE);
        if (!use_nonvolatile_registers || (nextFixedLocalRegister > LAST_FIXED_LOCAL_REGISTER.value())) {
            localFixedLocations[localIndex] = offsetToLocation(localOffset(localIndex));
        } else {
            localFixedLocations[localIndex] = nextFixedLocalRegister++;
        }
        localIndex++;
        nparam++;
    }
    for (int i = 0; i < types.length; i++, localIndex++) {
        TypeReference t = types[i];
        if (t.isLongType()) {
            if (VM.BuildFor64Addr) {
                if (!use_nonvolatile_registers || (nextFixedLocalRegister > LAST_FIXED_LOCAL_REGISTER.value())) {
                    localFixedLocations[localIndex] = offsetToLocation(localOffset(localIndex));
                } else {
                    localFixedLocations[localIndex] = nextFixedLocalRegister++;
                }
            } else {
                if (!use_nonvolatile_registers || (nextFixedLocalRegister >= LAST_FIXED_LOCAL_REGISTER.value())) {
                    localFixedLocations[localIndex] = // lo mem := lo register (== hi word)
                    offsetToLocation(localOffset(localIndex));
                // we don't fill in the second location !! Every access is through te location of the first half
                } else {
                    localFixedLocations[localIndex] = nextFixedLocalRegister++;
                    localFixedLocations[localIndex + 1] = nextFixedLocalRegister++;
                }
            }
            localIndex++;
        } else if (t.isFloatType()) {
            if (!use_nonvolatile_registers || (nextFloatLocalRegister > LAST_FLOAT_LOCAL_REGISTER.value())) {
                localFloatLocations[localIndex] = offsetToLocation(localOffset(localIndex));
            } else {
                localFloatLocations[localIndex] = nextFloatLocalRegister++;
            }
        } else if (t.isDoubleType()) {
            if (!use_nonvolatile_registers || (nextFloatLocalRegister > LAST_FLOAT_LOCAL_REGISTER.value())) {
                localFloatLocations[localIndex] = offsetToLocation(localOffset(localIndex));
            } else {
                localFloatLocations[localIndex] = nextFloatLocalRegister++;
            }
            localIndex++;
        } else if (t.isIntLikeType()) {
            if (!use_nonvolatile_registers || (nextFixedLocalRegister > LAST_FIXED_LOCAL_REGISTER.value())) {
                localFixedLocations[localIndex] = offsetToLocation(localOffset(localIndex));
            } else {
                localFixedLocations[localIndex] = nextFixedLocalRegister++;
            }
        } else {
            // t is object
            if (!use_nonvolatile_registers || (nextFixedLocalRegister > LAST_FIXED_LOCAL_REGISTER.value())) {
                localFixedLocations[localIndex] = offsetToLocation(localOffset(localIndex));
            } else {
                localFixedLocations[localIndex] = nextFixedLocalRegister++;
            }
        }
    }
    if (VM.VerifyAssertions)
        VM._assert(localIndex == nparam);
    // rest of locals, non parameters, could be reused for different types
    int nLocalWords = method.getLocalWords();
    for (; localIndex < nLocalWords; localIndex++) {
        byte currentLocal = localTypes[localIndex];
        if (needsFloatRegister(currentLocal)) {
            // float or double
            if (!use_nonvolatile_registers || (nextFloatLocalRegister > LAST_FLOAT_LOCAL_REGISTER.value())) {
                localFloatLocations[localIndex] = offsetToLocation(localOffset(localIndex));
            } else {
                localFloatLocations[localIndex] = nextFloatLocalRegister++;
            }
        }
        currentLocal = stripFloatRegisters(currentLocal);
        if (currentLocal != VOID_TYPE) {
            // object or intlike
            if (VM.BuildFor32Addr && containsLongType(currentLocal)) {
                // long
                if (!use_nonvolatile_registers || (nextFixedLocalRegister >= LAST_FIXED_LOCAL_REGISTER.value())) {
                    localFixedLocations[localIndex] = offsetToLocation(localOffset(localIndex));
                    // two longs next to each other, overlapping one location, last long can't be stored in registers anymore :
                    if (use_nonvolatile_registers && (nextFixedLocalRegister == LAST_FIXED_LOCAL_REGISTER.value()) && containsLongType(localTypes[localIndex - 1])) {
                        // if only 1 reg left, but already reserved by previous long, count it here !!
                        nextFixedLocalRegister++;
                    }
                } else {
                    localFixedLocations[localIndex] = nextFixedLocalRegister++;
                }
                localTypes[localIndex + 1] |= // there is at least one more, since this is long; mark so that we certainly assign a location to the second half
                INT_TYPE;
            } else if (!use_nonvolatile_registers || (nextFixedLocalRegister > LAST_FIXED_LOCAL_REGISTER.value())) {
                localFixedLocations[localIndex] = offsetToLocation(localOffset(localIndex));
            } else {
                localFixedLocations[localIndex] = nextFixedLocalRegister++;
            }
        }
    // else unused, assign nothing, can be the case after long or double
    }
    firstFixedStackRegister = (byte) nextFixedLocalRegister;
    firstFloatStackRegister = (byte) nextFloatLocalRegister;
    // define stack registers
    // KV: TODO
    lastFixedStackRegister = (byte) (firstFixedStackRegister - 1);
    lastFloatStackRegister = (byte) (firstFloatStackRegister - 1);
    if (USE_NONVOLATILE_REGISTERS && method.hasBaselineSaveLSRegistersAnnotation()) {
        // methods with SaveLSRegisters pragma need to save/restore ALL registers in their prolog/epilog
        lastFixedStackRegister = LAST_FIXED_STACK_REGISTER.value();
        lastFloatStackRegister = LAST_FLOAT_STACK_REGISTER.value();
    }
}
Also used : TypeReference(org.jikesrvm.classloader.TypeReference)

Example 62 with TypeReference

use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_resolved_getfield.

@Override
protected void emit_resolved_getfield(FieldReference fieldRef) {
    RVMField field = fieldRef.peekResolvedField();
    TypeReference fieldType = fieldRef.getFieldContentsType();
    Offset fieldOffset = field.getOffset();
    if (NEEDS_OBJECT_GETFIELD_BARRIER && fieldType.isReferenceType() && !field.isUntraced()) {
        Barriers.compileGetfieldBarrierImm(this, fieldOffset, fieldRef.getId());
        discardSlots(1);
        pushAddr(T0);
    } else {
        // T1 = object reference
        popAddr(T1);
        if (fieldType.isReferenceType() || fieldType.isWordLikeType()) {
            // 32/64bit reference/word load
            asm.emitLAddrOffset(T0, T1, fieldOffset);
            pushAddr(T0);
        } else if (fieldType.isBooleanType()) {
            // 8bit unsigned load
            asm.emitLBZoffset(T0, T1, fieldOffset);
            pushInt(T0);
        } else if (fieldType.isByteType()) {
            // 8bit signed load
            asm.emitLBZoffset(T0, T1, fieldOffset);
            // sign extend
            asm.emitEXTSB(T0, T0);
            pushInt(T0);
        } else if (fieldType.isShortType()) {
            // 16bit signed load
            asm.emitLHAoffset(T0, T1, fieldOffset);
            pushInt(T0);
        } else if (fieldType.isCharType()) {
            // 16bit unsigned load
            asm.emitLHZoffset(T0, T1, fieldOffset);
            pushInt(T0);
        } else if (fieldType.isIntType() || fieldType.isFloatType()) {
            // 32bit load
            asm.emitLIntOffset(T0, T1, fieldOffset);
            pushInt(T0);
        } else {
            // 64bit load
            if (VM.VerifyAssertions)
                VM._assert(fieldType.isLongType() || fieldType.isDoubleType());
            asm.emitLFDoffset(F0, T1, fieldOffset);
            pushDouble(F0);
        }
    }
    if (field.isVolatile()) {
        // JMM: post-barrier when first operation
        // LoadLoad and LoadStore barriers.
        asm.emitHWSYNC();
    }
}
Also used : RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) Offset(org.vmmagic.unboxed.Offset)

Example 63 with TypeReference

use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_unresolved_getstatic.

/*
  * field access
  */
@Override
protected void emit_unresolved_getstatic(FieldReference fieldRef) {
    emitDynamicLinkingSequence(T0, fieldRef, true);
    TypeReference fieldType = fieldRef.getFieldContentsType();
    if (NEEDS_OBJECT_GETSTATIC_BARRIER && fieldType.isReferenceType()) {
        Barriers.compileGetstaticBarrier(this, fieldRef.getId());
        pushAddr(T0);
    } else if (fieldRef.getSize() <= BYTES_IN_INT) {
        // field is one word
        asm.emitLIntX(T1, T0, JTOC);
        pushInt(T1);
    } else {
        // field is two words (double or long ( or address on PPC64))
        if (VM.VerifyAssertions)
            VM._assert(fieldRef.getSize() == BYTES_IN_LONG);
        if (VM.BuildFor64Addr && fieldRef.getNumberOfStackSlots() == 1) {
            // address only 1 stackslot!!!
            asm.emitLDX(T1, T0, JTOC);
            pushAddr(T1);
        } else {
            asm.emitLFDX(F0, T0, JTOC);
            pushDouble(F0);
        }
    }
    // JMM: could be volatile (post-barrier when first operation)
    // LoadLoad and LoadStore barriers.
    asm.emitHWSYNC();
}
Also used : TypeReference(org.jikesrvm.classloader.TypeReference)

Example 64 with TypeReference

use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method emit_resolved_getstatic.

@Override
protected void emit_resolved_getstatic(FieldReference fieldRef) {
    RVMField field = fieldRef.peekResolvedField();
    Offset fieldOffset = field.getOffset();
    TypeReference fieldType = fieldRef.getFieldContentsType();
    if (NEEDS_OBJECT_GETSTATIC_BARRIER && fieldType.isReferenceType() && !field.isUntraced()) {
        Barriers.compileGetstaticBarrierImm(this, fieldOffset, fieldRef.getId());
        pushAddr(T0);
    } else if (fieldRef.getSize() <= BYTES_IN_INT) {
        // field is one word
        asm.emitLIntToc(T0, fieldOffset);
        pushInt(T0);
    } else {
        // field is two words (double or long ( or address on PPC64))
        if (VM.VerifyAssertions)
            VM._assert(fieldRef.getSize() == BYTES_IN_LONG);
        if (VM.BuildFor64Addr && fieldRef.getNumberOfStackSlots() == 1) {
            // address only 1 stackslot!!!
            asm.emitLAddrToc(T0, fieldOffset);
            pushAddr(T0);
        } else {
            asm.emitLFDtoc(F0, fieldOffset, T0);
            pushDouble(F0);
        }
    }
    if (field.isVolatile()) {
        // JMM: post-barrier when first operation
        // LoadLoad and LoadStore barriers.
        asm.emitHWSYNC();
    }
}
Also used : RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) Offset(org.vmmagic.unboxed.Offset)

Example 65 with TypeReference

use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.

the class BaselineCompilerImpl method genMoveParametersToRegisters.

// load parameters into registers before calling method "m".
private void genMoveParametersToRegisters(boolean hasImplicitThisArg, MethodReference m) {
    spillOffset = STACKFRAME_HEADER_SIZE;
    int gp = FIRST_VOLATILE_GPR.value();
    int fp = FIRST_VOLATILE_FPR.value();
    int stackIndex = m.getParameterWords();
    if (hasImplicitThisArg) {
        if (gp > LAST_VOLATILE_GPR.value()) {
            genSpillSlot(stackIndex);
        } else {
            peekAddr(GPR.lookup(gp++), stackIndex);
        }
    }
    for (TypeReference t : m.getParameterTypes()) {
        if (t.isLongType()) {
            stackIndex -= 2;
            if (gp > LAST_VOLATILE_GPR.value()) {
                genSpillDoubleSlot(stackIndex);
            } else {
                if (VM.BuildFor64Addr) {
                    peekLong(GPR.lookup(gp), GPR.lookup(gp), stackIndex);
                    gp++;
                } else {
                    // lo register := lo mem (== hi order word)
                    peekInt(GPR.lookup(gp++), stackIndex);
                    if (gp > LAST_VOLATILE_GPR.value()) {
                        genSpillSlot(stackIndex + 1);
                    } else {
                        // hi register := hi mem (== lo order word)
                        peekInt(GPR.lookup(gp++), stackIndex + 1);
                    }
                }
            }
        } else if (t.isFloatType()) {
            stackIndex -= 1;
            if (fp > LAST_VOLATILE_FPR.value()) {
                genSpillSlot(stackIndex);
            } else {
                peekFloat(FPR.lookup(fp++), stackIndex);
            }
        } else if (t.isDoubleType()) {
            stackIndex -= 2;
            if (fp > LAST_VOLATILE_FPR.value()) {
                genSpillDoubleSlot(stackIndex);
            } else {
                peekDouble(FPR.lookup(fp++), stackIndex);
            }
        } else if (t.isIntLikeType()) {
            stackIndex -= 1;
            if (gp > LAST_VOLATILE_GPR.value()) {
                genSpillSlot(stackIndex);
            } else {
                peekInt(GPR.lookup(gp++), stackIndex);
            }
        } else {
            // t is object
            stackIndex -= 1;
            if (gp > LAST_VOLATILE_GPR.value()) {
                genSpillSlot(stackIndex);
            } else {
                peekAddr(GPR.lookup(gp++), stackIndex);
            }
        }
    }
    if (VM.VerifyAssertions)
        VM._assert(stackIndex == 0);
}
Also used : TypeReference(org.jikesrvm.classloader.TypeReference)

Aggregations

TypeReference (org.jikesrvm.classloader.TypeReference)164 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)58 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)43 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)38 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)30 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)28 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)27 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)25 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)24 RVMClass (org.jikesrvm.classloader.RVMClass)23 RVMField (org.jikesrvm.classloader.RVMField)21 Register (org.jikesrvm.compilers.opt.ir.Register)21 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)21 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)21 Address (org.vmmagic.unboxed.Address)21 RVMType (org.jikesrvm.classloader.RVMType)18 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)18 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)18 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)18 RVMMethod (org.jikesrvm.classloader.RVMMethod)17