public boolean preScreen(MethodGen mg) { ConstantPoolGen cpg = mg.getConstantPool(); int lockCount = mg.isSynchronized() ? 1 : 0; boolean sawWaitOrNotify = false; InstructionHandle handle = mg.getInstructionList().getStart(); while (handle != null && !(lockCount >= 2 && sawWaitOrNotify)) { Instruction ins = handle.getInstruction(); if (ins instanceof MONITORENTER) ++lockCount; else if (ins instanceof INVOKEVIRTUAL) { INVOKEVIRTUAL inv = (INVOKEVIRTUAL) ins; String methodName = inv.getMethodName(cpg); if (methodName.equals("wait") || methodName.startsWith("notify")) sawWaitOrNotify = true; } handle = handle.getNext(); } return lockCount >= 2 && sawWaitOrNotify; }
public int getDelta(Instruction ins, ValueNumberFrame frame) throws DataflowAnalysisException { int delta = 0; if (ins instanceof MONITORENTER) { if (frame == null || !isThisValue(frame.getTopValue())) ++delta; } else if (ins instanceof MONITOREXIT) { if (frame == null || !isThisValue(frame.getTopValue())) --delta; } return delta; }
public MatchResult match(InstructionHandle handle, ConstantPoolGen cpg, ValueNumberFrame before, ValueNumberFrame after, BindingSet bindingSet) throws DataflowAnalysisException { // Instruction must be MONITORENTER. Instruction ins = handle.getInstruction(); if (!(ins instanceof MONITORENTER)) return null; // Ensure the object being locked matches any previous // instructions which bound our variable name to a value. Variable lock = new LocalVariable(before.getTopValue()); return addOrCheckDefinition(lock, bindingSet); }
public int getDelta(Instruction ins, ValueNumberFrame frame) throws DataflowAnalysisException { int delta = 0; if (ins instanceof MONITORENTER) ++delta; else if (ins instanceof MONITOREXIT) --delta; return delta; }
/** * Scan a method for self call sites. * * @param node * the CallGraphNode for the method to be scanned */ private void scan(CallGraphNode node) throws CFGBuilderException { Method method = node.getMethod(); CFG cfg = classContext.getCFG(method); if (method.isSynchronized()) hasSynchronization = true; Iterator<BasicBlock> i = cfg.blockIterator(); while (i.hasNext()) { BasicBlock block = i.next(); Iterator<InstructionHandle> j = block.instructionIterator(); while (j.hasNext()) { InstructionHandle handle = j.next(); Instruction ins = handle.getInstruction(); if (ins instanceof InvokeInstruction) { InvokeInstruction inv = (InvokeInstruction) ins; Method called = isSelfCall(inv); if (called != null) { // Add edge to call graph CallSite callSite = new CallSite(method, block, handle); callGraph.createEdge(node, callGraph.getNodeForMethod(called), callSite); // Add to called method set calledMethodSet.add(called); } } else if (ins instanceof MONITORENTER || ins instanceof MONITOREXIT) { hasSynchronization = true; } } } }
@Override public void visitMONITORENTER(MONITORENTER obj) { // Don't know what this sync invocation is doing. // Kill all loads. ValueNumber topValue = null; try { topValue = getFrame().getStackValue(0); } catch (DataflowAnalysisException e) { AnalysisContext.logError("error handling monitor enter in value numbering", e); } getFrame().killAllLoadsExceptFor(topValue); handleNormalInstruction(obj); }
@Override public MatchResult match(InstructionHandle handle, ConstantPoolGen cpg, ValueNumberFrame before, ValueNumberFrame after, BindingSet bindingSet) throws DataflowAnalysisException { // Instruction must be MONITORENTER. Instruction ins = handle.getInstruction(); if (!(ins instanceof MONITORENTER)) return null; // Ensure the object being locked matches any previous // instructions which bound our variable name to a value. Variable lock = new LocalVariable(before.getTopValue()); return addOrCheckDefinition(lock, bindingSet); }