001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005: package com.tc.object.bytecode;
006:
007: import com.tc.asm.ClassVisitor;
008: import com.tc.asm.Label;
009: import com.tc.asm.MethodAdapter;
010: import com.tc.asm.MethodVisitor;
011: import com.tc.asm.Opcodes;
012: import com.tc.asm.Type;
013: import com.tc.object.SerializationUtil;
014: import com.tc.util.runtime.Vm;
015:
016: public class LinkedListAdapter {
017:
018: private static final String RENAMED_REMOVE = ByteCodeUtil.TC_METHOD_PREFIX
019: + "remove";
020: private static final String RENAMED_SIG = "(Ljava/util/LinkedList$Entry;Z)";
021:
022: public static class RemoveMethodCreator implements MethodCreator,
023: Opcodes {
024:
025: public void createMethods(ClassVisitor cv) {
026: boolean hasReturnValue = Vm.isJDK15Compliant();
027: String retType = hasReturnValue ? "Ljava/lang/Object;"
028: : "V";
029:
030: MethodVisitor mv = cv.visitMethod(ACC_PRIVATE
031: | ACC_SYNTHETIC, RENAMED_REMOVE, RENAMED_SIG
032: + retType, null, null);
033:
034: mv.visitCode();
035: if (!hasReturnValue) {
036: mv.visitVarInsn(ALOAD, 1);
037: mv.visitFieldInsn(GETFIELD,
038: "java/util/LinkedList$Entry", "element",
039: "Ljava/lang/Object;");
040: mv.visitVarInsn(ASTORE, 4);
041: }
042: mv.visitVarInsn(ALOAD, 0);
043: mv.visitVarInsn(ALOAD, 1);
044: mv.visitMethodInsn(INVOKESPECIAL, "java/util/LinkedList",
045: "remove", "(Ljava/util/LinkedList$Entry;)"
046: + retType);
047: if (hasReturnValue) {
048: mv.visitVarInsn(ASTORE, 3);
049: }
050: mv.visitVarInsn(ILOAD, 2);
051: Label notShared = new Label();
052: mv.visitJumpInsn(IFEQ, notShared);
053: mv.visitVarInsn(ALOAD, 0);
054: mv.visitLdcInsn(SerializationUtil.REMOVE_SIGNATURE);
055: mv.visitInsn(ICONST_1);
056: mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
057: mv.visitInsn(DUP);
058: mv.visitInsn(ICONST_0);
059: mv.visitVarInsn(ALOAD, hasReturnValue ? 3 : 4);
060: mv.visitInsn(AASTORE);
061: mv
062: .visitMethodInsn(INVOKESTATIC,
063: "com/tc/object/bytecode/ManagerUtil",
064: "logicalInvoke",
065: "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V");
066: mv.visitLabel(notShared);
067: if (hasReturnValue) {
068: mv.visitVarInsn(ALOAD, 3);
069: mv.visitInsn(ARETURN);
070: } else {
071: mv.visitInsn(RETURN);
072: }
073: mv.visitMaxs(0, 0);
074: mv.visitEnd();
075: }
076:
077: }
078:
079: public static class RemoveAdapter extends AbstractMethodAdapter {
080:
081: public MethodVisitor adapt(ClassVisitor classVisitor) {
082: MethodVisitor mv = visitOriginal(classVisitor);
083: return new Adapter(mv);
084: }
085:
086: public boolean doesOriginalNeedAdapting() {
087: return false;
088: }
089:
090: private static class Adapter extends MethodAdapter implements
091: Opcodes {
092:
093: public Adapter(MethodVisitor mv) {
094: super (mv);
095: }
096:
097: public void visitCode() {
098: super .visitCode();
099:
100: ByteCodeUtil.pushThis(this );
101: super .visitMethodInsn(INVOKESTATIC,
102: "com/tc/object/bytecode/ManagerUtil",
103: "isManaged", "(Ljava/lang/Object;)Z");
104: super .visitVarInsn(ISTORE, 4);
105:
106: super .visitVarInsn(ILOAD, 4);
107: Label notShared = new Label();
108: super .visitJumpInsn(IFEQ, notShared);
109: ByteCodeUtil.pushThis(this );
110: super .visitMethodInsn(INVOKESTATIC,
111: "com/tc/object/bytecode/ManagerUtil",
112: "checkWriteAccess", "(Ljava/lang/Object;)V");
113: super .visitLabel(notShared);
114: }
115:
116: public void visitMethodInsn(int opcode, String owner,
117: String name, String desc) {
118: if (opcode == INVOKESPECIAL
119: && "remove".equals(name)
120: && "java/util/LinkedList".equals(owner)
121: && desc
122: .startsWith("(Ljava/util/LinkedList$Entry;)")) {
123:
124: name = RENAMED_REMOVE;
125: desc = "(Ljava/util/LinkedList$Entry;Z)"
126: + Type.getReturnType(desc);
127: super .visitVarInsn(ILOAD, 4);
128: }
129:
130: super .visitMethodInsn(opcode, owner, name, desc);
131: }
132: }
133:
134: }
135:
136: public static class ListIteratorAdapter extends
137: AbstractMethodAdapter {
138:
139: public MethodVisitor adapt(ClassVisitor classVisitor) {
140: MethodVisitor mv = visitOriginal(classVisitor);
141: return new Adapter(mv);
142: }
143:
144: public boolean doesOriginalNeedAdapting() {
145: return false;
146: }
147:
148: private static class Adapter extends MethodAdapter implements
149: Opcodes {
150:
151: public Adapter(MethodVisitor mv) {
152: super (mv);
153: mv
154: .visitTypeInsn(NEW,
155: "com/tc/util/ListIteratorWrapper");
156: mv.visitInsn(DUP);
157: mv.visitVarInsn(ALOAD, 0);
158: }
159:
160: public void visitInsn(int opcode) {
161: if (ARETURN == opcode) {
162: mv
163: .visitMethodInsn(INVOKESPECIAL,
164: "com/tc/util/ListIteratorWrapper",
165: "<init>",
166: "(Ljava/util/List;Ljava/util/ListIterator;)V");
167: }
168: super.visitInsn(opcode);
169: }
170:
171: }
172: }
173: }
|