Search in sources :

Example 1 with U64

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 */
}
Also used : UDATA(com.ibm.j9ddr.vm29.types.UDATA) U32(com.ibm.j9ddr.vm29.types.U32) IDATA(com.ibm.j9ddr.vm29.types.IDATA)

Example 2 with U64

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;
}
Also used : U32Pointer(com.ibm.j9ddr.vm29.pointer.U32Pointer)

Example 3 with U64

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;
}
Also used : GCVMThreadListIterator(com.ibm.j9ddr.vm29.j9.gc.GCVMThreadListIterator) UDATA(com.ibm.j9ddr.vm29.types.UDATA) VoidPointer(com.ibm.j9ddr.vm29.pointer.VoidPointer) J9IndexableObjectPointer(com.ibm.j9ddr.vm29.pointer.generated.J9IndexableObjectPointer) J9VMThreadPointer(com.ibm.j9ddr.vm29.pointer.generated.J9VMThreadPointer) GCScavengerForwardedHeader(com.ibm.j9ddr.vm29.j9.gc.GCScavengerForwardedHeader) CorruptDataException(com.ibm.j9ddr.CorruptDataException) InvalidDataTypeException(com.ibm.j9ddr.InvalidDataTypeException)

Example 4 with U64

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;
}
Also used : U64(com.ibm.j9ddr.vm29.types.U64) ImageSection(com.ibm.dtfj.image.ImageSection) J9DDRImageSection(com.ibm.j9ddr.view.dtfj.image.J9DDRImageSection)

Example 5 with U64

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);
}
Also used : U64(com.ibm.j9ddr.vm29.types.U64) GCClassLoaderIterator(com.ibm.j9ddr.vm29.j9.gc.GCClassLoaderIterator) GCVMThreadListIterator(com.ibm.j9ddr.vm29.j9.gc.GCVMThreadListIterator) MemoryCategoryIterator(com.ibm.j9ddr.vm29.j9.walkers.MemoryCategoryIterator) J9DDRDTFJUtils.corruptIterator(com.ibm.j9ddr.view.dtfj.J9DDRDTFJUtils.corruptIterator) J9MemTagIterator(com.ibm.j9ddr.vm29.j9.walkers.J9MemTagIterator) Iterator(java.util.Iterator) DTFJMonitorIterator(com.ibm.j9ddr.vm29.view.dtfj.java.j9.DTFJMonitorIterator) ImageSection(com.ibm.dtfj.image.ImageSection) J9DDRImageSection(com.ibm.j9ddr.view.dtfj.image.J9DDRImageSection) LinkedList(java.util.LinkedList) J9DDRImageSection(com.ibm.j9ddr.view.dtfj.image.J9DDRImageSection)

Aggregations

UDATA (com.ibm.j9ddr.vm29.types.UDATA)4 U32Pointer (com.ibm.j9ddr.vm29.pointer.U32Pointer)3 U32 (com.ibm.j9ddr.vm29.types.U32)3 ImageSection (com.ibm.dtfj.image.ImageSection)2 CorruptDataException (com.ibm.j9ddr.CorruptDataException)2 J9DDRImageSection (com.ibm.j9ddr.view.dtfj.image.J9DDRImageSection)2 GCVMThreadListIterator (com.ibm.j9ddr.vm29.j9.gc.GCVMThreadListIterator)2 PointerPointer (com.ibm.j9ddr.vm29.pointer.PointerPointer)2 U64 (com.ibm.j9ddr.vm29.types.U64)2 InvalidDataTypeException (com.ibm.j9ddr.InvalidDataTypeException)1 DDRInteractiveCommandException (com.ibm.j9ddr.tools.ddrinteractive.DDRInteractiveCommandException)1 J9DDRDTFJUtils.corruptIterator (com.ibm.j9ddr.view.dtfj.J9DDRDTFJUtils.corruptIterator)1 GCClassLoaderIterator (com.ibm.j9ddr.vm29.j9.gc.GCClassLoaderIterator)1 GCScavengerForwardedHeader (com.ibm.j9ddr.vm29.j9.gc.GCScavengerForwardedHeader)1 J9MemTagIterator (com.ibm.j9ddr.vm29.j9.walkers.J9MemTagIterator)1 MemoryCategoryIterator (com.ibm.j9ddr.vm29.j9.walkers.MemoryCategoryIterator)1 AbstractPointer (com.ibm.j9ddr.vm29.pointer.AbstractPointer)1 U64Pointer (com.ibm.j9ddr.vm29.pointer.U64Pointer)1 VoidPointer (com.ibm.j9ddr.vm29.pointer.VoidPointer)1 J9ConstantPoolPointer (com.ibm.j9ddr.vm29.pointer.generated.J9ConstantPoolPointer)1