public AsyncMethodNode readAsync(DataInput input, MethodReference method) throws IOException { AsyncMethodNode node = new AsyncMethodNode(method); node.getModifiers().addAll(unpackModifiers(input.readInt())); int varCount = input.readShort(); for (int i = 0; i < varCount; ++i) { node.getVariables().add(readVariable(input)); } int partCount = input.readShort(); for (int i = 0; i < partCount; ++i) { AsyncMethodPart part = new AsyncMethodPart(); part.setStatement(readStatement(input)); node.getBody().add(part); } return node; }
boolean[] preservedVars = new boolean[method.getVariables().size()]; ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size()); stats.analyze(splitter.getProgram(i)); applyParametersToWriteStats(stats, method.getReference()); AsyncMethodPart part = method.getBody().get(i); BreakEliminator breakEliminator = new BreakEliminator(); breakEliminator.eliminate(part.getStatement()); int paramCount = method.getReference().parameterCount(); UnusedVariableEliminator unusedEliminator = new UnusedVariableEliminator(paramCount, method.getVariables()); for (AsyncMethodPart part : method.getBody()) { part.getStatement().acceptVisitor(unusedEliminator); method.getVariables().clear(); method.getVariables().addAll(unusedEliminator.getReorderedVariables()); for (AsyncMethodPart part : method.getBody()) { part.getStatement().acceptVisitor(labelEliminator); for (int i = 0; i < method.getVariables().size(); ++i) { method.getVariables().get(i).setIndex(i);
public void writeAsync(DataOutput output, AsyncMethodNode method) throws IOException { output.writeInt(ElementModifier.pack(method.getModifiers())); output.writeShort(method.getVariables().size()); for (VariableNode var : method.getVariables()) { write(output, var); } try { output.writeShort(method.getBody().size()); for (int i = 0; i < method.getBody().size(); ++i) { method.getBody().get(i).getStatement().acceptVisitor(new NodeWriter(output)); } } catch (IOExceptionWrapper e) { throw new IOException("Error writing method body", e.getCause()); } }
statementRenderer.setAsync(true); this.async = true; MethodReference ref = methodNode.getReference(); for (int i = 0; i < methodNode.getVariables().size(); ++i) { debugEmitter.emitVariable(new String[] { methodNode.getVariables().get(i).getName() }, statementRenderer.variableName(i)); for (VariableNode var : methodNode.getVariables()) { variableCount = Math.max(variableCount, var.getIndex() + 1); for (AsyncMethodPart part : methodNode.getBody()) { if (!tryCatchFinder.tryCatchFound) { part.getStatement().acceptVisitor(tryCatchFinder); if (methodNode.getModifiers().contains(ElementModifier.STATIC)) { firstToSave = 1; if (methodNode.getModifiers().contains(ElementModifier.SYNCHRONIZED)) { writer.append("try").ws().append('{').indent().softNewLine(); for (int i = 0; i < methodNode.getBody().size(); ++i) { writer.append("case ").append(i).append(":").indent().softNewLine(); if (i == 0 && methodNode.getModifiers().contains(ElementModifier.SYNCHRONIZED)) { writer.appendMethodBody(NameFrequencyEstimator.MONITOR_ENTER_METHOD); writer.append("("); AsyncMethodPart part = methodNode.getBody().get(i); statementRenderer.setEnd(true); statementRenderer.setCurrentPart(i);
public String[] extract(AsyncMethodNode node) { for (AsyncMethodPart part : node.getBody()) { part.getStatement().acceptVisitor(visitor); } String[] result = visitor.dependencies.toArray(new String[0]); visitor.dependencies.clear(); return result; }
statementRenderer.setAsync(true); this.async = true; MethodReference ref = methodNode.getReference(); for (int i = 0; i < methodNode.getVariables().size(); ++i) { debugEmitter.emitVariable(new String[] { methodNode.getVariables().get(i).getName() }, statementRenderer.variableName(i)); for (VariableNode var : methodNode.getVariables()) { variableCount = Math.max(variableCount, var.getIndex() + 1); for (AsyncMethodPart part : methodNode.getBody()) { if (!tryCatchFinder.tryCatchFound) { part.getStatement().acceptVisitor(tryCatchFinder); if (methodNode.getModifiers().contains(ElementModifier.STATIC)) { firstToSave = 1; if (methodNode.getModifiers().contains(ElementModifier.SYNCHRONIZED)) { writer.append("try").ws().append('{').indent().softNewLine(); for (int i = 0; i < methodNode.getBody().size(); ++i) { writer.append("case ").append(i).append(":").indent().softNewLine(); if (i == 0 && methodNode.getModifiers().contains(ElementModifier.SYNCHRONIZED)) { writer.appendMethodBody(new MethodReference(Object.class, "monitorEnter", Object.class, void.class)); AsyncMethodPart part = methodNode.getBody().get(i); statementRenderer.setEnd(true); statementRenderer.setCurrentPart(i);
public void writeAsync(DataOutput output, AsyncMethodNode method) throws IOException { output.writeInt(packModifiers(method.getModifiers())); output.writeShort(method.getVariables().size()); for (VariableNode var : method.getVariables()) { write(output, var); } try { output.writeShort(method.getBody().size()); for (int i = 0; i < method.getBody().size(); ++i) { method.getBody().get(i).getStatement().acceptVisitor(new NodeWriter(output)); } } catch (IOExceptionWrapper e) { throw new IOException("Error writing method body", e.getCause()); } }
@Override public void visit(AsyncMethodNode methodNode) { async = true; for (AsyncMethodPart part : methodNode.getBody()) { part.getStatement().acceptVisitor(this); } }
private AsyncMethodNode decompileAsyncCacheMiss(MethodHolder method) { AsyncMethodNode node = new AsyncMethodNode(method.getReference()); AsyncProgramSplitter splitter = new AsyncProgramSplitter(classSource, splitMethods); splitter.split(method.getProgram()); for (int i = 0; i < splitter.size(); ++i) { AsyncMethodPart part; try { part = getRegularMethodStatement(splitter.getProgram(i), splitter.getBlockSuccessors(i), i > 0); } catch (RuntimeException e) { StringBuilder sb = new StringBuilder("Error decompiling method " + method.getReference() + " part " + i + ":\n"); sb.append(new ListingBuilder().buildListing(splitter.getProgram(i), " ")); throw new DecompilationException(sb.toString(), e); } node.getBody().add(part); } Program program = method.getProgram(); TypeInferer typeInferer = new TypeInferer(); typeInferer.inferTypes(program, method.getReference()); for (int i = 0; i < program.variableCount(); ++i) { VariableNode variable = new VariableNode(program.variableAt(i).getRegister(), typeInferer.typeOf(i)); variable.setName(program.variableAt(i).getDebugName()); node.getVariables().add(variable); } Optimizer optimizer = new Optimizer(moveConstants); optimizer.optimize(node, splitter, friendlyToDebugger); node.getModifiers().addAll(method.getModifiers()); return node; }
boolean[] preservedVars = new boolean[method.getVariables().size()]; ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size()); stats.analyze(splitter.getProgram(i)); AsyncMethodPart part = method.getBody().get(i); BreakEliminator breakEliminator = new BreakEliminator(); breakEliminator.eliminate(part.getStatement()); int paramCount = method.getReference().parameterCount(); UnusedVariableEliminator unusedEliminator = new UnusedVariableEliminator(paramCount, method.getVariables()); for (AsyncMethodPart part : method.getBody()) { part.getStatement().acceptVisitor(unusedEliminator); method.getVariables().clear(); method.getVariables().addAll(unusedEliminator.getReorderedVariables()); for (AsyncMethodPart part : method.getBody()) { part.getStatement().acceptVisitor(labelEliminator); for (int i = 0; i < method.getVariables().size(); ++i) { method.getVariables().get(i).setIndex(i);
@Override public void visit(AsyncMethodNode methodNode) { async = true; for (AsyncMethodPart part : methodNode.getBody()) { part.getStatement().acceptVisitor(this); } }
public AsyncMethodNode readAsync(DataInput input, MethodReference method) throws IOException { AsyncMethodNode node = new AsyncMethodNode(method); node.getModifiers().addAll(unpackModifiers(input.readInt())); int varCount = input.readShort(); for (int i = 0; i < varCount; ++i) { node.getVariables().add(readVariable(input)); } int partCount = input.readShort(); for (int i = 0; i < partCount; ++i) { AsyncMethodPart part = new AsyncMethodPart(); part.setStatement(readStatement(input)); node.getBody().add(part); } return node; }
private boolean checkAsyncRelevant(AsyncMethodNode node) { AsyncCallsFinder asyncCallsFinder = new AsyncCallsFinder(); for (AsyncMethodPart part : node.getBody()) { part.getStatement().acceptVisitor(asyncCallsFinder); } for (MethodReference asyncCall : asyncCallsFinder.asyncCalls) { if (!splitMethods.contains(asyncCall)) { return false; } } asyncCallsFinder.allCalls.removeAll(asyncCallsFinder.asyncCalls); for (MethodReference asyncCall : asyncCallsFinder.allCalls) { if (splitMethods.contains(asyncCall)) { return false; } } return true; }
private AsyncMethodNode decompileAsyncCacheMiss(MethodHolder method) { AsyncMethodNode node = new AsyncMethodNode(method.getReference()); AsyncProgramSplitter splitter = new AsyncProgramSplitter(classSource, splitMethods); splitter.split(method.getProgram()); for (int i = 0; i < splitter.size(); ++i) { AsyncMethodPart part; try { part = getRegularMethodStatement(splitter.getProgram(i), splitter.getBlockSuccessors(i), i > 0); } catch (RuntimeException e) { StringBuilder sb = new StringBuilder("Error decompiling method " + method.getReference() + " part " + i + ":\n"); sb.append(new ListingBuilder().buildListing(splitter.getProgram(i), " ")); throw new DecompilationException(sb.toString(), e); } node.getBody().add(part); } Program program = method.getProgram(); TypeInferer typeInferer = new TypeInferer(); typeInferer.inferTypes(program, method.getReference()); for (int i = 0; i < program.variableCount(); ++i) { VariableNode variable = new VariableNode(program.variableAt(i).getRegister(), typeInferer.typeOf(i)); variable.setName(program.variableAt(i).getDebugName()); node.getVariables().add(variable); } Optimizer optimizer = new Optimizer(); optimizer.optimize(node, splitter, friendlyToDebugger); node.getModifiers().addAll(method.getModifiers()); return node; }
AstDependencyAnalyzer analyzer = new AstDependencyAnalyzer(); AsyncMethodNode node = asyncCache.get(method).node; for (AsyncMethodPart part : node.getBody()) { part.getStatement().acceptVisitor(analyzer);