use of org.vmmagic.pragma.Interruptible 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!");
}
}
}
}
use of org.vmmagic.pragma.Interruptible in project JikesRVM by JikesRVM.
the class OptCompiledMethod method createCodePatchMaps.
/**
* Create the code patching maps from the IR for the method
* @param ir the ir
*/
@Interruptible
public void createCodePatchMaps(IR ir) {
// (1) count the patch points
int patchPoints = 0;
for (Instruction s = ir.firstInstructionInCodeOrder(); s != null; s = s.nextInstructionInCodeOrder()) {
if (s.operator() == IG_PATCH_POINT) {
patchPoints++;
}
}
// (2) if we have patch points, create the map.
if (patchPoints != 0) {
patchMap = new int[patchPoints * 2];
MachineCodeOffsets mcOffsets = ir.MIRInfo.mcOffsets;
int idx = 0;
for (Instruction s = ir.firstInstructionInCodeOrder(); s != null; s = s.nextInstructionInCodeOrder()) {
if (s.operator() == IG_PATCH_POINT) {
int patchPoint = mcOffsets.getMachineCodeOffset(s);
int newTarget = mcOffsets.getMachineCodeOffset(InlineGuard.getTarget(s).target);
// and the new branch immediate to lay down if the code is ever patched.
if (VM.BuildForIA32) {
patchMap[idx++] = patchPoint - 1;
patchMap[idx++] = newTarget - patchPoint;
} else if (VM.BuildForPowerPC) {
/* since currently we use only one NOP scheme, the offset
* is adjusted for one word
*/
patchMap[idx++] = (patchPoint >> ArchConstants.getLogInstructionWidth()) - 1;
patchMap[idx++] = (newTarget - patchPoint + (1 << ArchConstants.getLogInstructionWidth()));
} else if (VM.VerifyAssertions) {
VM._assert(VM.NOT_REACHED);
}
}
}
}
}
use of org.vmmagic.pragma.Interruptible in project JikesRVM by JikesRVM.
the class OptCompiledMethod method printStackTrace.
@Override
@Interruptible
public void printStackTrace(Offset instructionOffset, PrintLN out) {
OptMachineCodeMap map = getMCMap();
int iei = map.getInlineEncodingForMCOffset(instructionOffset);
if (iei >= 0) {
int[] inlineEncoding = map.inlineEncoding;
int bci = map.getBytecodeIndexForMCOffset(instructionOffset);
for (int j = iei; j >= 0; j = OptEncodedCallSiteTree.getParent(j, inlineEncoding)) {
int mid = OptEncodedCallSiteTree.getMethodID(j, inlineEncoding);
NormalMethod m = (NormalMethod) MemberReference.getMethodRef(mid).peekResolvedMethod();
// might be 0 if unavailable.
int lineNumber = m.getLineNumberForBCIndex(bci);
out.print("\tat ");
out.print(m.getDeclaringClass());
out.print('.');
out.print(m.getName());
out.print('(');
out.print(m.getDeclaringClass().getSourceName());
out.print(':');
out.print(lineNumber);
out.print(')');
out.println();
if (j > 0) {
bci = OptEncodedCallSiteTree.getByteCodeOffset(j, inlineEncoding);
}
}
} else {
out.print("\tat ");
out.print(method.getDeclaringClass());
out.print('.');
out.print(method.getName());
out.print('(');
out.print(method.getDeclaringClass().getSourceName());
out.print("; machine code offset: ");
out.printHex(instructionOffset.toInt());
out.print(')');
out.println();
}
}
use of org.vmmagic.pragma.Interruptible in project JikesRVM by JikesRVM.
the class OptEncodedCallSiteTree method getEncoding.
@Interruptible
public static int[] getEncoding(CallSiteTree tree) {
int size = 0;
if (tree.isEmpty()) {
return null;
} else {
Enumeration<TreeNode> e = tree.elements();
while (e.hasMoreElements()) {
TreeNode x = e.nextElement();
if (x.getLeftChild() == null) {
size += 2;
} else {
size += 3;
}
}
int[] encoding = new int[size];
getEncoding((CallSiteTreeNode) tree.getRoot(), 0, -1, encoding);
return encoding;
}
}
use of org.vmmagic.pragma.Interruptible in project JikesRVM by JikesRVM.
the class OptGCMap method generateGCMapEntry.
/**
* Construct the GCMap for the argument GCIRMapElement
* @param irMapElem The IR Map element to create a GCMap for
* @return the GCMap index.
*/
@Interruptible
public int generateGCMapEntry(GCIRMapElement irMapElem) {
// the index into the GC maps we will use for this instruction.
int mapIndex = NO_MAP_ENTRY;
// Before requesting the (first) map entry, lets make sure we
// will need it. If the reg/spill list is empty, we don't
// need a map slot, i.e., no references are live at this instruction
List<RegSpillListElement> regSpillList = irMapElem.regSpillList();
if (!regSpillList.isEmpty()) {
// For efficiency we create our own bit map and then set the
// appropriate array value
int bitMap = 0;
// count the spills so we know how big of an array we'll need
int numSpills = 0;
int numRegs = 0;
// process the register
for (RegSpillListElement elem : regSpillList) {
if (elem.isSpill()) {
numSpills++;
} else {
numRegs++;
int realRegNumber = elem.getRealRegNumber();
if (VM.VerifyAssertions && realRegNumber > LAST_GCMAP_REG) {
System.out.println(elem);
System.out.println(LAST_GCMAP_REG);
VM._assert(VM.NOT_REACHED, "reg > last GC Map Reg!!");
}
// get the bit position for this register number
int bitPosition = getRegBitPosition(realRegNumber);
// Set the appropriate bit
bitMap = bitMap | (NEXT_BIT >>> bitPosition);
}
}
// get the next free Map entry
int index = setRegisterBitMap(bitMap);
int[] spillArray = new int[numSpills];
int spillIndex = 0;
// first, get a fresh enumerator
for (RegSpillListElement elem : regSpillList) {
if (elem.isSpill()) {
spillArray[spillIndex++] = elem.getSpill();
}
}
// add the spills into the map
addAllSpills(spillArray);
// don't forget to report that there are no more spills
mapIndex = endCurrentMap(index);
}
return mapIndex;
}
Aggregations