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.ClassAdapter;
008: import com.tc.asm.ClassVisitor;
009: import com.tc.asm.Label;
010: import com.tc.asm.MethodVisitor;
011: import com.tc.asm.Opcodes;
012: import com.tc.util.runtime.Vm;
013:
014: public class JavaUtilConcurrentHashMapEntryIteratorAdapter extends
015: ClassAdapter implements Opcodes {
016:
017: public JavaUtilConcurrentHashMapEntryIteratorAdapter(ClassVisitor cv) {
018: super (cv);
019: }
020:
021: public void visit(int version, int access, String name,
022: String signature, String super Name, String[] interfaces) {
023: String[] interfacesNew = new String[interfaces.length + 1];
024: System.arraycopy(interfaces, 0, interfacesNew, 0,
025: interfaces.length);
026: interfacesNew[interfacesNew.length - 1] = TCMapEntry.class
027: .getName().replace('.', '/');
028: super .visit(version, access, name, signature, super Name,
029: interfacesNew);
030: }
031:
032: public MethodVisitor visitMethod(int access, String name,
033: String desc, String signature, String[] exceptions) {
034: MethodVisitor mv = super .visitMethod(access, name, desc,
035: signature, exceptions);
036: if (Vm.isJDK16Compliant() && "next".equals(name)
037: && "()Ljava/util/Map$Entry;".equals(desc)) {
038: return mv;
039: } else {
040: return new JavaUtilConcurrentHashMapLazyValuesMethodAdapter(
041: access, desc, mv, false);
042: }
043: }
044:
045: public void visitEnd() {
046: createTCRawSetValueMethod();
047: createTCIsFaultedInMethod();
048:
049: super .visitEnd();
050: }
051:
052: private void createTCRawSetValueMethod() {
053: MethodVisitor mv = super .visitMethod(ACC_PUBLIC
054: | ACC_SYNCHRONIZED,
055: TCMapEntry.TC_RAWSETVALUE_METHOD_NAME,
056: TCMapEntry.TC_RAWSETVALUE_METHOD_DESC, null, null);
057: mv.visitCode();
058:
059: mv.visitVarInsn(ALOAD, 0);
060: mv.visitFieldInsn(GETFIELD,
061: "java/util/concurrent/ConcurrentHashMap$EntryIterator",
062: "lastReturned",
063: "Ljava/util/concurrent/ConcurrentHashMap$HashEntry;");
064: Label lastReturnedNotNull = new Label();
065: mv.visitJumpInsn(IFNONNULL, lastReturnedNotNull);
066: mv.visitTypeInsn(NEW, "java/lang/IllegalStateException");
067: mv.visitInsn(DUP);
068: mv.visitLdcInsn("Entry was removed");
069: mv.visitMethodInsn(INVOKESPECIAL,
070: "java/lang/IllegalStateException", "<init>",
071: "(Ljava/lang/String;)V");
072: mv.visitInsn(ATHROW);
073: mv.visitLabel(lastReturnedNotNull);
074:
075: mv.visitVarInsn(ALOAD, 0);
076: mv.visitFieldInsn(GETFIELD,
077: "java/util/concurrent/ConcurrentHashMap$EntryIterator",
078: "lastReturned",
079: "Ljava/util/concurrent/ConcurrentHashMap$HashEntry;");
080: mv.visitVarInsn(ALOAD, 1);
081: mv.visitMethodInsn(INVOKEINTERFACE,
082: "com/tc/object/bytecode/TCMapEntry",
083: TCMapEntry.TC_RAWSETVALUE_METHOD_NAME,
084: TCMapEntry.TC_RAWSETVALUE_METHOD_DESC);
085: mv.visitInsn(RETURN);
086: mv.visitMaxs(2, 2);
087: mv.visitEnd();
088: }
089:
090: private void createTCIsFaultedInMethod() {
091: MethodVisitor mv = super .visitMethod(ACC_PUBLIC
092: | ACC_SYNCHRONIZED,
093: TCMapEntry.TC_ISVALUEFAULTEDIN_METHOD_NAME,
094: TCMapEntry.TC_ISVALUEFAULTEDIN_METHOD_DESC, null, null);
095: mv.visitCode();
096:
097: mv.visitVarInsn(ALOAD, 0);
098: mv.visitFieldInsn(GETFIELD,
099: "java/util/concurrent/ConcurrentHashMap$EntryIterator",
100: "lastReturned",
101: "Ljava/util/concurrent/ConcurrentHashMap$HashEntry;");
102: Label lastReturnedNotNull = new Label();
103: mv.visitJumpInsn(IFNONNULL, lastReturnedNotNull);
104: mv.visitTypeInsn(NEW, "java/lang/IllegalStateException");
105: mv.visitInsn(DUP);
106: mv.visitLdcInsn("Entry was removed");
107: mv.visitMethodInsn(INVOKESPECIAL,
108: "java/lang/IllegalStateException", "<init>",
109: "(Ljava/lang/String;)V");
110: mv.visitInsn(ATHROW);
111: mv.visitLabel(lastReturnedNotNull);
112:
113: mv.visitVarInsn(ALOAD, 0);
114: mv.visitFieldInsn(GETFIELD,
115: "java/util/concurrent/ConcurrentHashMap$EntryIterator",
116: "lastReturned",
117: "Ljava/util/concurrent/ConcurrentHashMap$HashEntry;");
118: mv.visitMethodInsn(INVOKEINTERFACE,
119: "com/tc/object/bytecode/TCMapEntry",
120: TCMapEntry.TC_ISVALUEFAULTEDIN_METHOD_NAME,
121: TCMapEntry.TC_ISVALUEFAULTEDIN_METHOD_DESC);
122: mv.visitInsn(IRETURN);
123: mv.visitMaxs(1, 1);
124: mv.visitEnd();
125: }
126: }
|