Search in sources :

Example 1 with LongEnumeration

use of com.ibm.dtfj.phd.util.LongEnumeration in project openj9 by eclipse.

the class PHDJavaRuntime method findLoaders.

/**
 * Helper method to try to allocate classes to the correct class loader
 * There isn't an explicit mention of the loader, but an outbound reference might be to the loader.
 * First find all the objects which are class loaders.
 * The look at each file, see if it has a reference to a loader object and if so allocate it to
 * that loader.
 * @param file
 * @throws IOException
 */
private void findLoaders(HeapdumpReader newreader) throws IOException {
    // Where all the classes orginally have been put
    final PHDJavaClassLoader boot = loaders.get(null);
    // Might fail to find a class with a very corrupt dump
    final JavaClass jlc = findClass("java/lang/Class");
    final long jlcAddress = jlc == null || jlc.getID() == null ? 0 : jlc.getID().getAddress();
    // Find all the class loader classes
    final JavaClass jcl = findClass("java/lang/ClassLoader");
    final HashMap<Long, JavaClass> classLoaderClasses = new HashMap<Long, JavaClass>();
    for (Iterator<JavaClass> it = boot.getDefinedClasses(); it.hasNext(); ) {
        JavaClass cls = it.next();
        if (cls instanceof CorruptData)
            continue;
        try {
            // Avoid bug with superclass loops by remembering superclasses
            // PHD Version 4 bug - bad superclass: J2RE 5.0 IBM J9 2.3 AIX ppc64-64 build 20080314_17962_BHdSMr
            HashSet<JavaClass> supers = new HashSet<JavaClass>();
            for (JavaClass j1 = cls; j1 != null && supers.add(j1); j1 = j1.getSuperclass()) {
                /* 
					 * See if either a superclass is java.lang.ClassLoader
					 * or if no superclass information is available (old Java 5)
					 * whether the name ends with "ClassLoader"
					 */
                if (j1.equals(jcl) || cls.getSuperclass() == null && !j1.isArray() && j1.getName().endsWith("ClassLoader")) {
                    ImagePointer ip = cls.getID();
                    if (ip != null) {
                        classLoaderClasses.put(ip.getAddress(), cls);
                    }
                }
            }
        } catch (CorruptDataException e) {
        // Ignore
        }
    }
    // Number of class objects not found at class addresses
    final int[] onHeapClasses = new int[1];
    // Find all the objects which are class loaders
    final PHDJavaHeap heap = heaps.get(0);
    final HashMap<Long, JavaObject> classObjects = new HashMap<Long, JavaObject>();
    // HeapdumpReader newreader = new HeapdumpReader(file, parentImage);
    final int adjustLen = newreader.version() == 4 && newreader.isJ9() ? 1 : 0;
    try {
        newreader.parse(new PortableHeapDumpListener() {

            public void classDump(long address, long superAddress, String name, int size, int flags, int hashCode, LongEnumeration refs) throws Exception {
            }

            public void objectArrayDump(long address, long classAddress, int flags, int hashCode, LongEnumeration refs, int length, long instanceSize) throws Exception {
                if (extraObjectsCache.containsKey(address)) {
                    // Don't bother saving reference information - we can get it later
                    JavaObject jo = new PHDJavaObject.Builder(heap, address, arrayOf(classAddress, refs, adjustLen), flags, hashCode).length(length - adjustLen).instanceSize(instanceSize).build();
                    extraObjectsCache.put(address, jo);
                }
            }

            public void objectDump(long address, long classAddress, int flags, int hashCode, LongEnumeration refs, long instanceSize) throws Exception {
                JavaClass cls = classLoaderClasses.get(classAddress);
                JavaObject jo;
                if (cls != null) {
                    // Object of type java.lang.ClassLoader, so create the object and the class loader
                    jo = new PHDJavaObject.Builder(heap, address, cls, flags, hashCode).refs(refs, 0).length(PHDJavaObject.SIMPLE_OBJECT).instanceSize(instanceSize).build();
                    PHDJavaClassLoader load = new PHDJavaClassLoader(jo);
                    loaders.put(jo, load);
                } else if (classAddress == jlcAddress) {
                    if (boot.findClass(address) == null) {
                        ++onHeapClasses[0];
                    }
                    jo = new PHDJavaObject.Builder(heap, address, jlc, flags, hashCode).refs(refs, 0).length(PHDJavaObject.SIMPLE_OBJECT).instanceSize(instanceSize).build();
                    classObjects.put(address, jo);
                } else {
                    jo = null;
                }
                if (extraObjectsCache.containsKey(address)) {
                    if (jo == null) {
                        jo = new PHDJavaObject.Builder(heap, address, findClass(classAddress), flags, hashCode).refs(refs, 0).length(PHDJavaObject.SIMPLE_OBJECT).build();
                    }
                    extraObjectsCache.put(address, jo);
                }
            }

            public void primitiveArrayDump(long address, int type, int length, int flags, int hashCode, long instanceSize) throws Exception {
                if (extraObjectsCache.containsKey(address)) {
                    // Create a full object as we have the data
                    JavaObject jo = new PHDJavaObject.Builder(heap, address, findArrayOfType(type), flags, hashCode).refsAsArray(NOREFS, 0).length(length).instanceSize(instanceSize).build();
                    extraObjectsCache.put(address, jo);
                }
            }
        });
    } catch (Exception e) {
    // Ignore the exception - we will have seen it elsewhere
    // e.printStackTrace();
    } finally {
        newreader.close();
        newreader = null;
    }
    // Assign classes to the correct loaders
    // Also try to set up on/off-heap class addresses
    PHDJavaClassLoader boot2 = null;
    int foundLoader = 0;
    int notFoundLoader = 0;
    // How many java/lang classes the possible boot loader has loaded
    int loaderJavaLangCount = 0;
    boolean useFirstObjectRefAsLoader = onHeapClasses[0] == 0;
    for (Iterator<JavaClass> it = boot.getDefinedClasses(); it.hasNext(); ) {
        JavaClass j1 = it.next();
        PHDJavaClassLoader bestLoader = null;
        for (Iterator<JavaReference> it2 = j1.getReferences(); it2.hasNext(); ) {
            JavaReference jr = it2.next();
            try {
                // Is the first outbound object reference to a class loader?
                if (jr.isObjectReference()) {
                    JavaObject jo = (JavaObject) jr.getTarget();
                    PHDJavaClassLoader newLoader = loaders.get(jo);
                    if (newLoader != null) {
                        if (bestLoader == null || !useFirstObjectRefAsLoader) {
                            bestLoader = newLoader;
                        }
                    } else if (onHeapClasses[0] > 0) {
                        long addr = jo.getID().getAddress();
                        JavaObject jo2 = classObjects.get(addr);
                        if (jo2 != null) {
                            // For Java 6 jdmpview PHD files the on-heap class object is the last ref
                            // retrieve the full JavaObject from walking the heap earlier
                            ((PHDJavaClass) j1).setJavaObject(jo2);
                        }
                    }
                    // unless using off-heap classes when it is the last reference.
                    if (!j1.isArray() && useFirstObjectRefAsLoader && onHeapClasses[0] == 0)
                        break;
                }
            } catch (CorruptDataException e) {
            // e.printStackTrace();
            } catch (DataUnavailable e) {
            // e.printStackTrace();
            }
        }
        if (bestLoader != null) {
            ++foundLoader;
            // Don't remove the classes from the original loader, nor change the loader
            // as otherwise finding the array type fails
            bestLoader.prepareToMove(boot, j1);
            // Is the class by any chance the type of the class loader?
            try {
                if (boot2 == null && (j1.equals(jlc) || j1.equals(bestLoader.getObject().getJavaClass()))) {
                    // We have found the new bootstrap class loader
                    // Beware java 1.4.2 com/ibm/rmi/util/ClassInfo$NULL_CL_CLASS passes this test!
                    boot2 = bestLoader;
                }
                if (boot2 == bestLoader && j1.getName().startsWith("java/lang/"))
                    ++loaderJavaLangCount;
            } catch (CorruptDataException e) {
            }
        } else {
            ++notFoundLoader;
        }
        // Try retrieving the full JavaObject for the JavaClass
        try {
            JavaObject jo = j1.getObject();
            if (jo != null) {
                long addr = jo.getID().getAddress();
                JavaObject jo2 = classObjects.get(addr);
                if (jo2 != null) {
                    ((PHDJavaClass) j1).setJavaObject(jo2);
                }
            }
        } catch (CorruptDataException e) {
        }
    }
    // Ignore a bootstrap loader which hasn't loaded 5 java/lang classes
    if (loaderJavaLangCount < 5)
        boot2 = null;
    // Haven't found any loaders, but have a javacore file with loader information
    if (metaJavaRuntime != null) {
        for (Iterator i = metaJavaRuntime.getJavaClassLoaders(); i.hasNext(); ) {
            Object next = i.next();
            if (next instanceof CorruptData)
                continue;
            JavaClassLoader jcl2 = (JavaClassLoader) next;
            try {
                JavaObject lo = jcl2.getObject();
                if (lo != null) {
                    ImagePointer addr = lo.getID();
                    if (addr != null) {
                        ImagePointer ip = space.getPointer(addr.getAddress());
                        JavaObject jo = getObjectAtAddress(ip);
                        PHDJavaClassLoader newLoader = loaders.get(jo);
                        JavaClass loaderClass;
                        if (newLoader == null) {
                            try {
                                // Should be safe to find the class of 'jo' without rereading the PHD file
                                // as at least a dummy object should be in the extra objects cache.
                                // It could be that the object is still a dummy one with no proper class.
                                loaderClass = jo.getJavaClass();
                            } catch (CorruptDataException e) {
                                loaderClass = null;
                            }
                            JavaClass javacoreLoaderClass;
                            try {
                                javacoreLoaderClass = lo.getJavaClass();
                            } catch (CorruptDataException e) {
                                javacoreLoaderClass = null;
                            }
                            // Mismatch occurs with J2RE 5.0 IBM J9 2.3 Linux amd64-64 build j9vmxa6423-20091104
                            if (loaderClass != null && javacoreLoaderClass != null && (loaderClass.isArray() || loaderClass.getID() != null && javacoreLoaderClass.getID() != null && loaderClass.getID().getAddress() != javacoreLoaderClass.getID().getAddress())) {
                            // System.out.println("Skipping loader "+newLoader+" "+jo+" "+jo.getJavaClass()+" "+lo+" "+lo.getJavaClass()+" "+Long.toHexString(addr.getAddress())+" "+ip);
                            } else {
                                // The object should have been listed in the extra objects, so may now be the proper object
                                newLoader = new PHDJavaClassLoader(jo);
                                loaders.put(jo, newLoader);
                            }
                        } else {
                            // Replace with the offical object
                            jo = newLoader.getObject();
                            loaderClass = jo.getJavaClass();
                        }
                        if (newLoader != null) {
                            for (Iterator i2 = jcl2.getDefinedClasses(); i2.hasNext(); ) {
                                Object next2 = i2.next();
                                if (next2 instanceof CorruptData)
                                    continue;
                                JavaClass jc2 = (JavaClass) next2;
                                ImagePointer ip2 = jc2.getID();
                                JavaClass j1;
                                if (ip2 != null) {
                                    long claddr = ip2.getAddress();
                                    j1 = boot.findClass(claddr);
                                    // Not found by address, so try by name.
                                    if (j1 == null) {
                                        // But only if it is the only class of that name
                                        j1 = boot.findClassUnique(jc2.getName());
                                    } else {
                                        // Found by address
                                        try {
                                            j1.getName();
                                        } catch (CorruptDataException e) {
                                            // Our class doesn't have a name, so perhaps the javacore has the name
                                            try {
                                                String actualName = jc2.getName();
                                                PHDJavaClass pj1 = (PHDJavaClass) j1;
                                                // We will need to reindex the classloader as the name as changed
                                                pj1.setName(actualName);
                                            } catch (CorruptDataException e2) {
                                            }
                                        }
                                    }
                                } else {
                                    // But only if it is the only class of that name
                                    j1 = boot.findClassUnique(jc2.getName());
                                }
                                if (j1 != null) {
                                    newLoader.prepareToMove(boot, j1);
                                    // listed in javacore causes problems as byte etc. aren't listed
                                    if (j1.equals(loaderClass) || j1.equals(jlc)) {
                                        // We have found the new bootstrap class loader
                                        boot2 = newLoader;
                                    }
                                    for (Iterator i3 = jc2.getDeclaredMethods(); i3.hasNext(); ) {
                                        Object next3 = i3.next();
                                        if (next3 instanceof CorruptData)
                                            continue;
                                        JavaMethod jm = (JavaMethod) next3;
                                        PHDJavaClass pj1 = (PHDJavaClass) j1;
                                        pj1.addMethod(new PHDJavaMethod(space, pj1, jm));
                                    }
                                }
                            }
                        }
                    }
                }
            } catch (CorruptDataException e) {
            } catch (DataUnavailable e) {
            } catch (MemoryAccessException e) {
            }
        }
    }
    // Move the classes to the correct class loaders
    for (Iterator<JavaClass> it = boot.getDefinedClasses(); it.hasNext(); ) {
        JavaClass j1 = it.next();
        try {
            JavaClassLoader jcl2 = j1.getClassLoader();
            if (!boot.equals(jcl2) && jcl2 instanceof PHDJavaClassLoader) {
                transferClass(boot, (PHDJavaClassLoader) jcl2, j1);
            }
        } catch (CorruptDataException e) {
        }
    }
    // Reindex the loaders to account for the removed classes
    for (PHDJavaClassLoader loader : loaders.values()) {
        loader.initCache();
    }
    if (boot2 != null) {
        // Move remaining classes to new boot loader
        for (Iterator<JavaClass> it = boot.getDefinedClasses(); it.hasNext(); ) {
            JavaClass j1 = it.next();
            boot2.prepareToMove(boot, j1);
            transferClass(boot, boot2, j1);
        }
        // index the new boot loader to account for the added files
        boot2.initCache();
        // Remove the original boot class loader as it has no classes
        loaders.remove(null);
    } else {
        // There may be duplicate array classes in the boot loader
        for (Iterator<JavaClass> it = boot.getDefinedClasses(); it.hasNext(); ) {
            JavaClass j1 = it.next();
            JavaClass j2 = boot.setArrayType(this, boot, j1);
        }
        // index the boot loader to account for the added files
        boot.initCache();
    }
}
Also used : PortableHeapDumpListener(com.ibm.dtfj.phd.parser.PortableHeapDumpListener) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) CorruptDataException(com.ibm.dtfj.image.CorruptDataException) ImagePointer(com.ibm.dtfj.image.ImagePointer) JavaReference(com.ibm.dtfj.java.JavaReference) LongEnumeration(com.ibm.dtfj.phd.util.LongEnumeration) Iterator(java.util.Iterator) DataUnavailable(com.ibm.dtfj.image.DataUnavailable) JavaMethod(com.ibm.dtfj.java.JavaMethod) MemoryAccessException(com.ibm.dtfj.image.MemoryAccessException) HashSet(java.util.HashSet) MemoryAccessException(com.ibm.dtfj.image.MemoryAccessException) IOException(java.io.IOException) CorruptDataException(com.ibm.dtfj.image.CorruptDataException) JavaClass(com.ibm.dtfj.java.JavaClass) JavaObject(com.ibm.dtfj.java.JavaObject) JavaClassLoader(com.ibm.dtfj.java.JavaClassLoader) CorruptData(com.ibm.dtfj.image.CorruptData) JavaObject(com.ibm.dtfj.java.JavaObject)

Example 2 with LongEnumeration

use of com.ibm.dtfj.phd.util.LongEnumeration in project openj9 by eclipse.

the class PHDJavaHeap method getObjects.

/**
 * Return all the objects in the heap
 * This uses a modified version of the HeapdumpReader which allows abort and resume.
 */
public Iterator<JavaObject> getObjects() {
    final PHDJavaHeap heap = this;
    try {
        return new Iterator<JavaObject>() {

            HeapdumpReader reader = null;

            {
                if (stream == null) {
                    reader = new HeapdumpReader(file, image);
                } else {
                    reader = new HeapdumpReader(stream, image);
                }
            }

            final int adjustLen = reader.version() == 4 && reader.isJ9() ? 1 : 0;

            final long[] current = new long[1];

            static final boolean withRefs = true;

            JavaObject jo;

            int count = 0;

            PortableHeapDumpListener listen = new PortableHeapDumpListener() {

                public void classDump(long address, long superAddress, String name, int size, int flags, int hashCode, LongEnumeration refs) throws Exception {
                }

                public void objectArrayDump(long address, long classAddress, int flags, int hashCode, LongEnumeration refs, int length, long instanceSize) throws Exception {
                    current[0] = address;
                    int refsLen = refs.numberOfElements();
                    int adjustLen2 = Math.min(adjustLen, refsLen);
                    // Use adjustLen for array class so for corrupt Java 5 with 0 refs we have no array class
                    PHDJavaObject.Builder b = new PHDJavaObject.Builder(heap, address, runtime.arrayOf(classAddress, refs, adjustLen), flags, hashCode).instanceSize(instanceSize);
                    jo = withRefs ? b.refs(refs, adjustLen2).length(length - adjustLen2).build() : b.length(length - adjustLen2).build();
                    current[0] = 0;
                    reader.exitParse();
                }

                public void objectDump(long address, long classAddress, int flags, int hashCode, LongEnumeration refs, long instanceSize) throws Exception {
                    current[0] = address;
                    PHDJavaObject.Builder b = new PHDJavaObject.Builder(heap, address, runtime.findClass(classAddress), flags, hashCode).length(PHDJavaObject.SIMPLE_OBJECT).instanceSize(instanceSize);
                    jo = withRefs ? b.refs(refs, 0).build() : b.build();
                    current[0] = 0;
                    reader.exitParse();
                }

                public void primitiveArrayDump(long address, int type, int length, int flags, int hashCode, long instanceSize) throws Exception {
                    current[0] = address;
                    jo = new PHDJavaObject.Builder(heap, address, runtime.findArrayOfType(type), flags, hashCode).refsAsArray(NOREFS, 0).length(length).instanceSize(instanceSize).build();
                    current[0] = 0;
                    reader.exitParse();
                }
            };

            public boolean hasNext() {
                if (jo == null)
                    getNext();
                return jo != null;
            }

            public JavaObject next() {
                if (!hasNext())
                    throw new NoSuchElementException();
                JavaObject ret = jo;
                jo = null;
                ++count;
                return ret;
            }

            private void getNext() {
                try {
                    // but presumes the reader can restart parsing where it left off.
                    if (reader != null && !reader.parse(listen)) {
                        reader.close();
                        reader = null;
                    }
                } catch (EOFException e) {
                    jo = new PHDCorruptJavaObject("Truncated dump found while building object " + count + "/" + reader.totalObjects(), space.getPointer(0), e);
                    reader.close();
                    reader = null;
                } catch (IOException e) {
                    jo = new PHDCorruptJavaObject("Corrupted dump found while building object " + count + "/" + reader.totalObjects(), space.getPointer(0), e);
                    reader.close();
                    reader = null;
                } catch (Exception e) {
                    // Is this right?
                    if (current[0] != 0) {
                        // Only add an exception object the first time it happens
                        // Give up if exception occurs between objects
                        jo = new PHDCorruptJavaObject("Building object " + count + "/" + reader.totalObjects(), space.getPointer(current[0]), e);
                    } else {
                        jo = new PHDCorruptJavaObject("Building object " + count + "/" + reader.totalObjects(), space.getPointer(0), e);
                        reader.close();
                        reader = null;
                    }
                }
            }

            public void remove() {
                throw new UnsupportedOperationException();
            }

            protected void finalize() throws Throwable {
                // but the client doesn't have to run the iterator to the end, so we're accounting for that here
                if (reader != null) {
                    reader.close();
                }
            }
        };
    } catch (IOException e) {
        return new ArrayList<JavaObject>().iterator();
    }
}
Also used : PortableHeapDumpListener(com.ibm.dtfj.phd.parser.PortableHeapDumpListener) HeapdumpReader(com.ibm.dtfj.phd.parser.HeapdumpReader) ArrayList(java.util.ArrayList) IOException(java.io.IOException) IOException(java.io.IOException) EOFException(java.io.EOFException) CorruptDataException(com.ibm.dtfj.image.CorruptDataException) NoSuchElementException(java.util.NoSuchElementException) LongEnumeration(com.ibm.dtfj.phd.util.LongEnumeration) JavaObject(com.ibm.dtfj.java.JavaObject) Iterator(java.util.Iterator) EOFException(java.io.EOFException) NoSuchElementException(java.util.NoSuchElementException)

Example 3 with LongEnumeration

use of com.ibm.dtfj.phd.util.LongEnumeration in project openj9 by eclipse.

the class PHDJavaClass method getReferences.

public Iterator<JavaReference> getReferences() {
    final JavaClass source = this;
    return new Iterator<JavaReference>() {

        int count;

        JavaClass sup;

        JavaObject load;

        {
            try {
                sup = getSuperclass();
                if (sup != null)
                    count = -1;
            } catch (CorruptDataException e) {
            }
            try {
                load = loader.getObject();
                if (load != null)
                    count = -2;
            } catch (CorruptDataException e) {
            }
        }

        public boolean hasNext() {
            if (count < 0) {
                return true;
            } else if (refs instanceof LongEnumeration) {
                LongEnumeration le = (LongEnumeration) refs;
                return le.hasMoreElements();
            } else if (refs instanceof long[]) {
                long[] arefs = (long[]) refs;
                return count < arefs.length;
            } else if (refs instanceof int[]) {
                int[] arefs = (int[]) refs;
                return count < arefs.length;
            } else {
                return false;
            }
        }

        public JavaReference next() {
            if (!hasNext())
                throw new NoSuchElementException("" + count++);
            long ref;
            int refType = PHDJavaReference.REFERENCE_UNKNOWN;
            Object cls = null;
            if (count == -2) {
                cls = load;
                ++count;
                // Skip over the superclass if not present
                if (sup == null)
                    ++count;
                ref = 0;
                refType = PHDJavaReference.REFERENCE_CLASS_LOADER;
            } else if (count == -1) {
                cls = sup;
                ++count;
                ref = 0;
                refType = PHDJavaReference.REFERENCE_SUPERCLASS;
            } else {
                if (refs instanceof LongEnumeration) {
                    LongEnumeration le = (LongEnumeration) refs;
                    ref = le.nextLong();
                    ++count;
                } else if (refs instanceof int[]) {
                    int[] arefs = (int[]) refs;
                    ref = runtime.expandAddress(arefs[count++]);
                } else {
                    long[] arefs = (long[]) refs;
                    ref = arefs[count++];
                }
                cls = runtime.findClass(ref);
            }
            if (cls != null) {
                return new PHDJavaReference(cls, source, PHDJavaReference.REACHABILITY_STRONG, refType, PHDJavaReference.HEAP_ROOT_UNKNOWN, "?");
            } else {
                return new PHDJavaReference(new PHDJavaObject.Builder((PHDJavaHeap) (runtime.getHeaps().next()), ref, null, PHDJavaObject.NO_HASHCODE, -1).build(), source, PHDJavaReference.REACHABILITY_STRONG, refType, PHDJavaReference.HEAP_ROOT_UNKNOWN, "?");
            }
        }

        public void remove() {
            throw new UnsupportedOperationException();
        }
    };
}
Also used : CorruptDataException(com.ibm.dtfj.image.CorruptDataException) LongEnumeration(com.ibm.dtfj.phd.util.LongEnumeration) JavaClass(com.ibm.dtfj.java.JavaClass) JavaObject(com.ibm.dtfj.java.JavaObject) Iterator(java.util.Iterator) JavaObject(com.ibm.dtfj.java.JavaObject) NoSuchElementException(java.util.NoSuchElementException)

Example 4 with LongEnumeration

use of com.ibm.dtfj.phd.util.LongEnumeration in project openj9 by eclipse.

the class PHDJavaClassLoader method processData.

private void processData(HeapdumpReader reader, final PHDImage parentImage, final ImageAddressSpace space, final PHDJavaRuntime runtime) throws IOException {
    final JavaClassLoader loader = this;
    final int adjustLen = reader.version() == 4 && reader.isJ9() ? 1 : 0;
    final int[] realClasses = new int[1];
    try {
        reader.parse(new PortableHeapDumpListener() {

            long prevAddress;

            PHDJavaClass prevObjClass;

            private void updateSizes(long address) {
                if (prevObjClass != null)
                    prevObjClass.updateSize(prevAddress, address);
                prevObjClass = null;
                prevAddress = address;
            }

            public void classDump(long address, long superAddress, String name, int size, int flags, int hashCode, LongEnumeration refs) throws Exception {
                updateSizes(address);
                classes.put(address, new PHDJavaClass.Builder(space, runtime, loader, address, superAddress, name).size(size).flags(flags).hashCode(hashCode).refs(refs).build());
                updateAddresses(address, size, name);
                ++realClasses[0];
            }

            public void objectArrayDump(long address, long classAddress, int flags, int hashCode, LongEnumeration refs, int length, long instanceSize) throws Exception {
                int refsLen = refs.numberOfElements();
                int adjustLen2 = Math.min(adjustLen, refsLen);
                updateSizes(address);
                updateAddresses(address, classAddress, length - adjustLen2);
                long classAddress2 = adjustLen2 == 1 ? refs.nextLong() : 0;
                genArrayClasses(space, runtime, loader, adjustLen2, classAddress, classAddress2);
            }

            public void objectDump(long address, long classAddress, int flags, int hashCode, LongEnumeration refs, long instanceSize) throws Exception {
                updateSizes(address);
                updateAddresses(address, classAddress, -1);
                genObjectClass(space, runtime, loader, classAddress, hashCode);
            }

            public void primitiveArrayDump(long address, int type, int length, int flags, int hashCode, long instanceSize) throws Exception {
                updateSizes(address);
                updateAddresses(address, type, length);
            }

            private void genObjectClass(final ImageAddressSpace space, final PHDJavaRuntime runtime, final JavaClassLoader loader, long classAddress, int hashCode) {
                if (!classes.containsKey(classAddress)) {
                    PHDJavaClass objClass = new PHDJavaClass.Builder(space, runtime, loader, classAddress, PHDJavaClass.UNKNOWN_SUPERCLASS, PHDJavaClass.UNKNOWN_NONARRAY).build();
                    classes.put(classAddress, objClass);
                    updateAddresses(classAddress, 100, null);
                }
                prevObjClass = (PHDJavaClass) findClass(classAddress);
            }

            private PHDJavaClass genArrayClass(final ImageAddressSpace space, final PHDJavaRuntime runtime, final JavaClassLoader loader, long classAddress, long sup, String name) {
                PHDJavaClass elemCls;
                int size = 100;
                elemCls = new PHDJavaClass.Builder(space, runtime, loader, classAddress, sup, name).build();
                classes.put(classAddress, elemCls);
                updateAddresses(classAddress, size, name);
                return elemCls;
            }

            private void genArrayClasses(final ImageAddressSpace space, final PHDJavaRuntime runtime, final JavaClassLoader loader, final int adjustLen, long classAddress, long classAddress2) {
                if (adjustLen == 1) {
                    // Java 5.0 arrays with type = base component type e.g. String
                    // First reference = actual array type e.g. [[Ljava.lang.String;
                    JavaClass arrayCls;
                    if (!classes.containsKey(classAddress2)) {
                        String name = PHDJavaClass.UNKNOWN_ARRAY;
                        arrayCls = genArrayClass(space, runtime, loader, classAddress2, jlo, name);
                    } else {
                        arrayCls = findClass(classAddress2);
                    }
                    arrayClasses.put(classAddress, arrayCls);
                    if (!classes.containsKey(classAddress)) {
                        String name = PHDJavaClass.UNKNOWN_NONARRAY;
                        genArrayClass(space, runtime, loader, classAddress, PHDJavaClass.UNKNOWN_SUPERCLASS, name);
                    }
                } else {
                    arrayClasses.put(classAddress, null);
                }
                return;
            }
        });
    } catch (EOFException e) {
        classes.put(runtime.nextDummyClassAddr(), new PHDCorruptJavaClass("Truncated dump found building class " + realClasses[0], null, e));
    } catch (IOException e) {
        classes.put(runtime.nextDummyClassAddr(), new PHDCorruptJavaClass("Corrupted dump found building class " + realClasses[0], null, e));
    } catch (Exception e) {
        classes.put(runtime.nextDummyClassAddr(), new PHDCorruptJavaClass("Building class " + realClasses[0], null, e));
    } finally {
        reader.close();
        reader = null;
    }
    jlo = 0;
    // Use an uncached search as the index hasn't been built.
    JavaClass jco = findClassUncached("java/lang/Object");
    if (jco != null) {
        ImagePointer ip = jco.getID();
        if (ip != null)
            jlo = ip.getAddress();
    } else {
        // If the dump is very corrupt it won't have java.lang.Object - so create one
        jco = new PHDJavaClass.Builder(space, runtime, loader, 0, 0, "java/lang/Object").build();
        jlo = runtime.nextDummyClassAddr();
        classes.put(jlo, jco);
    }
    // If the dump is very corrupt it won't have java.lang.Class - so create one
    JavaClass jcl = findClassUncached("java/lang/Class");
    if (jcl == null) {
        jcl = new PHDJavaClass.Builder(space, runtime, loader, 0, jlo, "java/lang/Class").build();
        classes.put(runtime.nextDummyClassAddr(), jcl);
    }
    // nor will it have primitive array classes
    for (int i = 0; i < PHDJavaRuntime.arrayTypeName.length; ++i) {
        JavaClass jc = findClassUncached(PHDJavaRuntime.arrayTypeName[i]);
        if (jc == null) {
            jc = new PHDJavaClass.Builder(space, runtime, loader, 0, jlo, PHDJavaRuntime.arrayTypeName[i]).build();
            classes.put(runtime.nextDummyClassAddr(), jc);
        }
    }
    // Bug in PHD dumps - some Java 6 types have the type of an array being the whole array, not the elements
    // Is the type of the array the whole array or the type of an element?
    boolean arrayTypeIsArray = true;
    for (Long id : arrayClasses.keySet()) {
        JavaClass cl1 = findClass(id);
        // Corrupt dump might not have the class!
        if (cl1 == null)
            continue;
        try {
            if (!cl1.isArray()) {
                arrayTypeIsArray = false;
            }
        } catch (CorruptDataException e) {
            // If we don't know the type then presume they are not arrays
            arrayTypeIsArray = false;
        }
    }
    // Create a mapping from the phd id of an array object to the type of the whole array
    for (Long id : arrayClasses.keySet()) {
        JavaClass cl1 = findClass(id);
        if (cl1 == null) {
            String name = arrayTypeIsArray ? PHDJavaClass.UNKNOWN_ARRAY : null;
            long sup = arrayTypeIsArray ? jlo : PHDJavaClass.UNKNOWN_SUPERCLASS;
            cl1 = new PHDJavaClass.Builder(space, runtime, loader, id, sup, name).build();
            classes.put(id, cl1);
        }
        JavaClass ar = arrayClasses.get(id);
        if (ar != null) {
            ImagePointer ip = ar.getID();
            if (ip != null) {
                JavaClass ar2 = findClass(ip.getAddress());
                if (ar2 != null) {
                    ar = ar2;
                }
            }
        // cl1 is not a component type for multidimensional arrays, but is the scalar type
        // ((PHDJavaClass)ar).setComponentType(cl1);
        }
        JavaClass cl2;
        if (arrayTypeIsArray) {
            cl2 = cl1;
        } else if (ar != null) {
            cl2 = ar;
        } else {
            try {
                String name = cl1.getName();
                String arrayName = arrayName(name);
                Set<JavaClass> s = findClasses(arrayName);
                if (s.size() == 0) {
                    // Array class doesn't exist, so create a dummy one
                    cl2 = new PHDJavaClass.Builder(space, runtime, loader, 0, jlo, arrayName).componentType(cl1).build();
                } else if (s.size() == 1) {
                    // Only one, so use it
                    cl2 = s.iterator().next();
                } else {
                    // Multiple classes, so if possible choose one
                    cl2 = null;
                    for (JavaClass cl3 : s) {
                        // If so then it is the one.
                        if (PHDJavaClass.referencesClass(cl3, cl1)) {
                            cl2 = cl3;
                            break;
                        }
                    }
                }
            } catch (CorruptDataException e) {
                // Array class doesn't exist, so create a dummy one
                cl2 = new PHDJavaClass.Builder(space, runtime, loader, 0, jlo, PHDJavaClass.UNKNOWN_ARRAY).componentType(cl1).build();
            }
            if (cl2 instanceof PHDJavaClass) {
                // We know the component type, so remember it for later
                ((PHDJavaClass) cl2).setComponentType(cl1);
            }
        }
        // Even if the array class is null (we couldn't decide), mark it so we know for later
        arrayClasses.put(id, cl2);
    }
    initCache();
}
Also used : PortableHeapDumpListener(com.ibm.dtfj.phd.parser.PortableHeapDumpListener) Set(java.util.Set) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) IOException(java.io.IOException) CorruptDataException(com.ibm.dtfj.image.CorruptDataException) IOException(java.io.IOException) EOFException(java.io.EOFException) CorruptDataException(com.ibm.dtfj.image.CorruptDataException) ImageAddressSpace(com.ibm.dtfj.image.ImageAddressSpace) ImagePointer(com.ibm.dtfj.image.ImagePointer) LongEnumeration(com.ibm.dtfj.phd.util.LongEnumeration) JavaClassLoader(com.ibm.dtfj.java.JavaClassLoader) JavaClass(com.ibm.dtfj.java.JavaClass) EOFException(java.io.EOFException)

Example 5 with LongEnumeration

use of com.ibm.dtfj.phd.util.LongEnumeration in project openj9 by eclipse.

the class PHDJavaObject method getReferences.

public Iterator<JavaReference> getReferences() {
    fillInDetails(true);
    final JavaObject source = this;
    return new Iterator<JavaReference>() {

        int count = -1;

        Iterator<JavaClass> loaderCls = heap.runtime.getLoaderClasses(source);

        public boolean hasNext() {
            if (count < 0) {
                return true;
            } else if (loaderCls.hasNext()) {
                return true;
            } else if (refs instanceof LongEnumeration) {
                LongEnumeration le = (LongEnumeration) refs;
                return count < le.numberOfElements();
            } else if (refs instanceof long[]) {
                long[] arefs = (long[]) refs;
                return count < arefs.length;
            } else if (refs instanceof int[]) {
                int[] arefs = (int[]) refs;
                return count < arefs.length;
            } else {
                return false;
            }
        }

        public JavaReference next() {
            if (!hasNext())
                throw new NoSuchElementException("" + count++);
            long ref;
            int refType = PHDJavaReference.REFERENCE_UNKNOWN;
            JavaClass cls1;
            if (count == -1) {
                // Add the type
                cls1 = cls;
                // Doesn't matter
                ref = 0;
                ++count;
                refType = PHDJavaReference.REFERENCE_CLASS;
            } else if (loaderCls.hasNext()) {
                refType = PHDJavaReference.REFERENCE_LOADED_CLASS;
                cls1 = loaderCls.next();
                // Doesn't matter
                ref = 0;
            } else {
                if (refs instanceof LongEnumeration) {
                    LongEnumeration le = (LongEnumeration) refs;
                    ref = le.nextLong();
                    ++count;
                } else if (refs instanceof int[]) {
                    int[] arefs = (int[]) refs;
                    ref = heap.getJavaRuntime().expandAddress(arefs[count++]);
                } else {
                    long[] arefs = (long[]) refs;
                    ref = arefs[count++];
                }
                if (length >= 0) {
                    refType = PHDJavaReference.REFERENCE_ARRAY_ELEMENT;
                } else {
                    refType = PHDJavaReference.REFERENCE_FIELD;
                }
                cls1 = heap.getJavaRuntime().findClass(ref);
            }
            if (cls1 != null) {
                return new PHDJavaReference(cls1, source, PHDJavaReference.REACHABILITY_STRONG, refType, PHDJavaReference.HEAP_ROOT_UNKNOWN, "?");
            } else {
                return new PHDJavaReference(new PHDJavaObject.Builder(heap, ref, null, PHDJavaObject.NO_HASHCODE, -1).build(), source, PHDJavaReference.REACHABILITY_STRONG, refType, PHDJavaReference.HEAP_ROOT_UNKNOWN, "?");
            }
        }

        public void remove() {
            throw new UnsupportedOperationException();
        }
    };
}
Also used : LongEnumeration(com.ibm.dtfj.phd.util.LongEnumeration) JavaObject(com.ibm.dtfj.java.JavaObject) JavaClass(com.ibm.dtfj.java.JavaClass) Iterator(java.util.Iterator) NoSuchElementException(java.util.NoSuchElementException)

Aggregations

LongEnumeration (com.ibm.dtfj.phd.util.LongEnumeration)6 CorruptDataException (com.ibm.dtfj.image.CorruptDataException)5 JavaClass (com.ibm.dtfj.java.JavaClass)5 JavaObject (com.ibm.dtfj.java.JavaObject)5 Iterator (java.util.Iterator)4 PortableHeapDumpListener (com.ibm.dtfj.phd.parser.PortableHeapDumpListener)3 IOException (java.io.IOException)3 NoSuchElementException (java.util.NoSuchElementException)3 ImagePointer (com.ibm.dtfj.image.ImagePointer)2 JavaClassLoader (com.ibm.dtfj.java.JavaClassLoader)2 EOFException (java.io.EOFException)2 HashSet (java.util.HashSet)2 CorruptData (com.ibm.dtfj.image.CorruptData)1 DataUnavailable (com.ibm.dtfj.image.DataUnavailable)1 ImageAddressSpace (com.ibm.dtfj.image.ImageAddressSpace)1 MemoryAccessException (com.ibm.dtfj.image.MemoryAccessException)1 JavaMethod (com.ibm.dtfj.java.JavaMethod)1 JavaReference (com.ibm.dtfj.java.JavaReference)1 HeapdumpReader (com.ibm.dtfj.phd.parser.HeapdumpReader)1 ArrayList (java.util.ArrayList)1