Source Code Cross Referenced for ClassInfo.java in  » Code-Analyzer » javapathfinder » gov » nasa » jpf » jvm » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Code Analyzer » javapathfinder » gov.nasa.jpf.jvm 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        //
0002:        // Copyright (C) 2005 United States Government as represented by the
0003:        // Administrator of the National Aeronautics and Space Administration
0004:        // (NASA).  All Rights Reserved.
0005:        // 
0006:        // This software is distributed under the NASA Open Source Agreement
0007:        // (NOSA), version 1.3.  The NOSA has been approved by the Open Source
0008:        // Initiative.  See the file NOSA-1.3-JPF at the top of the distribution
0009:        // directory tree for the complete NOSA document.
0010:        // 
0011:        // THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
0012:        // KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
0013:        // LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
0014:        // SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
0015:        // A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
0016:        // THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
0017:        // DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
0018:        //
0019:        package gov.nasa.jpf.jvm;
0020:
0021:        import gov.nasa.jpf.*;
0022:        import gov.nasa.jpf.jvm.bytecode.Instruction;
0023:        import gov.nasa.jpf.util.*;
0024:        import gov.nasa.jpf.util.Debug;
0025:
0026:        import java.io.*;
0027:
0028:        import java.util.*;
0029:
0030:        import org.apache.bcel.classfile.*;
0031:        import org.apache.bcel.util.SyntheticRepository;
0032:        import org.apache.bcel.generic.ConstantPoolGen;
0033:
0034:        /**
0035:         * Describes the JVM's view of a java class.  Contains descriptions of the
0036:         * static and dynamic fields, methods, and information relevant to the
0037:         * class.
0038:         */
0039:        public class ClassInfo {
0040:            /**
0041:             * this is our BCEL class repository. Note that this actually might be
0042:             * turned into a call or ClassInfo instance field if we ever support
0043:             * ClassLoaders (for now we keep it simple)
0044:             */
0045:            protected static SyntheticRepository repository;
0046:
0047:            /**
0048:             * Map of the loaded classes.
0049:             */
0050:            protected static Hashtable loadedClasses;
0051:
0052:            /**
0053:             * optionally used to determine atomic methods of a class (during class loading)
0054:             */
0055:            protected static Attributor attributor;
0056:
0057:            /**
0058:             * here we get infinitly recursive, so keep it around for
0059:             * identity checks
0060:             */
0061:            static ClassInfo classClassInfo;
0062:
0063:            /*
0064:             * some distinguished classInfos we keep around for efficiency reasons 
0065:             */
0066:            static ClassInfo objectClassInfo;
0067:            static ClassInfo stringClassInfo;
0068:            static ClassInfo weakRefClassInfo;
0069:            static ClassInfo refClassInfo;
0070:
0071:            static FieldInfo[] emptyFields = new FieldInfo[0];
0072:
0073:            /**
0074:             * Initializes a class. A class is initialized atomically without being
0075:             * interleaved with any other thread.
0076:             *
0077:             * <2do> pcm - wrong. static init of a class is only synced on the class
0078:             * object itself
0079:             */
0080:            static int level;
0081:
0082:            /**
0083:             * Name of the class.
0084:             */
0085:            protected final String name;
0086:
0087:            // various class attributes
0088:            protected boolean isClass = true;
0089:            protected boolean isWeakReference = false;
0090:            protected MethodInfo finalizer = null;
0091:            protected boolean isArray = false;
0092:            protected boolean isReferenceArray = false;
0093:
0094:            /** type based object attributes (for GC, partial order reduction and
0095:             * property checks)
0096:             */
0097:            protected int elementInfoAttrs = 0;
0098:
0099:            /**
0100:             * all our declared methods (we don't flatten, this is not
0101:             * a high-performance VM)
0102:             */
0103:            protected final Map methods;
0104:
0105:            /**
0106:             * our instance fields.
0107:             * Note these are NOT flattened, i.e. only contain the declared ones
0108:             */
0109:            protected FieldInfo[] iFields;
0110:
0111:            /** the storage size of instances of this class (stored as an int[]) */
0112:            protected int instanceDataSize;
0113:
0114:            /** where in the instance data array (int[]) do our declared fields start */
0115:            protected int instanceDataOffset;
0116:
0117:            /** total number of instance fields (flattened, not only declared ones) */
0118:            protected int nInstanceFields;
0119:
0120:            /**
0121:             * our static fields. Again, not flattened
0122:             */
0123:            protected FieldInfo[] sFields;
0124:
0125:            /** the storage size of static fields of this class (stored as an int[]) */
0126:            protected int staticDataSize;
0127:
0128:            protected final ClassInfo super Class;
0129:
0130:            /**
0131:             * Interfaces implemented by the class.
0132:             */
0133:            protected final Set interfaces;
0134:
0135:            /** all interfaces (parent interfaces and interface parents) - lazy eval */
0136:            protected Set allInterfaces;
0137:
0138:            /** Name of the package. */
0139:            protected final String packageName;
0140:
0141:            /** Name of the file which contains the source of this class. */
0142:            protected String sourceFileName;
0143:
0144:            /**
0145:             * this is the object we use to execute methods in the underlying JVM
0146:             * (it replaces Reflection)
0147:             * <2do> pcm - set this private once MethodInfo is cleaned up
0148:             */
0149:            NativePeer nativePeer;
0150:
0151:            /** Source file associated with the class.*/
0152:            protected Source source;
0153:
0154:            static String[] assertionPatterns;
0155:            boolean enableAssertions;
0156:
0157:            static boolean init(Config config) throws Config.Exception {
0158:                loadedClasses = new Hashtable();
0159:                classClassInfo = null;
0160:                objectClassInfo = null;
0161:                stringClassInfo = null;
0162:                weakRefClassInfo = null;
0163:
0164:                setSourceRoots(config);
0165:                repository = createRepository(config);
0166:
0167:                attributor = (Attributor) config.getEssentialInstance(
0168:                        "vm.attributor.class", Attributor.class);
0169:
0170:                assertionPatterns = config
0171:                        .getStringArray("vm.enable_assertions");
0172:
0173:                return true;
0174:            }
0175:
0176:            /**
0177:             * ClassInfo ctor used for builtin types (arrays and primitive types)
0178:             * i.e. classes we don't have class files for
0179:             */
0180:            protected ClassInfo(String builtinClassName) {
0181:                isArray = (builtinClassName.charAt(0) == '[');
0182:                isReferenceArray = isArray && builtinClassName.endsWith(";");
0183:
0184:                name = builtinClassName;
0185:
0186:                Debug.print(Debug.DEBUG, "generating builtin class ");
0187:                Debug.println(Debug.DEBUG, name);
0188:
0189:                packageName = ""; // builtin classes don't reside in java.lang !
0190:                sourceFileName = null;
0191:                source = null;
0192:
0193:                // no fields
0194:                iFields = emptyFields;
0195:                sFields = emptyFields;
0196:
0197:                if (isArray) {
0198:                    super Class = objectClassInfo;
0199:                    interfaces = loadArrayInterfaces();
0200:                    methods = loadArrayMethods();
0201:                } else {
0202:                    super Class = null; // strange, but true, a 'no object' class
0203:                    interfaces = loadBuiltinInterfaces(name);
0204:                    methods = loadBuiltinMethods(name);
0205:                }
0206:
0207:                enableAssertions = true; // doesn't really matter - no code associated
0208:
0209:                loadedClasses.put(name, this );
0210:            }
0211:
0212:            /**
0213:             * Creates a new class from the JavaClass information.
0214:             */
0215:            protected ClassInfo(JavaClass jc) {
0216:                name = jc.getClassName();
0217:
0218:                Debug.print(Debug.DEBUG, "loading class ");
0219:                Debug.println(Debug.DEBUG, name);
0220:
0221:                loadedClasses.put(name, this );
0222:
0223:                if ((objectClassInfo == null)
0224:                        && name.equals("java.lang.Object")) {
0225:                    objectClassInfo = this ;
0226:                } else if ((classClassInfo == null)
0227:                        && name.equals("java.lang.Class")) {
0228:                    classClassInfo = this ;
0229:                } else if ((stringClassInfo == null)
0230:                        && name.equals("java.lang.String")) {
0231:                    stringClassInfo = this ;
0232:                } else if ((weakRefClassInfo == null)
0233:                        && name.equals("java.lang.ref.WeakReference")) {
0234:                    weakRefClassInfo = this ;
0235:                } else if ((refClassInfo == null)
0236:                        && name.equals("java.lang.ref.Reference")) {
0237:                    refClassInfo = this ;
0238:                }
0239:
0240:                isClass = jc.isClass();
0241:                super Class = loadSuperClass(jc);
0242:
0243:                interfaces = loadInterfaces(jc);
0244:                packageName = jc.getPackageName();
0245:
0246:                iFields = loadInstanceFields(jc);
0247:                instanceDataSize = computeInstanceDataSize();
0248:                instanceDataOffset = computeInstanceDataOffset();
0249:                nInstanceFields = (super Class != null) ? super Class.nInstanceFields
0250:                        + iFields.length
0251:                        : iFields.length;
0252:
0253:                sFields = loadStaticFields(jc);
0254:                staticDataSize = computeStaticDataSize();
0255:
0256:                methods = loadMethods(jc);
0257:
0258:                // Used to execute native methods (in JVM land).
0259:                // This needs to be initialized AFTER we get our
0260:                // MethodInfos, since it does a reverse lookup to determine which
0261:                // ones are handled by the peer (by means of setting MethodInfo attributes)
0262:                nativePeer = NativePeer.getNativePeer(this );
0263:
0264:                sourceFileName = jc.getSourceFileName();
0265:
0266:                // bcel seems to behave differently on Windows, returning <Unknown>,
0267:                // which gives us problems when writing/reading XML traces
0268:                if (sourceFileName.equalsIgnoreCase("<Unknown>")) {
0269:                    sourceFileName = "Unkown";
0270:                }
0271:
0272:                if (packageName.length() > 0) {
0273:                    sourceFileName = packageName.replace('.',
0274:                            File.separatorChar)
0275:                            + File.separator + sourceFileName;
0276:                }
0277:
0278:                source = null;
0279:
0280:                isWeakReference = isWeakReference0();
0281:                finalizer = getFinalizer0();
0282:
0283:                // get type specific object and field attributes
0284:                elementInfoAttrs = loadElementInfoAttrs(jc);
0285:
0286:                // the corresponding java.lang.Class object gets set when we initialize
0287:                // this class from StaticArea.newClass() - we don't know the
0288:                // DynamicArea (Heap) here, until we turn this into a global object
0289:
0290:                enableAssertions = getAssertionStatus();
0291:
0292:                // be advised - we don't have fields initialized yet
0293:                JVM.getVM().notifyClassLoaded(this );
0294:            }
0295:
0296:            boolean getAssertionStatus() {
0297:                if ((assertionPatterns == null)
0298:                        || (assertionPatterns.length == 0)) {
0299:                    return false;
0300:                } else if ("*".equals(assertionPatterns[0])) {
0301:                    return true;
0302:                } else {
0303:                    for (int i = 0; i < assertionPatterns.length; i++) {
0304:                        if (name.matches(assertionPatterns[i])) { // Ok, not very efficient
0305:                            return true;
0306:                        }
0307:                    }
0308:
0309:                    return false;
0310:                }
0311:            }
0312:
0313:            public boolean isArray() {
0314:                return isArray;
0315:            }
0316:
0317:            public boolean isReferenceArray() {
0318:                return isReferenceArray;
0319:            }
0320:
0321:            /**
0322:             * Loads the class specified.
0323:             * @param cname The fully qualified name of the class to load.
0324:             * @return Returns the ClassInfo for the classname passed in,
0325:             * or null.
0326:             */
0327:            public static synchronized ClassInfo getClassInfo(String cname) {
0328:                JavaClass jc = null;
0329:
0330:                if (cname == null) {
0331:                    return null;
0332:                }
0333:
0334:                cname = cname.replace('/', '.');
0335:
0336:                ClassInfo ci = (ClassInfo) loadedClasses.get(cname);
0337:
0338:                if (ci == null) {
0339:                    if (isBuiltinClass(cname)) {
0340:                        // this is a array class - there's no class file for this, it
0341:                        // gets automatically generated by the VM
0342:                        ci = new ClassInfo(cname);
0343:                    } else {
0344:                        try {
0345:                            jc = repository.loadClass(cname);
0346:                        } catch (ClassNotFoundException x) {
0347:                            throw new JPFException("could not load class "
0348:                                    + cname);
0349:                        }
0350:
0351:                        // <?> pm - looks like a memory housekeeping issue (since we cache
0352:                        // ourselves). Might have to be changed with JavaClass/ClassInfo unification
0353:                        // and/or ClassLoader support
0354:                        repository.clear();
0355:
0356:                        ci = new ClassInfo(jc);
0357:                    }
0358:                }
0359:
0360:                return ci;
0361:            }
0362:
0363:            public boolean areAssertionsEnabled() {
0364:                return enableAssertions;
0365:            }
0366:
0367:            public int getClassObjectRef() {
0368:                // NOTE - we can't simply store our classObject, because this can be
0369:                // backtracked to a state where the class wasn't loaded yet, and hence
0370:                // the classObject would be different. Maybe we should pin classObjects
0371:                // down and store them here
0372:                StaticArea sa = JVM.getVM().getStaticArea();
0373:
0374:                // <2do> Watch out, it's never null, is that what we want?
0375:                StaticElementInfo sei = sa.get(name);
0376:
0377:                return (sei != null) ? sei.getClassObjectRef() : -1;
0378:            }
0379:
0380:            /**
0381:             * Note that 'uniqueName' is the name plus the argument type part of the
0382:             * signature, i.e. everything that's relevant for overloading
0383:             * (besides saving some const space, we also ease reverse lookup
0384:             * of natives that way).
0385:             * Note also that we don't have to make any difference between
0386:             * class and instance methods, because that just matters in the
0387:             * INVOKExx instruction, when looking up the relevant ClassInfo to start
0388:             * searching in (either by means of the object type, or by means of the
0389:             * constpool classname entry).
0390:             */
0391:            public MethodInfo getMethod(String uniqueName,
0392:                    boolean isRecursiveLookup) {
0393:                MethodInfo mi = null;
0394:
0395:                if (uniqueName.charAt(uniqueName.length() - 1) != ')') {
0396:                    // somebody slipped us a full signature?
0397:                    uniqueName = uniqueName.substring(0, uniqueName
0398:                            .indexOf(')') + 1);
0399:                }
0400:
0401:                mi = (MethodInfo) methods.get(uniqueName);
0402:
0403:                if ((mi == null) && isRecursiveLookup && (super Class != null)) {
0404:                    mi = super Class.getMethod(uniqueName, true);
0405:                }
0406:
0407:                return mi;
0408:            }
0409:
0410:            public FieldInfo getStaticField(String clsBase, String fName) {
0411:                FieldInfo fi;
0412:                ClassInfo c = getClassBase(clsBase);
0413:
0414:                while (c != null) {
0415:                    fi = c.getDeclaredStaticField(fName);
0416:                    if (fi != null)
0417:                        return fi;
0418:                    c = c.super Class;
0419:                }
0420:
0421:                return null;
0422:            }
0423:
0424:            public FieldInfo getStaticField(String fname) {
0425:                return getStaticField(null, fname);
0426:            }
0427:
0428:            /**
0429:             * FieldInfo lookup in the static fields that are declared in this class
0430:             * <2do> pcm - should employ a map at some point, but it's usually not that
0431:             * important since we can cash the returned FieldInfo in the PUT/GET_STATIC insns
0432:             */
0433:            public FieldInfo getDeclaredStaticField(String fName) {
0434:                for (int i = 0; i < sFields.length; i++) {
0435:                    if (sFields[i].getName().equals(fName))
0436:                        return sFields[i];
0437:                }
0438:
0439:                return null;
0440:            }
0441:
0442:            /**
0443:             * base relative FieldInfo lookup - the workhorse
0444:             * <2do> again, should eventually use Maps
0445:             * @param clsBase - the class where we start the lookup (self or some super)
0446:             * @param fName - the field name
0447:             */
0448:            public FieldInfo getInstanceField(String clsBase, String fName) {
0449:                FieldInfo fi;
0450:                ClassInfo c = getClassBase(clsBase);
0451:
0452:                while (c != null) {
0453:                    fi = c.getDeclaredInstanceField(fName);
0454:                    if (fi != null)
0455:                        return fi;
0456:                    c = c.super Class;
0457:                }
0458:
0459:                return null;
0460:            }
0461:
0462:            /**
0463:             * complete bottom-up FieldInfo lookup
0464:             */
0465:            public FieldInfo getInstanceField(String fName) {
0466:                return getInstanceField(null, fName);
0467:            }
0468:
0469:            /**
0470:             * FieldInfo lookup in the fields that are declared in this class
0471:             */
0472:            public FieldInfo getDeclaredInstanceField(String fName) {
0473:                for (int i = 0; i < iFields.length; i++) {
0474:                    if (iFields[i].getName().equals(fName))
0475:                        return iFields[i];
0476:                }
0477:
0478:                return null;
0479:            }
0480:
0481:            /**
0482:             * consult nativePeer to check if method is deterministic
0483:             */
0484:            public boolean isMethodCondDeterministic(ThreadInfo th,
0485:                    MethodInfo mi) {
0486:                if (nativePeer != null) {
0487:                    return nativePeer.isMethodCondDeterministic(th, mi);
0488:                }
0489:
0490:                return false;
0491:            }
0492:
0493:            /**
0494:             * consult nativePeer to check if method is executable
0495:             */
0496:            public boolean isMethodCondExecutable(ThreadInfo th, MethodInfo mi) {
0497:                if (nativePeer != null) {
0498:                    return nativePeer.isMethodCondExecutable(th, mi);
0499:                }
0500:
0501:                return false;
0502:            }
0503:
0504:            /**
0505:             * Returns the name of the class.
0506:             */
0507:            public String getName() {
0508:                return name;
0509:            }
0510:
0511:            public String getPackageName() {
0512:                return packageName;
0513:            }
0514:
0515:            public int getFieldAttrs(int fieldIndex) {
0516:                return 0;
0517:            }
0518:
0519:            public int getElementInfoAttrs() {
0520:                return elementInfoAttrs;
0521:            }
0522:
0523:            public Source getSource() {
0524:                if (source == null) {
0525:                    source = loadSource();
0526:                }
0527:
0528:                return source;
0529:            }
0530:
0531:            public String getSourceFileName() {
0532:                return sourceFileName;
0533:            }
0534:
0535:            /**
0536:             * Returns the information about a static field.
0537:             */
0538:            public FieldInfo getStaticField(int index) {
0539:                return sFields[index];
0540:            }
0541:
0542:            /**
0543:             * Returns the name of a static field.
0544:             */
0545:            public String getStaticFieldName(int index) {
0546:                return getStaticField(index).getName();
0547:            }
0548:
0549:            /**
0550:             * Checks if a static method call is deterministic, but only for
0551:             * abtraction based determinism, due to Bandera.choose() calls
0552:             */
0553:            public boolean isStaticMethodAbstractionDeterministic(
0554:                    ThreadInfo th, MethodInfo mi) {
0555:                //    Reflection r = reflection.instantiate();
0556:                //    return r.isStaticMethodAbstractionDeterministic(th, mi);
0557:                // <2do> - still has to be implemented
0558:                return true;
0559:            }
0560:
0561:            /**
0562:             * Return the super class.
0563:             */
0564:            public ClassInfo getSuperClass() {
0565:                return super Class;
0566:            }
0567:
0568:            /**
0569:             * return the ClassInfo for the provided superclass name. If this is equal
0570:             * to ourself, return this (a little bit strange if we hit it in the first place)
0571:             */
0572:            public ClassInfo getSuperClass(String clsName) {
0573:                if (clsName.equals(name))
0574:                    return this ;
0575:
0576:                if (super Class != null) {
0577:                    return super Class.getSuperClass(clsName);
0578:                } else {
0579:                    return null;
0580:                }
0581:            }
0582:
0583:            public boolean isInstanceOf(ClassInfo ci) {
0584:                ClassInfo c = this ;
0585:                do {
0586:                    if (c == ci) {
0587:                        return true;
0588:                    }
0589:                    c = c.super Class;
0590:                } while (c != null);
0591:
0592:                return false;
0593:            }
0594:
0595:            /**
0596:             * Returns true if the class is a system class.
0597:             */
0598:            public boolean isSystemClass() {
0599:                return name.startsWith("java.") || name.startsWith("javax.");
0600:            }
0601:
0602:            /**
0603:             * Returns the type of a class.
0604:             */
0605:            public String getType() {
0606:                return "L" + name.replace('.', '/') + ";";
0607:            }
0608:
0609:            /**
0610:             * is this a (subclass of) WeakReference? this must be efficient, since it's
0611:             * called in the mark phase on all live objects
0612:             */
0613:            public boolean isWeakReference() {
0614:                return isWeakReference;
0615:            }
0616:
0617:            /**
0618:             * note this only returns true is this is really the java.lang.ref.Reference classInfo
0619:             */
0620:            public boolean isRefClass() {
0621:                return (this  == refClassInfo);
0622:            }
0623:
0624:            /**
0625:             * Creates the fields for an object.
0626:             */
0627:            public Fields createInstanceFields() {
0628:                return new DynamicFields(getType(), this );
0629:            }
0630:
0631:            boolean hasRefField(int ref, Fields fv) {
0632:                ClassInfo c = this ;
0633:
0634:                do {
0635:                    FieldInfo[] fia = c.iFields;
0636:                    for (int i = 0; i < fia.length; i++) {
0637:                        FieldInfo fi = c.iFields[i];
0638:                        if (fi.isReference()
0639:                                && (fv.getIntValue(fi.getStorageOffset()) == ref))
0640:                            return true;
0641:                    }
0642:                    c = c.super Class;
0643:                } while (c != null);
0644:
0645:                return false;
0646:            }
0647:
0648:            boolean hasImmutableInstances() {
0649:                return ((elementInfoAttrs & ElementInfo.ATTR_IMMUTABLE) != 0);
0650:            }
0651:
0652:            public Instruction executeNativeMethod(ThreadInfo th, MethodInfo mi) {
0653:                if (nativePeer != null) {
0654:                    return nativePeer.executeMethod(th, mi);
0655:                }
0656:
0657:                return th.createAndThrowException(
0658:                        "java.lang.UnsatisfiedLinkError", name + '.'
0659:                                + mi.getName() + " (no peer)");
0660:            }
0661:
0662:            public static boolean exists(String cname) {
0663:                // <?> pcm - is this really intended to load the thing?
0664:                // (I assume not, and therefor replace repository.lookupClass())
0665:                return (repository.findClass(cname) != null);
0666:            }
0667:
0668:            public void initializeClass(ThreadInfo th) {
0669:                if (th == null) {
0670:                    return; // no thread stack, nothing we can execute (called from vm.init)
0671:                }
0672:
0673:                Debug.print(Debug.DEBUG, "initializing class ");
0674:                Debug.println(Debug.DEBUG, name);
0675:
0676:                MethodInfo mi = getMethod("<clinit>()", false); // only local lookup
0677:
0678:                if (mi != null) {
0679:                    // <2do> sync on class object here
0680:                    // no args
0681:                    th.executeMethod(mi);
0682:                    // <2do> unsync
0683:                }
0684:            }
0685:
0686:            /**
0687:             * Returns true if the given class is an instance of the class
0688:             * or interface specified.
0689:             */
0690:            public boolean instanceOf(String cname) {
0691:                cname = cname.replace('/', '.');
0692:
0693:                // trivial case - ourself
0694:                if (name.equals(cname)) {
0695:                    return true;
0696:                }
0697:
0698:                // (recursive) parent
0699:                if ((super Class != null) && (super Class.instanceOf(cname))) {
0700:                    return true;
0701:                }
0702:
0703:                // direct interface
0704:                if (interfaces.contains(cname)) {
0705:                    return true;
0706:                }
0707:
0708:                // now it's getting more expensive - look for all interfaces
0709:                if (getAllInterfaces().contains(cname)) {
0710:                    return true;
0711:                }
0712:
0713:                // Ok, we give up
0714:                return false;
0715:            }
0716:
0717:            /**
0718:             * clean up statics for another 'main' run
0719:             */
0720:            public static void reset() {
0721:                if (repository != null) {
0722:                    repository.clear();
0723:                }
0724:
0725:                loadedClasses = new Hashtable();
0726:
0727:                classClassInfo = null;
0728:                objectClassInfo = null;
0729:                stringClassInfo = null;
0730:            }
0731:
0732:            /**
0733:             * provide a default path from where to load essential model classes
0734:             * (associated with native peers that JPF needs)
0735:             */
0736:            static String getDefaultBootClassPath() {
0737:                StringBuffer sb = new StringBuffer();
0738:
0739:                // assuming we are in the JPF root dir, add build/env/jpf for explicit classes
0740:                sb.append("build");
0741:                sb.append(File.separatorChar);
0742:                sb.append("env");
0743:                sb.append(File.separatorChar);
0744:                sb.append("jpf");
0745:
0746:                // but maybe this is a binary distrib, so add lib/env_jpf.jar
0747:                sb.append(File.pathSeparatorChar);
0748:                sb.append("lib");
0749:                sb.append(File.separatorChar);
0750:                sb.append("env_jpf.jar");
0751:
0752:                return sb.toString();
0753:            }
0754:
0755:            /**
0756:             * this is for application specific classes that should not be seen by the host VM 
0757:             */
0758:            static String getDefaultClassPath() {
0759:                return null;
0760:            }
0761:
0762:            protected static SyntheticRepository createRepository(Config config) {
0763:                // <2do> pm  - we have a collision with jpf.ClassPath (PCM)
0764:                // unfortunately, it's different enough to the JPF counterpart so that we
0765:                // have to keep both versions for now
0766:                org.apache.bcel.util.ClassPath cpath;
0767:                StringBuffer buf = new StringBuffer(128);
0768:                String sep = System.getProperty("path.separator");
0769:                String v;
0770:
0771:                // this is where we get our essential model classes from (java.lang.Thread etc)
0772:                if ((v = config.getExpandedString("vm.bootclasspath")) == null) {
0773:                    v = getDefaultBootClassPath();
0774:                }
0775:                buf.append(v);
0776:
0777:                // that's where the application specific environment should be loaded from
0778:                if ((v = config.getExpandedString("vm.classpath")) == null) {
0779:                    v = getDefaultClassPath();
0780:                }
0781:
0782:                if (v != null) {
0783:                    buf.append(sep);
0784:                    buf.append(v);
0785:                }
0786:
0787:                // now we look into the system classpath (all stuff loaded from here is
0788:                // the same codebase that's also used by the host VM)
0789:                if (buf.length() > 0) {
0790:                    buf.append(sep);
0791:                }
0792:
0793:                buf.append(System.getProperty("java.class.path"));
0794:
0795:                // finally, we load from the standard Java libraries
0796:                if (buf.length() > 0) {
0797:                    buf.append(sep);
0798:                }
0799:
0800:                buf.append(System.getProperty("sun.boot.class.path"));
0801:
0802:                cpath = new org.apache.bcel.util.ClassPath(buf.toString());
0803:
0804:                return SyntheticRepository.getInstance(cpath);
0805:            }
0806:
0807:            protected static Set loadArrayInterfaces() {
0808:                Set interfaces;
0809:
0810:                interfaces = new HashSet();
0811:                interfaces.add("java.lang.Cloneable");
0812:                interfaces.add("java.io.Serializable");
0813:
0814:                return Collections.unmodifiableSet(interfaces);
0815:            }
0816:
0817:            protected static Set loadBuiltinInterfaces(String type) {
0818:                return Collections.unmodifiableSet(new HashSet(0));
0819:            }
0820:
0821:            /**
0822:             * Loads the interfaces of a class.
0823:             */
0824:            protected static Set loadInterfaces(JavaClass jc) {
0825:                Set interfaces;
0826:                String[] interfaceNames;
0827:
0828:                interfaceNames = jc.getInterfaceNames();
0829:                interfaces = new HashSet();
0830:
0831:                for (int i = 0, l = interfaceNames.length; i < l; i++) {
0832:                    interfaces.add(interfaceNames[i]);
0833:                }
0834:
0835:                return Collections.unmodifiableSet(interfaces);
0836:            }
0837:
0838:            FieldInfo[] loadInstanceFields(JavaClass jc) {
0839:                Field[] fields = jc.getFields();
0840:                int i, j, n;
0841:                int off = (super Class != null) ? super Class.instanceDataSize
0842:                        : 0;
0843:
0844:                for (i = 0, n = 0; i < fields.length; i++) {
0845:                    if (!fields[i].isStatic())
0846:                        n++;
0847:                }
0848:
0849:                int idx = (super Class != null) ? super Class.nInstanceFields : 0;
0850:                FieldInfo[] ifa = new FieldInfo[n];
0851:
0852:                for (i = 0, j = 0; i < fields.length; i++) {
0853:                    Field f = fields[i];
0854:                    if (!f.isStatic()) {
0855:                        FieldInfo fi = FieldInfo.create(f, this , idx, off);
0856:                        ifa[j++] = fi;
0857:                        off += fi.getStorageSize();
0858:                        idx++;
0859:
0860:                        if (attributor != null) {
0861:                            fi.setAttributes(attributor.getFieldAttributes(jc,
0862:                                    f));
0863:                        }
0864:                    }
0865:                }
0866:
0867:                return ifa;
0868:            }
0869:
0870:            int computeInstanceDataOffset() {
0871:                if (super Class == null) {
0872:                    return 0;
0873:                } else {
0874:                    return super Class.getInstanceDataSize();
0875:                }
0876:            }
0877:
0878:            int getInstanceDataOffset() {
0879:                return instanceDataOffset;
0880:            }
0881:
0882:            ClassInfo getClassBase(String clsBase) {
0883:                if ((clsBase == null) || (name.equals(clsBase)))
0884:                    return this ;
0885:
0886:                if (super Class != null) {
0887:                    return super Class.getClassBase(clsBase);
0888:                }
0889:
0890:                return null; // Eeek - somebody asked for a class that isn't in the base list
0891:            }
0892:
0893:            int computeInstanceDataSize() {
0894:                int n = getDataSize(iFields);
0895:
0896:                for (ClassInfo c = super Class; c != null; c = c.super Class) {
0897:                    n += c.getDataSize(c.iFields);
0898:                }
0899:
0900:                return n;
0901:            }
0902:
0903:            int getInstanceDataSize() {
0904:                return instanceDataSize;
0905:            }
0906:
0907:            int getDataSize(FieldInfo[] fields) {
0908:                int n = 0;
0909:                for (int i = 0; i < fields.length; i++) {
0910:                    n += fields[i].getStorageSize();
0911:                }
0912:
0913:                return n;
0914:            }
0915:
0916:            public int getNumberOfDeclaredInstanceFields() {
0917:                return iFields.length;
0918:            }
0919:
0920:            FieldInfo getDeclaredInstanceField(int i) {
0921:                return iFields[i];
0922:            }
0923:
0924:            public int getNumberOfInstanceFields() {
0925:                return nInstanceFields;
0926:            }
0927:
0928:            FieldInfo getInstanceField(int i) {
0929:                int idx = i - (nInstanceFields - iFields.length);
0930:                if (idx >= 0) {
0931:                    return ((idx < iFields.length) ? iFields[idx] : null);
0932:                } else {
0933:                    return ((super Class != null) ? super Class
0934:                            .getInstanceField(i) : null);
0935:                }
0936:            }
0937:
0938:            FieldInfo[] loadStaticFields(JavaClass jc) {
0939:                Field[] fields = jc.getFields();
0940:                int i, j, n;
0941:                int off = 0;
0942:
0943:                for (i = 0, n = 0; i < fields.length; i++) {
0944:                    if (fields[i].isStatic())
0945:                        n++;
0946:                }
0947:
0948:                FieldInfo[] sfa = new FieldInfo[n];
0949:                int idx = 0;
0950:
0951:                for (i = 0; i < fields.length; i++) {
0952:                    Field f = fields[i];
0953:                    if (f.isStatic()) {
0954:                        FieldInfo fi = FieldInfo.create(f, this , idx, off);
0955:                        sfa[idx] = fi;
0956:                        idx++;
0957:                        off += fi.getStorageSize();
0958:                    }
0959:                }
0960:
0961:                return sfa;
0962:            }
0963:
0964:            int getStaticDataSize() {
0965:                return staticDataSize;
0966:            }
0967:
0968:            int computeStaticDataSize() {
0969:                return getDataSize(sFields);
0970:            }
0971:
0972:            public int getNumberOfStaticFields() {
0973:                return sFields.length;
0974:            }
0975:
0976:            protected Source loadSource() {
0977:                return Source.getSource(sourceFileName);
0978:            }
0979:
0980:            static boolean isBuiltinClass(String cname) {
0981:                char c = cname.charAt(0);
0982:
0983:                // array class
0984:                if (c == '[') {
0985:                    return true;
0986:                }
0987:
0988:                // primitive type class
0989:                if (Character.isLowerCase(c)) {
0990:                    if ("int".equals(cname) || "byte".equals(cname)
0991:                            || "boolean".equals(cname)
0992:                            || "double".equals(cname) || "long".equals(cname)
0993:                            || "char".equals(cname) || "short".equals(cname)
0994:                            || "float".equals(cname)) {
0995:                        return true;
0996:                    }
0997:                }
0998:
0999:                return false;
1000:            }
1001:
1002:            /**
1003:             * set the locations where we look up sources
1004:             */
1005:            static void setSourceRoots(Config config) {
1006:                String srcPath = config.getExpandedString("vm.sourcepath");
1007:                if (srcPath == null) { // our fallbacks, assuming we are in the JPF root dir
1008:                    Source.addSourceRoot("examples");
1009:                    Source.addSourceRoot("test");
1010:                } else {
1011:                    StringTokenizer st = new StringTokenizer(srcPath,
1012:                            File.pathSeparator);
1013:                    while (st.hasMoreTokens()) {
1014:                        String sroot = st.nextToken();
1015:
1016:                        if ((sroot.length() > 0) && !sroot.endsWith(".jar")) {
1017:                            Source.addSourceRoot(sroot);
1018:                        }
1019:                    }
1020:                }
1021:            }
1022:
1023:            Set getAllInterfaces() {
1024:                if (allInterfaces == null) {
1025:                    HashSet set = new HashSet();
1026:
1027:                    // load all own interfaces
1028:                    loadInterfaceRec(set, this );
1029:
1030:                    // all parent class interfaces
1031:                    loadInterfaceRec(set, super Class);
1032:
1033:                    allInterfaces = Collections.unmodifiableSet(set);
1034:                }
1035:
1036:                return allInterfaces;
1037:            }
1038:
1039:            ClassInfo getComponentClassInfo() {
1040:                if (isArray()) {
1041:                    String cn = name.substring(1);
1042:
1043:                    if (cn.charAt(0) != '[') {
1044:                        cn = Types.getTypeName(cn);
1045:                    }
1046:
1047:                    ClassInfo cci = getClassInfo(cn);
1048:
1049:                    return cci;
1050:                }
1051:
1052:                return null;
1053:            }
1054:
1055:            /**
1056:             * most definitely not a public method, but handy for the NativePeer
1057:             */
1058:            Map getDeclaredMethods() {
1059:                return methods;
1060:            }
1061:
1062:            MethodInfo getFinalizer() {
1063:                return finalizer;
1064:            }
1065:
1066:            int createClassObject(ThreadInfo th, int cref) {
1067:                int objref;
1068:                int cnref;
1069:                DynamicArea da = JVM.getVM().getDynamicArea();
1070:
1071:                objref = da.newObject(classClassInfo, th);
1072:                cnref = da.newString(name, th);
1073:
1074:                // we can't execute methods nicely for which we don't have caller bytecode
1075:                // (would run into a (pc == null) assertion), so we have to bite the bullet
1076:                // and init the java.lang.Class object explicitly. But that's probably Ok
1077:                // since it is a very special beast, anyway
1078:                ElementInfo e = da.get(objref);
1079:
1080:                try {
1081:                    e.setReferenceField("name", cnref);
1082:
1083:                    // this is the StaticArea ElementInfo index of what we refer to
1084:                    e.setIntField("cref", cref);
1085:                } catch (Exception x) {
1086:                    // if we don't have the right (JPF specific) java.lang.Class version,
1087:                    // we are screwed in terms of java.lang.Class usage
1088:                    if (classClassInfo == null) { // report it just once
1089:                        Debug.println(Debug.ERROR);
1090:                        Debug.println(Debug.ERROR,
1091:                                "FATAL ERROR: wrong java.lang.Class version");
1092:                        Debug.println(Debug.ERROR,
1093:                                "             you need to set 'vm.classpath'");
1094:                        Debug
1095:                                .println(Debug.ERROR,
1096:                                        "             or start jpf from its root directory");
1097:                        Debug.println(Debug.ERROR);
1098:                        Debug
1099:                                .println(Debug.ERROR,
1100:                                        "             !! assertions or java.lang.Class usage will fail !!");
1101:                        Debug.println(Debug.ERROR);
1102:                    }
1103:
1104:                    return -1;
1105:                }
1106:
1107:                return objref;
1108:            }
1109:
1110:            /**
1111:             * Creates the fields for a class.  This gets called by the StaticArea
1112:             * when a class is loaded.
1113:             */
1114:            Fields createStaticFields(StaticArea staticArea) {
1115:                return new StaticFields(this );
1116:            }
1117:
1118:            void initializeStaticData(Fields f) {
1119:                for (int i = 0; i < sFields.length; i++) {
1120:                    FieldInfo fi = sFields[i];
1121:                    fi.initialize(f);
1122:                }
1123:            }
1124:
1125:            void initializeInstanceData(Fields f) {
1126:                // Note this is only used for field inits, and array elements are not fields!
1127:                // Since Java has only limited element init requirements (either 0 or null),
1128:                // we do this ad hoc in the ArrayFields ctor
1129:
1130:                // the order of inits should not matter, since this is only
1131:                // for constant inits. In case of a "class X { int a=42; int b=a; ..}"
1132:                // we have a explicit "GETFIELD a, PUTFIELD b" in the ctor
1133:                for (int i = 0; i < iFields.length; i++) {
1134:                    FieldInfo fi = iFields[i];
1135:                    fi.initialize(f);
1136:                }
1137:                if (super Class != null) {
1138:                    super Class.initializeInstanceData(f);
1139:                }
1140:            }
1141:
1142:            Map loadArrayMethods() {
1143:                return new HashMap(0);
1144:            }
1145:
1146:            Map loadBuiltinMethods(String type) {
1147:                return new HashMap(0);
1148:            }
1149:
1150:            void loadInterfaceRec(Set set, ClassInfo ci) {
1151:                if (ci != null) {
1152:                    Iterator it = ci.interfaces.iterator();
1153:
1154:                    while (it.hasNext()) {
1155:                        String iname = (String) it.next();
1156:                        set.add(iname);
1157:
1158:                        ci = getClassInfo(iname);
1159:                        loadInterfaceRec(set, ci);
1160:                    }
1161:                }
1162:            }
1163:
1164:            /**
1165:             * this is a optimization to work around the BCEL strangeness that some
1166:             * insn info (types etc.) are only accessible with modifiable ConstPools
1167:             * (the ConstantPoolGen, which is costly to create), and some others
1168:             * (toString) are only provided via ConstPools. It's way to expensive
1169:             * to create this always on the fly, for each relevant insn, so we cache it
1170:             * here
1171:             */
1172:            static ConstantPool cpCache;
1173:            static ConstantPoolGen cpgCache;
1174:
1175:            public static ConstantPoolGen getConstantPoolGen(ConstantPool cp) {
1176:                if (cp != cpCache) {
1177:                    cpCache = cp;
1178:                    cpgCache = new ConstantPoolGen(cp);
1179:                }
1180:
1181:                return cpgCache;
1182:            }
1183:
1184:            /** avoid memory leaks */
1185:            static void resetCPCache() {
1186:                cpCache = null;
1187:                cpgCache = null;
1188:            }
1189:
1190:            Map loadMethods(JavaClass jc) {
1191:                Method[] ms = jc.getMethods();
1192:                HashMap map = new HashMap(ms.length);
1193:
1194:                for (int i = 0; i < ms.length; i++) {
1195:                    MethodInfo mi = MethodInfo.newInstance(ms[i], this );
1196:                    String id = mi.getUniqueName();
1197:                    map.put(id, mi);
1198:
1199:                    if (attributor != null) {
1200:                        mi.setAtomic(attributor.isMethodAtomic(jc, ms[i], id));
1201:                        mi.setSchedulingRelevance(attributor
1202:                                .getSchedulingRelevance(jc, ms[i], id));
1203:                    }
1204:                }
1205:
1206:                resetCPCache(); // no memory leaks
1207:
1208:                return map;
1209:            }
1210:
1211:            ClassInfo loadSuperClass(JavaClass jc) {
1212:                if (this  == objectClassInfo) {
1213:                    return null;
1214:                } else {
1215:                    String super Name = jc.getSuperclassName();
1216:
1217:                    return getClassInfo(super Name);
1218:                }
1219:            }
1220:
1221:            int loadElementInfoAttrs(JavaClass jc) {
1222:                // we use the atomicizer for it because the only attribute for now is the
1223:                // immutability, and it is used to determine if a field insn should be
1224:                // a step boundary. Otherwise it's a bit artificial, but we don't want
1225:                // to intro another load time class attributor for now
1226:                if (attributor != null) {
1227:                    return attributor.getObjectAttributes(jc);
1228:                }
1229:
1230:                return 0;
1231:            }
1232:
1233:            private MethodInfo getFinalizer0() {
1234:                MethodInfo mi = getMethod("finalize()", true);
1235:
1236:                // we are only interested in non-empty method bodies, Object.finalize()
1237:                // is a dummy
1238:                if ((mi != null) && (mi.getClassInfo() != objectClassInfo)) {
1239:                    return mi;
1240:                }
1241:
1242:                return null;
1243:            }
1244:
1245:            private boolean isWeakReference0() {
1246:                for (ClassInfo ci = this ; ci != objectClassInfo; ci = ci.super Class) {
1247:                    if (ci == weakRefClassInfo) {
1248:                        return true;
1249:                    }
1250:                }
1251:
1252:                return false;
1253:            }
1254:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.