Commit 892fb628 authored by Yi Lin's avatar Yi Lin

use table for yieldpoint

parent d347c7a9
......@@ -71,9 +71,9 @@ public final class YieldpointCounterData extends StringEventCounterData implemen
// VM.sysWrite("Method Entry Total: " + methodEntryTotal + "\n");
// VM.sysWrite("Total Yieldpoints: " + total + "\n");
}
public double reportTotalYieldpoints() {
return collectData(null);
public double reportEpilogueYieldpoints() {
return collectData("METHOD EXIT");
}
public double reportPrologueYieldpoints() {
......@@ -88,16 +88,16 @@ public final class YieldpointCounterData extends StringEventCounterData implemen
return collectData("BASE");
}
public double reportO0Yieldpoints() {
return collectData("O0");
public double reportOptYieldpoints() {
return collectData("OPT");
}
public double reportO1Yieldpoints() {
return collectData("O1");
public double reportJNIYieldpoints() {
return collectData("JNI");
}
public double reportO2Yieldpoints() {
return collectData("O2");
public double reportTrapYieldpoints() {
return collectData("TRAP");
}
private double collectData(String keyword) {
......
......@@ -100,9 +100,9 @@ public class InsertYieldpointCounters extends CompilerPhase {
double incrementValue = 1.0;
if (i.operator() == YIELDPOINT_EPILOGUE) {
prefix = "METHOD ENTRY ";
} else if (i.operator() == YIELDPOINT_PROLOGUE) {
prefix = "METHOD EXIT ";
} else if (i.operator() == YIELDPOINT_PROLOGUE) {
prefix = "METHOD ENTRY ";
} else {
prefix = "BACKEDGE ";
incrementValue = 1.0;
......@@ -112,8 +112,13 @@ public class InsertYieldpointCounters extends CompilerPhase {
if (compileType == CompiledMethod.BASELINE)
prefix += "(BASE) ";
else if (compileType == CompiledMethod.OPT) {
int o = ir.compiledMethod.getOptLevel();
prefix += "(O" + o + ") ";
prefix += "(OPT) ";
}
else if (compileType == CompiledMethod.JNI) {
prefix += "(JNI) ";
}
else if (compileType == CompiledMethod.TRAP) {
prefix += "(TRAP) ";
}
// Create an instruction to increment the counter for this
......
......@@ -3935,6 +3935,7 @@ public abstract class BaselineCompilerImpl extends BaselineCompiler implements B
if (YieldpointStatistics.ENABLE_YP_COUNT) {
asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.baselineYieldpointCounterMethod.getOffset()));
YieldpointStatistics.yieldpointBaselineInserted++;
}
// thread switch requested ??
......
......@@ -29,6 +29,7 @@ import org.vmmagic.pragma.Interruptible;
import org.vmmagic.pragma.Uninterruptible;
import org.vmmagic.pragma.Unpreemptible;
import org.vmmagic.unboxed.Address;
import org.vmmagic.unboxed.AddressArray;
import org.vmmagic.unboxed.ObjectReference;
import org.vmmagic.unboxed.Offset;
import org.vmmagic.unboxed.Word;
......@@ -88,6 +89,7 @@ public abstract class CompiledMethod {
private static final int MAX_YP = 512;
private int[] ypOffsets = new int[MAX_YP];
private int ypOffsetsIndex = 0;
@Uninterruptible
public final void addYPOffset(int offset) {
......@@ -96,12 +98,14 @@ public abstract class CompiledMethod {
// VM.sysWrite(method.getDeclaringClass().getDescriptor());
// VM.sysWriteln(method.getName());
if (ypOffsetsIndex < MAX_YP) {
ypOffsets[ypOffsetsIndex] = offset;
ypOffsetsIndex ++;
} else {
VM.sysFail("increase MAX_YP in CompiledMethod");
}
// if (ypOffsetsIndex < MAX_YP) {
// ypOffsets[ypOffsetsIndex] = offset;
// ypOffsetsIndex ++;
// } else {
// VM.sysFail("increase MAX_YP in CompiledMethod");
// }
CompiledMethods.addToYPGlobalTable(this, offset);
}
static final byte INT3 = (byte) 0xcc;
......
......@@ -28,9 +28,12 @@ import org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod;
import org.jikesrvm.jni.JNICompiledMethod;
import org.jikesrvm.runtime.Magic;
import org.jikesrvm.runtime.Memory;
import org.jikesrvm.scheduler.NoYieldpointsMonitor;
import org.jikesrvm.scheduler.YieldpointStatistics;
import org.vmmagic.pragma.Uninterruptible;
import org.vmmagic.unboxed.Address;
import org.vmmagic.unboxed.AddressArray;
import org.vmmagic.unboxed.ObjectReference;
/**
* Manage pool of compiled methods. <p>
......@@ -332,29 +335,68 @@ public class CompiledMethods {
}
}
public static final int MAX_YP = 65536;
// public static final AddressArray ypAddrTable = AddressArray.create(MAX_YP);
public static final CompiledMethod[] ypCMTable = new CompiledMethod[MAX_YP];
public static final int[] ypOffsetTable = new int[MAX_YP];
public static int ypIndex = 0;
public static NoYieldpointsMonitor ypTableLock;
@Uninterruptible
public static synchronized void addToYPGlobalTable(CompiledMethod cm, int offset) {
// CompiledMethods.ypTableLock.lockNoHandshake();
if (ypIndex < MAX_YP) {
ypCMTable[ypIndex] = cm;
ypOffsetTable[ypIndex] = offset;
CompiledMethods.ypIndex++;
} else {
VM.sysFail("increase MAX_YP in CompiledMethod");
}
// CompiledMethods.ypTableLock.unlock();
}
@Uninterruptible
public static void setNOP2CALL() {
// VM.sysWriteln("-----Start patching code-----");
VM.sysWriteln("-----Start patching code-----");
int patched = 0;
long start = Magic.getTimeBase();
for (int i = 0, n = numCompiledMethods(); i < n; i ++) {
CompiledMethod cm = getCompiledMethodUnchecked(i);
// for (int i = 0, n = numCompiledMethods(); i < n; i ++) {
// CompiledMethod cm = getCompiledMethodUnchecked(i);
// if (cm == null || !cm.isCompiled())
// continue;
// if (cm.getCompilerType() != CompiledMethod.OPT)
// continue;
//
// cm.nop2call();
// patched ++;
// }
for (int i = 0; i < ypIndex; i++) {
int offset = ypOffsetTable[i];
CompiledMethod cm = ypCMTable[i];
if (cm == null || !cm.isCompiled())
continue;
if (cm.getCompilerType() != CompiledMethod.OPT)
continue;
cm.nop2call();
patched ++;
cm.instructions.set(offset, CompiledMethod.INT3);
cm.instructions.set(offset+1, CompiledMethod.CALL[1]);
cm.instructions.set(offset+2, CompiledMethod.CALL[2]);
cm.instructions.set(offset+3, CompiledMethod.CALL[3]);
cm.instructions.set(offset+4, CompiledMethod.CALL[4]);
cm.instructions.set(offset+5, CompiledMethod.CALL[5]);
cm.instructions.set(offset, CompiledMethod.CALL[0]);
patched++;
}
long time = Magic.getTimeBase() - start;
YieldpointStatistics.methodsPatched(patched);
// VM.sysWriteln("patched ", patched, " methods ");
// VM.sysWriteln(" in ", time, " cycles. ");
VM.sysWriteln("patched ", patched, " YPs ");
VM.sysWriteln(" in ", time, " cycles. ");
}
@Uninterruptible
......@@ -362,15 +404,35 @@ public class CompiledMethods {
int patched = 0;
long start = Magic.getTimeBase();
for (int i = 0, n = numCompiledMethods(); i < n; i ++) {
CompiledMethod cm = getCompiledMethodUnchecked(i);
// for (int i = 0, n = numCompiledMethods(); i < n; i ++) {
// CompiledMethod cm = getCompiledMethodUnchecked(i);
// if (cm == null || !cm.isCompiled())
// continue;
// if (cm.getCompilerType() != CompiledMethod.OPT)
// continue;
//
// cm.call2nop();
// patched ++;
// }
for (int i = 0; i < ypIndex; i++) {
int offset = ypOffsetTable[i];
CompiledMethod cm = ypCMTable[i];
if (cm == null || !cm.isCompiled())
continue;
if (cm.getCompilerType() != CompiledMethod.OPT)
continue;
cm.call2nop();
patched ++;
cm.instructions.set(offset, CompiledMethod.INT3);
cm.instructions.set(offset+1, CompiledMethod.NOP6[1]);
cm.instructions.set(offset+2, CompiledMethod.NOP6[2]);
cm.instructions.set(offset+3, CompiledMethod.NOP6[3]);
cm.instructions.set(offset+4, CompiledMethod.NOP6[4]);
cm.instructions.set(offset+5, CompiledMethod.NOP6[5]);
cm.instructions.set(offset, CompiledMethod.NOP6[0]);
patched++;
}
long time = Magic.getTimeBase() - start;
......
......@@ -410,6 +410,9 @@ public class FinalMIRExpansion extends IRTools {
break;
case YIELDPOINT_PROLOGUE_opcode:
if (YieldpointStatistics.ENABLE_YP_COUNT)
YieldpointStatistics.yieldpointOptInsertedForPrologue++;
// checking
if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_CHECKING_YP)
expandYieldpoint(p, ir, Entrypoints.optThreadSwitchFromPrologueMethod, IA32ConditionOperand.NE());
......@@ -494,6 +497,9 @@ public class FinalMIRExpansion extends IRTools {
break;
case YIELDPOINT_BACKEDGE_opcode:
if (YieldpointStatistics.ENABLE_YP_COUNT)
YieldpointStatistics.yieldpointOptInsertedForBackedge++;
if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_CHECKING_YP)
expandYieldpoint(p, ir, Entrypoints.optThreadSwitchFromBackedgeMethod, IA32ConditionOperand.GT());
else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_CHECKING_YP) {
......
......@@ -1388,6 +1388,7 @@ public final class RVMThread extends ThreadContext {
dumpLock = new Monitor();
acctLock = new NoYieldpointsMonitor();
patchCodeLock = new NoYieldpointsMonitor();
CompiledMethods.ypTableLock = new NoYieldpointsMonitor();
debugLock = new NoYieldpointsMonitor();
outputLock = new NoYieldpointsMonitor();
softHandshakeDataLock = new Monitor();
......
......@@ -13,7 +13,12 @@
package org.jikesrvm.scheduler;
import org.jikesrvm.VM;
import org.jikesrvm.compilers.common.CompiledMethod;
import org.jikesrvm.compilers.common.CompiledMethods;
import org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod;
import static org.jikesrvm.runtime.SysCall.sysCall;
import org.vmmagic.pragma.NonMoving;
import org.vmmagic.pragma.Uninterruptible;
import org.vmmagic.pragma.UninterruptibleNoWarn;
......@@ -42,33 +47,62 @@ public class TimerThread extends SystemThread {
// TODO: consider allowing GC to be sampled to enable profile-directed optimization of MMTk.
@Override
public void run() {
// return;
VM.disableYieldpoints();
if (verbose>=1) VM.sysWriteln("TimerThread run routine entered");
try {
for (;;) {
sysCall.sysNanoSleep(1000L*1000L*VM.interruptQuantum);
if (VM.BuildForAdaptiveSystem) {
// grab the lock to prevent threads from getting GC'd while we are
// iterating (since this thread doesn't stop for GC)
RVMThread.acctLock.lockNoHandshake();
RVMThread.timerTicks++;
for (int i=0;i<RVMThread.numThreads;++i) {
RVMThread candidate=RVMThread.threads[i];
if (candidate!=null && candidate.shouldBeSampled() && candidate.eligibleForTimerThread()) {
candidate.timeSliceExpired++;
candidate.turnOnLocalYieldpoints();
}
}
RVMThread.acctLock.unlock();
}
RVMThread.checkDebugRequest();
}
} catch (Throwable e) {
printExceptionAndDie(e);
}
// VM.disableYieldpoints();
// if (verbose>=1) VM.sysWriteln("TimerThread run routine entered");
// try {
// for (;;) {
// sysCall.sysNanoSleep(1000L*1000L*VM.interruptQuantum);
//
//// int total = 0;
//// int base = 0;
//// int o0 = 0, o1 = 0, o2 = 0;
////
//// for (int i = 0; i < CompiledMethods.numCompiledMethods(); i++) {
//// CompiledMethod cm = CompiledMethods.getCompiledMethod(i);
//// if (cm == null || !cm.isCompiled())
//// continue;
////
//// total ++;
////
//// if (cm.getCompilerType() == CompiledMethod.BASELINE)
//// base ++;
//// else if (cm.getCompilerType() == CompiledMethod.OPT) {
//// int olvl = ((OptCompiledMethod)cm).getOptLevel();
//// if (olvl == 0)
//// o0++;
//// else if (olvl == 1)
//// o1++;
//// else if (olvl == 2)
//// o2++;
//// }
//// }
////
//// VM.sysWriteln("Total: ", total);
//// VM.sysWriteln(" Base: ", base);
//// VM.sysWriteln(" O0: ", o0);
//// VM.sysWriteln(" O1: ", o1);
//// VM.sysWriteln(" O2: ", o2);
//
// if (VM.BuildForAdaptiveSystem) {
// // grab the lock to prevent threads from getting GC'd while we are
// // iterating (since this thread doesn't stop for GC)
// RVMThread.acctLock.lockNoHandshake();
// RVMThread.timerTicks++;
// for (int i=0;i<RVMThread.numThreads;++i) {
// RVMThread candidate=RVMThread.threads[i];
// if (candidate!=null && candidate.shouldBeSampled() && candidate.eligibleForTimerThread()) {
// candidate.timeSliceExpired++;
// candidate.turnOnLocalYieldpoints();
// }
// }
// RVMThread.acctLock.unlock();
// }
//
// RVMThread.checkDebugRequest();
// }
// } catch (Throwable e) {
// printExceptionAndDie(e);
// }
}
@UninterruptibleNoWarn
private static void printExceptionAndDie(Throwable e) {
......
......@@ -16,13 +16,17 @@ import org.vmmagic.pragma.Uninterruptible;
@Uninterruptible
public class YieldpointStatistics {
// use -X:aos:insert_yieldpoint_counters with this flag
public static final boolean ENABLE_YP_COUNT = false;
public static final boolean ENABLE_YP_COUNT = true;
// how many yieldpoint are executed in baseline code
public static SynchronizedCounter baselineYieldpointExecuted = new SynchronizedCounter();
// how many yieldpoints taken in total
public static SynchronizedCounter yieldpointTaken = new SynchronizedCounter();
public static long yieldpointOptInsertedForPrologue = 0;
public static long yieldpointOptInsertedForBackedge = 0;
public static long yieldpointBaselineInserted = 0;
public static long gcRequestBlockTime;
......@@ -42,6 +46,9 @@ public class YieldpointStatistics {
yieldpointTaken.reset();
baselineYieldpointExecuted.reset();
// yieldpointOptInsertedForPrologue.reset();
// yieldpointOptInsertedForBackedge.reset();
AOSDatabase.yieldpointCounterData.reset();
Instrumentation.enableInstrumentation();
}
......@@ -97,13 +104,16 @@ public class YieldpointStatistics {
printColumn("maxMethodsPatched");
if (ENABLE_YP_COUNT) {
printColumn("yieldpointTaken");
printColumn("yieldpointExecuted");
printColumn("yieldpointExecutedFromPrologue");
printColumn("yieldpointExecutedFromEpilogue");
printColumn("yieldpointExecutedFromBackedge");
printColumn("yieldpointExecutedFromBaseline");
printColumn("yieldpointExecutedFromO0");
printColumn("yieldpointExecutedFromO1");
printColumn("yieldpointExecutedFromO2");
printColumn("yieldpointExecutedFromOpt");
printColumn("yieldpointExecutedFromJNI");
printColumn("yieldpointExecutedFromTrap");
printColumn("yieldpointInsertedForPrologue");
printColumn("yieldpointInsertedForBackedge");
printColumn("yieldpointInsertedForBaseline");
}
printNewLine();
printColumn(yieldpointTurnedOnLatency);
......@@ -112,14 +122,16 @@ public class YieldpointStatistics {
printColumn(maxMethodsPatched);
if (ENABLE_YP_COUNT) {
printColumn(yieldpointTaken.peek());
printColumn(AOSDatabase.yieldpointCounterData.reportTotalYieldpoints());
printColumn(AOSDatabase.yieldpointCounterData.reportPrologueYieldpoints());
printColumn(AOSDatabase.yieldpointCounterData.reportEpilogueYieldpoints());
printColumn(AOSDatabase.yieldpointCounterData.reportBackEdgeYieldpoints());
// printColumn(AOSDatabase.yieldpointCounterData.reportBaselineYieldpoints());
printColumn((double)baselineYieldpointExecuted.peek());
printColumn(AOSDatabase.yieldpointCounterData.reportO0Yieldpoints());
printColumn(AOSDatabase.yieldpointCounterData.reportO1Yieldpoints());
printColumn(AOSDatabase.yieldpointCounterData.reportO2Yieldpoints());
printColumn(AOSDatabase.yieldpointCounterData.reportOptYieldpoints());
printColumn(AOSDatabase.yieldpointCounterData.reportJNIYieldpoints());
printColumn(AOSDatabase.yieldpointCounterData.reportTrapYieldpoints());
printColumn((double)yieldpointOptInsertedForPrologue);
printColumn((double)yieldpointOptInsertedForBackedge);
printColumn((double)yieldpointBaselineInserted);
}
printNewLine();
VM.sysWriteln("------------------------------ End Tabulate Statistics -----------------------------");
......
......@@ -666,7 +666,7 @@ hardwareTrapHandler(int signo, siginfo_t *si, void *context)
*sp = instructionFollowing;
unsigned int yieldPointHandlerAddress =
*(unsigned int *) (localJTOC + bootRecord->yieldpointFromPrologueOptOffset);
*(unsigned int *) (localJTOC + bootRecord->yieldpointFromPrologueOptOffset);
IA32_EIP(context) = yieldPointHandlerAddress;
return;
}
......@@ -685,7 +685,7 @@ hardwareTrapHandler(int signo, siginfo_t *si, void *context)
*sp = instructionFollowing;
unsigned int yieldPointHandlerAddress =
*(unsigned int *) (localJTOC + bootRecord->yieldpointCheckOffset);
*(unsigned int *) (localJTOC + bootRecord->yieldpointCheckOffset);
IA32_EIP(context) = yieldPointHandlerAddress;
return;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment