/** * Align the offsets of the fields in the class optimized for minimal object size. * * @param fields * @return The objectsize taken by all the fields */ private static final int alignInstanceFields(VmField[] fields, int slotSize) { int objectSize = 0; for (byte currentTypeSize : TYPE_SIZES) { boolean aligned = false; for (VmField f : fields) { if (!f.isStatic() && (f.getTypeSize() == currentTypeSize)) { if (!aligned) { // Align on the current type size objectSize = align(objectSize, Math.min(currentTypeSize, slotSize)); aligned = true; } final VmInstanceField fld = (VmInstanceField) f; fld.setOffset(objectSize); objectSize += currentTypeSize; } } } // Make sure the object size is 32-bit aligned return align(objectSize, 4); }
/** Do the prepare action required to instantiate this object */ protected void prepareForInstantiation() { // Step 3: Calculate the object size final VmNormalClass superCls = getSuperClass(); int sc_size = (superCls != null) ? superCls.getObjectSize() : 0; objectSize += sc_size; // System.out.println(getName() + " objsz:" + objectSize + " sc_size:" + sc_size); // Step 4a: Fix the offset for all declared non-static fields final int cnt = getNoDeclaredFields(); final int[] superRefOffsets = (superCls != null) ? superCls.getReferenceOffsets() : null; int refOffsetsSize = (superCls != null) ? superRefOffsets.length : 0; int startRefIdx = refOffsetsSize; for (int i = 0; i < cnt; i++) { final VmField field = getDeclaredField(i); // fs.resolve(loader); if (!field.isStatic()) { final VmInstanceField inf = (VmInstanceField) field; inf.resolveOffset(sc_size); if (!field.isPrimitive()) { if (!field.isAddressType()) { refOffsetsSize++; } else { // System.out.println("Found address in field " + fs.getName()); } } } } // Step 4b: Create the referenceOffsets field referenceOffsets = new int[refOffsetsSize]; if (superCls != null) { System.arraycopy(superRefOffsets, 0, referenceOffsets, 0, startRefIdx); } for (int i = 0; i < cnt; i++) { final VmField field = getDeclaredField(i); if (!field.isStatic()) { final VmInstanceField inf = (VmInstanceField) field; if (!field.isPrimitive()) { if (!field.isAddressType()) { referenceOffsets[startRefIdx++] = inf.getOffset(); } } final int off = inf.getOffset(); if (off + inf.getTypeSize() > objectSize) { throw new Error( "Invalid offset in class " + getName() + " ofs " + off + " size " + objectSize); } } } }