use of org.jikesrvm.compilers.common.CodeArray in project JikesRVM by JikesRVM.
the class PartialCallGraph method dumpGraph.
/**
* Dump all profile data to the given file
* @param fn output file name
*/
public synchronized void dumpGraph(String fn) {
final BufferedWriter f;
try {
f = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fn), "ISO-8859-1"));
} catch (IOException e) {
VM.sysWriteln();
VM.sysWriteln();
VM.sysWrite("PartialCallGraph.dumpGraph: Error opening output file!!");
VM.sysWriteln();
VM.sysWriteln();
return;
}
TreeSet<CallSite> tmp = new TreeSet<CallSite>(new OrderByTotalWeight());
tmp.addAll(callGraph.keySet());
for (final CallSite cs : tmp) {
WeightedCallTargets ct = callGraph.get(cs);
ct.visitTargets(new WeightedCallTargets.Visitor() {
@Override
public void visit(RVMMethod callee, double weight) {
CodeArray callerArray = cs.getMethod().getCurrentEntryCodeArray();
CodeArray calleeArray = callee.getCurrentEntryCodeArray();
try {
f.write("CallSite " + cs.getMethod().getMemberRef() + " " + callerArray.length() + " " + +cs.getBytecodeIndex() + " " + callee.getMemberRef() + " " + +calleeArray.length() + " weight: " + weight + "\n");
f.flush();
} catch (IOException exc) {
System.err.println("I/O error writing to dynamic call graph profile.");
}
}
});
}
}
use of org.jikesrvm.compilers.common.CodeArray in project JikesRVM by JikesRVM.
the class Reflection method outOfLineInvoke.
private static Object outOfLineInvoke(RVMMethod method, Object thisArg, Object[] otherArgs, boolean isNonvirtual) {
// the class must be initialized before we can invoke a method
//
RVMClass klass = method.getDeclaringClass();
if (!klass.isInitialized()) {
RuntimeEntrypoints.initializeClassForDynamicLink(klass);
}
// remember return type
// Determine primitive type-ness early to avoid call (possible yield)
// later while refs are possibly being held in int arrays.
//
TypeReference returnType = method.getReturnType();
boolean returnIsPrimitive = returnType.isPrimitiveType();
// decide how to pass parameters
//
int triple = 0;
if (VM.BuildForIA32) {
triple = org.jikesrvm.ia32.MachineReflection.countParameters(method);
} else {
if (VM.VerifyAssertions)
VM._assert(VM.BuildForPowerPC);
triple = org.jikesrvm.ppc.MachineReflection.countParameters(method);
}
int gprs = triple & REFLECTION_GPRS_MASK;
WordArray GPRs = (gprs > 0) ? WordArray.create(gprs) : emptyWordArray;
int fprs = (triple >> REFLECTION_GPRS_BITS) & 0x1F;
double[] FPRs = (fprs > 0) ? new double[fprs] : emptyDoubleArray;
byte[] FPRmeta;
if (BuildForSSE2Full) {
FPRmeta = (fprs > 0) ? new byte[fprs] : emptyByteArray;
} else {
FPRmeta = null;
}
int spillCount = triple >> (REFLECTION_GPRS_BITS + REFLECTION_FPRS_BITS);
WordArray Spills = (spillCount > 0) ? WordArray.create(spillCount) : emptyWordArray;
if (firstUse) {
// force dynamic link sites in unwrappers to get resolved,
// before disabling gc.
// this is a bit silly, but I can't think of another way to do it [--DL]
unwrapBoolean(wrapBoolean(0));
unwrapByte(wrapByte((byte) 0));
unwrapChar(wrapChar((char) 0));
unwrapShort(wrapShort((short) 0));
unwrapInt(wrapInt(0));
unwrapLong(wrapLong(0));
unwrapFloat(wrapFloat(0));
unwrapDouble(wrapDouble(0));
firstUse = false;
}
// choose actual method to be called
//
RVMMethod targetMethod;
if (isNonvirtual || method.isStatic() || method.isObjectInitializer()) {
targetMethod = method;
} else {
RVMClass C = Magic.getObjectType(thisArg).asClass();
if (!method.getDeclaringClass().isInterface()) {
int tibIndex = method.getOffset().toInt() >>> LOG_BYTES_IN_ADDRESS;
targetMethod = C.getVirtualMethods()[tibIndex - TIB_FIRST_VIRTUAL_METHOD_INDEX];
} else {
RVMClass I = method.getDeclaringClass();
if (!RuntimeEntrypoints.isAssignableWith(I, C))
throw new IncompatibleClassChangeError();
targetMethod = C.findVirtualMethod(method.getName(), method.getDescriptor());
if (targetMethod == null)
throw new IncompatibleClassChangeError();
}
}
// getCurrentCompiledMethod is synchronized but Unpreemptible.
// Therefore there are no possible yieldpoints from the time
// the compiledMethod is loaded in getCurrentCompiledMethod
// to when we disable GC below.
// We can't allow any yieldpoints between these points because of the way in which
// we GC compiled code. Once a method is marked as obsolete, if it is not
// executing on the stack of some thread, then the process of collecting the
// code and meta-data might be initiated.
targetMethod.compile();
CompiledMethod cm = targetMethod.getCurrentCompiledMethod();
while (cm == null) {
targetMethod.compile();
cm = targetMethod.getCurrentCompiledMethod();
}
RVMThread.getCurrentThread().disableYieldpoints();
CodeArray code = cm.getEntryCodeArray();
if (VM.BuildForIA32) {
org.jikesrvm.ia32.MachineReflection.packageParameters(method, thisArg, otherArgs, GPRs, FPRs, FPRmeta, Spills);
} else {
if (VM.VerifyAssertions)
VM._assert(VM.BuildForPowerPC);
org.jikesrvm.ppc.MachineReflection.packageParameters(method, thisArg, otherArgs, GPRs, FPRs, FPRmeta, Spills);
}
// critical: no yieldpoints/GCpoints between here and the invoke of code!
// We may have references hidden in the GPRs and Spills arrays!!!
RVMThread.getCurrentThread().enableYieldpoints();
if (!returnIsPrimitive) {
return Magic.invokeMethodReturningObject(code, GPRs, FPRs, FPRmeta, Spills);
}
if (returnType.isVoidType()) {
Magic.invokeMethodReturningVoid(code, GPRs, FPRs, FPRmeta, Spills);
return null;
}
if (returnType.isBooleanType()) {
int x = Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
return x == 1;
}
if (returnType.isByteType()) {
int x = Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
return (byte) x;
}
if (returnType.isShortType()) {
int x = Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
return (short) x;
}
if (returnType.isCharType()) {
int x = Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
return (char) x;
}
if (returnType.isIntType()) {
return Magic.invokeMethodReturningInt(code, GPRs, FPRs, FPRmeta, Spills);
}
if (returnType.isLongType()) {
return Magic.invokeMethodReturningLong(code, GPRs, FPRs, FPRmeta, Spills);
}
if (returnType.isFloatType()) {
return Magic.invokeMethodReturningFloat(code, GPRs, FPRs, FPRmeta, Spills);
}
if (returnType.isDoubleType()) {
return Magic.invokeMethodReturningDouble(code, GPRs, FPRs, FPRmeta, Spills);
}
if (VM.VerifyAssertions)
VM._assert(NOT_REACHED);
return null;
}
use of org.jikesrvm.compilers.common.CodeArray in project JikesRVM by JikesRVM.
the class PostThreadSwitch method postProcess.
/* This method must be inlined to keep the correctness
* This method is called at the end of threadSwitch, the caller
* is threadSwitchFrom<...>
*/
@NoInline
public static void postProcess(RVMThread myThread) {
/* We need to generate thread specific code and install new code.
* We have to make sure that no GC happens from here and before
* the new code get executed.
*/
// add branch instruction from CTR.
CodeArray bridge = myThread.bridgeInstructions;
Address bridgeaddr = Magic.objectAsAddress(bridge);
Offset offset = myThread.fooFPOffset.plus(STACKFRAME_RETURN_ADDRESS_OFFSET);
Magic.objectAsAddress(myThread.getStack()).store(bridgeaddr, offset);
myThread.fooFPOffset = Offset.zero();
myThread.isWaitingForOsr = false;
myThread.bridgeInstructions = null;
}
use of org.jikesrvm.compilers.common.CodeArray in project JikesRVM by JikesRVM.
the class Assembler method getMachineCodes.
/**
* Return a copy of the generated code as a CodeArray.
* @return a copy of the generated code as a CodeArray.
*/
@Override
public CodeArray getMachineCodes() {
int len = getMachineCodeIndex();
CodeArray trimmed = CodeArray.Factory.create(len, isHot);
for (int i = 0; i < len; i++) {
trimmed.set(i, machineCodes[i]);
}
return trimmed;
}
use of org.jikesrvm.compilers.common.CodeArray in project JikesRVM by JikesRVM.
the class OptCompiledMethod method applyCodePatches.
/**
* Applies the code patches to the INSTRUCTION array of cm.
*
* @param cm the method which will be patched
*/
@Interruptible
public void applyCodePatches(CompiledMethod cm) {
if (patchMap != null) {
for (int idx = 0; idx < patchMap.length; idx += 2) {
CodeArray code = cm.codeArrayForOffset(Offset.fromIntZeroExtend(patchMap[idx]));
if (VM.BuildForIA32) {
org.jikesrvm.compilers.common.assembler.ia32.Assembler.patchCode(code, patchMap[idx], patchMap[idx + 1]);
} else if (VM.BuildForPowerPC) {
org.jikesrvm.compilers.opt.mir2mc.ppc.AssemblerOpt.patchCode(code, patchMap[idx], patchMap[idx + 1]);
} else if (VM.VerifyAssertions) {
VM._assert(VM.NOT_REACHED);
}
}
if (VM.BuildForPowerPC) {
// we need synchronization on PPC to handle the weak memory model
// and its icache/dcache synchronization requirements.
// Before the class loading finishes, other processors must get
// synchronized.
boolean DEBUG_CODE_PATCH = false;
// let other processors see changes.
Magic.fence();
// All other processors now will see the patched code in their data cache.
// We now need to force everyone's instruction caches to be in synch with their
// data caches. Some of the work of this call is redundant (since we already have
// forced the data caches to be in synch), but we need the icbi instructions
// to invalidate the instruction caches.
Memory.sync(Magic.objectAsAddress(instructions), instructions.length() << ArchConstants.getLogInstructionWidth());
// Force all other threads to execute isync at the next thread switch point
// so that the icbi instructions take effect. Another effect is that
// prefetched instructions are discarded.
// Note: it would be sufficient to execute isync once for each
// physical processor.
RVMThread.softHandshake(codePatchSyncRequestVisitor);
if (DEBUG_CODE_PATCH) {
VM.sysWriteln("all processors got synchronized!");
}
}
}
}
Aggregations