use of org.jikesrvm.classloader.RVMField in project JikesRVM by JikesRVM.
the class GenerateInterfaceDeclarations method emitCDeclarationsForJavaType.
static void emitCDeclarationsForJavaType(String Cname, RVMClass cls) {
// How many instance fields are there?
//
RVMField[] allFields = cls.getDeclaredFields();
int fieldCount = 0;
for (RVMField field : allFields) {
if (!field.isStatic()) {
fieldCount++;
}
}
RVMField[] fields = new RVMField[fieldCount];
for (int i = 0, j = 0; i < allFields.length; i++) {
if (!allFields[i].isStatic()) {
fields[j++] = allFields[i];
}
}
Arrays.sort(fields, new AscendingOffsetComparator());
// Emit field declarations
//
pln("struct " + Cname + " {");
// Set up cursor - scalars will waste 4 bytes on 64-bit arch
//
boolean needsAlign = VM.BuildFor64Addr;
int addrSize = VM.BuildFor32Addr ? 4 : 8;
// Header Space for objects
int startOffset = ObjectModel.objectStartOffset(cls);
Offset current = Offset.fromIntSignExtend(startOffset);
for (int i = 0; current.sLT(fields[0].getOffset()); i++) {
pln(" uint32_t headerPadding" + i + ";");
current = current.plus(4);
}
for (int i = 0; i < fields.length; i++) {
RVMField field = fields[i];
TypeReference t = field.getType();
Offset offset = field.getOffset();
String name = field.getName().toString();
// Align by blowing 4 bytes if needed
if (needsAlign && current.plus(4).EQ(offset)) {
pln(" uint32_t padding" + i + ";");
current = current.plus(4);
}
if (!current.EQ(offset)) {
System.err.printf("current (%s) and offset (%s) are neither identical nor differ by 4", unboxedValueString(current), unboxedValueString(offset));
System.exit(1);
}
if (t.isIntType()) {
current = current.plus(4);
pln(" uint32_t " + name + ";");
} else if (t.isLongType()) {
current = current.plus(8);
pln(" uint64_t " + name + ";");
} else if (t.isWordLikeType()) {
pln(" Address " + name + ";");
current = current.plus(addrSize);
} else if (t.isArrayType() && t.getArrayElementType().isWordLikeType()) {
pln(" Address * " + name + ";");
current = current.plus(addrSize);
} else if (t.isArrayType() && t.getArrayElementType().isIntType()) {
pln(" unsigned int * " + name + ";");
current = current.plus(addrSize);
} else if (t.isReferenceType()) {
pln(" Address " + name + ";");
current = current.plus(addrSize);
} else {
System.err.println("Unexpected field " + name + " with type " + t);
throw new RuntimeException("unexpected field type");
}
}
pln("};");
}
use of org.jikesrvm.classloader.RVMField in project JikesRVM by JikesRVM.
the class EntrypointHelper method verifyPresenceOfEntrypointAnnotation.
private static void verifyPresenceOfEntrypointAnnotation(RVMMember member) {
if (VM.VerifyAssertions && !(member.isAnnotationPresent(Entrypoint.class))) {
// For certain methods, it's clear that they're accessed by the
// compiler, so an annotation is not required:
boolean annotationRequired = true;
if (member instanceof RVMMethod) {
RVMMethod m = (RVMMethod) member;
RVMClass declClass = m.getDeclaringClass();
if (declClass.getTypeRef().isMagicType() || declClass.getTypeRef().isUnboxedType() || // it's the VM's job to handle those correctly
declClass.getPackageName().startsWith("java.lang")) {
annotationRequired = false;
}
}
// Don't require annotations on fields for the class library.
if (member instanceof RVMField) {
RVMField field = (RVMField) member;
RVMClass declClass = field.getDeclaringClass();
if (declClass.getPackageName().startsWith("java.lang")) {
annotationRequired = false;
}
}
if (annotationRequired) {
String msg = "WARNING: MISSING @Entrypoint ANNOTATION: " + member + " is missing an @Entrypoint annotation!";
throw new Error(msg);
}
}
}
use of org.jikesrvm.classloader.RVMField 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.RVMField 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.RVMField in project JikesRVM by JikesRVM.
the class GenerateMachineSpecificMagic method generateMagic.
/**
* "Semantic inlining" of methods of the Magic class.
* Based on the methodName, generate a sequence of opt instructions
* that implement the magic, updating the stack as necessary
*
* @param bc2ir the bc2ir object generating the ir containing this magic
* @param gc == bc2ir.gc
* @param meth the RVMMethod that is the magic method
* @return {@code true} if and only if magic was generated
*/
public static boolean generateMagic(BC2IR bc2ir, GenerationContext gc, MethodReference meth) throws MagicNotImplementedException {
Atom methodName = meth.getName();
PhysicalRegisterSet phys = gc.getTemps().getPhysicalRegisterSet().asIA32();
if (methodName == MagicNames.getESIAsThread) {
RegisterOperand rop = gc.getTemps().makeTROp();
bc2ir.markGuardlessNonNull(rop);
bc2ir.push(rop);
} else if (methodName == MagicNames.setESIAsThread) {
Operand val = bc2ir.popRef();
if (val instanceof RegisterOperand) {
bc2ir.appendInstruction(Move.create(REF_MOVE, gc.getTemps().makeTROp(), val));
} else {
String msg = " Unexpected operand Magic.setESIAsThread";
throw MagicNotImplementedException.UNEXPECTED(msg);
}
} else if (methodName == MagicNames.getFramePointer) {
gc.forceFrameAllocation();
RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Address);
RVMField f = ArchEntrypoints.framePointerField;
RegisterOperand pr = new RegisterOperand(phys.getESI(), TypeReference.Address);
bc2ir.appendInstruction(GetField.create(GETFIELD, val, pr.copy(), new AddressConstantOperand(f.getOffset()), new LocationOperand(f), new TrueGuardOperand()));
bc2ir.push(val.copyD2U());
} else if (methodName == MagicNames.getJTOC || methodName == MagicNames.getTocPointer) {
TypeReference t = (methodName == MagicNames.getJTOC ? TypeReference.IntArray : TypeReference.Address);
RegisterOperand val = gc.getTemps().makeTemp(t);
AddressConstantOperand addr = new AddressConstantOperand(Magic.getTocPointer());
bc2ir.appendInstruction(Move.create(REF_MOVE, val, addr));
bc2ir.push(val.copyD2U());
} else if (methodName == MagicNames.synchronizeInstructionCache) {
// nothing required on Intel
} else if (methodName == MagicNames.prefetch) {
bc2ir.appendInstruction(CacheOp.create(PREFETCH, bc2ir.popAddress()));
} else if (methodName == MagicNames.pause) {
bc2ir.appendInstruction(Empty.create(PAUSE));
} else if (methodName == MagicNames.illegalInstruction) {
bc2ir.appendInstruction(Empty.create(ILLEGAL_INSTRUCTION));
} else if (methodName == MagicNames.getCallerFramePointer) {
Operand fp = bc2ir.popAddress();
RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Address);
bc2ir.appendInstruction(Load.create(REF_LOAD, val, fp, offsetOperand(STACKFRAME_FRAME_POINTER_OFFSET), null));
bc2ir.push(val.copyD2U());
} else if (methodName == MagicNames.setCallerFramePointer) {
Operand val = bc2ir.popAddress();
Operand fp = bc2ir.popAddress();
bc2ir.appendInstruction(Store.create(REF_STORE, val, fp, offsetOperand(STACKFRAME_FRAME_POINTER_OFFSET), null));
} else if (methodName == MagicNames.getCompiledMethodID) {
Operand fp = bc2ir.popAddress();
RegisterOperand val = gc.getTemps().makeTempInt();
bc2ir.appendInstruction(Load.create(INT_LOAD, val, fp, offsetOperand(STACKFRAME_METHOD_ID_OFFSET), null));
bc2ir.push(val.copyD2U());
} else if (methodName == MagicNames.setCompiledMethodID) {
Operand val = bc2ir.popInt();
Operand fp = bc2ir.popAddress();
bc2ir.appendInstruction(Store.create(INT_STORE, val, fp, offsetOperand(STACKFRAME_METHOD_ID_OFFSET), null));
} else if (methodName == MagicNames.getReturnAddressLocation) {
Operand fp = bc2ir.popAddress();
Instruction s = bc2ir._binaryHelper(REF_ADD, fp, offsetOperand(STACKFRAME_RETURN_ADDRESS_OFFSET), TypeReference.Address);
bc2ir.appendInstruction(s);
} else {
// Distinguish between magics that we know we don't implement
// (and never plan to implement) and those (usually new ones)
// that we want to be warned that we don't implement.
String msg = " Magic method not implemented: " + meth;
if (methodName == MagicNames.returnToNewStack) {
throw MagicNotImplementedException.EXPECTED(msg);
} else {
return false;
// throw MagicNotImplementedException.UNEXPECTED(msg);
}
}
return true;
}
Aggregations