001: /*
002: * All content copyright (c) 2003-2007 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.object.SerializationUtil;
013:
014: public class ArrayListAdapter {
015:
016: private static final String FAST_REMOVE_RENAMED = ByteCodeUtil.TC_METHOD_PREFIX
017: + "fastRemove";
018: private static final String FAST_REMOVE_RENAMED_SIG = "(IZ)V";
019:
020: public static class FastRemoveMethodCreator implements
021: MethodCreator, Opcodes {
022:
023: public void createMethods(ClassVisitor cv) {
024: MethodVisitor mv = cv.visitMethod(ACC_PRIVATE
025: | ACC_SYNTHETIC, FAST_REMOVE_RENAMED,
026: FAST_REMOVE_RENAMED_SIG, null, null);
027: mv.visitCode();
028: mv.visitInsn(ACONST_NULL);
029: mv.visitVarInsn(ASTORE, 3);
030: mv.visitVarInsn(ILOAD, 2);
031: Label isSharedCheck1 = new Label();
032: mv.visitJumpInsn(IFEQ, isSharedCheck1);
033: mv.visitVarInsn(ALOAD, 0);
034: mv.visitVarInsn(ILOAD, 1);
035: mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/ArrayList",
036: "get", "(I)Ljava/lang/Object;");
037: mv.visitVarInsn(ASTORE, 3);
038: mv.visitLabel(isSharedCheck1);
039: mv.visitVarInsn(ALOAD, 0);
040: mv.visitVarInsn(ILOAD, 1);
041: mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList",
042: "fastRemove", "(I)V");
043: mv.visitVarInsn(ILOAD, 2);
044: Label isSharedCheck2 = new Label();
045: mv.visitJumpInsn(IFEQ, isSharedCheck2);
046: mv.visitVarInsn(ALOAD, 0);
047: mv.visitLdcInsn(SerializationUtil.REMOVE_SIGNATURE);
048: mv.visitInsn(ICONST_1);
049: mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
050: mv.visitInsn(DUP);
051: mv.visitInsn(ICONST_0);
052: mv.visitVarInsn(ALOAD, 3);
053: mv.visitInsn(AASTORE);
054: mv
055: .visitMethodInsn(INVOKESTATIC,
056: "com/tc/object/bytecode/ManagerUtil",
057: "logicalInvoke",
058: "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V");
059: mv.visitLabel(isSharedCheck2);
060: mv.visitInsn(RETURN);
061: mv.visitMaxs(0, 0);
062: mv.visitEnd();
063: }
064: }
065:
066: public static class RemoveAdaptor extends AbstractMethodAdapter {
067:
068: public MethodVisitor adapt(ClassVisitor classVisitor) {
069: MethodVisitor mv = visitOriginal(classVisitor);
070: return new Adapter(mv);
071: }
072:
073: public boolean doesOriginalNeedAdapting() {
074: return false;
075: }
076:
077: private static class Adapter extends MethodAdapter implements
078: Opcodes {
079:
080: public Adapter(MethodVisitor mv) {
081: super (mv);
082: }
083:
084: public void visitCode() {
085: super .visitCode();
086:
087: ByteCodeUtil.pushThis(this );
088: super .visitMethodInsn(INVOKESTATIC,
089: "com/tc/object/bytecode/ManagerUtil",
090: "isManaged", "(Ljava/lang/Object;)Z");
091: super .visitVarInsn(ISTORE, 4);
092:
093: super .visitVarInsn(ILOAD, 4);
094: Label notShared = new Label();
095: super .visitJumpInsn(IFEQ, notShared);
096: ByteCodeUtil.pushThis(this );
097: super .visitMethodInsn(INVOKESTATIC,
098: "com/tc/object/bytecode/ManagerUtil",
099: "checkWriteAccess", "(Ljava/lang/Object;)V");
100: super .visitLabel(notShared);
101: }
102:
103: public void visitMethodInsn(int opcode, String owner,
104: String name, String desc) {
105:
106: if (opcode == INVOKESPECIAL
107: && "fastRemove".equals(name)
108: && "java/util/ArrayList".equals(owner)
109: && "(I)V".equals(desc)) {
110: name = FAST_REMOVE_RENAMED;
111: desc = FAST_REMOVE_RENAMED_SIG;
112: super .visitVarInsn(ILOAD, 4);
113: }
114:
115: super.visitMethodInsn(opcode, owner, name, desc);
116: }
117:
118: }
119:
120: }
121:
122: }
|