use of org.objectweb.asm.tree.AbstractInsnNode in project quasar by puniverse.
the class InstrumentMethod method collectCallsites.
private void collectCallsites() {
if (suspCallsBcis == null) {
suspCallsBcis = new int[8];
final int numIns = mn.instructions.size();
int currSourceLine = -1;
int count = 0;
final Set<String> callSiteNames = new HashSet<>();
for (int i = 0; i < numIns; i++) {
final Frame f = frames[i];
if (f != null) {
// reachable ?
final AbstractInsnNode in = mn.instructions.get(i);
if (in.getType() == AbstractInsnNode.LINE) {
final LineNumberNode lnn = (LineNumberNode) in;
currSourceLine = lnn.line;
if (startSourceLine == -1 || currSourceLine < startSourceLine)
startSourceLine = currSourceLine;
if (endSourceLine == -1 || currSourceLine > endSourceLine)
endSourceLine = currSourceLine;
} else if (in.getType() == AbstractInsnNode.METHOD_INSN || in.getType() == AbstractInsnNode.INVOKE_DYNAMIC_INSN) {
if (isSuspendableCall(db, in)) {
if (count >= suspCallsBcis.length)
suspCallsBcis = Arrays.copyOf(suspCallsBcis, suspCallsBcis.length * 2);
if (count >= suspCallsSourceLines.length)
suspCallsSourceLines = Arrays.copyOf(suspCallsSourceLines, suspCallsSourceLines.length * 2);
suspCallsBcis[count] = i;
suspCallsSourceLines[count] = currSourceLine;
callSiteNames.add(getSuspendableCallName(in));
count++;
} else
possiblyWarnAboutBlocking(in);
}
}
}
if (count < suspCallsSourceLines.length)
suspCallsSourceLines = Arrays.copyOf(suspCallsSourceLines, count);
if (count < suspCallsBcis.length)
suspCallsBcis = Arrays.copyOf(suspCallsBcis, count);
suspCallsNames = callSiteNames.toArray(new String[0]);
}
}
use of org.objectweb.asm.tree.AbstractInsnNode in project quasar by puniverse.
the class InstrumentMethod method isForwardingToSuspendable.
private boolean isForwardingToSuspendable(int[] susCallsBcis) {
if (susCallsBcis.length != 1)
// we allow exactly one suspendable call
return false;
final int susCallBci = susCallsBcis[0];
final AbstractInsnNode susCall = mn.instructions.get(susCallBci);
assert isSuspendableCall(db, susCall);
if (isYieldMethod(getMethodOwner(susCall), getMethodName(susCall)))
// yield calls require instrumentation (to skip the call when resuming)
return false;
if (isReflectInvocation(getMethodOwner(susCall), getMethodName(susCall)))
// Reflective calls require instrumentation to handle SuspendExecution wrapped in InvocationTargetException
return false;
if (hasSuspendableTryCatchBlocksAround(susCallBci))
// Catching `SuspendableExecution needs instrumentation in order to propagate it
return false;
// before suspendable call:
for (int i = 0; i < susCallBci; i++) {
final AbstractInsnNode ins = mn.instructions.get(i);
if (ins.getType() == AbstractInsnNode.METHOD_INSN || ins.getType() == AbstractInsnNode.INVOKE_DYNAMIC_INSN)
// methods calls might have side effects
return false;
if (ins.getType() == AbstractInsnNode.FIELD_INSN)
// side effects
return false;
if (ins instanceof JumpInsnNode && mn.instructions.indexOf(((JumpInsnNode) ins).label) <= i)
// back branches may be costly, so we'd rather capture state
return false;
if (!db.isAllowMonitors() && (ins.getOpcode() == Opcodes.MONITORENTER || ins.getOpcode() == Opcodes.MONITOREXIT))
// we need collectCodeBlocks to warn about monitors
return false;
}
// after suspendable call
for (int i = susCallBci + 1; i <= mn.instructions.size() - 1; i++) {
final AbstractInsnNode ins = mn.instructions.get(i);
if (ins instanceof JumpInsnNode && mn.instructions.indexOf(((JumpInsnNode) ins).label) <= susCallBci)
// if we jump before the suspendable call we suspend more than once -- need instrumentation
return false;
if (!db.isAllowMonitors() && (ins.getOpcode() == Opcodes.MONITORENTER || ins.getOpcode() == Opcodes.MONITOREXIT))
// we need collectCodeBlocks to warn about monitors
return false;
if (!db.isAllowBlocking() && (ins instanceof MethodInsnNode && blockingCallIdx((MethodInsnNode) ins) != -1))
// we need collectCodeBlocks to warn about blocking calls
return false;
}
return true;
}
use of org.objectweb.asm.tree.AbstractInsnNode in project spring-loaded by spring-projects.
the class TypeDiffComputer method sameInsnNode.
private static boolean sameInsnNode(AbstractInsnNode o, AbstractInsnNode n) {
InsnNode oi = (InsnNode) o;
if (!(n instanceof InsnNode)) {
return false;
}
InsnNode ni = (InsnNode) n;
return oi.getOpcode() == ni.getOpcode();
}
use of org.objectweb.asm.tree.AbstractInsnNode in project maple-ir by LLVM-but-worse.
the class OpcodeInfo method getInstructions.
/**
* Retrieve filtered {@link AbstractInsnNode}'s of a {@link MethodNode} and put them into an array.
* @param m MethodNode to get instructions from.
* @param filter Filter to filter instructions.
* @return Filtered {@link AbstractInsnNode}'s.
*/
public static AbstractInsnNode[] getInstructions(MethodNode m, InstructionFilter filter) {
ArrayList<AbstractInsnNode> insns = new ArrayList<AbstractInsnNode>();
ListIterator<?> it = m.instructions.iterator();
while (it.hasNext()) {
AbstractInsnNode ain = (AbstractInsnNode) it.next();
if (filter.accept(ain))
insns.add(ain);
}
return insns.toArray(new AbstractInsnNode[insns.size()]);
}
use of org.objectweb.asm.tree.AbstractInsnNode in project malmo by Microsoft.
the class OverclockingClassTransformer method overclockServer.
private static void overclockServer(ClassNode node, boolean isObfuscated) {
// We're attempting to replace this code (from the heart of MinecraftServer.run):
/*
{
while (i > 50L)
{
i -= 50L;
this.tick();
}
}
Thread.sleep(Math.max(1L, 50L - i));
*/
// With this:
/*
{
while (i > TimeHelper.serverTickLength)
{
i -= TimeHelper.serverTickLength;
this.tick();
}
}
Thread.sleep(Math.max(1L, TimeHelper.serverTickLength - i));
*/
// This allows us to alter the tick length via TimeHelper.
final String methodName = "run";
// No params, returns void.
final String methodDescriptor = "()V";
System.out.println("MALMO: Found MinecraftServer, attempting to transform it");
for (MethodNode method : node.methods) {
if (method.name.equals(methodName) && method.desc.equals(methodDescriptor)) {
System.out.println("MALMO: Found MinecraftServer.run() method, attempting to transform it");
for (AbstractInsnNode instruction : method.instructions.toArray()) {
if (instruction.getOpcode() == Opcodes.LDC) {
Object cst = ((LdcInsnNode) instruction).cst;
if ((cst instanceof Long) && (Long) cst == 50) {
System.out.println("MALMO: Transforming LDC");
AbstractInsnNode replacement = new FieldInsnNode(Opcodes.GETSTATIC, "com/microsoft/Malmo/Utils/TimeHelper", "serverTickLength", "J");
method.instructions.set(instruction, replacement);
}
}
}
}
}
}
Aggregations