Commit 32cea859 authored by Yi Lin's avatar Yi Lin

working on code patching

parent 29012852
......@@ -50,6 +50,7 @@ import org.jikesrvm.compilers.baseline.BaselineCompiledMethod;
import org.jikesrvm.compilers.baseline.BaselineCompiler;
import org.jikesrvm.compilers.baseline.EdgeCounts;
import org.jikesrvm.compilers.common.CompiledMethod;
import org.jikesrvm.compilers.common.CompiledMethods;
import org.jikesrvm.compilers.common.assembler.ForwardReference;
import org.jikesrvm.compilers.common.assembler.ia32.Assembler;
import org.jikesrvm.ia32.BaselineConstants;
......@@ -3960,6 +3961,9 @@ public abstract class BaselineCompilerImpl extends BaselineCompiler implements B
int asmOffset = asm.getMachineCodeIndex();
compiledMethod.addYPOffset(asmOffset);
asm.emitNOP(1);
if (CompiledMethods.methodWeCare == -1)
CompiledMethods.methodWeCare = compiledMethod.getId();
}
// nop yp
else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_NOP1_YP) {
......
......@@ -27,6 +27,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.ObjectReference;
import org.vmmagic.unboxed.Offset;
import org.vmmagic.unboxed.Word;
......@@ -101,15 +102,54 @@ public abstract class CompiledMethod {
@Uninterruptible
public final void nop2int() {
int instrSize = instructions.length();
for (int i = 0; i < ypOffsetsIndex; i++) {
instructions.set(i, INT3);
if (ypOffsets[i] >= instrSize) {
VM.sysWriteln("for method cmid:", getId());
VM.sysWriteln("instructions.length=", instrSize);
VM.sysWriteln("ypOffsets[i]=", ypOffsets[i]);
VM.sysFail("patching code that is not code!");
}
instructions.set(ypOffsets[i], INT3);
}
}
@Uninterruptible
public void nop2intDebug() {
VM.sysWriteln("Before patching:");
printInstructions();
VM.sysWriteln("Print nop offsets:");
for (int i = 0; i < ypOffsetsIndex; i++)
VM.sysWriteln(ypOffsets[i]);
VM.sysWriteln();
nop2int();
VM.sysWriteln("After patching:");
printInstructions();
}
@Uninterruptible
public void printInstructions() {
Address address = ObjectReference.fromObject(instructions).toAddress();
int length = instructions.length();
Address end = address.plus(length);
Address current = address;
while(current.LT(end)) {
VM.sysWriteHex(current.loadByte());
VM.sysWriteln();
current = current.plus(1);
}
VM.sysWriteln();
}
@Uninterruptible
public final void int2nop() {
for (int i = 0; i < ypOffsetsIndex; i++) {
instructions.set(i, NOP);
instructions.set(ypOffsets[i], NOP);
}
}
......
......@@ -331,25 +331,47 @@ public class CompiledMethods {
}
}
public static int methodWeCare = -1;
@Uninterruptible
public static void setNOP2INT() {
int patched = 0;
long start = Magic.getTimeBase();
for (int i = 0, n = numCompiledMethods(); i < n; i ++) {
CompiledMethod cm = getCompiledMethodUnchecked(i);
if (cm == null || !cm.isCompiled())
continue;
cm.nop2int();
if (cm.getId() == methodWeCare)
cm.nop2intDebug();
else cm.nop2int();
patched ++;
}
long time = Magic.getTimeBase() - start;
VM.sysWriteln("patched ", patched, " methods ");
VM.sysWriteln(" in ", time, " cycles. ");
}
@Uninterruptible
public static void setINT2NOP() {
int patched = 0;
long start = Magic.getTimeBase();
for (int i = 0, n = numCompiledMethods(); i < n; i ++) {
CompiledMethod cm = getCompiledMethodUnchecked(i);
if (cm == null || !cm.isCompiled())
continue;
cm.int2nop();
patched ++;
}
long time = Magic.getTimeBase() - start;
VM.sysWriteln("patched ", patched, " methods ");
VM.sysWriteln(" in ", time, " cycles. ");
}
}
......@@ -4039,8 +4039,14 @@ public final class RVMThread extends ThreadContext {
public static void yieldpoint(int whereFrom, Address yieldpointServiceMethodFP) {
if (YieldpointStatistics.ENABLE_YP_COUNT)
YieldpointStatistics.yieldpointTaken.increment();
VM.sysWriteln("service method: ", yieldpointServiceMethodFP);
RVMThread.dumpStack();
RVMThread t = getCurrentThread();
VM.sysWriteln("Thread ", t.getName(), " reaches yieldpoints");
boolean wasAtYieldpoint = t.atYieldpoint;
t.atYieldpoint = true;
t.yieldpointsTaken++;
......@@ -5627,25 +5633,27 @@ public final class RVMThread extends ThreadContext {
public static final Extent PROTECT_PAGE_SIZE = Extent.fromIntSignExtend(BYTES_IN_PAGE);
public void turnOnLocalYieldpoints() {
// takeYieldpoint = 1;
//
// if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_PAGE_PROTECTION_READ_YP ||
// org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_PAGE_PROTECTION_WRITE_YP) {
// Address pageAddr = Magic.objectAsAddress(this).plus(PROTECT_PAGE_OFFSET_BL).toWord().and(Word.fromIntZeroExtend(0xfffff000)).toAddress();
// Memory.mprotect(pageAddr, PROTECT_PAGE_SIZE, Memory.PROT_NONE);
// } else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_CODE_PATCHING_YP) {
takeYieldpoint = 1;
if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_PAGE_PROTECTION_READ_YP ||
org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_PAGE_PROTECTION_WRITE_YP) {
Address pageAddr = Magic.objectAsAddress(this).plus(PROTECT_PAGE_OFFSET_BL).toWord().and(Word.fromIntZeroExtend(0xfffff000)).toAddress();
Memory.mprotect(pageAddr, PROTECT_PAGE_SIZE, Memory.PROT_NONE);
}
// else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_CODE_PATCHING_YP) {
// CompiledMethods.setNOP2INT();
// }
}
public void turnOffLocalYieldpoints() {
// takeYieldpoint = 0;
//
// if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_PAGE_PROTECTION_READ_YP ||
// org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_PAGE_PROTECTION_WRITE_YP) {
// Address pageAddr = Magic.objectAsAddress(this).plus(PROTECT_PAGE_OFFSET_BL).toWord().and(Word.fromIntZeroExtend(0xfffff000)).toAddress();
// Memory.mprotect(pageAddr, PROTECT_PAGE_SIZE, Memory.PROT_EXEC | Memory.PROT_READ | Memory.PROT_WRITE);
// } else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_CODE_PATCHING_YP) {
takeYieldpoint = 0;
if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_PAGE_PROTECTION_READ_YP ||
org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_PAGE_PROTECTION_WRITE_YP) {
Address pageAddr = Magic.objectAsAddress(this).plus(PROTECT_PAGE_OFFSET_BL).toWord().and(Word.fromIntZeroExtend(0xfffff000)).toAddress();
Memory.mprotect(pageAddr, PROTECT_PAGE_SIZE, Memory.PROT_EXEC | Memory.PROT_READ | Memory.PROT_WRITE);
}
// else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_CODE_PATCHING_YP) {
// CompiledMethods.setINT2NOP();
// }
}
......@@ -5655,20 +5663,27 @@ public final class RVMThread extends ThreadContext {
public static final Address PROTECT_GLOBAL_PAGE_OPT = PROTECT_GLOBAL_PAGE_BL.plus(4);
public static void turnOnGlobalYieldpoints() {
// if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_CHECKING_YP)
// takeYieldpointGlobal = 1;
// else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_PAGE_PROTECTION_READ_YP ||
// org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_PAGE_PROTECTION_WRITE_YP) {
// Memory.mprotect(PROTECT_GLOBAL_PAGE_BL, PROTECT_PAGE_SIZE, Memory.PROT_NONE);
// }
if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_CHECKING_YP)
takeYieldpointGlobal = 1;
else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_PAGE_PROTECTION_READ_YP ||
org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_PAGE_PROTECTION_WRITE_YP) {
Memory.mprotect(PROTECT_GLOBAL_PAGE_BL, PROTECT_PAGE_SIZE, Memory.PROT_NONE);
}
else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_CODE_PATCHING_YP) {
CompiledMethods.setNOP2INT();
CompiledMethods.setINT2NOP();
}
}
public static void turnOffGlobalYieldpoints() {
// if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_CHECKING_YP)
// takeYieldpointGlobal = 0;
// else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_PAGE_PROTECTION_READ_YP ||
// org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_PAGE_PROTECTION_WRITE_YP) {
// Memory.mprotect(PROTECT_GLOBAL_PAGE_BL, PROTECT_PAGE_SIZE, Memory.PROT_EXEC | Memory.PROT_READ | Memory.PROT_WRITE);
// }
if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_CHECKING_YP)
takeYieldpointGlobal = 0;
else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_PAGE_PROTECTION_READ_YP ||
org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_PAGE_PROTECTION_WRITE_YP) {
Memory.mprotect(PROTECT_GLOBAL_PAGE_BL, PROTECT_PAGE_SIZE, Memory.PROT_EXEC | Memory.PROT_READ | Memory.PROT_WRITE);
}
else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_CODE_PATCHING_YP) {
// CompiledMethods.setINT2NOP();
}
}
}
......@@ -104,7 +104,7 @@ const char *bootDataFilename = 0;
const char *bootRMapFilename = 0;
/* Emit trace information? */
int lib_verbose = 0;
int lib_verbose = 1;
/* Location of jtoc within virtual machine image. */
static Address VmToc;
......@@ -657,10 +657,11 @@ hardwareTrapHandler(int signo, siginfo_t *si, void *context)
/* Insert artifical stackframe at the stack top */
Address * sp = (Address *)(IA32_ESP(context) - 4);
IA32_ESP(context) = IA32_ESP(context) - 4;
// instructionFollowing = getInstructionFollowing(localInstructionAddress);
*sp = localInstructionAddress;
if (lib_verbose)
fprintf(SysTraceFile,"NOPYP handler\n");
instructionFollowing = getInstructionFollowing(localInstructionAddress);
*sp = instructionFollowing;
printf("code patching YP handler\n");
unsigned int yieldPointHandlerAddress =
*(unsigned int *) (localJTOC + bootRecord->yieldpointFromPrologueOffset);
IA32_EIP(context) = yieldPointHandlerAddress;
......
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