use of com.ibm.j9ddr.vm29.pointer.generated.J9ClassPointer 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.J9ClassPointer in project openj9 by eclipse.
the class VMConstantPool method getFieldOffset.
/**
* Get a field offset from the constant pool.
* @param index A J9VmconstantpoolConstants index into the constant pool. Must be for a static or instance field reference.
* @return Either the offset to the object, or null if the field's class is not resolved in the constant pool.
* @throws CorruptDataException If the field cannot be found in the related class or the CP index is not a field reference.
*/
public static J9ObjectFieldOffset getFieldOffset(long index) throws CorruptDataException {
if (_constantPool.length <= index || 0 > index) {
throw new IndexOutOfBoundsException("Index outside of constant pool bounds");
}
int cpIndex = (int) index;
long shapeDesc = ConstantPoolHelpers.J9_CP_TYPE(_cpShapeDescription, cpIndex);
if (J9CPTYPE_FIELD != shapeDesc) {
throw new CorruptDataException("VMConstantPool[" + index + "] CP_TYPE is not J9CPTYPE_FIELD");
}
/* The offset of the field, to be returned */
J9ObjectFieldOffset offset = null;
if (null != _constantPool[cpIndex]) {
offset = (J9ObjectFieldOffset) _constantPool[cpIndex];
} else {
J9ROMFieldRefPointer romRef = J9ROMFieldRefPointer.cast(_romCPStart.add(cpIndex));
J9ClassPointer refClass = getClass(romRef.classRefCPIndex().longValue());
J9ClassPointer currentClass = refClass;
if (currentClass.notNull()) {
/* If the current class is J9ClassPointer.NULL, return null as the field offset */
/* Resolve the fieldname, starting from the current class,
* and working up the class hierarchy towards the super classes. This should
* properly handle shadowed fields.
*/
String fieldName = J9UTF8Helper.stringValue(romRef.nameAndSignature().name());
String signature = J9UTF8Helper.stringValue(romRef.nameAndSignature().signature());
while (currentClass.notNull() && (null == offset)) {
Iterator<J9ObjectFieldOffset> fields = J9ClassHelper.getFieldOffsets(currentClass);
while (fields.hasNext()) {
J9ObjectFieldOffset field = fields.next();
if (field.getName().equals(fieldName) && field.getSignature().equals(signature)) {
offset = field;
break;
}
}
currentClass = J9ClassHelper.superclass(currentClass);
}
if (null == offset) {
/* The field should exist in the class it points to, unless the constant pool is corrupt or wrong */
throw new CorruptDataException("VMConstantPool[" + index + "] field not found: " + J9ClassHelper.getName(refClass) + "." + fieldName + " " + signature);
} else {
_constantPool[cpIndex] = offset;
}
}
}
return offset;
}
use of com.ibm.j9ddr.vm29.pointer.generated.J9ClassPointer in project openj9 by eclipse.
the class VMConstantPool method getClass.
/**
* Get a class from the constant pool.
* @param index A J9VmconstantpoolConstants index into the constant pool. Must be for a class reference.
* @return Either the loaded class, or if its not in the constant pool, J9ClassPointer.NULL.
* @throws CorruptDataException If the CPShape of the index is not a class.
*/
public static J9ClassPointer getClass(long index) throws CorruptDataException {
if (_constantPool.length <= index || 0 > index) {
throw new IndexOutOfBoundsException("Index outside of constant pool bounds");
}
int cpIndex = (int) index;
long shapeDesc = ConstantPoolHelpers.J9_CP_TYPE(_cpShapeDescription, cpIndex);
if (J9CPTYPE_CLASS != shapeDesc) {
throw new CorruptDataException("VMConstantPool[" + index + "] CP_TYPE is not J9CPTYPE_CLASS");
}
J9ClassPointer classPointer = null;
if (null != _constantPool[cpIndex]) {
classPointer = (J9ClassPointer) _constantPool[cpIndex];
} else {
J9RAMConstantPoolItemPointer ramEntry = _ramCPStart.add(index);
classPointer = J9RAMClassRefPointer.cast(ramEntry).value();
_constantPool[cpIndex] = classPointer;
}
return classPointer;
}
use of com.ibm.j9ddr.vm29.pointer.generated.J9ClassPointer in project openj9 by eclipse.
the class GCConstantPoolSlotIterator method initializeSlots_V1.
protected void initializeSlots_V1(J9ClassPointer clazz, boolean returnClassSlots, boolean returnObjectSlots) throws CorruptDataException {
U32Pointer cpDescriptionSlots = clazz.romClass().cpShapeDescription();
PointerPointer cpEntry = PointerPointer.cast(clazz.ramConstantPool());
long cpDescription = 0;
long cpEntryCount = clazz.romClass().ramConstantPoolCount().longValue();
long cpDescriptionIndex = 0;
ArrayList<AbstractPointer> slots = new ArrayList<AbstractPointer>();
ArrayList<VoidPointer> addresses = new ArrayList<VoidPointer>();
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;
}
long slotType = cpDescription & J9_CP_DESCRIPTION_MASK;
if ((slotType == J9CPTYPE_STRING) || (slotType == J9CPTYPE_ANNOTATION_UTF8)) {
if (returnObjectSlots) {
J9RAMStringRefPointer ref = J9RAMStringRefPointer.cast(cpEntry);
J9ObjectPointer slot = ref.stringObject();
if (slot.notNull()) {
slots.add(slot);
addresses.add(VoidPointer.cast(ref.stringObjectEA()));
}
}
} else if (slotType == J9CPTYPE_METHOD_TYPE) {
if (returnObjectSlots) {
J9RAMMethodTypeRefPointer ref = J9RAMMethodTypeRefPointer.cast(cpEntry);
J9ObjectPointer slot = ref.type();
if (slot.notNull()) {
slots.add(slot);
addresses.add(VoidPointer.cast(ref.typeEA()));
}
}
} else if (slotType == J9CPTYPE_METHODHANDLE) {
if (returnObjectSlots) {
J9RAMMethodHandleRefPointer ref = J9RAMMethodHandleRefPointer.cast(cpEntry);
J9ObjectPointer slot = ref.methodHandle();
if (slot.notNull()) {
slots.add(slot);
addresses.add(VoidPointer.cast(ref.methodHandleEA()));
}
}
} else if (slotType == J9CPTYPE_CLASS) {
if (returnClassSlots) {
J9RAMClassRefPointer ref = J9RAMClassRefPointer.cast(cpEntry);
J9ClassPointer slot = ref.value();
if (slot.notNull()) {
slots.add(slot);
addresses.add(VoidPointer.cast(ref.valueEA()));
}
}
}
cpEntry = cpEntry.addOffset(J9RAMConstantPoolItem.SIZEOF);
cpEntryCount -= 1;
cpDescription >>= J9_CP_BITS_PER_DESCRIPTION;
cpDescriptionIndex -= 1;
}
slotIterator = slots.iterator();
addressIterator = addresses.iterator();
}
use of com.ibm.j9ddr.vm29.pointer.generated.J9ClassPointer in project openj9 by eclipse.
the class GCClassLoaderSegmentClassesIterator method next.
public J9ClassPointer next() {
if (!hasNext()) {
throw new NoSuchElementException("There are no more items available through this iterator");
}
J9ClassPointer next = _nextClass;
advanceIterator();
return next;
}
Aggregations