You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2011/04/22 03:37:07 UTC
svn commit: r1095856 -
/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
Author: hlship
Date: Fri Apr 22 01:37:07 2011
New Revision: 1095856
URL: http://svn.apache.org/viewvc?rev=1095856&view=rev
Log:
TAP5-853: Optimize field interceptor methods
Now checks to see if a file read or write interceptor method is actually used; if not, it can be removed from the ClassNode, reducing
the size of the generated class.
Modified:
tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
Modified: tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java?rev=1095856&r1=1095855&r2=1095856&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java (original)
+++ tapestry/tapestry5/trunk/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticClassImpl.java Fri Apr 22 01:37:07 2011
@@ -769,7 +769,7 @@ public class PlasticClassImpl extends Lo
addMethod(mn);
- fieldToWriteMethod.put(node.name, setAccessName);
+ fieldToWriteMethod.put(node.name, mn);
}
private void replaceFieldReadAccess(String conduitFieldName)
@@ -794,7 +794,7 @@ public class PlasticClassImpl extends Lo
addMethod(mn);
- fieldToReadMethod.put(node.name, getAccessName);
+ fieldToReadMethod.put(node.name, mn);
}
private void pushFieldConduitOntoStack(String conduitFileName, InstructionBuilder builder)
@@ -815,7 +815,7 @@ public class PlasticClassImpl extends Lo
addMethod(mn);
- fieldToWriteMethod.put(node.name, setAccessName);
+ fieldToWriteMethod.put(node.name, mn);
node.access |= ACC_FINAL;
}
@@ -1374,13 +1374,13 @@ public class PlasticClassImpl extends Lo
* Maps a field name to a replacement method that should be invoked instead of reading the
* field.
*/
- private final Map<String, String> fieldToReadMethod = new HashMap<String, String>();
+ private final Map<String, MethodNode> fieldToReadMethod = PlasticInternalUtils.newMap();
/**
* Maps a field name to a replacement method that should be invoked instead of writing the
* field.
*/
- private final Map<String, String> fieldToWriteMethod = new HashMap<String, String>();
+ private final Map<String, MethodNode> fieldToWriteMethod = PlasticInternalUtils.newMap();
/**
* This normal no-arguments constructor, or null. By the end of the transformation
@@ -1564,10 +1564,10 @@ public class PlasticClassImpl extends Lo
{
lock();
- interceptFieldAccess();
-
createShimIfNeeded();
+ interceptFieldAccess();
+
rewriteAdvisedMethods();
completeConstructor();
@@ -1877,17 +1877,31 @@ public class PlasticClassImpl extends Lo
/**
* Iterates over all non-introduced methods, including the original constructor. For each
- * method, the bytecode is
- * scanned for field reads and writes. When a match is found against an intercepted field, the
- * operation is
- * replaced with a method invocation.
+ * method, the bytecode is scanned for field reads and writes. When a match is found against an intercepted field,
+ * the operation is replaced with a method invocation. This is invoked only after THE {@link PlasticClassHandleShim}
+ * for the class has been created, as the shim may create methods
+ * that contain references to fields that may be subject to field access interception.
*/
private void interceptFieldAccess()
{
+ Set<MethodNode> unusedAccessMethods = PlasticInternalUtils.newSet();
+
+ // Track all the access methods created for the fields.
+
+ unusedAccessMethods.addAll(fieldToReadMethod.values());
+ unusedAccessMethods.addAll(fieldToWriteMethod.values());
+
for (MethodNode node : fieldTransformMethods)
{
- interceptFieldAccess(node);
+ // Intercept field access inside the method, tracking which access methods
+ // are actually used by removing them from accessMethods
+
+ interceptFieldAccess(node, unusedAccessMethods);
}
+
+ // Remove all added methods that aren't actually used.
+
+ classNode.methods.removeAll(unusedAccessMethods);
}
/**
@@ -2065,7 +2079,7 @@ public class PlasticClassImpl extends Lo
}
}
- private void interceptFieldAccess(MethodNode methodNode)
+ private void interceptFieldAccess(MethodNode methodNode, Set<MethodNode> unusedAccessMethods)
{
InsnList insns = methodNode.instructions;
@@ -2088,20 +2102,22 @@ public class PlasticClassImpl extends Lo
if (!fnode.owner.equals(classNode.name))
continue;
- Map<String, String> fieldToMethod = opcode == GETFIELD ? fieldToReadMethod : fieldToWriteMethod;
+ Map<String, MethodNode> fieldToMethod = opcode == GETFIELD ? fieldToReadMethod : fieldToWriteMethod;
- String methodName = fieldToMethod.get(fnode.name);
+ MethodNode mn = fieldToMethod.get(fnode.name);
- if (methodName == null)
+ if (mn == null)
continue;
String methodDescription = opcode == GETFIELD ? "()" + fnode.desc : "(" + fnode.desc + ")V";
// Replace the field access node with the appropriate method invocation.
- insns.insertBefore(fnode, new MethodInsnNode(INVOKEVIRTUAL, fnode.owner, methodName, methodDescription));
+ insns.insertBefore(fnode, new MethodInsnNode(INVOKEVIRTUAL, fnode.owner, mn.name, methodDescription));
it.remove();
+
+ unusedAccessMethods.remove(mn);
}
}
@@ -2255,7 +2271,6 @@ public class PlasticClassImpl extends Lo
return this;
}
-
public boolean isMethodImplemented(MethodDescription description)
{
return methodBundle.isImplemented(description.methodName, nameCache.toDesc(description));