use of com.ibm.j9ddr.vm29.types.U64 in project openj9 by eclipse.
the class J9ObjectFieldOffsetIterator_V1 method calculateInstanceSize.
private void calculateInstanceSize(J9ROMClassPointer romClass, J9ClassPointer superClazz) throws CorruptDataException {
lockwordNeeded = NO_LOCKWORD_NEEDED;
/* if we only care about statics we can skip all work related to instance size calculations */
if (!walkFlags.anyBitsIn(J9VM_FIELD_OFFSET_WALK_INCLUDE_INSTANCE | J9VM_FIELD_OFFSET_WALK_CALCULATE_INSTANCE_SIZE)) {
return;
}
ObjectFieldInfo fieldInfo = new ObjectFieldInfo(romClass);
/*
* Step 1: Calculate the size of the superclass and backfill offset.
* Inherit the instance size and backfillOffset from the superclass.
*/
if (superClazz.notNull()) {
/*
* Note that in the J9Class, we do not store -1 to indicate no back fill,
* we store the total instance size (including the header) instead.
*/
fieldInfo.setSuperclassFieldsSize(superClazz.totalInstanceSize().intValue());
if (!superClazz.backfillOffset().eq(superClazz.totalInstanceSize().add(J9Object.SIZEOF))) {
fieldInfo.setSuperclassBackfillOffset(superClazz.backfillOffset().sub(J9Object.SIZEOF).intValue());
}
} else {
fieldInfo.setSuperclassFieldsSize(0);
}
lockwordNeeded = checkLockwordNeeded(romClass, superClazz, instanceClass);
/*
* remove the lockword from Object (if there is one) only if we don't need a lockword or we do need one
* and we are not re-using the one from Object which we can tell because lockwordNeeded is LOCKWORD_NEEDED as
* opposed to the value of the existing offset.
*/
if ((LOCKWORD_NEEDED.equals(lockwordNeeded)) || (NO_LOCKWORD_NEEDED.equals(lockwordNeeded))) {
if (superClazz.notNull() && !superClazz.lockOffset().eq(new UDATA(-1)) && J9ClassHelper.classDepth(superClazz).isZero()) {
int newSuperSize = fieldInfo.getSuperclassFieldsSize() - LOCKWORD_SIZE;
/* this may have been rounded to 8 bytes so also get rid of the padding */
if (fieldInfo.isSuperclassBackfillSlotAvailable()) {
/* j.l.Object was not end aligned */
newSuperSize -= BACKFILL_SIZE;
fieldInfo.setSuperclassBackfillOffset(NO_BACKFILL_AVAILABLE);
}
fieldInfo.setSuperclassFieldsSize(newSuperSize);
}
}
/*
* Step 2: Determine which extra hidden fields we need and prepend them to the list of hidden fields.
*/
LinkedList<HiddenInstanceField> extraHiddenFields = copyHiddenInstanceFieldsList(vm);
finalizeLinkOffset = new UDATA(0);
if (!superClazz.isNull() && !superClazz.finalizeLinkOffset().isZero()) {
/* Superclass is finalizeable */
finalizeLinkOffset = superClazz.finalizeLinkOffset();
} else {
/* Superclass is not finalizeable */
if (J9ROMClassHelper.finalizeNeeded(romClass)) {
extraHiddenFields.addFirst(new HiddenInstanceField(vm.hiddenFinalizeLinkFieldShape()));
}
}
lockOffset = new UDATA(lockwordNeeded);
if (lockOffset.eq(LOCKWORD_NEEDED)) {
extraHiddenFields.addFirst(new HiddenInstanceField(vm.hiddenLockwordFieldShape()));
}
/*
* Step 3: Calculate the number of various categories of fields: single word primitive, double word primitive, and object references.
* Iterate over fields to count instance fields by size.
*/
fieldInfo.countInstanceFields();
fieldInfo.countAndCopyHiddenFields(extraHiddenFields, hiddenInstanceFieldList);
new UDATA(fieldInfo.calculateTotalFieldsSizeAndBackfill());
firstDoubleOffset = new UDATA(fieldInfo.calculateFieldDataStart());
firstObjectOffset = new UDATA(fieldInfo.addDoublesArea(firstDoubleOffset.intValue()));
firstSingleOffset = new UDATA(fieldInfo.addObjectsArea(firstObjectOffset.intValue()));
if (fieldInfo.isMyBackfillSlotAvailable() && fieldInfo.isBackfillSuitableFieldAvailable()) {
if (fieldInfo.isBackfillSuitableInstanceSingleAvailable()) {
walkFlags = walkFlags.bitOr(J9VM_FIELD_OFFSET_WALK_BACKFILL_SINGLE_FIELD);
} else if (fieldInfo.isBackfillSuitableInstanceObjectAvailable()) {
walkFlags = walkFlags.bitOr(J9VM_FIELD_OFFSET_WALK_BACKFILL_OBJECT_FIELD);
}
}
/*
* Calculate offsets (from the object header) for hidden fields. Hidden fields follow immediately the instance fields of the same type.
* Give instance fields priority for backfill slots.
* Note that the hidden fields remember their offsets, so this need be done once only.
*/
if (!hiddenInstanceFieldList.isEmpty()) {
UDATA hiddenSingleOffset = firstSingleOffset.add(J9Object.SIZEOF + (fieldInfo.getNonBackfilledInstanceSingleCount() * U32.SIZEOF));
UDATA hiddenDoubleOffset = firstDoubleOffset.add(J9Object.SIZEOF + (fieldInfo.getInstanceDoubleCount() * U64.SIZEOF));
UDATA hiddenObjectOffset = firstObjectOffset.add(J9Object.SIZEOF + (fieldInfo.getNonBackfilledInstanceObjectCount() * fj9object_t_SizeOf));
boolean useBackfillForObject = false;
boolean useBackfillForSingle = false;
if (fieldInfo.isMyBackfillSlotAvailable() && !walkFlags.anyBitsIn(J9VM_FIELD_OFFSET_WALK_BACKFILL_OBJECT_FIELD | J9VM_FIELD_OFFSET_WALK_BACKFILL_SINGLE_FIELD)) {
/* There are no backfill-suitable instance fields, so let the hidden fields use the backfill slot */
if (fieldInfo.isBackfillSuitableSingleAvailable()) {
useBackfillForSingle = true;
} else if (fieldInfo.isBackfillSuitableObjectAvailable()) {
useBackfillForObject = true;
}
}
for (HiddenInstanceField hiddenField : hiddenInstanceFieldList) {
U32 modifiers = hiddenField.shape().modifiers();
if (modifiers.allBitsIn(J9FieldFlagObject)) {
if (useBackfillForObject) {
hiddenField.setFieldOffset(fieldInfo.getMyBackfillOffsetForHiddenField());
useBackfillForObject = false;
} else {
hiddenField.setFieldOffset(hiddenObjectOffset);
hiddenObjectOffset = hiddenObjectOffset.add(fj9object_t_SizeOf);
}
} else if (modifiers.allBitsIn(J9FieldSizeDouble)) {
hiddenField.setFieldOffset(hiddenDoubleOffset);
hiddenDoubleOffset = hiddenDoubleOffset.add(U64.SIZEOF);
} else {
if (useBackfillForSingle) {
hiddenField.setFieldOffset(fieldInfo.getMyBackfillOffsetForHiddenField());
useBackfillForSingle = false;
} else {
hiddenField.setFieldOffset(hiddenSingleOffset);
hiddenSingleOffset = hiddenSingleOffset.add(U32.SIZEOF);
}
}
}
}
backfillOffsetToUse = new IDATA(fieldInfo.getMyBackfillOffset());
/* backfill offset for this class's fields */
}
use of com.ibm.j9ddr.vm29.types.U64 in project openj9 by eclipse.
the class J9ROMFieldShapeHelper method getFieldAnnotationLocation.
private static U32Pointer getFieldAnnotationLocation(J9ROMFieldShapePointer fieldShapePointer) throws CorruptDataException {
long size = 0;
if ((fieldShapePointer.modifiers().allBitsIn(J9FieldFlagConstant))) {
size += ((fieldShapePointer.modifiers().allBitsIn(J9FieldSizeDouble)) ? U64.SIZEOF : U32.SIZEOF);
}
if (fieldShapePointer.modifiers().allBitsIn(J9FieldFlagHasGenericSignature)) {
size += U32.SIZEOF;
}
// move past J9ROMFieldShape struct and then add size in bytes
U32Pointer fieldAnnotationOffset = U32Pointer.cast(fieldShapePointer.add(1)).addOffset(size);
return fieldAnnotationOffset;
}
use of com.ibm.j9ddr.vm29.types.U64 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.types.U64 in project openj9 by eclipse.
the class DTFJJavaRuntime method validHeapAddress.
/*
* Quickly check if an object address is within a memory range that we
* know is part of the heap.
* (Heap sections are usually contiguous so we can merge them down to
* just a few ranges. This is important in balanced mode where there
* may be thousands. See See PR 103197)
*/
private boolean validHeapAddress(ImagePointer address) {
if (mergedHeapSections == null) {
mergeSections();
}
U64 addr = new U64(address.getAddress());
for (ImageSection i : mergedHeapSections) {
U64 baseAddress = new U64(i.getBaseAddress().getAddress());
if (baseAddress.gt(addr)) {
// found the pointer in a heap.
return false;
}
U64 endAddress = new U64(i.getBaseAddress().getAddress() + i.getSize());
if (endAddress.gt(addr)) {
return true;
}
}
return false;
}
use of com.ibm.j9ddr.vm29.types.U64 in project openj9 by eclipse.
the class DTFJJavaRuntime method mergeSections.
/*
* Merge all the sections of the heap together to simplify range checks for
* getObjectAtAddress. (This is very important with balanced heaps where there
* are thousands of heap sections but they are actually contiguous. See PR 103197)
*/
private synchronized void mergeSections() {
// Get the list of all the heap sections.
if (mergedHeapSections != null) {
return;
}
Iterator heaps = getHeaps();
List<ImageSection> heapSections = new LinkedList<ImageSection>();
// If there are no heap sections this can't be valid.
if (!heaps.hasNext()) {
return;
}
while (heaps.hasNext()) {
DTFJJavaHeap heap = (DTFJJavaHeap) heaps.next();
Iterator sections = heap.getSections();
while (sections.hasNext()) {
heapSections.add((ImageSection) sections.next());
}
}
// Sort them.
Collections.sort(heapSections, new Comparator<ImageSection>() {
public int compare(ImageSection arg0, ImageSection arg1) {
U64 ptr0 = new U64(arg0.getBaseAddress().getAddress());
U64 ptr1 = new U64(arg1.getBaseAddress().getAddress());
// not a java long comparison.
if (ptr0.lt(ptr1)) {
return -1;
} else if (ptr0.gt(ptr1)) {
return 1;
} else {
return 0;
}
}
});
mergedHeapSections = new LinkedList<ImageSection>();
Iterator<ImageSection> itr = heapSections.iterator();
// We know we have at least one section.
ImageSection currentSection = itr.next();
while (itr.hasNext()) {
ImageSection nextSection = itr.next();
// If the sections are contiguous, merge them.
if (currentSection.getBaseAddress().getAddress() + currentSection.getSize() == nextSection.getBaseAddress().getAddress()) {
currentSection = new J9DDRImageSection(DTFJContext.getProcess(), currentSection.getBaseAddress().getAddress(), currentSection.getSize() + nextSection.getSize(), null);
} else {
mergedHeapSections.add(currentSection);
currentSection = nextSection;
}
}
mergedHeapSections.add(currentSection);
}
Aggregations