Commit b32e0068 authored by Yi Lin's avatar Yi Lin

change to per-thread page protection

parent 5fd8238e
......@@ -3952,9 +3952,9 @@ public abstract class BaselineCompilerImpl extends BaselineCompiler implements B
} else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_NO_YP) {
// dont do anything
} else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_PAGE_PROTECTION_READ_YP) {
asm.emitTEST_Abs_Imm(RVMThread.PROTECT_GLOBAL_PAGE_BL, 0);
ThreadLocalState.emitCompareFieldWithImm(asm, Offset.fromIntSignExtend(RVMThread.PROTECT_PAGE_OFFSET_BL), 0);
} else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_PAGE_PROTECTION_WRITE_YP) {
asm.emitMOV_Abs_Imm(RVMThread.PROTECT_GLOBAL_PAGE_BL, 0);
ThreadLocalState.emitMoveImmToField(asm, Offset.fromIntSignExtend(RVMThread.PROTECT_PAGE_OFFSET_BL), 0);
} else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_CODE_PATCHING_YP) {
int asmOffset = asm.getMachineCodeIndex();
compiledMethod.addYPOffset(asmOffset);
......
......@@ -449,12 +449,12 @@ public class FinalMIRExpansion extends IRTools {
}
private static void expandPageProtectionReadYieldpoint(Instruction p, IR ir) {
Operand mem = MemoryOperand.D(RVMThread.PROTECT_GLOBAL_PAGE_OPT, (byte) 4, null, null);
Operand mem = MemoryOperand.BD(ir.regpool.makeTROp(), Offset.fromIntSignExtend(RVMThread.PROTECT_PAGE_OFFSET_OPT), (byte) 4, null, null);
MIR_Test.mutate(p, IA32_TEST, mem, IC(0));
}
private static void expandPageProtectionWriteYieldpoint(Instruction p, IR ir) {
Operand mem = MemoryOperand.D(RVMThread.PROTECT_GLOBAL_PAGE_OPT, (byte) 4, null, null);
Operand mem = MemoryOperand.BD(ir.regpool.makeTROp(), Offset.fromIntSignExtend(RVMThread.PROTECT_PAGE_OFFSET_OPT), (byte) 4, null, null);
MIR_Move.mutate(p, IA32_MOV, mem, IC(0));
}
......
......@@ -30,6 +30,7 @@ import static org.jikesrvm.ArchitectureSpecific.StackframeLayoutConstants.STACKF
import static org.jikesrvm.ArchitectureSpecific.StackframeLayoutConstants.STACK_SIZE_GUARD;
import static org.jikesrvm.ArchitectureSpecific.StackframeLayoutConstants.STACKFRAME_METHOD_ID_OFFSET;
import static org.jikesrvm.ArchitectureSpecific.StackframeLayoutConstants.STACKFRAME_RETURN_ADDRESS_OFFSET;
import static org.jikesrvm.SizeConstants.BYTES_IN_PAGE;
import org.jikesrvm.ArchitectureSpecific.BaselineConstants;
import org.jikesrvm.ArchitectureSpecific.ThreadLocalState;
......@@ -74,6 +75,7 @@ import org.vmmagic.pragma.Untraced;
import org.vmmagic.pragma.NoCheckStore;
import org.vmmagic.unboxed.Address;
import org.vmmagic.unboxed.Extent;
import org.vmmagic.unboxed.ObjectReference;
import org.vmmagic.unboxed.Word;
import org.vmmagic.unboxed.Offset;
......@@ -161,7 +163,7 @@ import org.jikesrvm.tuningfork.Feedlet;
*/
@Uninterruptible
@NonMoving
public final class RVMThread extends ThreadContext {
public final class RVMThread extends ThreadContext {
/*
* debug and statistics
*/
......@@ -2142,6 +2144,7 @@ public final class RVMThread extends ThreadContext {
" is terminating, returning as if blocked in TERMINATED state.");
result = TERMINATED;
} else {
turnOnYieldpoints();
takeYieldpoint = 1;
// CAS the execStatus field
int newState = setBlockedExecStatus();
......@@ -3789,8 +3792,6 @@ public final class RVMThread extends ThreadContext {
public static void blockAllMutatorsForGC() {
// request block - timestamp
YieldpointStatistics.gcRequestBlockTime = Magic.getTimeBase();
turnOnYieldpoints();
// yieldpoints turned on - timestamp
long turnOnLatency = (Magic.getTimeBase() - YieldpointStatistics.gcRequestBlockTime);
......@@ -3847,8 +3848,6 @@ public final class RVMThread extends ThreadContext {
// all thread blocked - time stamp
YieldpointStatistics.allThreadBlockedLatency += (Magic.getTimeBase() - YieldpointStatistics.gcRequestBlockTime);
turnOffYieldpoints();
}
/**
......@@ -4039,6 +4038,7 @@ public final class RVMThread extends ThreadContext {
*/
@Unpreemptible("May block if the thread was asked to do so but otherwise does not perform actions that may lead to blocking")
public static void yieldpoint(int whereFrom, Address yieldpointServiceMethodFP) {
// VM.sysWriteln("yieldpoint reached");
RVMThread t = getCurrentThread();
boolean wasAtYieldpoint = t.atYieldpoint;
t.atYieldpoint = true;
......@@ -5620,25 +5620,28 @@ public final class RVMThread extends ThreadContext {
sloppyExecStatusHistogram[newState]++;
}
public static final Address PROTECT_GLOBAL_PAGE_BL = Address.fromIntSignExtend(0x50000000);
public static final Address PROTECT_GLOBAL_PAGE_OPT = PROTECT_GLOBAL_PAGE_BL.plus(4);
public static final Extent PROTECT_PAGE_SIZE = Extent.fromIntSignExtend(SizeConstants.BYTES_IN_PAGE);
public static void turnOnYieldpoints() {
public static final int FIXED_SIZE = BYTES_IN_PAGE * 2;
public static final int PROTECT_PAGE_OFFSET_BL = BYTES_IN_PAGE;
public static final int PROTECT_PAGE_OFFSET_OPT = BYTES_IN_PAGE + 4;
public static final Extent PROTECT_PAGE_SIZE = Extent.fromIntSignExtend(BYTES_IN_PAGE);
public void turnOnYieldpoints() {
// VM.sysWriteln("Turn on yieldpoints");
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) {
Memory.mprotect(PROTECT_GLOBAL_PAGE_BL, PROTECT_PAGE_SIZE, Memory.PROT_NONE);
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 static void turnOffYieldpoints() {
public void turnOffYieldpoints() {
// VM.sysWriteln("Turn off yieldpoints");
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) {
Memory.mprotect(PROTECT_GLOBAL_PAGE_BL, PROTECT_PAGE_SIZE, Memory.PROT_EXEC | Memory.PROT_READ | Memory.PROT_WRITE);
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();
}
......
......@@ -12,9 +12,12 @@ public class YieldpointStatistics {
public static SynchronizedCounter yieldpointTaken = new SynchronizedCounter();
public static long gcRequestBlockTime;
public static long resumeMutatorMillis;
public static long yieldpointTurnedOnLatency = 0;
public static long allThreadBlockedLatency = 0;
public static long mutatorMillis = 0;
public static void reset() {
yieldpointTaken.reset();
......
......@@ -445,8 +445,8 @@ public class GenerateInterfaceDeclarations {
// yieldpoint
p("static const int YIELDPOINT_IMPL = " + org.mmtk.vm.VM.config.YIELDPOINT_IMPL + ";\n");
p("static const unsigned int PROTECT_GLOBAL_PAGE_BL = " + RVMThread.PROTECT_GLOBAL_PAGE_BL + ";\n");
p("static const unsigned int PROTECT_GLOBAL_PAGE_OPT = " + RVMThread.PROTECT_GLOBAL_PAGE_OPT + ";\n");
p("static const unsigned int PROTECT_PAGE_OFFSET_BL = " + RVMThread.PROTECT_PAGE_OFFSET_BL + ";\n");
p("static const unsigned int PROTECT_PAGE_OFFSET_OPT = " + RVMThread.PROTECT_PAGE_OFFSET_OPT + ";\n");
p("static const unsigned int PROTECT_PAGE_SIZE = " + RVMThread.PROTECT_PAGE_SIZE + ";\n");
pln();
......
......@@ -670,8 +670,9 @@ hardwareTrapHandler(int signo, siginfo_t *si, void *context)
/* page protection yieldpoint */
if (YIELDPOINT_IMPL == 1 || YIELDPOINT_IMPL == 2) {
unsigned int faultAddress = (unsigned int) si->si_addr;
int offset = faultAddress - IA32_ESI(context);
if (faultAddress == PROTECT_GLOBAL_PAGE_BL || faultAddress == PROTECT_GLOBAL_PAGE_OPT) {
if (offset == PROTECT_PAGE_OFFSET_BL || offset == PROTECT_PAGE_OFFSET_OPT) {
if (lib_verbose) {
printf("Thread %x in exception handler\n", IA32_ESI(context));
}
......@@ -682,9 +683,16 @@ hardwareTrapHandler(int signo, siginfo_t *si, void *context)
instructionFollowing = getInstructionFollowing(localInstructionAddress);
*sp = instructionFollowing;
// unprotect the page
char * pageAddr = (char*) (faultAddress & (~0xfff));
if (mprotect(pageAddr, PROTECT_PAGE_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
printf("cannot unprotect page in exception handler\n");
_exit(EXIT_STATUS_DYING_WITH_UNCAUGHT_EXCEPTION);
}
// get handler address
unsigned int yieldpointHandlerAddress;
if (faultAddress == PROTECT_GLOBAL_PAGE_BL)
if (offset == PROTECT_PAGE_OFFSET_BL)
yieldpointHandlerAddress = *(unsigned int*) (localJTOC + bootRecord->yieldpointFromPrologueOffset);
else
yieldpointHandlerAddress = *(unsigned int*) (localJTOC + bootRecord->yieldpointFromPrologueOptOffset);
......@@ -977,21 +985,21 @@ mapImageFile(const char *fileName, const void *targetAddress, int prot,
void *bootRegion = 0;
if (YIELDPOINT_IMPL == 1 || YIELDPOINT_IMPL == 2) {
if ((unsigned int)targetAddress == 0x60000000) {
bootRegion = mmap((void*)PROTECT_GLOBAL_PAGE_BL, 4096, prot, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
if (bootRegion == (void*) MAP_FAILED) {
printf("mmap failed\n");
return 0;
}
printf("mmap on %x\n", bootRegion);
*(int*)bootRegion = 0;
}
}
bootRegion = 0;
// if (YIELDPOINT_IMPL == 1 || YIELDPOINT_IMPL == 2) {
// if ((unsigned int)targetAddress == 0x60000000) {
// bootRegion = mmap((void*)PROTECT_GLOBAL_PAGE_BL, 4096, prot, MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
//
// if (bootRegion == (void*) MAP_FAILED) {
// printf("mmap failed\n");
// return 0;
// }
//
// printf("mmap on %x\n", bootRegion);
// *(int*)bootRegion = 0;
// }
// }
//
// bootRegion = 0;
bootRegion = mmap((void*)targetAddress, *roundedImageSize,
prot,
......
......@@ -1370,6 +1370,9 @@ public class BootImageWriter extends BootImageWriterMessages {
//
bootImageTypes.put(typeName, type);
}
RVMClass classrvm = (RVMClass) TypeReference.Thread.peekType();
classrvm.setInstanceSizeInternal(RVMThread.FIXED_SIZE);
if (profile) {
stopTime = System.currentTimeMillis();
......
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