use of org.jikesrvm.jni.JNIEnvironment in project JikesRVM by JikesRVM.
the class JNIHelpers method packageParameterFromVarArg.
/**
* Repackage the arguments passed as a variable argument list into an array of Object,
* used by the JNI functions CallStatic<type>MethodV
* @param targetMethod The target {@link RVMMethod}
* @param argAddress an address into the C space for the array of jvalue unions;
* each element is 2-word and holds the argument of the appropriate type
* @return an Object array holding the arguments wrapped at Objects
*/
static Object[] packageParameterFromVarArg(MethodReference targetMethod, Address argAddress) {
TypeReference[] argTypes = targetMethod.getParameterTypes();
int argCount = argTypes.length;
Object[] argObjectArray = new Object[argCount];
Address vaListCopy = SysCall.sysCall.sysVaCopy(argAddress);
JNIEnvironment env = RVMThread.getCurrentThread().getJNIEnv();
for (int i = 0; i < argCount; i++) {
// convert and wrap the argument according to the expected type
if (argTypes[i].isReferenceType()) {
argObjectArray[i] = env.getJNIRef(SysCall.sysCall.sysVaArgJobject(vaListCopy));
} else if (argTypes[i].isIntType()) {
argObjectArray[i] = SysCall.sysCall.sysVaArgJint(vaListCopy);
} else if (argTypes[i].isLongType()) {
argObjectArray[i] = SysCall.sysCall.sysVaArgJlong(vaListCopy);
} else if (argTypes[i].isBooleanType()) {
argObjectArray[i] = SysCall.sysCall.sysVaArgJboolean(vaListCopy);
} else if (argTypes[i].isByteType()) {
argObjectArray[i] = SysCall.sysCall.sysVaArgJbyte(vaListCopy);
} else if (argTypes[i].isCharType()) {
argObjectArray[i] = SysCall.sysCall.sysVaArgJchar(vaListCopy);
} else if (argTypes[i].isShortType()) {
argObjectArray[i] = SysCall.sysCall.sysVaArgJshort(vaListCopy);
} else if (argTypes[i].isFloatType()) {
argObjectArray[i] = SysCall.sysCall.sysVaArgJfloat(vaListCopy);
} else {
if (VM.VerifyAssertions)
VM._assert(argTypes[i].isDoubleType());
argObjectArray[i] = SysCall.sysCall.sysVaArgJdouble(vaListCopy);
}
}
SysCall.sysCall.sysVaEnd(vaListCopy);
return argObjectArray;
}
use of org.jikesrvm.jni.JNIEnvironment in project JikesRVM by JikesRVM.
the class JNIHelpers method packageParameterFromDotArgSVR4.
/* The method reads out parameters from registers saved in native->java glue stack frame (glueFP)
* and the spill area of native stack frame (caller of glueFP).
*
* NOTE: assuming the stack frame won't get moved, (see pushVarArgToSpillArea)
* the row address glueFP can be replaced by offset to the stack.
*
* @param targetMethod, the call target
* @param glueFP, the glue stack frame pointer
*/
static Object[] packageParameterFromDotArgSVR4(MethodReference targetMethod, Address glueFP, boolean skip4Args) {
if (!VM.BuildForSVR4ABI) {
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
return null;
}
// native method's stack frame
Address nativeFP = Magic.getCallerFramePointer(glueFP);
TypeReference[] argTypes = targetMethod.getParameterTypes();
int argCount = argTypes.length;
Object[] argObjectArray = new Object[argCount];
JNIEnvironment env = RVMThread.getCurrentThread().getJNIEnv();
// GPR r3 - r10 and FPR f1 - f8 are saved in glue stack frame
Address regsavearea = glueFP.plus(STACKFRAME_HEADER_SIZE);
// spill area offset
Address overflowarea = nativeFP.plus(NATIVE_FRAME_HEADER_SIZE);
// overflowarea is aligned to 8 bytes
if (VM.VerifyAssertions)
VM._assert(overflowarea.toWord().and(Word.fromIntZeroExtend(0x07)).isZero());
// adjust gpr and fpr to normal numbering, make life easier
// r3 - env, r4 - cls, r5 - method id
int gpr = (skip4Args) ? 7 : 6;
int fpr = 1;
// not set the starting gprs array address
// and fpr starting array address, so we can use gpr and fpr to
// calculate the right position to get values
// GPR starts with r3;
Address gprarray = regsavearea.plus(-3 * BYTES_IN_ADDRESS);
Address fprarray = regsavearea.plus(8 * BYTES_IN_ADDRESS - 2 * BYTES_IN_ADDRESS);
// call the common function for SVR4
packageArgumentForSVR4(argTypes, argObjectArray, gprarray, fprarray, overflowarea, gpr, fpr, env);
return argObjectArray;
}
use of org.jikesrvm.jni.JNIEnvironment in project JikesRVM by JikesRVM.
the class JNIHelpers method packageParameterFromVarArg.
/**
* Repackage the arguments passed as a variable argument list into an array of Object,
* used by the JNI functions CallStatic<type>MethodV
* @param targetMethod The target {@link RVMMethod}
* @param argAddress an address into the C space for the array of jvalue unions;
* each element is 2-word and holds the argument of the appropriate type
* @return an Object array holding the arguments wrapped at Objects
*/
static Object[] packageParameterFromVarArg(MethodReference targetMethod, Address argAddress) {
TypeReference[] argTypes = targetMethod.getParameterTypes();
int argCount = argTypes.length;
Object[] argObjectArray = new Object[argCount];
// get the JNIEnvironment for this thread in case we need to dereference any object arg
JNIEnvironment env = RVMThread.getCurrentThread().getJNIEnv();
// VM.sysWriteln("JNI packageParameterFromVarArg: packaging " + argCount + " arguments");
Address addr = argAddress;
for (int i = 0; i < argCount; i++) {
long hiword = VM.BuildFor64Addr ? addr.loadLong() : (long) addr.loadInt();
// VM.sysWrite("JNI packageParameterFromVarArg: arg " + i + " = " + hiword +
// " or " + Services.intAsHexString(hiword) + "\n");
addr = addr.plus(BYTES_IN_ADDRESS);
if (argTypes[i].isFloatType()) {
// so we have to extract it as a double and convert it back to a float
if (VM.BuildFor32Addr) {
int loword = addr.loadInt();
addr = addr.plus(BYTES_IN_ADDRESS);
long doubleBits = (hiword << BITS_IN_INT) | (loword & 0xFFFFFFFFL);
argObjectArray[i] = Reflection.wrapFloat((float) (Double.longBitsToDouble(doubleBits)));
} else {
argObjectArray[i] = Reflection.wrapFloat((float) (Double.longBitsToDouble(hiword)));
}
} else if (argTypes[i].isDoubleType()) {
if (VM.BuildFor32Addr) {
int loword = addr.loadInt();
addr = addr.plus(BYTES_IN_ADDRESS);
long doubleBits = (hiword << BITS_IN_INT) | (loword & 0xFFFFFFFFL);
argObjectArray[i] = Reflection.wrapDouble(Double.longBitsToDouble(doubleBits));
} else {
argObjectArray[i] = Reflection.wrapDouble(Double.longBitsToDouble(hiword));
}
} else if (argTypes[i].isLongType()) {
if (VM.BuildFor32Addr) {
int loword = addr.loadInt();
addr = addr.plus(BYTES_IN_ADDRESS);
long longValue = (hiword << BITS_IN_INT) | (loword & 0xFFFFFFFFL);
argObjectArray[i] = Reflection.wrapLong(longValue);
} else {
argObjectArray[i] = Reflection.wrapLong(hiword);
}
} else if (argTypes[i].isBooleanType()) {
// the 0/1 bit is stored in the high byte
argObjectArray[i] = Reflection.wrapBoolean((int) hiword);
} else if (argTypes[i].isByteType()) {
// the target byte is stored in the high byte
argObjectArray[i] = Reflection.wrapByte((byte) hiword);
} else if (argTypes[i].isCharType()) {
// char is stored in the high 2 bytes
argObjectArray[i] = Reflection.wrapChar((char) hiword);
} else if (argTypes[i].isShortType()) {
// short is stored in the high 2 bytes
argObjectArray[i] = Reflection.wrapShort((short) hiword);
} else if (argTypes[i].isReferenceType()) {
// for object, the arg is a JREF index, dereference to get the real object
argObjectArray[i] = env.getJNIRef((int) hiword);
} else if (argTypes[i].isIntType()) {
argObjectArray[i] = Reflection.wrapInt((int) hiword);
} else {
return null;
}
}
return argObjectArray;
}
use of org.jikesrvm.jni.JNIEnvironment in project JikesRVM by JikesRVM.
the class JNIHelpers method packageParameterFromVarArgSVR4.
// linux has totally different layout of va_list
// see /usr/lib/gcc-lib/powerpc-linux/xxxx/include/va-ppc.h
//
// va_list is defined as following
//
// struct {
// char unsigned gpr; // compiled to 1 byte, index of gprs in saved area
// // 0 -> r3, 1 -> r4, ....
// char unsigned fpr; // compiled to 1 byte, index to fprs in saved area
// // 0 -> fr1, 1 -> fr2, ....
// char * over_flow_area;
// char * reg_save_area;
// }
//
// The interpretation of data can be found in PowerPC Processor ABI Supplement
//
// The reg_save area lays out r3 - r10, f1 - f8
//
// I am not sure if GCC understand the ABI in a right way, it saves GPRs 1 - 10
// in the area, while only gprs starting from r3 are used.
//
// -- Feng
//
static Object[] packageParameterFromVarArgSVR4(MethodReference targetMethod, Address argAddress) {
if (!VM.BuildForSVR4ABI) {
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
return null;
}
TypeReference[] argTypes = targetMethod.getParameterTypes();
int argCount = argTypes.length;
Object[] argObjectArray = new Object[argCount];
JNIEnvironment env = RVMThread.getCurrentThread().getJNIEnv();
// the va_list has following layout on PPC/Linux
// GPR FPR 0 0 (4 bytes)
// overflowarea (pointer)
// reg_save_area (pointer)
Address va_list_addr = argAddress;
int word1 = va_list_addr.loadWord().toInt();
int gpr = word1 >> 24;
int fpr = (word1 >> 16) & 0x0FF;
Address overflowarea = va_list_addr.loadAddress(Offset.fromIntSignExtend(BYTES_IN_ADDRESS));
Address regsavearea = va_list_addr.loadAddress(Offset.fromIntSignExtend(2 * BYTES_IN_ADDRESS));
if (VM.BuildForSVR4ABI) {
// overflowarea is aligned to 8 bytes
if (VM.VerifyAssertions)
VM._assert(overflowarea.toWord().and(Word.fromIntZeroExtend(0x07)).isZero());
}
// adjust gpr and fpr to normal numbering, make life easier
gpr += 3;
fpr += 1;
// not set the starting gprs array address
// and fpr starting array address, so we can use gpr and fpr to
// calculate the right position to get values
// GPR starts with r3;
Address gprarray = regsavearea.plus(-3 * BYTES_IN_ADDRESS);
Address fprarray = regsavearea.plus(8 * BYTES_IN_ADDRESS - 2 * BYTES_IN_ADDRESS);
// call the common function for SVR4
packageArgumentForSVR4(argTypes, argObjectArray, gprarray, fprarray, overflowarea, gpr, fpr, env);
return argObjectArray;
}
Aggregations