Source Code Cross Referenced for ElementInfo.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.JPFException;
0022:        import gov.nasa.jpf.util.Debug;
0023:        import gov.nasa.jpf.util.HashData;
0024:        import gov.nasa.jpf.util.HashPool;
0025:
0026:        import java.util.HashMap;
0027:        import java.util.Vector;
0028:
0029:        /**
0030:         * Describes an element of memory containing the field values of a class or an
0031:         * object. In the case of a class, contains the values of the static fields. For
0032:         * an object contains the values of the object fields.
0033:         * 
0034:         * @see gov.nasa.jpf.jvm.FieldInfo
0035:         */
0036:        public abstract class ElementInfo implements  Storable, Reference,
0037:                Cloneable {
0038:            static final int storingDataLength = 3;
0039:
0040:            protected static HashPool fieldsPool = new HashPool();
0041:
0042:            protected static HashPool monitorPool = new HashPool();
0043:
0044:            protected static HashPool racePool = new HashPool();
0045:
0046:            protected Fields fields;
0047:
0048:            protected Monitor monitor;
0049:
0050:            protected Area area;
0051:
0052:            protected int index;
0053:
0054:            // object attribute flag values
0055:            public static final int ATTR_NONE = 0x0;
0056:
0057:            public static final int ATTR_PROP_MASK = 0x0000ffff;
0058:
0059:            // the propagated ones - only lower 16 bits can be used
0060:
0061:            public static final int ATTR_TSHARED = 0x1; // reachable
0062:            // from
0063:            // different
0064:            // threads
0065:
0066:            // this one is redundant if we just base it on the ClassInfo
0067:            // (->fields->classinfo)
0068:            // but we might use code attrs in the future to set this on a per-instance
0069:            // basis
0070:            public static final int ATTR_IMMUTABLE = 0x2; // object
0071:            // doesn't
0072:            // change value
0073:
0074:            // don't promote to shared along this path
0075:            public static final int ATTR_NO_PROMOTE = 0x4;
0076:
0077:            // the non-propagated attributes - use only higher 16 bits
0078:
0079:            // to-be-done, would be code attr, too, and could easily be checked at runtime
0080:            // (hello, a new property)
0081:            public static final int ATTR_SINGLE_WRITER = 0x10000;
0082:
0083:            // don't propagate attributes through this object
0084:            public static final int ATTR_NO_PROPAGATE = 0x20000;
0085:
0086:            // object is assumed to be fully protected (i.e. no field access that is
0087:            // not protected by a lock)
0088:            public static final int ATTR_PROTECTED = 0x40000;
0089:
0090:            // don't reycle this object as long as the flag is set
0091:            public static final int ATTR_PINDOWN = 0x80000;
0092:
0093:            // these are our state-stored object attributes
0094:            // WATCH OUT! only include info that otherwise reflects a state change, so
0095:            // that
0096:            // we don't introduce new changes. It's value is used to hash the state!
0097:            // <2do> what a pity - 32 stored bits for (currently) only 2 bits of
0098:            // information,
0099:            // but we might use this as a hash for more complex reference info in the
0100:            // future.
0101:            // We distinguish between propagates and private object attributes, the first
0102:            // ones tored in the lower 2 bytes
0103:            protected int attributes;
0104:
0105:            /*
0106:             * The following information is used to cache the value of the indexes so that
0107:             * an explicit indexing is not necessary at each storing.
0108:             */
0109:            protected int fIndex = -1;
0110:
0111:            protected int mIndex = -1;
0112:
0113:            static HashMap lockDiscipline = new HashMap();
0114:
0115:            public ElementInfo(Fields f, Monitor m) {
0116:                fields = f;
0117:                monitor = m;
0118:
0119:                attributes = f.getClassInfo().getElementInfoAttrs();
0120:            }
0121:
0122:            protected ElementInfo() {
0123:            }
0124:
0125:            public String toString() {
0126:                return (getClassInfo().getName() + '@' + index);
0127:            }
0128:
0129:            public FieldLockInfo getFieldLockInfo(String fid) {
0130:                return (FieldLockInfo) lockDiscipline.get(fid);
0131:            }
0132:
0133:            public void setFieldLockInfo(String fid, FieldLockInfo flInfo) {
0134:                lockDiscipline.put(fid, flInfo);
0135:            }
0136:
0137:            /**
0138:             * do we have a reference field with value objRef?
0139:             */
0140:            boolean hasRefField(int objRef) {
0141:                return fields.hasRefField(objRef);
0142:            }
0143:
0144:            void setShared() {
0145:                attributes |= ATTR_TSHARED;
0146:            }
0147:
0148:            /**
0149:             * set shared, but only if the ATTR_TSHARED bit isn't masked out
0150:             */
0151:            void setShared(int attrMask) {
0152:                attributes |= (attrMask & ATTR_TSHARED);
0153:            }
0154:
0155:            /**
0156:             * the recursive phase2 marker entry, which propagates the attributes set by a
0157:             * previous phase1. This one is called on all 'root'-marked objects after
0158:             * phase1 is completed. ElementInfo is not an ideal place for this method, as
0159:             * it has to access some innards of both ClassInfo (FieldInfo container) and
0160:             * Fields. But on the other hand, we want to keep the whole heap traversal
0161:             * business as much centralized in ElementInfo and DynamicArea as possible
0162:             * 
0163:             * @aspects: gc
0164:             */
0165:            void markRecursive(int tid, int attrMask) {
0166:                DynamicArea heap = DynamicArea.getHeap();
0167:                int i, n;
0168:
0169:                if (isArray()) {
0170:                    if (fields.isReferenceArray()) {
0171:                        n = fields.arrayLength();
0172:                        for (i = 0; i < n; i++) {
0173:                            heap.markRecursive(fields.getIntValue(i), tid,
0174:                                    attributes, attrMask, null);
0175:                        }
0176:                    }
0177:                } else {
0178:                    ClassInfo ci = getClassInfo();
0179:                    boolean isWeakRef = ci.isWeakReference();
0180:
0181:                    do {
0182:                        n = ci.getNumberOfDeclaredInstanceFields();
0183:                        boolean isRef = isWeakRef && ci.isRefClass(); // is this the java.lang.ref.Reference part?
0184:
0185:                        for (i = 0; i < n; i++) {
0186:                            FieldInfo fi = ci.getDeclaredInstanceField(i);
0187:                            if (fi.isReference()) {
0188:                                if ((i == 0) && isRef) {
0189:                                    // we need to reset the ref field once the referenced object goes away
0190:                                    // NOTE: only the *first* WeakReference field is a weak ref
0191:                                    // (this is why we have our own implementation)
0192:                                    heap.registerWeakReference(fields);
0193:                                } else {
0194:
0195:                                    // the refAttrs are not immediately masked because we have to
0196:                                    // preserve
0197:                                    // the mask values up to the point where we would promote a
0198:                                    // otherwise
0199:                                    // unshared root object due to a different thread id (in case we
0200:                                    // didn't
0201:                                    // catch a mask on the way that prevents this)
0202:                                    heap.markRecursive(fields
0203:                                            .getReferenceValue(fi
0204:                                                    .getStorageOffset()), tid,
0205:                                            attributes, attrMask, fi);
0206:                                }
0207:                            }
0208:                        }
0209:                        ci = ci.getSuperClass();
0210:                    } while (ci != null);
0211:                }
0212:            }
0213:
0214:            boolean hasEqualPropagatedAttributes(int refAttrs, int attrMask) {
0215:                int mask = ATTR_PROP_MASK & attrMask;
0216:                return ((attributes & mask) == (refAttrs & mask));
0217:            }
0218:
0219:            void propagateAttributes(int refAttr, int attrMask) {
0220:                attributes |= ((refAttr & attrMask) & ATTR_PROP_MASK);
0221:            }
0222:
0223:            public boolean isShared() {
0224:                return ((attributes & ATTR_TSHARED) != 0);
0225:            }
0226:
0227:            public boolean isImmutable() {
0228:                return ((attributes & ATTR_IMMUTABLE) != 0);
0229:            }
0230:
0231:            public boolean isSchedulingRelevant() {
0232:                // only mutable, shared objects are relevant
0233:                return ((attributes & (ATTR_TSHARED | ATTR_IMMUTABLE)) == ATTR_TSHARED);
0234:            }
0235:
0236:            /**
0237:             * check if there are any propagated attributes in ei we don't have yet
0238:             */
0239:            public boolean needsAttributePropagationFrom(ElementInfo ei) {
0240:                int a = attributes;
0241:                int o = ei.attributes;
0242:
0243:                if (a != o) {
0244:                    if ((o & ATTR_PROP_MASK) > (a & ATTR_PROP_MASK))
0245:                        return true;
0246:
0247:                    for (int i = 0; i < 16; i++, o >>= 1, a >>= 1) {
0248:                        if ((o & 0x1) > (a & 0x1)) {
0249:                            return true;
0250:                        }
0251:                    }
0252:                }
0253:
0254:                return false;
0255:            }
0256:
0257:            public void setArea(Area newArea) {
0258:                area = newArea;
0259:            }
0260:
0261:            public Area getArea() {
0262:                return area;
0263:            }
0264:
0265:            /** a bit simplistic, but will do for object equalness */
0266:            public boolean equals(Object other) {
0267:                if (getClass() != other.getClass())
0268:                    return false;
0269:
0270:                ElementInfo ei = (ElementInfo) other;
0271:                return fields.equals(ei.fields);
0272:            }
0273:
0274:            public ClassInfo getClassInfo() {
0275:                return fields.getClassInfo();
0276:            }
0277:
0278:            abstract protected FieldInfo getFieldInfo(String clsBase,
0279:                    String fname);
0280:
0281:            abstract protected ElementInfo getElementInfo(ClassInfo ci);
0282:
0283:            protected FieldInfo getFieldInfo(String fname) {
0284:                return getFieldInfo(null, fname);
0285:            }
0286:
0287:            public int getIntField(String fname) {
0288:                return getIntField(fname, null);
0289:            }
0290:
0291:            public long getLongField(String fname) {
0292:                return getLongField(fname, null);
0293:            }
0294:
0295:            public void setIntField(FieldInfo fi, int value) {
0296:                //checkFieldInfo(fi); // in case somebody caches and uses the wrong
0297:                // FieldInfo
0298:                ElementInfo ei = getElementInfo(fi.getClassInfo()); // might not be 'this'
0299:                // in case of a static
0300:
0301:                if (!fi.isReference()) {
0302:                    ei.cloneFields().setIntValue(fi.getStorageOffset(), value);
0303:                } else {
0304:                    throw new JPFException("reference field: " + fi.getName());
0305:                }
0306:            }
0307:
0308:            public void setIntField(String fname, String clsBase, int value) {
0309:                setIntField(getFieldInfo(clsBase, fname), value);
0310:            }
0311:
0312:            public void setIntField(String fname, int value) {
0313:                setIntField(fname, null, value);
0314:            }
0315:
0316:            public void setLongField(String fname, long value) {
0317:                FieldInfo fi = getFieldInfo(fname);
0318:                ElementInfo ei = getElementInfo(fi.getClassInfo());
0319:                ei.cloneFields().setLongValue(fi.getStorageOffset(), value);
0320:            }
0321:
0322:            void updateReachability(int oldRef, int newRef) {
0323:                ThreadInfo ti = ThreadInfo.getCurrent(); // might be null if still in VM
0324:                // init
0325:                if ((ti == null) || ti.isInCtor() || !ti.usePor()) {
0326:                    return;
0327:                }
0328:
0329:                if (oldRef != newRef) {
0330:                    DynamicArea heap = DynamicArea.getHeap();
0331:                    ElementInfo oei, nei;
0332:
0333:                    if (isShared()) {
0334:                        if (oldRef != -1) {
0335:                            oei = heap.get(oldRef);
0336:                            if (!oei.isImmutable()) { // it's already shared, anyway
0337:                                // Ok, give up and do a full mark, the old object might not be
0338:                                // reachable anymore
0339:                                heap.analyzeHeap(false); // takes care of the newRef, too
0340:                                return;
0341:                            }
0342:                        }
0343:
0344:                        if (newRef != -1) {
0345:                            nei = heap.get(newRef);
0346:                            if (!nei.isShared() && !nei.isImmutable()) {
0347:                                // no need to walk the whole heap, just recursively promote nei
0348:                                // and all its reachables to 'shared'
0349:                                nei.setShared();
0350:                                heap.initGc(); // doesn't belong here, should be encapsulated in DA
0351:                                nei
0352:                                        .markRecursive(ti.getIndex(),
0353:                                                ATTR_PROP_MASK);
0354:                            }
0355:                        }
0356:                    } else { // we are not shared (oldRef can't change status)
0357:                        if (newRef != -1) {
0358:                            nei = heap.get(newRef);
0359:                            if (nei.isSchedulingRelevant()) { // shared and mutable
0360:                                // give up, nei might become non-shared
0361:                                heap.analyzeHeap(false);
0362:                            }
0363:                        }
0364:                    }
0365:                }
0366:
0367:                if (oldRef != -1) {
0368:                    JVM.getVM().getSystemState().activateGC(); // needs GC at the end of this
0369:                    // transition
0370:                }
0371:            }
0372:
0373:            public void setReferenceField(FieldInfo fi, int value) {
0374:                ElementInfo ei = getElementInfo(fi.getClassInfo()); // might not be 'this'
0375:                // in case of a static
0376:                Fields f = ei.cloneFields();
0377:                int off = fi.getStorageOffset();
0378:
0379:                if (fi.isReference()) {
0380:                    int oldValue = f.getReferenceValue(off);
0381:                    f.setReferenceValue(off, value);
0382:                    updateReachability(oldValue, value);
0383:                } else {
0384:                    throw new JPFException("not a reference field: "
0385:                            + fi.getName());
0386:                }
0387:            }
0388:
0389:            public void setReferenceField(String fname, String clsBase,
0390:                    int value) {
0391:                setReferenceField(getFieldInfo(clsBase, fname), value);
0392:            }
0393:
0394:            public void setReferenceField(String fname, int value) {
0395:                setReferenceField(fname, null, value);
0396:            }
0397:
0398:            public int getReferenceField(String fname, String clsBase) {
0399:                FieldInfo fi = getFieldInfo(clsBase, fname);
0400:                ElementInfo ei = getElementInfo(fi.getClassInfo());
0401:
0402:                if (!fi.isReference()) {
0403:                    throw new JPFException("not a reference field: "
0404:                            + fi.getName());
0405:                }
0406:                return ei.fields.getIntValue(fi.getStorageOffset());
0407:            }
0408:
0409:            public int getReferenceField(String fname) {
0410:                return getReferenceField(fname, null);
0411:            }
0412:
0413:            public int getIntField(String fname, String clsBase) {
0414:                // be aware of that static fields are not flattened (they are unique), i.e.
0415:                // the FieldInfo might actually refer to another ClassInfo/StaticElementInfo
0416:                FieldInfo fi = getFieldInfo(clsBase, fname);
0417:                ElementInfo ei = getElementInfo(fi.getClassInfo());
0418:                return ei.fields.getIntValue(fi.getStorageOffset());
0419:            }
0420:
0421:            public void setLongField(String fname, String clsBase, long value) {
0422:                FieldInfo fi = getFieldInfo(clsBase, fname);
0423:                ElementInfo ei = getElementInfo(fi.getClassInfo());
0424:                ei.cloneFields().setLongValue(fi.getStorageOffset(), value);
0425:            }
0426:
0427:            public long getLongField(String fname, String clsBase) {
0428:                FieldInfo fi = getFieldInfo(clsBase, fname);
0429:                ElementInfo ei = getElementInfo(fi.getClassInfo());
0430:                return ei.fields.getLongValue(fi.getStorageOffset());
0431:            }
0432:
0433:            public boolean getBooleanField(String fname, String refType) {
0434:                FieldInfo fi = getFieldInfo(refType, fname);
0435:                ElementInfo ei = getElementInfo(fi.getClassInfo());
0436:                return ei.fields.getBooleanValue(fi.getStorageOffset());
0437:            }
0438:
0439:            public byte getByteField(String fname, String refType) {
0440:                FieldInfo fi = getFieldInfo(refType, fname);
0441:                ElementInfo ei = getElementInfo(fi.getClassInfo());
0442:                return ei.fields.getByteValue(fi.getStorageOffset());
0443:            }
0444:
0445:            public char getCharField(String fname, String refType) {
0446:                FieldInfo fi = getFieldInfo(refType, fname);
0447:                ElementInfo ei = getElementInfo(fi.getClassInfo());
0448:                return ei.fields.getCharValue(fi.getStorageOffset());
0449:            }
0450:
0451:            public double getDoubleField(String fname, String refType) {
0452:                FieldInfo fi = getFieldInfo(refType, fname);
0453:                ElementInfo ei = getElementInfo(fi.getClassInfo());
0454:                return ei.fields.getDoubleValue(fi.getStorageOffset());
0455:            }
0456:
0457:            public float getFloatField(String fname, String refType) {
0458:                FieldInfo fi = getFieldInfo(refType, fname);
0459:                ElementInfo ei = getElementInfo(fi.getClassInfo());
0460:                return ei.fields.getFloatValue(fi.getStorageOffset());
0461:            }
0462:
0463:            public short getShortField(String fname, String refType) {
0464:                FieldInfo fi = getFieldInfo(refType, fname);
0465:                ElementInfo ei = getElementInfo(fi.getClassInfo());
0466:                return ei.fields.getShortValue(fi.getStorageOffset());
0467:            }
0468:
0469:            private void checkFieldInfo(FieldInfo fi) {
0470:                if (!getClassInfo().isInstanceOf(fi.getClassInfo())) {
0471:                    throw new JPFException("wrong FieldInfo : " + fi.getName()
0472:                            + " , no such field in " + getClassInfo().getName());
0473:                }
0474:            }
0475:
0476:            // those are the cached field value accessors. The caller is responsible
0477:            // for assuring type compatibility
0478:            public int getIntField(FieldInfo fi) {
0479:                checkFieldInfo(fi);
0480:                return fields.getIntValue(fi.getStorageOffset());
0481:            }
0482:
0483:            public long getLongField(FieldInfo fi) {
0484:                checkFieldInfo(fi);
0485:                return fields.getLongValue(fi.getStorageOffset());
0486:            }
0487:
0488:            public void setLongField(FieldInfo fi, long val) {
0489:                checkFieldInfo(fi);
0490:                cloneFields().setLongValue(fi.getStorageOffset(), val);
0491:            }
0492:
0493:            private void checkArray(int index) {
0494:                if (!isArray()) { // <2do> should check for !long array
0495:                    throw new JPFException(
0496:                            "cannot access non array objects by index");
0497:                }
0498:                if ((index < 0) || (index >= fields.size())) {
0499:                    throw new JPFException("illegal array offset: " + index);
0500:                }
0501:            }
0502:
0503:            private void checkLongArray(int index) {
0504:                if (!isArray()) { // <2do> should check for !int array
0505:                    throw new JPFException(
0506:                            "cannot access non array objects by index");
0507:                }
0508:                if ((index < 0) || (index >= (fields.size() - 1))) {
0509:                    throw new JPFException("illegal long array offset: "
0510:                            + index);
0511:                }
0512:            }
0513:
0514:            private boolean isReferenceArray() {
0515:                return getClassInfo().isReferenceArray();
0516:            }
0517:
0518:            // those are not really fields, so treat them differently!
0519:            public void setElement(int index, int value) {
0520:                checkArray(index);
0521:                if (isReferenceArray()) {
0522:                    cloneFields().setReferenceValue(index, value);
0523:                } else {
0524:                    cloneFields().setIntValue(index, value);
0525:                }
0526:            }
0527:
0528:            public void setLongElement(int index, long value) {
0529:                checkArray(index);
0530:                cloneFields().setLongValue(index * 2, value);
0531:            }
0532:
0533:            public int getElement(int index) {
0534:                checkArray(index);
0535:                return fields.getIntValue(index);
0536:            }
0537:
0538:            public long getLongElement(int index) {
0539:                checkArray(index);
0540:                return fields.getLongValue(index * 2);
0541:            }
0542:
0543:            public void setIndex(int newIndex) {
0544:                index = newIndex;
0545:            }
0546:
0547:            public int getIndex() {
0548:                return index;
0549:            }
0550:
0551:            public int getThisReference() {
0552:                return index;
0553:            }
0554:
0555:            public int getLockCount() {
0556:                return monitor.getLockCount();
0557:            }
0558:
0559:            public int getLockingThread() {
0560:                return monitor.getLockingThread();
0561:            }
0562:
0563:            public boolean isLocked() {
0564:                return (monitor.getLockCount() > 0);
0565:            }
0566:
0567:            public boolean isArray() {
0568:                return fields.isArray();
0569:            }
0570:
0571:            public String getArrayType() {
0572:                if (!fields.isArray()) {
0573:                    throw new JPFException("object is not an array");
0574:                }
0575:
0576:                return Types.getArrayElementType(fields.getType());
0577:            }
0578:
0579:            public Object getBacktrackData() {
0580:                return null;
0581:            }
0582:
0583:            public char getCharArrayElement(int index) {
0584:                return (char) getElement(index);
0585:            }
0586:
0587:            public int getIntArrayElement(int findex) {
0588:                return getElement(findex);
0589:            }
0590:
0591:            public long getLongArrayElement(int findex) {
0592:                return getLongElement(findex);
0593:            }
0594:
0595:            public boolean[] asBooleanArray() {
0596:                return fields.asBooleanArray();
0597:            }
0598:
0599:            public byte[] asByteArray() {
0600:                return fields.asByteArray();
0601:            }
0602:
0603:            public short[] asShortArray() {
0604:                return fields.asShortArray();
0605:            }
0606:
0607:            public char[] asCharArray() {
0608:                return fields.asCharArray();
0609:            }
0610:
0611:            public int[] asIntArray() {
0612:                return fields.asIntArray();
0613:            }
0614:
0615:            public long[] asLongArray() {
0616:                return fields.asLongArray();
0617:            }
0618:
0619:            public float[] asFloatArray() {
0620:                return fields.asFloatArray();
0621:            }
0622:
0623:            public double[] asDoubleArray() {
0624:                return fields.asDoubleArray();
0625:            }
0626:
0627:            public boolean isNull() {
0628:                return (index == -1);
0629:            }
0630:
0631:            public Reference getObjectField(String fname, String referenceType) {
0632:                return area.ks.da.get(getIntField(fname, referenceType));
0633:            }
0634:
0635:            // <2do> just here for the Storable interface - it's NOT the one that is
0636:            // used for heavy duty state storage, because we want to avoid all the
0637:            // small array allocations. Change the Storable interface at some point!
0638:            public int[] getStoringData() {
0639:                int[] data = new int[3];
0640:
0641:                data[0] = getFieldsIndex();
0642:                data[1] = getMonitorIndex();
0643:                data[2] = attributes;
0644:
0645:                return data;
0646:            }
0647:
0648:            /**
0649:             * <2do>pcm - these two will become the new Storable interface (but that has
0650:             * a huge fan out)
0651:             */
0652:            public int getStoringDataLength() {
0653:                return 3;
0654:            }
0655:
0656:            /**
0657:             * answer an estimate of the heap size in bytes (this is of course VM
0658:             * dependent, but we can give an upper bound for the fields/elements, and that
0659:             * should be good in terms of application specific properties)
0660:             */
0661:            public int getHeapSize() {
0662:                return fields.getHeapSize();
0663:            }
0664:
0665:            public String getStringField(String fname, String referenceType) {
0666:                int ref = getIntField(fname, referenceType);
0667:
0668:                if (ref != -1) {
0669:                    ElementInfo ei = area.ks.da.get(ref);
0670:                    if (ei == null) {
0671:                        System.out
0672:                                .println("OUTCH: " + ref + ", this: " + index);
0673:                    }
0674:                    return ei.asString();
0675:                } else {
0676:                    return "null";
0677:                }
0678:            }
0679:
0680:            public String getType() {
0681:                return fields.getType();
0682:            }
0683:
0684:            public int[] getWaitingThreads() {
0685:                return monitor.getWaitingThreads();
0686:            }
0687:
0688:            public int arrayLength() {
0689:                return fields.arrayLength();
0690:            }
0691:
0692:            public String asString() {
0693:                if (!fields.getClassInfo().instanceOf("java.lang.String")) {
0694:                    throw new JPFException(
0695:                            "object is not of type java.lang.String");
0696:                }
0697:
0698:                int value = getIntField("value", "java.lang.String");
0699:                int length = getIntField("count", "java.lang.String");
0700:                int offset = getIntField("offset", "java.lang.String");
0701:
0702:                ElementInfo e = area.get(value);
0703:
0704:                StringBuffer sb = new StringBuffer();
0705:
0706:                for (int i = offset; i < (offset + length); i++) {
0707:                    sb.append((char) e.fields.getIntValue(i));
0708:                }
0709:
0710:                return sb.toString();
0711:            }
0712:
0713:            void updateLockingInfo() {
0714:                int tid = monitor.getLockingThread();
0715:                if (tid != -1) {
0716:                    // here we can update ThreadInfo lock object info (so that we don't
0717:                    // have to store it separately)
0718:                    // NOTE - the threads need to be restored *before* the Areas, or this is
0719:                    // going to choke
0720:                    ThreadInfo ti = area.ks.tl.get(tid);
0721:                    // note that we add only once, i.e. rely on the monitor lockCount to
0722:                    // determine when to remove an object from our lock set
0723:                    ti.addLockedObject(this );
0724:                }
0725:            }
0726:
0727:            public void backtrackTo(ArrayOffset storing, Object backtrack) {
0728:                setFieldsIndex(storing.get());
0729:                setMonitorIndex(storing.get());
0730:
0731:                attributes = storing.get();
0732:
0733:                updateLockingInfo();
0734:            }
0735:
0736:            public boolean canLock(ThreadInfo th) {
0737:                return monitor.canLock(th);
0738:            }
0739:
0740:            public void checkArrayBounds(int index)
0741:                    throws ArrayIndexOutOfBoundsExecutiveException {
0742:                if (outOfBounds(index)) {
0743:                    throw new ArrayIndexOutOfBoundsExecutiveException(
0744:                            area.ks.ss
0745:                                    .getRunningThread()
0746:                                    .createAndThrowException(
0747:                                            "java.lang.ArrayIndexOutOfBoundsException"));
0748:                }
0749:            }
0750:
0751:            public void checkLongArrayBounds(int index)
0752:                    throws ArrayIndexOutOfBoundsExecutiveException {
0753:                checkArrayBounds(index);
0754:                checkArrayBounds(index + 1);
0755:            }
0756:
0757:            public Object clone() {
0758:                try {
0759:                    ElementInfo ei = (ElementInfo) super .clone();
0760:
0761:                    if (ei.fIndex == -1) {
0762:                        ei.fields = (Fields) fields.clone();
0763:                    }
0764:
0765:                    if (ei.mIndex == -1) {
0766:                        ei.monitor = (Monitor) monitor.clone();
0767:                    }
0768:
0769:                    area = null;
0770:                    index = -1;
0771:
0772:                    return ei;
0773:                } catch (CloneNotSupportedException e) {
0774:                    e.printStackTrace();
0775:                    throw new InternalError("should not happen");
0776:                }
0777:            }
0778:
0779:            public void hash(HashData hd) {
0780:                fields.hash(hd);
0781:                monitor.hash(hd);
0782:            }
0783:
0784:            public int hashCode() {
0785:                HashData hd = new HashData();
0786:
0787:                hash(hd);
0788:
0789:                return hd.getValue();
0790:            }
0791:
0792:            public boolean instanceOf(String type) {
0793:                return Types.instanceOf(fields.getType(), type);
0794:            }
0795:
0796:            public void interrupt() {
0797:                area.ks.tl.locate(index).interrupt();
0798:            }
0799:
0800:            public void lock(ThreadInfo th) {
0801:                cloneMonitor().lock(th, getRef());
0802:
0803:                // don't re-add if we are recursive - the lock count is avaliable in
0804:                // the monitor
0805:                if (monitor.getLockCount() == 1) {
0806:                    th.addLockedObject(this );
0807:                }
0808:            }
0809:
0810:            public void lockNotified(ThreadInfo th) {
0811:                cloneMonitor().lockNotified(th, getRef());
0812:
0813:                // pcm - this is important, if we later-on backtrack (reset the
0814:                // ThreadInfo.lockedObjects set, and then restore from the saved heap), the
0815:                // lock set would not include the lock when we continue to execute this
0816:                // thread
0817:                th.addLockedObject(this ); //wv: add locked object back here
0818:            }
0819:
0820:            abstract public int getNumberOfFields();
0821:
0822:            abstract public FieldInfo getFieldInfo(int i);
0823:
0824:            public void log() {
0825:                if (fIndex == -1) {
0826:                    Debug.println(Debug.MESSAGE, "(fields have changed)");
0827:                }
0828:
0829:                ClassInfo ci = getClassInfo();
0830:                int n = getNumberOfFields();
0831:                for (int i = 0; i < n; i++) {
0832:                    FieldInfo fi = getFieldInfo(i);
0833:                    Debug.println(Debug.MESSAGE, fi.getName() + ": "
0834:                            + fi.valueToString(fields));
0835:                }
0836:
0837:                if (mIndex == -1) {
0838:                    Debug.println(Debug.MESSAGE, "(monitor has changed)");
0839:                }
0840:
0841:                monitor.log();
0842:            }
0843:
0844:            public void notifies() {
0845:                cloneMonitor().notify(area.ks.ss);
0846:            }
0847:
0848:            public void notifiesAll() {
0849:                cloneMonitor().notifyAll(area.ks.ss);
0850:            }
0851:
0852:            public boolean outOfBounds(int index) {
0853:                if (!fields.isArray()) {
0854:                    throw new JPFException("object is not an array");
0855:                }
0856:
0857:                return (index < 0 || index >= fields.size());
0858:            }
0859:
0860:            /**
0861:             * imperatively set GC status
0862:             * 
0863:             * @param keepAlive -
0864:             *          true: keep alive no matter what, false: gc normally
0865:             */
0866:            public void pinDown(boolean keepAlive) {
0867:                if (keepAlive) {
0868:                    attributes |= ATTR_PINDOWN;
0869:                } else {
0870:                    attributes &= ~ATTR_PINDOWN;
0871:                }
0872:            }
0873:
0874:            /**
0875:             * this is the heavy duty state storer for ElementInfos
0876:             */
0877:            public int storeDataTo(int[] buffer, int idx) {
0878:                buffer[idx++] = getFieldsIndex();
0879:                buffer[idx++] = getMonitorIndex();
0880:                buffer[idx] = attributes;
0881:
0882:                return 3;
0883:            }
0884:
0885:            public void unlock(ThreadInfo th) {
0886:                cloneMonitor().unlock(th, getRef());
0887:
0888:                if (monitor.getLockCount() == 0) {
0889:                    th.removeLockedObject(this );
0890:                }
0891:            }
0892:
0893:            public void wait(ThreadInfo th) {
0894:                cloneMonitor().wait(th, getRef());
0895:                th.removeLockedObject(this ); //wv: remove locked object here
0896:            }
0897:
0898:            protected void setFieldsIndex(int index) {
0899:                if (fIndex == index) {
0900:                    return;
0901:                }
0902:
0903:                fIndex = index;
0904:                fields = (Fields) fieldsPool.getObject(index);
0905:            }
0906:
0907:            protected int getFieldsIndex() {
0908:                if (fIndex != -1) {
0909:                    return fIndex;
0910:                }
0911:
0912:                HashPool.PoolEntry e = fieldsPool.getEntry(fields);
0913:                fields = (Fields) e.getObject();
0914:
0915:                return fIndex = e.getIndex();
0916:            }
0917:
0918:            protected void setMonitorIndex(int index) {
0919:                if (mIndex == index) {
0920:                    return;
0921:                }
0922:
0923:                mIndex = index;
0924:                monitor = (Monitor) monitorPool.getObject(index);
0925:            }
0926:
0927:            protected int getMonitorIndex() {
0928:                if (mIndex != -1) {
0929:                    return mIndex;
0930:                }
0931:
0932:                HashPool.PoolEntry e = monitorPool.getEntry(monitor);
0933:                monitor = (Monitor) e.getObject();
0934:
0935:                return mIndex = e.getIndex();
0936:            }
0937:
0938:            /**
0939:             * The various lock methods need access to a Ref object to do their work. The
0940:             * subclass should return an appropriate type. This is a simple factory
0941:             * method.
0942:             * 
0943:             * @return the right kind of Ref object for the given ElementInfo
0944:             */
0945:            protected abstract Ref getRef();
0946:
0947:            protected Fields cloneFields() {
0948:                if (fIndex == -1) {
0949:                    return fields;
0950:                }
0951:
0952:                fIndex = -1;
0953:                area.ks.data = null;
0954:                area.hasChanged.set(index);
0955:                area.anyChanged = true;
0956:
0957:                return fields = (Fields) fields.clone();
0958:            }
0959:
0960:            protected Monitor cloneMonitor() {
0961:                if (mIndex == -1) {
0962:                    return monitor;
0963:                }
0964:
0965:                mIndex = -1;
0966:                area.ks.data = null;
0967:                area.hasChanged.set(index);
0968:                area.anyChanged = true;
0969:
0970:                monitor = (Monitor) monitor.clone();
0971:
0972:                return monitor;
0973:            }
0974:
0975:            boolean isLockedBy(ThreadInfo ti) {
0976:                return ((monitor != null) && (monitor.getLockingThread() == ti.index));
0977:            }
0978:
0979:            void _printAttributes(String cls, String msg, int oldAttrs) {
0980:                if (getClassInfo().getName().equals(cls)) {
0981:                    System.out.println(msg + " " + this  + " attributes: "
0982:                            + Integer.toHexString(attributes) + " was: "
0983:                            + Integer.toHexString(oldAttrs));
0984:                }
0985:            }
0986:
0987:            /*
0988:             * The following code is used to linearize a rooted structure in the heap
0989:             */
0990:
0991:            public Vector linearize(Vector result) {
0992:                DynamicArea heap = DynamicArea.getHeap();
0993:                int i, n;
0994:
0995:                if (isArray()) {
0996:                    if (fields.isReferenceArray()) {
0997:                        n = fields.arrayLength();
0998:                        for (i = 0; i < n; i++) {
0999:                            result = heap.linearize(fields.getIntValue(i),
1000:                                    result);
1001:                        }
1002:                    }
1003:                } else {
1004:                    ClassInfo ci = getClassInfo();
1005:                    do {
1006:                        n = ci.getNumberOfDeclaredInstanceFields();
1007:                        for (i = 0; i < n; i++) {
1008:                            FieldInfo fi = ci.getDeclaredInstanceField(i);
1009:                            if (fi.isReference()) {
1010:                                if ((i == 0) && ci.isWeakReference()) {
1011:                                    // we need to reset the ref field once the referenced object goes away
1012:                                    // NOTE: only the *first* WeakReference field is a weak ref
1013:                                    // (this is why we have our own implementation)
1014:
1015:                                    //dont' know what to do here?
1016:                                    return result;
1017:
1018:                                } else {
1019:                                    // the refAttrs are not immediately masked because we have to preserve
1020:                                    // the mask values up to the point where we would promote a otherwise
1021:                                    // unshared root object due to a different thread id (in case we didn't
1022:                                    // catch a mask on the way that prevents this)
1023:                                    result = heap.linearize(fields
1024:                                            .getReferenceValue(fi
1025:                                                    .getStorageOffset()),
1026:                                            result);
1027:                                }
1028:                            }
1029:                        }
1030:                        ci = ci.getSuperClass();
1031:                    } while (ci != null);
1032:                }
1033:                return result;
1034:            }
1035:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.