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();
}
}
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();
}
}
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();
}
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();
}
}
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);
}
Aggregations