use of com.ibm.j9ddr.vm29.pointer.generated.J9ROMClassPointer 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.pointer.generated.J9ROMClassPointer in project openj9 by eclipse.
the class FilteredROMClassesIterator method next.
@Override
public J9ROMClassPointer next() {
J9ROMClassPointer candidateClass = nextClass;
/* in the case where we called hasNext() previously */
nextClass = null;
/* destructive read */
try {
while ((null == candidateClass) && super.hasNext()) {
candidateClass = super.next();
String className;
className = J9UTF8Helper.stringValue(candidateClass.className());
if (!classPattern.isMatch(className)) {
candidateClass = null;
}
}
} catch (CorruptDataException e) {
throw new NoSuchElementException();
}
return candidateClass;
}
use of com.ibm.j9ddr.vm29.pointer.generated.J9ROMClassPointer in project openj9 by eclipse.
the class ROMClassesIterator method getNextClass.
private ClassAndSegment getNextClass() {
J9ROMClassPointer newNextClass = J9ROMClassPointer.NULL;
J9MemorySegmentPointer nextSegmentPtr = nextSegment;
try {
if (!nextSegment.isNull()) {
long newHeapPtr = 0;
if (nextClass == J9ROMClassPointer.NULL) {
newHeapPtr = nextSegmentPtr.heapBase().longValue();
} else {
newHeapPtr = nextClass.getAddress() + nextClass.romSize().longValue();
}
do {
if (nextSegmentPtr.type().anyBitsIn(MEMORY_TYPE_ROM_CLASS)) {
if (newHeapPtr < nextSegmentPtr.heapAlloc().longValue()) {
newNextClass = J9ROMClassPointer.cast(newHeapPtr);
try {
if (newNextClass.romSize().eq(0)) {
out.append("Size of ROMClass at " + newNextClass.getHexAddress() + "is invalid. Skipping to next segment.\n");
newNextClass = J9ROMClassPointer.NULL;
} else {
return new ClassAndSegment(newNextClass, nextSegmentPtr);
}
} catch (CorruptDataException e) {
out.append("Unable to read size of ROMClass at " + newNextClass.getHexAddress() + ". Skipping to next segment.\n");
newNextClass = J9ROMClassPointer.NULL;
}
}
}
/* move to next segment */
nextSegmentPtr = nextSegmentPtr.nextSegment();
if (!nextSegmentPtr.isNull()) {
newHeapPtr = nextSegmentPtr.heapBase().longValue();
}
} while (!nextSegmentPtr.isNull());
}
} catch (CorruptDataException e) {
newNextClass = J9ROMClassPointer.NULL;
}
return new ClassAndSegment(newNextClass, nextSegmentPtr);
}
use of com.ibm.j9ddr.vm29.pointer.generated.J9ROMClassPointer in project openj9 by eclipse.
the class J9ClassHelper method getMethodFromPCAndClass.
/*
* Returns a program space pointer to the matching J9Method for the
* specified class and PC.
*/
public static J9MethodPointer getMethodFromPCAndClass(J9ClassPointer localClass, U8Pointer pc) throws CorruptDataException {
J9ROMClassPointer localROMClass = localClass.romClass();
for (int i = 0; i < localROMClass.romMethodCount().longValue(); i++) {
J9MethodPointer localMethod = localClass.ramMethods().add(i);
J9ROMMethodPointer romMethod = J9MethodHelper.romMethod(localMethod);
boolean a = pc.gte(U8Pointer.cast(romMethod));
boolean b = pc.lte(J9ROMMethodHelper.bytecodeEnd(romMethod).subOffset(1));
if (a && b) {
return localMethod;
}
}
return J9MethodPointer.NULL;
}
use of com.ibm.j9ddr.vm29.pointer.generated.J9ROMClassPointer in project openj9 by eclipse.
the class RamClassWalker method allSlotsInConstantPoolDo.
private void allSlotsInConstantPoolDo() throws CorruptDataException {
final J9ROMClassPointer romClass = ramClass.romClass();
final int constPoolCount = romClass.ramConstantPoolCount().intValue();
final J9ConstantPoolPointer cpp = J9ConstantPoolPointer.cast(ramClass.ramConstantPool());
U32Pointer cpDescriptionSlots = romClass.cpShapeDescription();
PointerPointer cpEntry = PointerPointer.cast(ramClass.ramConstantPool());
long cpDescription = 0;
long cpEntryCount = ramClass.romClass().ramConstantPoolCount().longValue();
long cpDescriptionIndex = 0;
while (cpEntryCount > 0) {
if (0 == cpDescriptionIndex) {
// Load a new description word
cpDescription = cpDescriptionSlots.at(0).longValue();
cpDescriptionSlots = cpDescriptionSlots.add(1);
cpDescriptionIndex = J9_CP_DESCRIPTIONS_PER_U32;
}
/*
* A switch statement can't be used on long type, it might be
* erroneous to cast it to an int as it might change in the future.
*/
long slotType = cpDescription & J9_CP_DESCRIPTION_MASK;
if ((slotType == J9CPTYPE_STRING) || (slotType == J9CPTYPE_ANNOTATION_UTF8)) {
J9RAMStringRefPointer ref = J9RAMStringRefPointer.cast(cpEntry);
classWalkerCallback.addSlot(clazz, SlotType.J9_RAM_UTF8, ref.stringObjectEA(), "stringObject");
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.unusedEA(), "unused");
if (slotType == J9CPTYPE_STRING) {
classWalkerCallback.addSection(clazz, ref, J9RAMStringRef.SIZEOF, "J9CPTYPE_STRING", false);
} else {
classWalkerCallback.addSection(clazz, ref, J9RAMStringRef.SIZEOF, "J9CPTYPE_ANNOTATION_UTF8", false);
}
} else if (slotType == J9CPTYPE_METHOD_TYPE) {
J9RAMMethodTypeRefPointer ref = J9RAMMethodTypeRefPointer.cast(cpEntry);
J9ObjectPointer slot = ref.type();
if (slot.notNull()) {
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.typeEA(), "type", "!j9object");
} else {
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.typeEA(), "type");
}
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.slotCountEA(), "slotCount");
classWalkerCallback.addSection(clazz, ref, J9RAMMethodTypeRef.SIZEOF, "J9CPTYPE_METHOD_TYPE", false);
} else if (slotType == J9CPTYPE_METHODHANDLE) {
J9RAMMethodHandleRefPointer ref = J9RAMMethodHandleRefPointer.cast(cpEntry);
J9ObjectPointer slot = ref.methodHandle();
if (slot.notNull()) {
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.methodHandleEA(), "methodHandle", "!j9object");
} else {
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.methodHandleEA(), "methodHandle");
}
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.unusedEA(), "unused");
classWalkerCallback.addSection(clazz, ref, J9RAMMethodHandleRef.SIZEOF, "J9CPTYPE_METHODHANDLE", false);
} else if (slotType == J9CPTYPE_CLASS) {
J9RAMClassRefPointer ref = J9RAMClassRefPointer.cast(cpEntry);
if (ref.value().notNull()) {
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.valueEA(), "value", "!j9class");
} else {
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.valueEA(), "value");
}
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.modifiersEA(), "modifiers");
classWalkerCallback.addSection(clazz, ref, J9RAMClassRef.SIZEOF, "J9CPTYPE_CLASS", false);
} else if (slotType == J9CPTYPE_INT) {
J9RAMConstantRefPointer ref = J9RAMConstantRefPointer.cast(cpEntry);
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.slot1EA(), "cpFieldInt");
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.slot2EA(), "cpFieldIntUnused");
classWalkerCallback.addSection(clazz, ref, J9RAMConstantRef.SIZEOF, "J9CPTYPE_INT", false);
} else if (slotType == J9CPTYPE_FLOAT) {
J9RAMConstantRefPointer ref = J9RAMConstantRefPointer.cast(cpEntry);
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.slot1EA(), "cpFieldFloat");
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.slot2EA(), "cpFieldIntUnused");
classWalkerCallback.addSection(clazz, ref, J9RAMConstantRef.SIZEOF, "J9CPTYPE_FLOAT", false);
} else if (slotType == J9CPTYPE_LONG) {
J9RAMConstantRefPointer ref = J9RAMConstantRefPointer.cast(cpEntry);
classWalkerCallback.addSlot(clazz, SlotType.J9_I64, I64Pointer.cast(cpEntry), "J9CPTYPE_LONG");
classWalkerCallback.addSection(clazz, ref, J9RAMConstantRef.SIZEOF, "J9CPTYPE_LONG", false);
} else if (slotType == J9CPTYPE_DOUBLE) {
J9RAMConstantRefPointer ref = J9RAMConstantRefPointer.cast(cpEntry);
classWalkerCallback.addSlot(clazz, SlotType.J9_I64, I64Pointer.cast(cpEntry), "J9CPTYPE_DOUBLE");
classWalkerCallback.addSection(clazz, ref, I64.SIZEOF, "J9CPTYPE_DOUBLE", false);
} else if (slotType == J9CPTYPE_FIELD) {
J9RAMFieldRefPointer ref = J9RAMFieldRefPointer.cast(cpEntry);
J9RAMStaticFieldRefPointer staticRef = J9RAMStaticFieldRefPointer.cast(cpEntry);
/* if the field ref is resolved static, it has 'flagsAndClass', for other cases (unresolved and resolved instance) it has 'flags'. */
if ((staticRef.flagsAndClass().longValue() > 0) && (staticRef.valueOffset().longValue() != -1)) {
classWalkerCallback.addSlot(clazz, SlotType.J9_IDATA, staticRef.flagsAndClassEA(), "flagsAndClass");
} else {
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.flagsEA(), "flags");
}
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.valueOffsetEA(), "valueOffset");
classWalkerCallback.addSection(clazz, ref, J9RAMFieldRef.SIZEOF, "J9CPTYPE_FIELD", false);
} else if (slotType == J9CPTYPE_INTERFACE_METHOD) {
J9RAMInterfaceMethodRefPointer ref = J9RAMInterfaceMethodRefPointer.cast(cpEntry);
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.interfaceClassEA(), "interfaceClass", "!j9class");
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.methodIndexAndArgCountEA(), "methodIndexAndArgCount");
classWalkerCallback.addSection(clazz, ref, J9RAMInterfaceMethodRef.SIZEOF, "J9CPTYPE_INTERFACE_METHOD", false);
} else if (slotType == J9CPTYPE_STATIC_METHOD) {
J9RAMStaticMethodRefPointer ref = J9RAMStaticMethodRefPointer.cast(cpEntry);
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.methodEA(), "method", "!j9method");
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.methodIndexAndArgCountEA(), "unused");
classWalkerCallback.addSection(clazz, ref, J9RAMStaticMethodRef.SIZEOF, "J9CPTYPE_STATIC_METHOD", false);
} else if ((slotType == J9CPTYPE_UNUSED) || (slotType == J9CPTYPE_UNUSED8)) {
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, cpEntry, "unused");
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, cpEntry.add(1), "unused");
classWalkerCallback.addSection(clazz, cpEntry, 2 * UDATA.SIZEOF, "J9CPTYPE_UNUSED", false);
} else if (slotType == J9CPTYPE_INSTANCE_METHOD) {
J9RAMMethodRefPointer ref = J9RAMMethodRefPointer.cast(cpEntry);
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.methodIndexAndArgCountEA(), "methodIndexAndArgCount");
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.methodEA(), "method", "!j9method");
classWalkerCallback.addSection(clazz, ref, J9RAMMethodRef.SIZEOF, "J9CPTYPE_INSTANCE_METHOD", false);
} else if (slotType == J9CPTYPE_HANDLE_METHOD) {
J9RAMMethodRefPointer ref = J9RAMMethodRefPointer.cast(cpEntry);
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.methodIndexAndArgCountEA(), "methodTypeIndexAndArgCount");
classWalkerCallback.addSlot(clazz, SlotType.J9_UDATA, ref.methodEA(), "unused");
classWalkerCallback.addSection(clazz, ref, J9RAMMethodRef.SIZEOF, "J9CPTYPE_HANDLE_METHOD", false);
}
cpEntry = cpEntry.addOffset(J9RAMConstantPoolItem.SIZEOF);
cpEntryCount -= 1;
cpDescription >>= J9_CP_BITS_PER_DESCRIPTION;
cpDescriptionIndex -= 1;
}
// The spaces at the end of "Constant Pool" are important since the
// regions are sorted
// by address and size, but when they are equal they are sorted by
// longest name and "Constant Pool" has to come first
classWalkerCallback.addSection(clazz, cpp, constPoolCount * 2 * UDATA.SIZEOF, "Constant Pool ", false);
}
Aggregations