use of com.ibm.j9ddr.vm29.j9.gc.GCScavengerForwardedHeader in project openj9 by eclipse.
the class CheckEngine method checkJ9ObjectPointer.
private int checkJ9ObjectPointer(J9ObjectPointer object, J9ObjectPointer[] newObject, GCHeapRegionDescriptor[] regionDesc) throws CorruptDataException {
newObject[0] = object;
if (object.isNull()) {
return J9MODRON_GCCHK_RC_OK;
}
regionDesc[0] = findRegionForPointer(object, regionDesc[0]);
if (regionDesc[0] == null) {
/* Is the object on the stack? */
GCVMThreadListIterator threadListIterator = GCVMThreadListIterator.from();
while (threadListIterator.hasNext()) {
J9VMThreadPointer vmThread = threadListIterator.next();
if (isObjectOnStack(object, vmThread.stackObject())) {
return J9MODRON_GCCHK_RC_STACK_OBJECT;
}
}
UDATA classSlot = UDATA.cast(object.clazz());
if (classSlot.eq(J9MODRON_GCCHK_J9CLASS_EYECATCHER)) {
return J9MODRON_GCCHK_RC_OBJECT_SLOT_POINTS_TO_J9CLASS;
}
return J9MODRON_GCCHK_RC_NOT_FOUND;
}
// if (0 == regionDesc->objectAlignment) {
if (!regionDesc[0].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;
}
/* Now we know object is not on stack we can check that it's correctly aligned
* for a J9Object.
*/
if (object.anyBitsIn(J9MODRON_GCCHK_J9OBJECT_ALIGNMENT_MASK)) {
return J9MODRON_GCCHK_RC_UNALIGNED;
}
if (isMidscavengeFlagSet()) {
if (GCExtensions.isVLHGC() || (regionDesc[0].getTypeFlags().allBitsIn(MEMORY_TYPE_NEW))) {
// TODO: ideally, we should only check this in the evacuate segment
// TODO: do some safety checks first -- is there enough room in the segment?
GCScavengerForwardedHeader scavengerForwardedHeader = GCScavengerForwardedHeader.fromJ9Object(object);
if (scavengerForwardedHeader.isForwardedPointer()) {
newObject[0] = scavengerForwardedHeader.getForwardedObject();
reportForwardedObject(object, newObject[0]);
// Replace the object and resume
object = newObject[0];
regionDesc[0] = findRegionForPointer(object, regionDesc[0]);
if (regionDesc[0] == null) {
/* Is the object on the stack? */
GCVMThreadListIterator threadListIterator = GCVMThreadListIterator.from();
while (threadListIterator.hasNext()) {
J9VMThreadPointer vmThread = threadListIterator.next();
if (isObjectOnStack(object, vmThread.stackObject())) {
return J9MODRON_GCCHK_RC_STACK_OBJECT;
}
}
return J9MODRON_GCCHK_RC_NOT_FOUND;
}
// if (0 == regionDesc->objectAlignment) {
if (!regionDesc[0].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;
}
/* make sure the forwarded pointer is also aligned */
if (object.anyBitsIn(J9MODRON_GCCHK_J9OBJECT_ALIGNMENT_MASK)) {
return J9MODRON_GCCHK_RC_UNALIGNED;
}
}
}
}
if (isScavengerBackoutFlagSet()) {
GCScavengerForwardedHeader scavengerForwardedHeader = GCScavengerForwardedHeader.fromJ9Object(object);
if (scavengerForwardedHeader.isReverseForwardedPointer()) {
newObject[0] = scavengerForwardedHeader.getReverseForwardedPointer();
reportForwardedObject(object, newObject[0]);
// Replace the object and resume
object = newObject[0];
regionDesc[0] = findRegionForPointer(object, regionDesc[0]);
if (regionDesc[0] == null) {
return J9MODRON_GCCHK_RC_NOT_FOUND;
}
if (!regionDesc[0].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 (!regionDesc[0].getTypeFlags().allBitsIn(MEMORY_TYPE_NEW)) {
/* reversed forwarded should point to Evacuate */
return J9MODRON_GCCHK_RC_REVERSED_FORWARDED_OUTSIDE_EVACUATE;
}
/* make sure the forwarded pointer is also aligned */
if (object.anyBitsIn(J9MODRON_GCCHK_J9OBJECT_ALIGNMENT_MASK)) {
return J9MODRON_GCCHK_RC_UNALIGNED;
}
}
}
/* Check that elements of a double array are aligned on an 8-byte boundary. For continuous
* arrays, verifying that the J9Indexable object is aligned on an 8-byte boundary is sufficient.
* For arraylets, depending on the layout, elements of the array may be stored on arraylet leafs
* or on the spine. Arraylet leafs should always be aligned on 8-byte boundaries. Checking both
* the first and last element will ensure that we are always checking that elements are aligned
* on the spine.
* */
long classShape = -1;
try {
classShape = ObjectModel.getClassShape(J9ObjectHelper.clazz(object)).longValue();
} catch (CorruptDataException cde) {
/* don't bother to report an error yet -- a later step will catch this. */
}
if (classShape == OBJECT_HEADER_SHAPE_DOUBLES) {
J9IndexableObjectPointer array = J9IndexableObjectPointer.cast(object);
int size = 0;
VoidPointer elementPtr = VoidPointer.NULL;
try {
size = ObjectModel.getSizeInElements(object).intValue();
} catch (InvalidDataTypeException ex) {
// size in elements can not be larger then 2G but it is...
// We could report an error at this point, but the C version
// doesn't -- we'll catch it later
} catch (IllegalArgumentException ex) {
// We could report an error at this point, but the C version
// doesn't -- we'll catch it later
}
if (0 != size) {
elementPtr = ObjectModel.getElementAddress(array, 0, U64.SIZEOF);
if (elementPtr.anyBitsIn(U64.SIZEOF - 1)) {
return J9MODRON_GCCHK_RC_DOUBLE_ARRAY_UNALIGNED;
}
elementPtr = ObjectModel.getElementAddress(array, size - 1, U64.SIZEOF);
if (elementPtr.anyBitsIn(U64.SIZEOF - 1)) {
return J9MODRON_GCCHK_RC_DOUBLE_ARRAY_UNALIGNED;
}
}
}
return J9MODRON_GCCHK_RC_OK;
}
use of com.ibm.j9ddr.vm29.j9.gc.GCScavengerForwardedHeader in project openj9 by eclipse.
the class CheckObjectHeap method check.
@Override
public void check() {
// Use iterators directly
try {
GCHeapRegionIterator regions = GCHeapRegionIterator.from();
boolean midScavenge = _engine.isMidscavengeFlagSet();
boolean isVLHGC = GCExtensions.isVLHGC();
while (regions.hasNext()) {
GCHeapRegionDescriptor region = GCHeapRegionDescriptor.fromHeapRegionDescriptor(regions.next());
boolean isRegionTypeNew = region.getTypeFlags().allBitsIn(MEMORY_TYPE_NEW);
GCObjectHeapIterator heapIterator = region.objectIterator(true, true);
while (heapIterator.hasNext()) {
J9ObjectPointer object = heapIterator.peek();
if (midScavenge && (isVLHGC || isRegionTypeNew)) {
GCScavengerForwardedHeader scavengerForwardedHeader = GCScavengerForwardedHeader.fromJ9Object(object);
if (scavengerForwardedHeader.isForwardedPointer()) {
// forwarded pointer is discovered
// report it
_engine.reportForwardedObject(object, scavengerForwardedHeader.getForwardedObject());
// and skip it by advancing of iterator to the next object
UDATA objectSize = scavengerForwardedHeader.getObjectSize();
heapIterator.advance(objectSize);
_engine.pushPreviousObject(object);
continue;
}
}
int result = _engine.checkObjectHeap(object, region);
if (result != J9MODRON_SLOT_ITERATOR_OK) {
break;
}
heapIterator.next();
_engine.pushPreviousObject(object);
}
}
} catch (CorruptDataException e) {
// TODO: handle exception
}
}
use of com.ibm.j9ddr.vm29.j9.gc.GCScavengerForwardedHeader in project openj9 by eclipse.
the class CheckEngine method checkSlotRememberedSet.
public int checkSlotRememberedSet(PointerPointer objectIndirect, MM_SublistPuddlePointer puddle) {
J9ObjectPointer object;
try {
object = J9ObjectPointer.cast(objectIndirect.at(0));
if (isMidscavengeFlagSet()) {
/* during a scavenge, some RS entries may be tagged -- remove the tag */
if (object.anyBitsIn(DEFERRED_RS_REMOVE_FLAG)) {
object = object.untag(DEFERRED_RS_REMOVE_FLAG);
}
}
int result = checkObjectIndirect(object);
if (J9MODRON_GCCHK_RC_OK != result) {
CheckError error = new CheckError(puddle, objectIndirect, _cycle, _currentCheck, result, _cycle.nextErrorCount());
_reporter.report(error);
return J9MODRON_SLOT_ITERATOR_OK;
}
/* Additional checks for the remembered set */
if (object.notNull()) {
GCHeapRegionDescriptor objectRegion = findRegionForPointer(object, null);
if (objectRegion == null) {
/* shouldn't happen, since checkObjectIndirect() already verified this object */
CheckError error = new CheckError(puddle, objectIndirect, _cycle, _currentCheck, J9MODRON_GCCHK_RC_NOT_FOUND, _cycle.nextErrorCount());
_reporter.report(error);
return J9MODRON_SLOT_ITERATOR_OK;
}
/* we shouldn't have newspace references in the remembered set */
if (objectRegion.getTypeFlags().allBitsIn(MEMORY_TYPE_NEW)) {
CheckError error = new CheckError(puddle, objectIndirect, _cycle, _currentCheck, J9MODRON_GCCHK_RC_REMEMBERED_SET_WRONG_SEGMENT, _cycle.nextErrorCount());
_reporter.report(error);
return J9MODRON_SLOT_ITERATOR_OK;
}
boolean skipObject = false;
if (isScavengerBackoutFlagSet()) {
GCScavengerForwardedHeader scavengerForwardedHeader = GCScavengerForwardedHeader.fromJ9Object(object);
if (scavengerForwardedHeader.isReverseForwardedPointer()) {
/* There is no reason to check object - is gone */
skipObject = true;
}
}
if (!skipObject) {
/* content of Remembered Set should be Old and Remembered */
if (!ObjectModel.isOld(object) || !ObjectModel.isRemembered(object)) {
CheckError error = new CheckError(puddle, objectIndirect, _cycle, _currentCheck, J9MODRON_GCCHK_RC_REMEMBERED_SET_FLAGS, _cycle.nextErrorCount());
_reporter.report(error);
_reporter.reportObjectHeader(error, object, null);
return J9MODRON_SLOT_ITERATOR_OK;
}
}
}
} catch (CorruptDataException e) {
// TODO : cde should be part of the error
CheckError error = new CheckError(puddle, objectIndirect, _cycle, _currentCheck, J9MODRON_GCCHK_RC_CORRUPT_DATA_EXCEPTION, _cycle.nextErrorCount());
_reporter.report(error);
}
return J9MODRON_SLOT_ITERATOR_OK;
}
Aggregations