Search in sources :

Example 16 with GCHeapRegionDescriptor

use of com.ibm.j9ddr.vm29.j9.gc.GCHeapRegionDescriptor in project openj9 by eclipse.

the class ObjectRefsCommand method dumpHeapReferences.

/**
 * Write the on heap references stanza to the output stream.
 * @param vm
 * @param targetObject
 * @param out
 * @throws CorruptDataException
 */
private void dumpHeapReferences(J9JavaVMPointer vm, J9ObjectPointer targetObject, PrintStream out) throws CorruptDataException {
    if (GCExtensions.isVLHGC()) {
        Table table = new Table("On Heap References");
        table.row("object (!j9object)", "field (!j9object)", "!mm_heapregiondescriptorvlhgc", "AC (type)");
        /* iterate over all heap regions */
        GCHeapRegionIterator regionIterator = GCHeapRegionIterator.from();
        while (regionIterator.hasNext()) {
            GCHeapRegionDescriptor region = regionIterator.next();
            if (region.containsObjects()) {
                MM_HeapRegionDescriptorVLHGCPointer vlhgcRegion = MM_HeapRegionDescriptorVLHGCPointer.cast(region.getHeapRegionDescriptorPointer());
                MM_AllocationContextTarokPointer currentAllocationContextTarok = vlhgcRegion._allocateData()._owningContext();
                /* iterate over all objects in region */
                GCObjectHeapIterator heapObjectIterator = region.objectIterator(true, false);
                while (heapObjectIterator.hasNext()) {
                    J9ObjectPointer currentObject = heapObjectIterator.next();
                    /* Iterate over the object's fields and list any that point at @ref targetObject */
                    GCObjectIterator fieldIterator = GCObjectIterator.fromJ9Object(currentObject, false);
                    while (fieldIterator.hasNext()) {
                        J9ObjectPointer currentTargetObject = fieldIterator.next();
                        if (currentTargetObject.eq(targetObject)) {
                            /* found a reference to our targetObject, add it to the table */
                            J9ClassPointer objectClass = J9ObjectHelper.clazz(currentObject);
                            String objectClassString = J9ClassHelper.getJavaName(objectClass);
                            table.row(currentObject.getHexAddress() + " //" + objectClassString, currentTargetObject.getHexAddress(), vlhgcRegion.getHexAddress(), currentAllocationContextTarok.getHexAddress() + " (" + currentAllocationContextTarok._allocationContextType() + ")");
                        }
                    }
                }
            }
        }
        table.render(out);
    }
}
Also used : GCHeapRegionDescriptor(com.ibm.j9ddr.vm29.j9.gc.GCHeapRegionDescriptor) Table(com.ibm.j9ddr.tools.ddrinteractive.Table) MM_HeapRegionDescriptorVLHGCPointer(com.ibm.j9ddr.vm29.pointer.generated.MM_HeapRegionDescriptorVLHGCPointer) J9ClassPointer(com.ibm.j9ddr.vm29.pointer.generated.J9ClassPointer) GCHeapRegionIterator(com.ibm.j9ddr.vm29.j9.gc.GCHeapRegionIterator) GCObjectHeapIterator(com.ibm.j9ddr.vm29.j9.gc.GCObjectHeapIterator) GCObjectIterator(com.ibm.j9ddr.vm29.j9.gc.GCObjectIterator) MM_AllocationContextTarokPointer(com.ibm.j9ddr.vm29.pointer.generated.MM_AllocationContextTarokPointer) J9ObjectPointer(com.ibm.j9ddr.vm29.pointer.generated.J9ObjectPointer)

Example 17 with GCHeapRegionDescriptor

use of com.ibm.j9ddr.vm29.j9.gc.GCHeapRegionDescriptor in project openj9 by eclipse.

the class CheckEngine method checkJ9LinkedFreeHeader.

/**
 * Verify the integrity of an GCHeapLinkedFreeHeader (hole) on the heap.
 * Checks various aspects of hole integrity.
 *
 * @param hole Pointer to the hole
 * @param segment The segment containing the pointer
 * @param checkFlags Type/level of verification
 *
 * @return @ref GCCheckWalkStageErrorCodes
 * @throws CorruptDataException
 *
 * @see @ref checkFlags
 */
private int checkJ9LinkedFreeHeader(GCHeapLinkedFreeHeader hole, GCHeapRegionDescriptor regionDesc, int checkFlags) throws CorruptDataException {
    J9ObjectPointer object = hole.getObject();
    if (ObjectModel.isSingleSlotDeadObject(object)) {
        /* TODO: we can add warning here if header of single slot hole is not standard (0s or fs) */
        return J9MODRON_GCCHK_RC_OK;
    }
    UDATA holeSize = hole.getSize();
    /* Hole size can not be 0 */
    if (holeSize.eq(0)) {
        return J9MODRON_GCCHK_RC_DEAD_OBJECT_SIZE;
    }
    /* Hole size must be aligned */
    if (holeSize.anyBitsIn(J9MODRON_GCCHK_J9OBJECT_ALIGNMENT_MASK)) {
        return J9MODRON_GCCHK_RC_DEAD_OBJECT_SIZE_NOT_ALIGNED;
    }
    UDATA regionStart = UDATA.cast(regionDesc.getLowAddress());
    UDATA regionEnd = regionStart.add(regionDesc.getSize());
    UDATA delta = regionEnd.sub(UDATA.cast(object));
    /* Hole does not fit region */
    if (delta.lt(holeSize)) {
        return J9MODRON_GCCHK_RC_INVALID_RANGE;
    }
    GCHeapLinkedFreeHeader nextHole = hole.getNext();
    J9ObjectPointer nextObject = nextHole.getObject();
    if (!nextObject.isNull()) {
        /* Next must be a hole */
        if (!ObjectModel.isDeadObject(nextObject)) {
            return J9MODRON_GCCHK_RC_DEAD_OBJECT_NEXT_IS_NOT_HOLE;
        }
        /* Next should point to the same region */
        if (regionStart.gt(UDATA.cast(nextObject)) || regionEnd.lte(UDATA.cast(nextObject))) {
            return J9MODRON_GCCHK_RC_DEAD_OBJECT_NEXT_IS_NOT_IN_REGION;
        }
        /* next should not point to inside the hole */
        if (holeSize.add(UDATA.cast(object)).gt(UDATA.cast(nextObject)) && object.lt(nextObject)) {
            return J9MODRON_GCCHK_RC_DEAD_OBJECT_NEXT_IS_POINTED_INSIDE;
        }
    }
    return J9MODRON_GCCHK_RC_OK;
}
Also used : UDATA(com.ibm.j9ddr.vm29.types.UDATA) GCHeapLinkedFreeHeader(com.ibm.j9ddr.vm29.j9.gc.GCHeapLinkedFreeHeader) J9ObjectPointer(com.ibm.j9ddr.vm29.pointer.generated.J9ObjectPointer)

Example 18 with GCHeapRegionDescriptor

use of com.ibm.j9ddr.vm29.j9.gc.GCHeapRegionDescriptor in project openj9 by eclipse.

the class CheckEngine method checkJ9Object.

/**
 * Verify the integrity of an object on the heap.
 * Checks various aspects of object integrity based on the checkFlags.
 *
 * @param objectPtr Pointer to the object
 * @param segment The segment containing the pointer
 * @param checkFlags Type/level of verification
 *
 * @return @ref GCCheckWalkStageErrorCodes
 * @throws CorruptDataException
 *
 * @see @ref checkFlags
 */
private int checkJ9Object(J9ObjectPointer object, GCHeapRegionDescriptor regionDesc, int checkFlags) throws CorruptDataException {
    if (object.isNull()) {
        return J9MODRON_GCCHK_RC_OK;
    }
    // if (0 == regionDesc->objectAlignment) {
    if (!regionDesc.containsObjects()) {
        /* this is a heap region, but it's not intended for objects (could be free or an arraylet leaf) */
        return J9MODRON_GCCHK_RC_NOT_IN_OBJECT_REGION;
    }
    if (object.anyBitsIn(J9MODRON_GCCHK_J9OBJECT_ALIGNMENT_MASK)) {
        return J9MODRON_GCCHK_RC_UNALIGNED;
    }
    if ((checkFlags & J9MODRON_GCCHK_VERIFY_CLASS_SLOT) != 0) {
        /* Check that the class pointer points to the class heap, etc. */
        int ret = checkJ9ClassPointer(J9ObjectHelper.clazz(object), true);
        if (J9MODRON_GCCHK_RC_OK != ret) {
            return ret;
        }
    }
    if ((checkFlags & J9MODRON_GCCHK_VERIFY_RANGE) != 0) {
        UDATA regionEnd = UDATA.cast(regionDesc.getLowAddress()).add(regionDesc.getSize());
        long delta = regionEnd.sub(UDATA.cast(object)).longValue();
        /* Basic check that there is enough room for the object header */
        if (delta < J9Object.SIZEOF) {
            return J9MODRON_GCCHK_RC_INVALID_RANGE;
        }
        /* TODO: find out what the indexable header size should really be */
        if (ObjectModel.isIndexable(object) && (delta < J9IndexableObjectContiguous.SIZEOF)) {
            return J9MODRON_GCCHK_RC_INVALID_RANGE;
        }
        if (delta < ObjectModel.getSizeInBytesWithHeader(object).longValue()) {
            return J9MODRON_GCCHK_RC_INVALID_RANGE;
        }
        if (J9BuildFlags.gc_arraylets && !J9BuildFlags.gc_hybridArraylets) {
        // TODO kmt : more code here
        }
        if ((checkFlags & J9MODRON_GCCHK_VERIFY_FLAGS) != 0) {
            // TODO : fix this test
            if (!checkIndexableFlag(object)) {
                return J9MODRON_GCCHK_RC_INVALID_FLAGS;
            }
            if (GCExtensions.isStandardGC()) {
                UDATA regionFlags = regionDesc.getTypeFlags();
                if (regionFlags.allBitsIn(MEMORY_TYPE_OLD)) {
                    /* All objects in an old segment must have old bit set */
                    if (!ObjectModel.isOld(object)) {
                        return J9MODRON_GCCHK_RC_OLD_SEGMENT_INVALID_FLAGS;
                    }
                } else {
                    if (regionFlags.allBitsIn(MEMORY_TYPE_NEW)) {
                        /* Object in a new segment can't have old bit or remembered bit set */
                        if (ObjectModel.isOld(object)) {
                            return J9MODRON_GCCHK_RC_NEW_SEGMENT_INVALID_FLAGS;
                        }
                    }
                }
            }
        }
    }
    return J9MODRON_GCCHK_RC_OK;
}
Also used : UDATA(com.ibm.j9ddr.vm29.types.UDATA)

Example 19 with GCHeapRegionDescriptor

use of com.ibm.j9ddr.vm29.j9.gc.GCHeapRegionDescriptor in project openj9 by eclipse.

the class CheckEngine method checkSlotObjectHeap.

public int checkSlotObjectHeap(J9ObjectPointer object, ObjectReferencePointer objectIndirect, GCHeapRegionDescriptor regionDesc, J9ObjectPointer objectIndirectBase) {
    if (object.isNull()) {
        return J9MODRON_SLOT_ITERATOR_OK;
    }
    int result = checkObjectIndirect(object);
    /* might the heap include dark matter? If so, ignore most errors */
    if ((_cycle.getMiscFlags() & J9MODRON_GCCHK_MISC_DARKMATTER) != 0) {
        /* only report a subset of errors -- the rest are expected to be found in dark matter */
        switch(result) {
            case J9MODRON_GCCHK_RC_OK:
            case J9MODRON_GCCHK_RC_UNALIGNED:
            case J9MODRON_GCCHK_RC_STACK_OBJECT:
                break;
            /* These errors are unlikely, but not impossible to find in dark matter. 
			 * Leave them enabled because they can help find real corruption
			 */
            case J9MODRON_GCCHK_RC_NOT_FOUND:
                /* can happen due to contraction */
                break;
            /* other errors in possible dark matter are expected, so ignore them and don't 
			 * investigate this pointer any further 
			 */
            default:
                return J9MODRON_GCCHK_RC_OK;
        }
    }
    boolean isIndexable = false;
    boolean scavengerEnabled = false;
    try {
        isIndexable = ObjectModel.isIndexable(objectIndirectBase);
        scavengerEnabled = GCExtensions.scavengerEnabled();
    } catch (CorruptDataException e) {
        // TODO : cde should be part of the error
        CheckError error = new CheckError(object, _cycle, _currentCheck, "Object ", J9MODRON_GCCHK_RC_CORRUPT_DATA_EXCEPTION, _cycle.nextErrorCount());
        _reporter.report(error);
        return J9MODRON_SLOT_ITERATOR_UNRECOVERABLE_ERROR;
    }
    if (J9MODRON_GCCHK_RC_OK != result) {
        String elementName = isIndexable ? "IObject " : "Object ";
        CheckError error = new CheckError(objectIndirectBase, objectIndirect, _cycle, _currentCheck, elementName, result, _cycle.nextErrorCount());
        _reporter.report(error);
        return J9MODRON_SLOT_ITERATOR_OK;
    }
    if (J9BuildFlags.gc_generational) {
        if (scavengerEnabled) {
            GCHeapRegionDescriptor objectRegion = findRegionForPointer(object, regionDesc);
            if (objectRegion == null) {
                /* should be impossible, since checkObjectIndirect() already verified that the object exists */
                return J9MODRON_GCCHK_RC_NOT_FOUND;
            }
            if (object.notNull()) {
                UDATA regionType;
                UDATA objectRegionType;
                boolean isRemembered;
                boolean isOld;
                try {
                    regionType = regionDesc.getTypeFlags();
                    objectRegionType = objectRegion.getTypeFlags();
                    isRemembered = ObjectModel.isRemembered(objectIndirectBase);
                    isOld = ObjectModel.isOld(object);
                } catch (CorruptDataException e) {
                    // TODO : cde should be part of the error
                    CheckError error = new CheckError(objectIndirectBase, _cycle, _currentCheck, "Object ", J9MODRON_GCCHK_RC_CORRUPT_DATA_EXCEPTION, _cycle.nextErrorCount());
                    _reporter.report(error);
                    return J9MODRON_SLOT_ITERATOR_UNRECOVERABLE_ERROR;
                }
                /* Old objects that point to new objects should have remembered bit ON */
                if (regionType.allBitsIn(MEMORY_TYPE_OLD) && objectRegionType.allBitsIn(MEMORY_TYPE_NEW) && !isRemembered) {
                    String elementName = isIndexable ? "IObject " : "Object ";
                    CheckError error = new CheckError(objectIndirectBase, objectIndirect, _cycle, _currentCheck, elementName, J9MODRON_GCCHK_RC_NEW_POINTER_NOT_REMEMBERED, _cycle.nextErrorCount());
                    _reporter.report(error);
                    return J9MODRON_SLOT_ITERATOR_OK;
                }
                /* Old objects that point to objects with old bit OFF should have remembered bit ON */
                if (regionType.allBitsIn(MEMORY_TYPE_OLD) && !isOld && !isRemembered) {
                    String elementName = isIndexable ? "IObject " : "Object ";
                    CheckError error = new CheckError(objectIndirectBase, objectIndirect, _cycle, _currentCheck, elementName, J9MODRON_GCCHK_RC_REMEMBERED_SET_OLD_OBJECT, _cycle.nextErrorCount());
                    _reporter.report(error);
                    return J9MODRON_SLOT_ITERATOR_OK;
                }
            }
        }
    }
    return J9MODRON_SLOT_ITERATOR_OK;
}
Also used : GCHeapRegionDescriptor(com.ibm.j9ddr.vm29.j9.gc.GCHeapRegionDescriptor) UDATA(com.ibm.j9ddr.vm29.types.UDATA) CorruptDataException(com.ibm.j9ddr.CorruptDataException)

Example 20 with GCHeapRegionDescriptor

use of com.ibm.j9ddr.vm29.j9.gc.GCHeapRegionDescriptor in project openj9 by eclipse.

the class CheckEngine method checkObjectHeap.

public int checkObjectHeap(J9ObjectPointer object, GCHeapRegionDescriptor regionDesc) {
    int result = J9MODRON_SLOT_ITERATOR_OK;
    boolean isDead = false;
    boolean isIndexable = false;
    J9ClassPointer clazz = null;
    try {
        if (ObjectModel.isDeadObject(object)) {
            /* this is a hole */
            result = checkJ9LinkedFreeHeader(GCHeapLinkedFreeHeader.fromJ9Object(object), regionDesc, _cycle.getCheckFlags());
            if (J9MODRON_GCCHK_RC_OK != result) {
                CheckError error = new CheckError(object, _cycle, _currentCheck, "Object", result, _cycle.nextErrorCount());
                _reporter.report(error);
                /* There are some error cases would not prevent further iteration */
                if (!((J9MODRON_GCCHK_RC_DEAD_OBJECT_NEXT_IS_NOT_HOLE == result) || (J9MODRON_GCCHK_RC_DEAD_OBJECT_NEXT_IS_NOT_IN_REGION == result) || (J9MODRON_GCCHK_RC_DEAD_OBJECT_NEXT_IS_POINTED_INSIDE == result))) {
                    _reporter.reportHeapWalkError(error, _lastHeapObject1, _lastHeapObject2, _lastHeapObject3);
                    return J9MODRON_SLOT_ITERATOR_UNRECOVERABLE_ERROR;
                }
            }
            return J9MODRON_SLOT_ITERATOR_OK;
        }
    } catch (CorruptDataException e) {
        // TODO : cde should be part of the error
        CheckError error = new CheckError(object, _cycle, _currentCheck, "Object ", J9MODRON_GCCHK_RC_CORRUPT_DATA_EXCEPTION, _cycle.nextErrorCount());
        _reporter.report(error);
        return J9MODRON_SLOT_ITERATOR_UNRECOVERABLE_ERROR;
    }
    try {
        // Prefetch this data to make CDE handling easy
        isIndexable = ObjectModel.isIndexable(object);
        clazz = J9ObjectHelper.clazz(object);
        result = checkJ9Object(object, regionDesc, _cycle.getCheckFlags());
    } catch (CorruptDataException cde) {
        // TODO : cde should be part of the error
        CheckError error = new CheckError(object, _cycle, _currentCheck, "Object ", J9MODRON_GCCHK_RC_CORRUPT_DATA_EXCEPTION, _cycle.nextErrorCount());
        _reporter.report(error);
        return J9MODRON_SLOT_ITERATOR_UNRECOVERABLE_ERROR;
    }
    if (J9MODRON_GCCHK_RC_OK != result) {
        String elementName = isIndexable ? "IObject " : "Object ";
        CheckError error = new CheckError(object, _cycle, _currentCheck, elementName, result, _cycle.nextErrorCount());
        _reporter.report(error);
        /* There are some error cases would not prevent further iteration */
        if (!(J9MODRON_GCCHK_RC_CLASS_IS_UNLOADED == result)) {
            _reporter.reportHeapWalkError(error, _lastHeapObject1, _lastHeapObject2, _lastHeapObject3);
            return J9MODRON_SLOT_ITERATOR_UNRECOVERABLE_ERROR;
        } else {
            return J9MODRON_SLOT_ITERATOR_OK;
        }
    }
    try {
        /* check Ownable Synchronizer Object consistency */
        if (needVerifyOwnableSynchronizerConsistency()) {
            if (J9Object.OBJECT_HEADER_SHAPE_MIXED == ObjectModel.getClassShape(clazz).intValue() && !J9ClassHelper.classFlags(clazz).bitAnd(J9AccClassOwnableSynchronizer).eq(0)) {
                if (ObjectAccessBarrier.isObjectInOwnableSynchronizerList(object).isNull()) {
                    CheckError error = new CheckError(object, _cycle, _currentCheck, "Object ", J9MODRON_GCCHK_OWNABLE_SYNCHRONIZER_OBJECT_IS_NOT_ATTACHED_TO_THE_LIST, _cycle.nextErrorCount());
                    _reporter.report(error);
                } else {
                    _ownableSynchronizerObjectCountOnHeap += 1;
                }
            }
        }
    } catch (CorruptDataException cde) {
        // TODO : cde should be part of the error
        CheckError error = new CheckError(object, _cycle, _currentCheck, "Object ", J9MODRON_GCCHK_RC_CORRUPT_DATA_EXCEPTION, _cycle.nextErrorCount());
        _reporter.report(error);
        return J9MODRON_SLOT_ITERATOR_UNRECOVERABLE_ERROR;
    }
    if (J9MODRON_GCCHK_RC_OK == result) {
        GCObjectIterator fieldIterator;
        GCObjectIterator addressIterator;
        try {
            fieldIterator = GCObjectIterator.fromJ9Object(object, true);
            addressIterator = GCObjectIterator.fromJ9Object(object, true);
        } catch (CorruptDataException e) {
            // TODO : cde should be part of the error
            CheckError error = new CheckError(object, _cycle, _currentCheck, "Object ", J9MODRON_GCCHK_RC_CORRUPT_DATA_EXCEPTION, _cycle.nextErrorCount());
            _reporter.report(error);
            return J9MODRON_SLOT_ITERATOR_UNRECOVERABLE_ERROR;
        }
        while (fieldIterator.hasNext()) {
            J9ObjectPointer field = fieldIterator.next();
            VoidPointer address = addressIterator.nextAddress();
            result = checkSlotObjectHeap(field, ObjectReferencePointer.cast(address), regionDesc, object);
            if (J9MODRON_SLOT_ITERATOR_OK != result) {
                break;
            }
        }
    }
    if (J9MODRON_GCCHK_RC_OK == result) {
        /* this heap object is OK. Record it in the cache in case we find a pointer to it soon */
        int cacheIndex = (int) (object.getAddress() % OBJECT_CACHE_SIZE);
        _checkedObjectCache[cacheIndex] = object;
    }
    return result;
}
Also used : VoidPointer(com.ibm.j9ddr.vm29.pointer.VoidPointer) J9ClassPointer(com.ibm.j9ddr.vm29.pointer.generated.J9ClassPointer) GCObjectIterator(com.ibm.j9ddr.vm29.j9.gc.GCObjectIterator) CorruptDataException(com.ibm.j9ddr.CorruptDataException) J9ObjectPointer(com.ibm.j9ddr.vm29.pointer.generated.J9ObjectPointer)

Aggregations

GCHeapRegionDescriptor (com.ibm.j9ddr.vm29.j9.gc.GCHeapRegionDescriptor)13 CorruptDataException (com.ibm.j9ddr.CorruptDataException)10 GCHeapRegionIterator (com.ibm.j9ddr.vm29.j9.gc.GCHeapRegionIterator)8 J9ObjectPointer (com.ibm.j9ddr.vm29.pointer.generated.J9ObjectPointer)7 UDATA (com.ibm.j9ddr.vm29.types.UDATA)7 GCObjectHeapIterator (com.ibm.j9ddr.vm29.j9.gc.GCObjectHeapIterator)4 GCObjectIterator (com.ibm.j9ddr.vm29.j9.gc.GCObjectIterator)3 GCScavengerForwardedHeader (com.ibm.j9ddr.vm29.j9.gc.GCScavengerForwardedHeader)3 U8Pointer (com.ibm.j9ddr.vm29.pointer.U8Pointer)3 J9ClassPointer (com.ibm.j9ddr.vm29.pointer.generated.J9ClassPointer)3 MM_HeapRegionDescriptorVLHGCPointer (com.ibm.j9ddr.vm29.pointer.generated.MM_HeapRegionDescriptorVLHGCPointer)3 Table (com.ibm.j9ddr.tools.ddrinteractive.Table)2 VoidPointer (com.ibm.j9ddr.vm29.pointer.VoidPointer)2 MM_AllocationContextTarokPointer (com.ibm.j9ddr.vm29.pointer.generated.MM_AllocationContextTarokPointer)2 MM_GCExtensionsPointer (com.ibm.j9ddr.vm29.pointer.generated.MM_GCExtensionsPointer)2 MM_HeapRegionDescriptorPointer (com.ibm.j9ddr.vm29.pointer.generated.MM_HeapRegionDescriptorPointer)2 MM_HeapRegionManagerPointer (com.ibm.j9ddr.vm29.pointer.generated.MM_HeapRegionManagerPointer)2 CorruptData (com.ibm.dtfj.image.CorruptData)1 InvalidDataTypeException (com.ibm.j9ddr.InvalidDataTypeException)1 DDRInteractiveCommandException (com.ibm.j9ddr.tools.ddrinteractive.DDRInteractiveCommandException)1