use of org.jikesrvm.classloader.TypeReference 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.TypeReference in project JikesRVM by JikesRVM.
the class MachineReflection method packageParameters.
/**
* Collect parameters into arrays of registers/spills, as required to call specified method.
*/
public static void packageParameters(RVMMethod method, Object thisArg, Object[] otherArgs, WordArray GPRs, double[] FPRs, byte[] FPRmeta, WordArray Spills) {
int GPR = GPRs.length();
int FPR = FPRs.length;
int Spill = Spills.length();
int gp = FIRST_VOLATILE_GPR.value();
int fp = FIRST_VOLATILE_FPR.value();
if (!method.isStatic()) {
if (gp > LAST_VOLATILE_GPR.value()) {
Spills.set(--Spill, Reflection.unwrapObject(thisArg).toWord());
} else {
gp++;
GPRs.set(--GPR, Reflection.unwrapObject(thisArg).toWord());
}
}
TypeReference[] types = method.getParameterTypes();
for (int i = 0; i < types.length; i++) {
TypeReference t = types[i];
if (t.isLongType()) {
long l = Reflection.unwrapLong(otherArgs[i]);
if (VM.BuildFor64Addr) {
if (gp > LAST_VOLATILE_GPR.value()) {
Spills.set(--Spill, Word.fromLong(l));
} else {
gp++;
GPRs.set(--GPR, Word.fromLong(l));
}
} else {
Word hi = Word.fromIntZeroExtend((int) (l >>> 32));
Word lo = Word.fromIntZeroExtend((int) l);
if (gp > LAST_VOLATILE_GPR.value()) {
Spills.set(--Spill, hi);
Spills.set(--Spill, lo);
} else {
gp++;
GPRs.set(--GPR, hi);
if (gp > LAST_VOLATILE_GPR.value()) {
Spills.set(--Spill, lo);
} else {
gp++;
GPRs.set(--GPR, lo);
}
}
}
} else if (t.isFloatType()) {
float f = Reflection.unwrapFloat(otherArgs[i]);
if (fp > LAST_VOLATILE_FPR.value()) {
Spills.set(--Spill, Word.fromIntZeroExtend(Float.floatToIntBits(f)));
} else {
fp++;
FPRs[--FPR] = f;
}
} else if (t.isDoubleType()) {
if (fp > LAST_VOLATILE_FPR.value()) {
double d = Reflection.unwrapDouble(otherArgs[i]);
long l = Double.doubleToLongBits(d);
if (VM.BuildFor64Addr) {
Spills.set(--Spill, Word.fromLong(l));
} else {
Spills.set(--Spill, Word.fromIntZeroExtend((int) (l >>> 32)));
Spills.set(--Spill, Word.fromIntZeroExtend((int) l));
}
} else {
fp++;
FPRs[--FPR] = Reflection.unwrapDouble(otherArgs[i]);
}
} else if (t.isBooleanType()) {
Word val = Word.fromIntZeroExtend(Reflection.unwrapBooleanAsInt(otherArgs[i]));
if (gp > LAST_VOLATILE_GPR.value()) {
Spills.set(--Spill, val);
} else {
gp++;
GPRs.set(--GPR, val);
}
} else if (t.isByteType()) {
Word val = Word.fromIntZeroExtend(Reflection.unwrapByte(otherArgs[i]));
if (gp > LAST_VOLATILE_GPR.value()) {
Spills.set(--Spill, val);
} else {
gp++;
GPRs.set(--GPR, val);
}
} else if (t.isCharType()) {
Word val = Word.fromIntZeroExtend(Reflection.unwrapChar(otherArgs[i]));
if (gp > LAST_VOLATILE_GPR.value()) {
Spills.set(--Spill, val);
} else {
gp++;
GPRs.set(--GPR, val);
}
} else if (t.isShortType()) {
Word val = Word.fromIntZeroExtend(Reflection.unwrapShort(otherArgs[i]));
if (gp > LAST_VOLATILE_GPR.value()) {
Spills.set(--Spill, val);
} else {
gp++;
GPRs.set(--GPR, val);
}
} else if (t.isIntType()) {
Word val = Word.fromIntZeroExtend(Reflection.unwrapInt(otherArgs[i]));
if (gp > LAST_VOLATILE_GPR.value()) {
Spills.set(--Spill, val);
} else {
gp++;
GPRs.set(--GPR, val);
}
} else if (!t.isPrimitiveType()) {
Word val = Reflection.unwrapObject(otherArgs[i]).toWord();
if (gp > LAST_VOLATILE_GPR.value()) {
Spills.set(--Spill, val);
} else {
gp++;
GPRs.set(--GPR, val);
}
} else {
if (VM.VerifyAssertions)
VM._assert(NOT_REACHED);
}
}
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class MultianewarrayHelper method newArrayArray.
/**
* Allocate something like {@code new Foo[cnt0][cnt1]...[cntN-1]},
* or {@code new int[cnt0][cnt1]...[cntN-1]}.
* @param methodId id of caller
* @param numDimensions number of array dimensions
* @param typeId {@link TypeReference} id of type of array
* @param argOffset position of word *above* `cnt0' argument within caller's frame
* This is used to access the number of elements to
* be allocated for each dimension.
* See also: bytecode 0xc5 ("multianewarray") in Compiler
* @return the new array
*/
@Entrypoint
static Object newArrayArray(int methodId, int numDimensions, int typeId, int argOffset) throws NoClassDefFoundError, NegativeArraySizeException, OutOfMemoryError {
if (numDimensions == 2) {
int dim0, dim1;
// fetch number of elements to be allocated for each array dimension
VM.disableGC();
Address argp = Magic.getFramePointer().loadAddress().plus(argOffset);
int offset = (BYTES_IN_STACKSLOT * 0) + BYTES_IN_INT;
dim0 = argp.minus(offset).loadInt();
offset = (BYTES_IN_STACKSLOT * 1) + BYTES_IN_INT;
dim1 = argp.minus(offset).loadInt();
VM.enableGC();
// validate arguments
if ((dim0 < 0) || (dim1 < 0))
throw new NegativeArraySizeException();
// create array
TypeReference tRef = TypeReference.getTypeRef(typeId);
RVMArray array = tRef.resolve().asArray();
return RuntimeEntrypoints.buildTwoDimensionalArray(methodId, dim0, dim1, array);
} else {
// fetch number of elements to be allocated for each array dimension
int[] numElements = new int[numDimensions];
VM.disableGC();
Address argp = Magic.getFramePointer().loadAddress().plus(argOffset);
for (int i = 0; i < numDimensions; ++i) {
int offset = (BYTES_IN_STACKSLOT * i) + BYTES_IN_INT;
numElements[i] = argp.minus(offset).loadInt();
}
VM.enableGC();
// validate arguments
for (int elements : numElements) {
if (elements < 0)
throw new NegativeArraySizeException();
}
// create array
TypeReference tRef = TypeReference.getTypeRef(typeId);
RVMArray array = tRef.resolve().asArray();
return RuntimeEntrypoints.buildMultiDimensionalArray(methodId, numElements, array);
}
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class EntrypointHelper method getMethod.
/**
* Get description of virtual machine method.
* @param klass class containing method
* @param member member name - something like "invokestatic"
* @param descriptor member descriptor - something like "()V"
* @return corresponding RVMMethod
*/
public static NormalMethod getMethod(Class<?> klass, String member, String descriptor) {
if (!VM.runningVM) {
// avoid compiling this code into the boot image
try {
TypeReference klassTRef = TypeReference.findOrCreate(klass);
RVMClass cls = klassTRef.resolve().asClass();
cls.resolve();
Atom memName = Atom.findOrCreateAsciiAtom(member);
Atom memDescriptor = Atom.findOrCreateAsciiAtom(descriptor);
NormalMethod m = (NormalMethod) cls.findDeclaredMethod(memName, memDescriptor);
if (m != null) {
verifyPresenceOfEntrypointAnnotation(m);
m.setRuntimeServiceMethod(true);
return m;
}
} catch (Throwable t) {
throw new Error("Entrypoints.getField: can't resolve class=" + klass + " member=" + member + " desc=" + descriptor, t);
}
}
throw new Error("Entrypoints.getMethod: can't resolve class=" + klass + " method=" + member + " desc=" + descriptor);
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class MainThread method run.
/**
* Run "main" thread.
* <p>
* This code could be made a little shorter by relying on Reflection
* to do the classloading and compilation. We intentionally do it here
* to give us a chance to provide error messages that are specific to
* not being able to find the main class the user wants to run.
* This may be a little silly, since it results in code duplication
* just to provide debug messages in a place where very little is actually
* likely to go wrong, but there you have it....
*/
@Override
@Entrypoint
public void run() {
launched = true;
if (dbg)
VM.sysWriteln("MainThread.run() starting ");
// Set up application class loader
ClassLoader cl = RVMClassLoader.getApplicationClassLoader();
setContextClassLoader(cl);
runAgents(cl);
if (dbg)
VM.sysWrite("[MainThread.run() loading class to run... ");
// find method to run
// load class specified by args[0]
RVMClass cls = null;
try {
Atom mainAtom = Atom.findOrCreateUnicodeAtom(args[0]);
TypeReference mainClass = TypeReference.findOrCreate(cl, mainAtom.descriptorFromClassName());
cls = mainClass.resolve().asClass();
cls.prepareForFirstUse();
} catch (NoClassDefFoundError e) {
if (dbg)
VM.sysWrite("failed.]");
// no such class
VM.sysWriteln(e.toString());
return;
}
if (dbg)
VM.sysWriteln("loaded.]");
// find "main" method
//
mainMethod = cls.findMainMethod();
if (mainMethod == null) {
// no such method
VM.sysWriteln(cls + " doesn't have a \"public static void main(String[])\" method to execute");
return;
}
if (dbg)
VM.sysWrite("[MainThread.run() making arg list... ");
// create "main" argument list
//
String[] mainArgs = new String[args.length - 1];
for (int i = 0, n = mainArgs.length; i < n; ++i) {
mainArgs[i] = args[i + 1];
}
if (dbg)
VM.sysWriteln("made.]");
if (dbg)
VM.sysWrite("[MainThread.run() compiling main(String[])... ");
mainMethod.compile();
if (dbg)
VM.sysWriteln("compiled.]");
// Notify other clients that the startup is complete.
//
Callbacks.notifyStartup();
if (dbg)
VM.sysWriteln("[MainThread.run() invoking \"main\" method... ");
// invoke "main" method with argument list
Reflection.invoke(mainMethod, null, null, new Object[] { mainArgs }, true);
if (dbg)
VM.sysWriteln(" MainThread.run(): \"main\" method completed.]");
}
Aggregations