Commit 5034667f authored by Yi Lin's avatar Yi Lin

work on global yieldpoint impl

parent daa41b33
......@@ -28,7 +28,13 @@ public class Config {
public static final int USE_PAGE_PROTECTION_READ_YP = 1;
public static final int USE_PAGE_PROTECTION_WRITE_YP = 2;
public static final int USE_CODE_PATCHING_YP = 3;
public static final int USE_NO_YP = 9;
public static final int USE_GLOBAL_CHECKING_YP = 10;
public static final int USE_GLOBAL_PAGE_PROTECTION_READ_YP = 11;
public static final int USE_GLOBAL_PAGE_PROTECTION_WRITE_YP = 12;
public static final int USE_NO_YP = 20;
public static final int USE_NOP_YP = 21;
public final boolean ENABLE_YP_STAT;
......@@ -46,7 +52,15 @@ public class Config {
YIELDPOINT_IMPL = USE_CODE_PATCHING_YP;
} else if (config.getBooleanProperty("mmtk.use_no_yp", false)) {
YIELDPOINT_IMPL = USE_NO_YP;
} else {
} else if (config.getBooleanProperty("mmtk.use_global_checking_yp", false)) {
YIELDPOINT_IMPL = USE_GLOBAL_CHECKING_YP;
} else if (config.getBooleanProperty("mmtk.use_global_page_protection_read_yp", false)) {
YIELDPOINT_IMPL = USE_GLOBAL_PAGE_PROTECTION_READ_YP;
} else if (config.getBooleanProperty("mmtk.use_global_page_protection_write_yp", false)) {
YIELDPOINT_IMPL = USE_GLOBAL_PAGE_PROTECTION_WRITE_YP;
}
else {
YIELDPOINT_IMPL = USE_CHECKING_YP;
}
......
#
# This file is part of the Jikes RVM project (http://jikesrvm.org).
#
# This file is licensed to You under the Eclipse Public License (EPL);
# You may not use this file except in compliance with the License. You
# may obtain a copy of the License at
#
# http://www.opensource.org/licenses/eclipse-1.0.php
#
# See the COPYRIGHT.txt file distributed with this work for information
# regarding copyright ownership.
#
# Default MMTk properties file.
mmtk.use_global_checking_yp = true
#
# This file is part of the Jikes RVM project (http://jikesrvm.org).
#
# This file is licensed to You under the Eclipse Public License (EPL);
# You may not use this file except in compliance with the License. You
# may obtain a copy of the License at
#
# http://www.opensource.org/licenses/eclipse-1.0.php
#
# See the COPYRIGHT.txt file distributed with this work for information
# regarding copyright ownership.
#
# Default MMTk properties file.
mmtk.use_global_page_protection_read_yp = true
#
# This file is part of the Jikes RVM project (http://jikesrvm.org).
#
# This file is licensed to You under the Eclipse Public License (EPL);
# You may not use this file except in compliance with the License. You
# may obtain a copy of the License at
#
# http://www.opensource.org/licenses/eclipse-1.0.php
#
# See the COPYRIGHT.txt file distributed with this work for information
# regarding copyright ownership.
#
# Default MMTk properties file.
mmtk.use_global_page_protection_write_yp = true
......@@ -3960,7 +3960,31 @@ public abstract class BaselineCompilerImpl extends BaselineCompiler implements B
int asmOffset = asm.getMachineCodeIndex();
compiledMethod.addYPOffset(asmOffset);
asm.emitNOP(1);
}
// global yieldpoint
else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_CHECKING_YP) {
asm.emitCMP_Abs_Imm(Magic.getTocPointer().plus(Entrypoints.takeYieldpointGlobalField.getOffset()), 0);
ForwardReference fr1;
if (whereFrom == RVMThread.PROLOGUE) {
// Take yieldpoint if yieldpoint flag is non-zero (either 1 or -1)
fr1 = asm.forwardJcc(EQ);
asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.yieldpointFromPrologueMethod.getOffset()));
} else if (whereFrom == RVMThread.BACKEDGE) {
// Take yieldpoint if yieldpoint flag is >0
fr1 = asm.forwardJcc(LE);
asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.yieldpointFromBackedgeMethod.getOffset()));
} else { // EPILOGUE
// Take yieldpoint if yieldpoint flag is non-zero (either 1 or -1)
fr1 = asm.forwardJcc(EQ);
asm.emitCALL_Abs(Magic.getTocPointer().plus(Entrypoints.yieldpointFromEpilogueMethod.getOffset()));
}
fr1.resolve(asm);
}
else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_PAGE_PROTECTION_READ_YP) {
asm.emitCMP_Abs_Imm(RVMThread.PROTECT_GLOBAL_PAGE_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);
}
if (VM.BuildForAdaptiveSystem && options.INVOCATION_COUNTERS) {
int id = compiledMethod.getId();
......
......@@ -15,6 +15,7 @@ package org.jikesrvm.compilers.opt.mir2mc.ia32;
import java.util.Enumeration;
import org.jikesrvm.VM;
import org.jikesrvm.classloader.NormalMethod;
import org.jikesrvm.classloader.RVMMethod;
import org.jikesrvm.compilers.opt.ir.BBend;
import org.jikesrvm.compilers.opt.ir.Label;
......@@ -405,6 +406,9 @@ public class FinalMIRExpansion extends IRTools {
case YIELDPOINT_PROLOGUE_opcode:
if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_CHECKING_YP)
expandYieldpoint(p, ir, Entrypoints.optThreadSwitchFromPrologueMethod, IA32ConditionOperand.NE());
else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_CHECKING_YP) {
expandYieldpointGlobal(p, ir, Entrypoints.optThreadSwitchFromPrologueMethod, IA32ConditionOperand.NE());
}
else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_NO_YP) {
// do nothing
removeYieldpoint(p, ir);
......@@ -412,12 +416,19 @@ public class FinalMIRExpansion extends IRTools {
expandPageProtectionReadYieldpoint(p, ir);
} else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_PAGE_PROTECTION_WRITE_YP) {
expandPageProtectionWriteYieldpoint(p, ir);
} else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_PAGE_PROTECTION_READ_YP) {
expandPageProtectionReadYieldpointGlobal(p, ir);
} else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_PAGE_PROTECTION_WRITE_YP) {
expandPageProtectionWriteYieldpointGlobal(p, ir);
}
break;
case YIELDPOINT_EPILOGUE_opcode:
if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_CHECKING_YP)
expandYieldpoint(p, ir, Entrypoints.optThreadSwitchFromEpilogueMethod, IA32ConditionOperand.NE());
else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_CHECKING_YP) {
expandYieldpointGlobal(p, ir, Entrypoints.optThreadSwitchFromEpilogueMethod, IA32ConditionOperand.NE());
}
else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_NO_YP) {
// do nothing
removeYieldpoint(p, ir);
......@@ -425,12 +436,19 @@ public class FinalMIRExpansion extends IRTools {
expandPageProtectionReadYieldpoint(p, ir);
} else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_PAGE_PROTECTION_WRITE_YP) {
expandPageProtectionWriteYieldpoint(p, ir);
} else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_PAGE_PROTECTION_READ_YP) {
expandPageProtectionReadYieldpointGlobal(p, ir);
} else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_PAGE_PROTECTION_WRITE_YP) {
expandPageProtectionWriteYieldpointGlobal(p, ir);
}
break;
case YIELDPOINT_BACKEDGE_opcode:
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) {
expandYieldpointGlobal(p, ir, Entrypoints.optThreadSwitchFromBackedgeMethod, IA32ConditionOperand.GT());
}
else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_NO_YP) {
// do nothing
removeYieldpoint(p, ir);
......@@ -438,6 +456,10 @@ public class FinalMIRExpansion extends IRTools {
expandPageProtectionReadYieldpoint(p, ir);
} else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_PAGE_PROTECTION_WRITE_YP) {
expandPageProtectionWriteYieldpoint(p, ir);
} else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_PAGE_PROTECTION_READ_YP) {
expandPageProtectionReadYieldpointGlobal(p, ir);
} else if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_GLOBAL_PAGE_PROTECTION_WRITE_YP) {
expandPageProtectionWriteYieldpointGlobal(p, ir);
}
break;
......@@ -450,8 +472,14 @@ public class FinalMIRExpansion extends IRTools {
}
return 0;
}
private static void expandPageProtectionReadYieldpoint(Instruction p, IR ir) {
private static void expandPageProtectionReadYieldpointGlobal(Instruction p,
IR ir) {
Operand mem = MemoryOperand.D(RVMThread.PROTECT_GLOBAL_PAGE_OPT, (byte) 4, null, null);
MIR_Test.mutate(p, IA32_TEST, mem, IC(0));
}
private static void expandPageProtectionReadYieldpoint(Instruction p, IR ir) {
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));
}
......@@ -460,6 +488,12 @@ public class FinalMIRExpansion extends IRTools {
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));
}
private static void expandPageProtectionWriteYieldpointGlobal(Instruction p,
IR ir) {
Operand mem = MemoryOperand.D(RVMThread.PROTECT_GLOBAL_PAGE_OPT, (byte) 4, null, null);
MIR_Move.mutate(p, IA32_MOV, mem, IC(0));
}
private static void removeYieldpoint(Instruction s, IR ir) {
s.remove();
......@@ -593,6 +627,42 @@ public class FinalMIRExpansion extends IRTools {
yieldpoint.makeJumpTarget(),
BranchProfileOperand.never()));
}
private static void expandYieldpointGlobal(Instruction s, IR ir,
NormalMethod meth, IA32ConditionOperand ypCond) {
// split the basic block after the yieldpoint, create a new
// block at the end of the IR to hold the yieldpoint,
// remove the yieldpoint (to prepare to out it in the new block at the end)
BasicBlock thisBlock = s.getBasicBlock();
BasicBlock nextBlock = thisBlock.splitNodeWithLinksAt(s, ir);
BasicBlock yieldpoint = thisBlock.createSubBlock(s.bcIndex, ir, 0);
thisBlock.insertOut(yieldpoint);
yieldpoint.insertOut(nextBlock);
ir.cfg.addLastInCodeOrder(yieldpoint);
s.remove();
// change thread switch instruction into call to thread switch routine
// NOTE: must make s the call instruction: it is the GC point!
// must also inform the GCMap that s has been moved!!!
Offset offset = meth.getOffset();
LocationOperand loc = new LocationOperand(offset);
Operand guard = TG();
Operand target = MemoryOperand.D(Magic.getTocPointer().plus(offset), (byte) 4, loc, guard);
MIR_Call.mutate0(s, CALL_SAVE_VOLATILE, null, null, target, MethodOperand.STATIC(meth));
yieldpoint.appendInstruction(s);
ir.MIRInfo.gcIRMap.moveToEnd(s);
yieldpoint.appendInstruction(MIR_Branch.create(IA32_JMP, nextBlock.makeJumpTarget()));
// Check to see if threadSwitch requested
MemoryOperand M = MemoryOperand.D(Magic.getTocPointer().plus(Entrypoints.takeYieldpointGlobalField.getOffset()), (byte) 4, null, null);
thisBlock.appendInstruction(MIR_Compare.create(IA32_CMP, M, IC(0)));
thisBlock.appendInstruction(MIR_CondBranch.create(IA32_JCC,
ypCond,
yieldpoint.makeJumpTarget(),
BranchProfileOperand.never()));
}
/* generate yieldpoint without checking threadSwith request
*/
......
......@@ -200,6 +200,9 @@ public class Entrypoints {
getField(org.jikesrvm.scheduler.RVMThread.class, "ECXSave", int.class);
public static final RVMField EDXSaveField =
getField(org.jikesrvm.scheduler.RVMThread.class, "EDXSave", int.class);
public static final RVMField takeYieldpointGlobalField =
getField(org.jikesrvm.scheduler.RVMThread.class, "takeYieldpointGlobal", int.class);
public static final RVMField execStatusField = getField(org.jikesrvm.scheduler.RVMThread.class, "execStatus", int.class);
......
......@@ -2144,7 +2144,7 @@ public final class RVMThread extends ThreadContext {
" is terminating, returning as if blocked in TERMINATED state.");
result = TERMINATED;
} else {
turnOnYieldpoints();
turnOnLocalYieldpoints();
// CAS the execStatus field
int newState = setBlockedExecStatus();
result = newState;
......@@ -3793,6 +3793,8 @@ public final class RVMThread extends ThreadContext {
// request block - timestamp
YieldpointStatistics.gcRequestBlockTime = Magic.getTimeBase();
turnOnGlobalYieldpoints();
RVMThread.handshakeLock.lockNoHandshake();
while (true) {
// (1) Find all the threads that need to be blocked for GC
......@@ -3851,6 +3853,7 @@ public final class RVMThread extends ThreadContext {
@Unpreemptible
public static void unblockAllMutatorsForGC() {
YieldpointStatistics.mutatorStartTimeMillis = sysCall.sysCurrentTimeMillis();
turnOffGlobalYieldpoints();
RVMThread.handshakeLock.lockNoHandshake();
RVMThread.acctLock.lockNoHandshake();
......@@ -5623,7 +5626,7 @@ public final class RVMThread extends ThreadContext {
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() {
public void turnOnLocalYieldpoints() {
// takeYieldpoint = 1;
//
// if (org.mmtk.vm.VM.config.YIELDPOINT_IMPL == org.mmtk.vm.Config.USE_PAGE_PROTECTION_READ_YP ||
......@@ -5634,4 +5637,38 @@ public final class RVMThread extends ThreadContext {
// 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) {
CompiledMethods.setINT2NOP();
}
}
public static int takeYieldpointGlobal = 0;
public static final Address PROTECT_GLOBAL_PAGE_BL = Address.fromIntZeroExtend(0x50000000);
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);
// }
}
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);
}
}
}
......@@ -448,6 +448,8 @@ public class GenerateInterfaceDeclarations {
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");
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");
pln();
// values in RuntimeEntrypoints
......
......@@ -652,7 +652,7 @@ hardwareTrapHandler(int signo, siginfo_t *si, void *context)
_exit(EXIT_STATUS_DYING_WITH_UNCAUGHT_EXCEPTION);
}
/* Test for nop yield point */
/* Test for code patching yield point */
if (YIELDPOINT_IMPL == 3 && signo == 5){
/* Insert artifical stackframe at the stack top */
Address * sp = (Address *)(IA32_ESP(context) - 4);
......@@ -667,7 +667,26 @@ hardwareTrapHandler(int signo, siginfo_t *si, void *context)
return;
}
/* page protection yieldpoint */
if (YIELDPOINT_IMPL == 11 || YIELDPOINT_IMPL == 12) {
unsigned int faultAddress = (unsigned int ) si->si_addr;
Addres* sp = (Address*) (IA32_ESP(context) - 4);
IA32_ESP(context) = IA32_ESP(context) - 4;
instructionFollowing = getInstructionFollowing(localInstructionAddress);
*sp = instructionFollowing;
unsigned int yieldpointHandlerAddress;
if (faultAddress == PROTECT_GLOBAL_PAGE_BL) {
yieldpointHandlerAddress = *(unsigned int*) (localJTOC + bootRecord->yieldpointFromPrologueOffset);
} else {
yieldpointHandlerAddress = *(unsigned int*) (localJTOC + bootRecord->yieldpointFromPrologueOptOffset);
}
IA32_EIP(context) = yieldpointHandlerAddress;
return;
}
/* page protection local yieldpoint */
if (YIELDPOINT_IMPL == 1 || YIELDPOINT_IMPL == 2) {
unsigned int faultAddress = (unsigned int) si->si_addr;
int offset = faultAddress - IA32_ESI(context);
......@@ -985,21 +1004,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 == 11 || YIELDPOINT_IMPL == 12) {
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,
......
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