001: /**
002: * Copyright (C) 2001-2005 France Telecom R&D
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */package org.objectweb.speedo.generation.enhancer.pc;
018:
019: import org.objectweb.asm.ClassVisitor;
020: import org.objectweb.asm.CodeVisitor;
021: import org.objectweb.asm.Type;
022: import org.objectweb.perseus.cache.api.CacheEntry;
023: import org.objectweb.perseus.cache.api.FixableCacheEntry;
024: import org.objectweb.perseus.cache.replacement.api.ReplaceableCacheEntry;
025: import org.objectweb.speedo.generation.enhancer.common.LoggedClassAdapter;
026: import org.objectweb.speedo.lib.Personality;
027: import org.objectweb.util.monolog.api.BasicLevel;
028: import org.objectweb.util.monolog.api.Logger;
029:
030: /**
031: * Is an ASM visitor adding the implementation of the ReplaceableCacheEntry
032: * interface.
033: *
034: * @author S.Chassande-Barrioz
035: */
036: public class CacheEntryAdder extends LoggedClassAdapter {
037:
038: public final static String FIX_FIELD_NAME = "speedoFixCount";
039:
040: public final static String AGE_FIELD_NAME = "speedoAge";
041:
042: private String classToWrite;
043:
044: public CacheEntryAdder(ClassVisitor classVisitor, Logger logger,
045: String className, Personality p) {
046: super (classVisitor, p, logger);
047: this .classToWrite = getJVMClassName(className);
048: }
049:
050: public void visit(final int version, final int access,
051: final String name, final String super Name,
052: final String[] interfaces, final String sourceFile) {
053: String[] itfs;
054: if (interfaces != null && interfaces.length > 0) {
055: itfs = new String[interfaces.length + 3];
056: System.arraycopy(interfaces, 0, itfs, 3, interfaces.length);
057: } else {
058: itfs = new String[3];
059: }
060: itfs[0] = Type.getInternalName(ReplaceableCacheEntry.class);
061: itfs[1] = Type.getInternalName(FixableCacheEntry.class);
062: itfs[2] = Type.getInternalName(CacheEntry.class);
063: cv.visit(version, access, name, super Name, itfs, sourceFile);
064: generateField();
065: generateGetCeObjectMethod();
066: generateGetCeIdentifierMethod();
067: generateFixCeMethod();
068: generateUnfixCeMethod();
069: generateGetCeFixCountMethod();
070: generateGetCeAgeMethod();
071: generateSetCeAgeMethod();
072: }
073:
074: /**
075: * Generates the field #FIX_FIELD_NAME and #AGE_FIELD_NAME
076: */
077: private void generateField() {
078: if (debug) {
079: logger.log(BasicLevel.DEBUG, "Generate the field: int "
080: + FIX_FIELD_NAME);
081: }
082: cv.visitField(ACC_TRANSIENT + ACC_PROTECTED, FIX_FIELD_NAME,
083: Type.INT_TYPE.getDescriptor(), null, null);
084:
085: if (debug) {
086: logger.log(BasicLevel.DEBUG, "Generate the field: long "
087: + AGE_FIELD_NAME);
088: }
089: cv.visitField(ACC_TRANSIENT + ACC_PROTECTED, AGE_FIELD_NAME,
090: Type.LONG_TYPE.getDescriptor(), null, null);
091: }
092:
093: /**
094: * Generates the method getCeObject():Object
095: *
096: * @param classToWrite
097: * is the class name
098: */
099: private void generateGetCeObjectMethod() {
100: if (debug) {
101: logger.log(BasicLevel.DEBUG,
102: "Generate the method: getCeObject");
103: }
104: CodeVisitor mv = cv.visitMethod(ACC_PUBLIC, "getCeObject",
105: "()Ljava/lang/Object;", null, null);
106: // return this;
107: mv.visitVarInsn(ALOAD, 0);
108: mv.visitInsn(ARETURN);
109: mv.visitMaxs(0, 0);
110: }
111:
112: /**
113: * Generates the method getCeIdentifier():Object
114: *
115: * @param classToWrite
116: * is the class name
117: */
118: private void generateGetCeIdentifierMethod() {
119: if (debug) {
120: logger.log(BasicLevel.DEBUG,
121: "Generate the method: getCeIdentifier");
122: }
123: CodeVisitor mv = cv.visitMethod(ACC_PUBLIC, "getCeIdentifier",
124: "()Ljava/lang/Object;", null, null);
125: // return getPName();
126: mv.visitVarInsn(ALOAD, 0);
127: mv.visitMethodInsn(INVOKEVIRTUAL, classToWrite, "getPName",
128: "()Lorg/objectweb/jorm/naming/api/PName;");
129: mv.visitInsn(ARETURN);
130: mv.visitMaxs(0, 0);
131: }
132:
133: /**
134: * Generates the method fixCe():void
135: *
136: * @param classToWrite
137: * is the class name
138: */
139: private void generateFixCeMethod() {
140: if (debug) {
141: logger.log(BasicLevel.DEBUG, "Generate the method: fixCe");
142: }
143: CodeVisitor mv = cv.visitMethod(ACC_PUBLIC, "fixCe", "()V",
144: null, null);
145: // speedoFixCount++;
146: mv.visitVarInsn(ALOAD, 0);
147: mv.visitInsn(DUP);
148: mv.visitFieldInsn(GETFIELD, classToWrite, FIX_FIELD_NAME, "I");
149: mv.visitInsn(ICONST_1);
150: mv.visitInsn(IADD);
151: mv.visitFieldInsn(PUTFIELD, classToWrite, FIX_FIELD_NAME, "I");
152:
153: mv.visitInsn(RETURN);
154: mv.visitMaxs(0, 0);
155: }
156:
157: /**
158: * Generates the method unfixCe():void
159: *
160: * @param classToWrite
161: * is the class name
162: */
163: private void generateUnfixCeMethod() {
164: if (debug) {
165: logger
166: .log(BasicLevel.DEBUG,
167: "Generate the method: unfixCe");
168: }
169: CodeVisitor mv = cv.visitMethod(ACC_PUBLIC, "unfixCe", "()V",
170: null, null);
171: // speedoFixCount--;
172: mv.visitVarInsn(ALOAD, 0);
173: mv.visitInsn(DUP);
174: mv.visitFieldInsn(GETFIELD, classToWrite, FIX_FIELD_NAME, "I");
175: mv.visitInsn(ICONST_1);
176: mv.visitInsn(ISUB);
177: mv.visitFieldInsn(PUTFIELD, classToWrite, FIX_FIELD_NAME, "I");
178:
179: mv.visitInsn(RETURN);
180: mv.visitMaxs(0, 0);
181: }
182:
183: /**
184: * Generates the method getCeFixCount():int
185: *
186: * @param classToWrite
187: * is the class name
188: */
189: private void generateGetCeFixCountMethod() {
190: if (debug) {
191: logger.log(BasicLevel.DEBUG,
192: "Generate the method: getCeFixCount");
193: }
194: CodeVisitor mv = cv.visitMethod(ACC_PUBLIC, "getCeFixCount",
195: "()I", null, null);
196: // return speedoFixCount;
197: mv.visitVarInsn(ALOAD, 0);
198: mv.visitFieldInsn(GETFIELD, classToWrite, FIX_FIELD_NAME, "I");
199: mv.visitInsn(IRETURN);
200: mv.visitMaxs(0, 0);
201: }
202:
203: /**
204: * Generates the method getCeAge():long
205: *
206: * @param classToWrite
207: * is the class name
208: */
209: private void generateGetCeAgeMethod() {
210: if (debug) {
211: logger.log(BasicLevel.DEBUG,
212: "Generate the method: getCeAge");
213: }
214: CodeVisitor mv = cv.visitMethod(ACC_PUBLIC, "getCeAge", "()J",
215: null, null);
216: // return speedoAge;
217: mv.visitVarInsn(ALOAD, 0);
218: mv.visitFieldInsn(GETFIELD, classToWrite, AGE_FIELD_NAME, "J");
219: mv.visitInsn(LRETURN);
220: mv.visitMaxs(0, 0);
221: }
222:
223: /**
224: * Generates the method setCeAge(long):void
225: *
226: * @param classToWrite
227: * is the class name
228: */
229: private void generateSetCeAgeMethod() {
230: if (debug) {
231: logger.log(BasicLevel.DEBUG,
232: "Generate the method: setCeAge");
233: }
234: CodeVisitor mv = cv.visitMethod(ACC_PUBLIC, "setCeAge", "(J)V",
235: null, null);
236: // this.speedoAge = a;
237: mv.visitVarInsn(ALOAD, 0);
238: mv.visitVarInsn(LLOAD, 1);
239: mv.visitFieldInsn(PUTFIELD, classToWrite, AGE_FIELD_NAME, "J");
240: mv.visitInsn(RETURN);
241: mv.visitMaxs(0, 0);
242: }
243: }
|