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);
}
}
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;
}
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;
}
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;
}
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;
}
Aggregations