You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2012/09/28 18:30:22 UTC
svn commit: r1391523 - in /commons/sandbox/nabla/trunk: ./
src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/
Author: luc
Date: Fri Sep 28 16:30:21 2012
New Revision: 1391523
URL: http://svn.apache.org/viewvc?rev=1391523&view=rev
Log:
Updated to asm 4.0.
Modified:
commons/sandbox/nabla/trunk/pom.xml
commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/ForwardModeClassDifferentiator.java
commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/MethodDifferentiator.java
commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/TrackingInterpreter.java
commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/TrackingValue.java
Modified: commons/sandbox/nabla/trunk/pom.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/pom.xml?rev=1391523&r1=1391522&r2=1391523&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/pom.xml (original)
+++ commons/sandbox/nabla/trunk/pom.xml Fri Sep 28 16:30:21 2012
@@ -80,25 +80,38 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>asm</groupId>
+ <!-- we need the debug version at compile time because the non-debug versions
+ do not contain generics information, so they fail compiling Nabla
+ TrackingInterpreter which extends Interpreter<V extends Value> -->
+ <groupId>org.ow2.asm</groupId>
+ <artifactId>asm-debug-all</artifactId>
+ <version>4.0</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.ow2.asm</groupId>
<artifactId>asm-analysis</artifactId>
- <version>3.3.1</version>
- </dependency>
+ <version>4.0</version>
+ <scope>runtime</scope>
+ </dependency>
<dependency>
- <groupId>asm</groupId>
+ <groupId>org.ow2.asm</groupId>
<artifactId>asm-tree</artifactId>
- <version>3.3.1</version>
- </dependency>
+ <version>4.0</version>
+ <scope>runtime</scope>
+ </dependency>
<dependency>
- <groupId>asm</groupId>
+ <groupId>org.ow2.asm</groupId>
<artifactId>asm-util</artifactId>
- <version>3.3.1</version>
- </dependency>
+ <version>4.0</version>
+ <scope>runtime</scope>
+ </dependency>
<dependency>
- <groupId>asm</groupId>
+ <groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
- <version>3.3.1</version>
- </dependency>
+ <version>4.0</version>
+ <scope>runtime</scope>
+ </dependency>
</dependencies>
<build>
Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/ForwardModeClassDifferentiator.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/ForwardModeClassDifferentiator.java?rev=1391523&r1=1391522&r2=1391523&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/ForwardModeClassDifferentiator.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/ForwardModeClassDifferentiator.java Fri Sep 28 16:30:21 2012
@@ -19,7 +19,6 @@ package org.apache.commons.nabla.algorit
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
-import java.util.List;
import java.util.Set;
import org.apache.commons.nabla.core.DifferentiationException;
@@ -75,7 +74,6 @@ public class ForwardModeClassDifferentia
* @exception DifferentiationException if class cannot be differentiated
* @throws IOException if class cannot be read
*/
- @SuppressWarnings("unchecked")
public ForwardModeClassDifferentiator(Class<? extends UnivariateDifferentiable> primitiveClass,
final Set<String> mathClasses)
throws DifferentiationException, IOException {
@@ -85,15 +83,15 @@ public class ForwardModeClassDifferentia
final String classResourceName = "/" + primitiveClass.getName().replace('.', '/') + ".class";
final InputStream stream = primitiveClass.getResourceAsStream(classResourceName);
final ClassReader reader = new ClassReader(stream);
- primitiveNode = new ClassNode();
+ primitiveNode = new ClassNode(Opcodes.ASM4);
reader.accept(primitiveNode, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
this.mathClasses = mathClasses;
- classNode = new ClassNode();
+ classNode = new ClassNode(Opcodes.ASM4);
// check the UnivariateDifferentiable interface is implemented
final Class<UnivariateDifferentiable> uDerClass = UnivariateDifferentiable.class;
boolean isDifferentiable = false;
- for (String interf : (List<String>) primitiveNode.interfaces) {
+ for (String interf : primitiveNode.interfaces) {
final String interfName = interf.replace('/', '.');
Class<?> interfClass = null;
try {
@@ -138,12 +136,11 @@ public class ForwardModeClassDifferentia
* @param derivativeDesc descriptor of the method in the derivative class
* @exception DifferentiationException if method cannot be differentiated
*/
- @SuppressWarnings("unchecked")
public void differentiateMethod(final String name, final String primitiveDesc,
final String derivativeDesc)
throws DifferentiationException {
- for (final MethodNode method : (List<MethodNode>) primitiveNode.methods) {
+ for (final MethodNode method : primitiveNode.methods) {
if (method.name.equals(name) && method.desc.equals(primitiveDesc)) {
final MethodDifferentiator differentiator =
@@ -165,7 +162,6 @@ public class ForwardModeClassDifferentia
/** Add the primitive field.
*/
- @SuppressWarnings("unchecked")
private void addPrimitiveField() {
FieldNode primitiveField =
new FieldNode(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL | Opcodes.ACC_SYNTHETIC,
@@ -175,7 +171,6 @@ public class ForwardModeClassDifferentia
/** Add the class constructor.
*/
- @SuppressWarnings("unchecked")
private void addConstructor() {
final String init = "<init>";
final MethodNode constructor =
@@ -193,7 +188,6 @@ public class ForwardModeClassDifferentia
/** Add the {@link UnivariateDerivative#getPrimitive() getPrimitive()} method.
*/
- @SuppressWarnings("unchecked")
private void addGetPrimitiveMethod() {
final MethodNode method =
new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, "getPrimitive",
@@ -207,7 +201,6 @@ public class ForwardModeClassDifferentia
/** Add the getPrimitiveField method.
*/
- @SuppressWarnings("unchecked")
private void addGetPrimitiveFieldMethod() {
final MethodNode method =
new MethodNode(Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC, "getPrimitiveField",
Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/MethodDifferentiator.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/MethodDifferentiator.java?rev=1391523&r1=1391522&r2=1391523&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/MethodDifferentiator.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/MethodDifferentiator.java Fri Sep 28 16:30:21 2012
@@ -104,7 +104,6 @@ import org.objectweb.asm.tree.TypeInsnNo
import org.objectweb.asm.tree.VarInsnNode;
import org.objectweb.asm.tree.analysis.Analyzer;
import org.objectweb.asm.tree.analysis.AnalyzerException;
-import org.objectweb.asm.tree.analysis.BasicValue;
import org.objectweb.asm.tree.analysis.Frame;
import org.objectweb.asm.tree.analysis.Interpreter;
@@ -167,7 +166,7 @@ public class MethodDifferentiator {
private final Set<TrackingValue> converted;
/** Frames for the original method. */
- private final Map<AbstractInsnNode, Frame> frames;
+ private final Map<AbstractInsnNode, Frame<TrackingValue>> frames;
/** Instructions successors array. */
private final Map<AbstractInsnNode, Set<AbstractInsnNode>> successors;
@@ -184,7 +183,7 @@ public class MethodDifferentiator {
this.mathClasses = mathClasses;
this.name = name;
this.converted = new HashSet<TrackingValue>();
- this.frames = new IdentityHashMap<AbstractInsnNode, Frame>();
+ this.frames = new IdentityHashMap<AbstractInsnNode, Frame<TrackingValue>>();
this.successors = new IdentityHashMap<AbstractInsnNode, Set<AbstractInsnNode>>();
this.clonedLabels = new HashMap<LabelNode, LabelNode>();
}
@@ -211,7 +210,7 @@ public class MethodDifferentiator {
// analyze the original code, tracing values production/consumption
final FlowAnalyzer analyzer =
new FlowAnalyzer(new TrackingInterpreter(), method.instructions);
- final Frame[] array = analyzer.analyze(primitiveName, method);
+ final Frame<TrackingValue>[] array = analyzer.analyze(primitiveName, method);
// convert the array into a map, since code changes will shift all indices
for (int i = 0; i < array.length; ++i) {
@@ -225,8 +224,8 @@ public class MethodDifferentiator {
// the method does not depend on the parameter at all!
// we replace all "return d;" by "return DifferentialPair.newConstant(d);"
- for (final Iterator<?> i = method.instructions.iterator(); i.hasNext();) {
- final AbstractInsnNode insn = (AbstractInsnNode) i.next();
+ for (final Iterator<AbstractInsnNode> i = method.instructions.iterator(); i.hasNext();) {
+ final AbstractInsnNode insn = i.next();
if (insn.getOpcode() == Opcodes.DRETURN) {
final InsnList list = new InsnList();
list.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
@@ -286,8 +285,8 @@ public class MethodDifferentiator {
*/
private void addSpareLocalVariables(final InsnList instructions)
throws DifferentiationException {
- for (final Iterator<?> i = instructions.iterator(); i.hasNext();) {
- final AbstractInsnNode insn = (AbstractInsnNode) i.next();
+ for (final Iterator<AbstractInsnNode> i = instructions.iterator(); i.hasNext();) {
+ final AbstractInsnNode insn = i.next();
if (insn.getType() == AbstractInsnNode.VAR_INSN) {
final VarInsnNode varInsn = (VarInsnNode) insn;
if (varInsn.var > 2) {
@@ -316,8 +315,8 @@ public class MethodDifferentiator {
* @see #addSpareLocalVariables()
*/
private void removeUnusedSpareLocalVariables(final InsnList instructions) {
- for (final Iterator<?> i = instructions.iterator(); i.hasNext();) {
- final AbstractInsnNode insn = (AbstractInsnNode) i.next();
+ for (final Iterator<AbstractInsnNode> i = instructions.iterator(); i.hasNext();) {
+ final AbstractInsnNode insn = i.next();
if (insn.getType() == AbstractInsnNode.VAR_INSN) {
shiftVariable((VarInsnNode) insn);
}
@@ -346,7 +345,7 @@ public class MethodDifferentiator {
// start by converting the parameter of the method,
// which is kept in local variable 1 of the initial frame
- final TrackingValue dpParameter = (TrackingValue) frames.get(instructions.get(0)).getLocal(1);
+ final TrackingValue dpParameter = frames.get(instructions.get(0)).getLocal(1);
pending.add(dpParameter);
// propagate the values conversions throughout the method
@@ -384,10 +383,9 @@ public class MethodDifferentiator {
// the various GETFIELD/PUTFIELD instructions must also be changed
// to retrieve the field from the outer class
- @SuppressWarnings("unchecked")
- ListIterator<AbstractInsnNode> iterator = (ListIterator<AbstractInsnNode>) instructions.iterator();
+ ListIterator<AbstractInsnNode> iterator = instructions.iterator();
while (iterator.hasNext()) {
- AbstractInsnNode ins = (AbstractInsnNode) iterator.next();
+ AbstractInsnNode ins = iterator.next();
if ((ins.getOpcode() == Opcodes.GETFIELD) || (ins.getOpcode() == Opcodes.PUTFIELD)) {
changes.add(ins);
}
@@ -406,7 +404,7 @@ public class MethodDifferentiator {
final List<TrackingValue> values = new ArrayList<TrackingValue>();
// get the frame before instruction execution
- final Frame before = frames.get(instruction);
+ final Frame<TrackingValue> before = frames.get(instruction);
final int beforeStackSize = before.getStackSize();
final int locals = before.getLocals();
@@ -417,13 +415,13 @@ public class MethodDifferentiator {
// loop over the successors of this instruction
for (final AbstractInsnNode successor : set) {
- final Frame produced = frames.get(successor);
+ final Frame<TrackingValue> produced = frames.get(successor);
// check the stack cells
for (int i = 0; i < produced.getStackSize(); ++i) {
- final TrackingValue value = (TrackingValue) produced.getStack(i);
+ final TrackingValue value = produced.getStack(i);
if (((i >= beforeStackSize) || (value != before.getStack(i))) &&
- value.getValue().equals(BasicValue.DOUBLE_VALUE) &&
+ value.getType().equals(Type.DOUBLE_TYPE) &&
!converted.contains(value)) {
values.add(value);
}
@@ -433,7 +431,7 @@ public class MethodDifferentiator {
for (int i = 0; i < locals; ++i) {
final TrackingValue value = (TrackingValue) produced.getLocal(i);
if ((value != before.getLocal(i)) &&
- value.getValue().equals(BasicValue.DOUBLE_VALUE) &&
+ value.getType().equals(Type.DOUBLE_TYPE) &&
!converted.contains(value)) {
values.add(value);
}
@@ -484,7 +482,7 @@ public class MethodDifferentiator {
throws DifferentiationException {
// get the frame at the start of the instruction
- final Frame frame = frames.get(insn);
+ final Frame<TrackingValue> frame = frames.get(insn);
final int size = frame.getStackSize();
final boolean stack1Converted = (size > 0) && converted.contains(frame.getStack(size - 2));
final boolean stack0Converted = (size > 1) && converted.contains(frame.getStack(size - 1));
@@ -602,6 +600,9 @@ public class MethodDifferentiator {
case Opcodes.INVOKEINTERFACE :
// TODO add support for INVOKEINTERFACE differentiation
throw new RuntimeException("INVOKEINTERFACE not handled yet");
+ case Opcodes.INVOKEDYNAMIC :
+ // TODO add support for INVOKEDYNAMIC differentiation
+ throw new RuntimeException("INVOKEDYNAMIC not handled yet");
case Opcodes.NEWARRAY :
// TODO add support for NEWARRAY differentiation
throw new RuntimeException("NEWARRAY not handled yet");
@@ -679,7 +680,8 @@ public class MethodDifferentiator {
}
list.add(new TypeInsnNode(Opcodes.CHECKCAST, boxedType.getInternalName()));
if (valueMethodName != null) {
- list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, boxedType.getInternalName(), valueMethodName,
+ list.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, boxedType.getInternalName(),
+ valueMethodName,
Type.getMethodDescriptor(type, new Type[0])));
}
@@ -830,7 +832,7 @@ public class MethodDifferentiator {
}
/** Analyzer preserving instructions successors information. */
- private class FlowAnalyzer extends Analyzer {
+ private class FlowAnalyzer extends Analyzer<TrackingValue> {
/** Instructions of the method. */
private final InsnList instructions;
@@ -839,7 +841,7 @@ public class MethodDifferentiator {
* @param interpreter associated interpreter
* @param instructions instructions of the method
*/
- public FlowAnalyzer(final Interpreter interpreter,
+ public FlowAnalyzer(final Interpreter<TrackingValue> interpreter,
final InsnList instructions) {
super(interpreter);
this.instructions = instructions;
Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/TrackingInterpreter.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/TrackingInterpreter.java?rev=1391523&r1=1391522&r2=1391523&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/TrackingInterpreter.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/TrackingInterpreter.java Fri Sep 28 16:30:21 2012
@@ -19,130 +19,345 @@ package org.apache.commons.nabla.algorit
import java.util.Iterator;
import java.util.List;
+import org.objectweb.asm.Handle;
+import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.FieldInsnNode;
+import org.objectweb.asm.tree.IntInsnNode;
+import org.objectweb.asm.tree.InvokeDynamicInsnNode;
+import org.objectweb.asm.tree.LdcInsnNode;
+import org.objectweb.asm.tree.MethodInsnNode;
+import org.objectweb.asm.tree.MultiANewArrayInsnNode;
+import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.analysis.AnalyzerException;
-import org.objectweb.asm.tree.analysis.BasicInterpreter;
-import org.objectweb.asm.tree.analysis.BasicValue;
-import org.objectweb.asm.tree.analysis.Value;
+import org.objectweb.asm.tree.analysis.Interpreter;
/** An interpreter tracking which instructions use which values.
- * <p>This interpreter wraps {@link org.objectweb.asm.tree.analysis.BasicValue
- * BasicValue} instances into {@link TrackingValue TrackingValue} instances.</p>
+ * <p>
+ * The implementation of this class is largely copied from the original BasicInterpreter from asm,
+ * which is distributed under the following terms:
+ * </p>
+ * <p>
+ * ASM: a very small and fast Java bytecode manipulation framework
+ * Copyright (c) 2000-2011 INRIA, France Telecom
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ * </p>
+ * @see TrackingValue
*/
-public class TrackingInterpreter extends BasicInterpreter {
+public class TrackingInterpreter extends Interpreter<TrackingValue> {
/** Build an interpreter.
*/
public TrackingInterpreter() {
+ super(Opcodes.ASM4);
}
/** {@inheritDoc} */
@Override
- public Value newValue(final Type type) {
- return (type == null) ? TrackingValue.UNINITIALIZED_VALUE : wrap(super.newValue(type), null);
+ public TrackingValue newValue(final Type type) {
+ return (type == null) ? TrackingValue.UNINITIALIZED_VALUE : new TrackingValue(type);
}
- /** {@inheritDoc} */
+ /** {@inheritDoc}
+ * <p>
+ * The implementation for this meth
+ */
@Override
- public Value newOperation(final AbstractInsnNode insn) throws AnalyzerException {
- return wrap(super.newOperation(insn), insn);
+ public TrackingValue newOperation(final AbstractInsnNode insn) throws AnalyzerException {
+ switch (insn.getOpcode()) {
+ case Opcodes.ACONST_NULL:
+ return new TrackingValue(Type.getObjectType("null"), insn);
+ case Opcodes.ICONST_M1:
+ case Opcodes.ICONST_0:
+ case Opcodes.ICONST_1:
+ case Opcodes.ICONST_2:
+ case Opcodes.ICONST_3:
+ case Opcodes.ICONST_4:
+ case Opcodes.ICONST_5:
+ return new TrackingValue(Type.INT_TYPE, insn);
+ case Opcodes.LCONST_0:
+ case Opcodes.LCONST_1:
+ return new TrackingValue(Type.LONG_TYPE, insn);
+ case Opcodes.FCONST_0:
+ case Opcodes.FCONST_1:
+ case Opcodes.FCONST_2:
+ return new TrackingValue(Type.FLOAT_TYPE, insn);
+ case Opcodes.DCONST_0:
+ case Opcodes.DCONST_1:
+ return new TrackingValue(Type.DOUBLE_TYPE, insn);
+ case Opcodes.BIPUSH:
+ case Opcodes.SIPUSH:
+ return new TrackingValue(Type.INT_TYPE, insn);
+ case Opcodes.LDC:
+ Object cst = ((LdcInsnNode) insn).cst;
+ if (cst instanceof Integer) {
+ return new TrackingValue(Type.INT_TYPE, insn);
+ } else if (cst instanceof Float) {
+ return new TrackingValue(Type.FLOAT_TYPE, insn);
+ } else if (cst instanceof Long) {
+ return new TrackingValue(Type.LONG_TYPE, insn);
+ } else if (cst instanceof Double) {
+ return new TrackingValue(Type.DOUBLE_TYPE, insn);
+ } else if (cst instanceof String) {
+ return new TrackingValue(Type.getType(String.class), insn);
+ } else if (cst instanceof Type) {
+ int sort = ((Type) cst).getSort();
+ if (sort == Type.OBJECT || sort == Type.ARRAY) {
+ return new TrackingValue(Type.getType(Class.class), insn);
+ } else if (sort == Type.METHOD) {
+ return new TrackingValue(Type.getObjectType("java/lang/invoke/MethodType"), insn);
+ } else {
+ throw new IllegalArgumentException("Illegal LDC constant " + cst);
+ }
+ } else if (cst instanceof Handle) {
+ return new TrackingValue(Type.getObjectType("java/lang/invoke/MethodHandle"), insn);
+ } else {
+ throw new IllegalArgumentException("Illegal LDC constant " + cst);
+ }
+ case Opcodes.JSR:
+ return new TrackingValue(Type.VOID_TYPE, insn); // return address value
+ case Opcodes.GETSTATIC:
+ return new TrackingValue(Type.getType(((FieldInsnNode) insn).desc), insn);
+ case Opcodes.NEW:
+ return new TrackingValue(Type.getObjectType(((TypeInsnNode) insn).desc), insn);
+ default:
+ throw new Error("Internal error.");
+ }
}
/** {@inheritDoc} */
- @Override
- public Value unaryOperation(final AbstractInsnNode insn,
- final Value value)
+ public TrackingValue unaryOperation(final AbstractInsnNode insn, final TrackingValue value)
throws AnalyzerException {
((TrackingValue) value).addConsumer(insn);
- return wrap(super.unaryOperation(insn, value), insn);
+ switch (insn.getOpcode()) {
+ case Opcodes.INEG:
+ case Opcodes.IINC:
+ case Opcodes.L2I:
+ case Opcodes.F2I:
+ case Opcodes.D2I:
+ case Opcodes.I2B:
+ case Opcodes.I2C:
+ case Opcodes.I2S:
+ return new TrackingValue(Type.INT_TYPE, insn);
+ case Opcodes.FNEG:
+ case Opcodes.I2F:
+ case Opcodes.L2F:
+ case Opcodes.D2F:
+ return new TrackingValue(Type.FLOAT_TYPE, insn);
+ case Opcodes.LNEG:
+ case Opcodes.I2L:
+ case Opcodes.F2L:
+ case Opcodes.D2L:
+ return new TrackingValue(Type.LONG_TYPE, insn);
+ case Opcodes.DNEG:
+ case Opcodes.I2D:
+ case Opcodes.L2D:
+ case Opcodes.F2D:
+ return new TrackingValue(Type.DOUBLE_TYPE, insn);
+ case Opcodes.IFEQ:
+ case Opcodes.IFNE:
+ case Opcodes.IFLT:
+ case Opcodes.IFGE:
+ case Opcodes.IFGT:
+ case Opcodes.IFLE:
+ case Opcodes.TABLESWITCH:
+ case Opcodes.LOOKUPSWITCH:
+ case Opcodes.IRETURN:
+ case Opcodes.LRETURN:
+ case Opcodes.FRETURN:
+ case Opcodes.DRETURN:
+ case Opcodes.ARETURN:
+ case Opcodes.PUTSTATIC:
+ return null;
+ case Opcodes.GETFIELD:
+ return new TrackingValue(Type.getType(((FieldInsnNode) insn).desc), insn);
+ case Opcodes.NEWARRAY:
+ switch (((IntInsnNode) insn).operand) {
+ case Opcodes.T_BOOLEAN:
+ return new TrackingValue(Type.getType("[Z"), insn);
+ case Opcodes.T_CHAR:
+ return new TrackingValue(Type.getType("[C"), insn);
+ case Opcodes.T_BYTE:
+ return new TrackingValue(Type.getType("[B"), insn);
+ case Opcodes.T_SHORT:
+ return new TrackingValue(Type.getType("[S"), insn);
+ case Opcodes.T_INT:
+ return new TrackingValue(Type.getType("[I"), insn);
+ case Opcodes.T_FLOAT:
+ return new TrackingValue(Type.getType("[F"), insn);
+ case Opcodes.T_DOUBLE:
+ return new TrackingValue(Type.getType("[D"), insn);
+ case Opcodes.T_LONG:
+ return new TrackingValue(Type.getType("[J"), insn);
+ default:
+ throw new AnalyzerException(insn, "Invalid array type");
+ }
+ case Opcodes.ANEWARRAY:
+ String desc = ((TypeInsnNode) insn).desc;
+ return new TrackingValue(Type.getType("[" + Type.getObjectType(desc)), insn);
+ case Opcodes.ARRAYLENGTH:
+ return new TrackingValue(Type.INT_TYPE, insn);
+ case Opcodes.ATHROW:
+ return null;
+ case Opcodes.CHECKCAST:
+ desc = ((TypeInsnNode) insn).desc;
+ return new TrackingValue(Type.getObjectType(desc), insn);
+ case Opcodes.INSTANCEOF:
+ return new TrackingValue(Type.INT_TYPE, insn);
+ case Opcodes.MONITORENTER:
+ case Opcodes.MONITOREXIT:
+ case Opcodes.IFNULL:
+ case Opcodes.IFNONNULL:
+ return null;
+ default:
+ throw new Error("Internal error.");
+ }
}
/** {@inheritDoc} */
- @Override
- public Value binaryOperation(final AbstractInsnNode insn,
- final Value value1, final Value value2)
+ public TrackingValue binaryOperation(final AbstractInsnNode insn,
+ final TrackingValue value1, final TrackingValue value2)
throws AnalyzerException {
((TrackingValue) value1).addConsumer(insn);
((TrackingValue) value2).addConsumer(insn);
- return wrap(super.binaryOperation(insn, value1, value2), insn);
+ switch (insn.getOpcode()) {
+ case Opcodes.IALOAD:
+ case Opcodes.BALOAD:
+ case Opcodes.CALOAD:
+ case Opcodes.SALOAD:
+ case Opcodes.IADD:
+ case Opcodes.ISUB:
+ case Opcodes.IMUL:
+ case Opcodes.IDIV:
+ case Opcodes.IREM:
+ case Opcodes.ISHL:
+ case Opcodes.ISHR:
+ case Opcodes.IUSHR:
+ case Opcodes.IAND:
+ case Opcodes.IOR:
+ case Opcodes.IXOR:
+ return new TrackingValue(Type.INT_TYPE, insn);
+ case Opcodes.FALOAD:
+ case Opcodes.FADD:
+ case Opcodes.FSUB:
+ case Opcodes.FMUL:
+ case Opcodes.FDIV:
+ case Opcodes.FREM:
+ return new TrackingValue(Type.FLOAT_TYPE, insn);
+ case Opcodes.LALOAD:
+ case Opcodes.LADD:
+ case Opcodes.LSUB:
+ case Opcodes.LMUL:
+ case Opcodes.LDIV:
+ case Opcodes.LREM:
+ case Opcodes.LSHL:
+ case Opcodes.LSHR:
+ case Opcodes.LUSHR:
+ case Opcodes.LAND:
+ case Opcodes.LOR:
+ case Opcodes.LXOR:
+ return new TrackingValue(Type.LONG_TYPE, insn);
+ case Opcodes.DALOAD:
+ case Opcodes.DADD:
+ case Opcodes.DSUB:
+ case Opcodes.DMUL:
+ case Opcodes.DDIV:
+ case Opcodes.DREM:
+ return new TrackingValue(Type.DOUBLE_TYPE, insn);
+ case Opcodes.AALOAD:
+ return new TrackingValue(Type.getType(Object.class), insn); // reference value
+ case Opcodes.LCMP:
+ case Opcodes.FCMPL:
+ case Opcodes.FCMPG:
+ case Opcodes.DCMPL:
+ case Opcodes.DCMPG:
+ return new TrackingValue(Type.INT_TYPE, insn);
+ case Opcodes.IF_ICMPEQ:
+ case Opcodes.IF_ICMPNE:
+ case Opcodes.IF_ICMPLT:
+ case Opcodes.IF_ICMPGE:
+ case Opcodes.IF_ICMPGT:
+ case Opcodes.IF_ICMPLE:
+ case Opcodes.IF_ACMPEQ:
+ case Opcodes.IF_ACMPNE:
+ case Opcodes.PUTFIELD:
+ return null;
+ default:
+ throw new Error("Internal error.");
+ }
}
/** {@inheritDoc} */
- @Override
- public Value ternaryOperation(final AbstractInsnNode insn,
- final Value value1, final Value value2,
- final Value value3)
+ public TrackingValue ternaryOperation(final AbstractInsnNode insn,
+ final TrackingValue value1, final TrackingValue value2,
+ final TrackingValue value3)
throws AnalyzerException {
- ((TrackingValue) value1).addConsumer(insn);
- ((TrackingValue) value2).addConsumer(insn);
- ((TrackingValue) value3).addConsumer(insn);
- return wrap(super.ternaryOperation(insn, value1, value2, value3), insn);
+ value1.addConsumer(insn);
+ value2.addConsumer(insn);
+ value3.addConsumer(insn);
+ return new TrackingValue(null, insn);
}
/** {@inheritDoc} */
- @SuppressWarnings("rawtypes")
- @Override
- public Value naryOperation(final AbstractInsnNode insn,
- final List values)
+ public TrackingValue naryOperation(final AbstractInsnNode insn, final List<? extends TrackingValue> values)
throws AnalyzerException {
for (final Iterator<?> iterator = values.iterator(); iterator.hasNext();) {
((TrackingValue) iterator.next()).addConsumer(insn);
}
- return wrap(super.naryOperation(insn, values), insn);
+ int opcode = insn.getOpcode();
+ if (opcode == Opcodes.MULTIANEWARRAY) {
+ return new TrackingValue(Type.getType(((MultiANewArrayInsnNode) insn).desc), insn);
+ } else if (opcode == Opcodes.INVOKEDYNAMIC){
+ return new TrackingValue(Type.getReturnType(((InvokeDynamicInsnNode) insn).desc), insn);
+ } else {
+ return new TrackingValue(Type.getReturnType(((MethodInsnNode) insn).desc), insn);
+ }
}
/** {@inheritDoc} */
- @Override
- public Value copyOperation(final AbstractInsnNode insn,
- final Value value)
+ public TrackingValue copyOperation(final AbstractInsnNode insn, final TrackingValue value)
throws AnalyzerException {
// we reuse the same instance instead of wrapping it again
// thus simplifying transitive dependencies propagation
- final TrackingValue tv = (TrackingValue) value;
- tv.addConsumer(insn);
- tv.addProducer(insn);
+ value.addConsumer(insn);
+ value.addProducer(insn);
return value;
}
/** {@inheritDoc} */
- @Override
- public Value merge(final Value v, final Value w) {
-
- final TrackingValue tv = (TrackingValue) v;
- final TrackingValue tw = (TrackingValue) w;
- TrackingValue.merge(tv, tw);
-
- final BasicValue superMerged = (BasicValue) super.merge(tv.getValue(), tw.getValue());
- return (superMerged == tv.getValue()) ? tv : new TrackingValue(superMerged);
-
+ public TrackingValue merge(final TrackingValue v, final TrackingValue w) {
+ TrackingValue.merge(v, w);
+ return v;
}
- /** Wrap a value returned by the superclass.
- * @param value underlying value (may be null)
- * @param producer instruction producing the value (may be null)
- * @return the wrapped value
- */
- private TrackingValue wrap(final Value value,
- final AbstractInsnNode producer) {
-
- if (value == null) {
- return null;
- }
-
- // values produced by the superclass are either BasicValue instances
- // (like BasicValue.DOUBLE_VALUE) or already TrackingValue if the
- // superclass called our local implementation of newValue or newOperation
- final TrackingValue tv = (value instanceof TrackingValue) ?
- (TrackingValue) value :
- new TrackingValue((BasicValue) value);
-
- if (producer != null) {
- tv.addProducer(producer);
- }
-
- return tv;
-
+ /** {@inheritDoc} */
+ public void returnOperation(AbstractInsnNode insn, TrackingValue value, TrackingValue expected) {
+ // nothing to do here, as unaryOperation has already been called
}
}
Modified: commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/TrackingValue.java
URL: http://svn.apache.org/viewvc/commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/TrackingValue.java?rev=1391523&r1=1391522&r2=1391523&view=diff
==============================================================================
--- commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/TrackingValue.java (original)
+++ commons/sandbox/nabla/trunk/src/main/java/org/apache/commons/nabla/algorithmic/forward/analysis/TrackingValue.java Fri Sep 28 16:30:21 2012
@@ -19,8 +19,8 @@ package org.apache.commons.nabla.algorit
import java.util.HashSet;
import java.util.Set;
+import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
-import org.objectweb.asm.tree.analysis.BasicValue;
import org.objectweb.asm.tree.analysis.Value;
/** A value that keep track of both instructions producing and consuming it.
@@ -28,11 +28,10 @@ import org.objectweb.asm.tree.analysis.V
public class TrackingValue implements Value {
/** Special value for uninitialized values. */
- public static final TrackingValue UNINITIALIZED_VALUE =
- new TrackingValue((BasicValue) BasicValue.UNINITIALIZED_VALUE);
+ public static final TrackingValue UNINITIALIZED_VALUE = new TrackingValue(null);
- /** Underlying value. */
- private final BasicValue value;
+ /** Value type. */
+ private final Type type;
/** Instructions that consume this value. */
private Set<AbstractInsnNode> consumers;
@@ -44,26 +43,35 @@ public class TrackingValue implements Va
private Set<TrackingValue> merged;
/** Build a new value without any link to instructions.
- * @param value wrapped {@link BasicValue} value
+ * @param type value type
*/
- public TrackingValue(final BasicValue value) {
- this.value = value;
+ public TrackingValue(final Type type) {
+ this.type = type;
consumers = new HashSet<AbstractInsnNode>();
producers = new HashSet<AbstractInsnNode>();
merged = new HashSet<TrackingValue>();
merged.add(this);
}
- /** Get the wrapped {@link BasicValue}.
- * @return wrapped {@link BasicValue}
+ /** Build a new value produced by a specified instruction.
+ * @param type value type
+ * @param producer producer for this value
+ */
+ public TrackingValue(final Type type, final AbstractInsnNode producer) {
+ this(type);
+ producers.add(producer);
+ }
+
+ /** Get the value type.
+ * @return value type
*/
- public BasicValue getValue() {
- return value;
+ public Type getType() {
+ return type;
}
/** {@inheritDoc} */
public int getSize() {
- return value.getSize();
+ return type == Type.LONG_TYPE || type == Type.DOUBLE_TYPE ? 2 : 1;
}
/** Add a consumer for this value.
@@ -101,8 +109,7 @@ public class TrackingValue implements Va
* @param value1 first value to merge
* @param value2 second value to merge
*/
- public static void merge(final TrackingValue value1,
- final TrackingValue value2) {
+ public static void merge(final TrackingValue value1, final TrackingValue value2) {
if (value1.merged.contains(value2)) {
// the values have already been merged