Exemplo n.º 1
0
 /**
  * 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);
 }
Exemplo n.º 2
0
  /** 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);
        }
      }
    }
  }
Exemplo n.º 3
0
  /**
   * Read the fields table
   *
   * @param cls
   * @param fieldDatas
   * @param sharedStatics
   * @param isolatedStatics
   * @param slotSize
   * @param pragmaFlags
   */
  private static void createFields(
      VmType<?> cls,
      FieldData[] fieldDatas,
      VmSharedStatics sharedStatics,
      VmIsolatedStatics isolatedStatics,
      int slotSize,
      int pragmaFlags) {
    final int fcount = fieldDatas.length;
    final VmField[] ftable = new VmField[fcount];

    int objectSize = 0;
    for (int i = 0; i < fcount; i++) {
      final FieldData fd = fieldDatas[i];
      final boolean wide;
      int modifiers = fd.modifiers;
      final String name = fd.name;
      final String signature = fd.signature;
      switch (signature.charAt(0)) {
        case 'J':
        case 'D':
          modifiers = modifiers | Modifier.ACC_WIDE;
          wide = true;
          break;
        default:
          wide = false;
      }
      final boolean isstatic = (modifiers & Modifier.ACC_STATIC) != 0;
      final int staticsIdx;
      final VmField fs;
      final VmStatics statics;
      if (isstatic) {
        // Determine if the static field should be shared.
        final boolean shared = cls.isSharedStatics();
        if (shared) {
          statics = sharedStatics;
        } else {
          statics = isolatedStatics;
        }

        // If static allocate space for it.
        switch (signature.charAt(0)) {
          case 'B':
            staticsIdx = statics.allocIntField();
            break;
          case 'C':
            staticsIdx = statics.allocIntField();
            break;
          case 'D':
            staticsIdx = statics.allocLongField();
            break;
          case 'F':
            staticsIdx = statics.allocIntField();
            break;
          case 'I':
            staticsIdx = statics.allocIntField();
            break;
          case 'J':
            staticsIdx = statics.allocLongField();
            break;
          case 'S':
            staticsIdx = statics.allocIntField();
            break;
          case 'Z':
            staticsIdx = statics.allocIntField();
            break;
          default:
            {
              if (Modifier.isAddressType(signature)) {
                staticsIdx = statics.allocAddressField();
              } else {
                staticsIdx = statics.allocObjectField();
                // System.out.println(NumberUtils.hex(staticsIdx)
                // + "\t" + cls.getName() + "." + name);
              }
              break;
            }
        }
        fs = new VmStaticField(name, signature, modifiers, staticsIdx, cls, slotSize, shared);
      } else {
        staticsIdx = -1;
        statics = null;
        final int fieldOffset;
        // Set the offset (keep in mind that this will be fixed
        // by ClassResolver with respect to the objectsize of the
        // super-class.
        fieldOffset = objectSize;
        // Increment the objectSize
        if (wide) objectSize += 8;
        else if (Modifier.isPrimitive(signature)) {
          objectSize += 4;
        } else {
          objectSize += slotSize;
        }
        fs = new VmInstanceField(name, signature, modifiers, fieldOffset, cls, slotSize);
      }
      ftable[i] = fs;

      // Read field attributes
      if (isstatic && (fd.constantValue != null)) {
        switch (signature.charAt(0)) {
          case 'B':
          case 'C':
          case 'I':
          case 'S':
          case 'Z':
            statics.setInt(staticsIdx, ((VmConstInt) fd.constantValue).intValue());
            break;
          case 'D':
            final long lval =
                Double.doubleToRawLongBits(((VmConstDouble) fd.constantValue).doubleValue());
            statics.setLong(staticsIdx, lval);
            break;
          case 'F':
            final int ival =
                Float.floatToRawIntBits(((VmConstFloat) fd.constantValue).floatValue());
            statics.setInt(staticsIdx, ival);
            break;
          case 'J':
            statics.setLong(staticsIdx, ((VmConstLong) fd.constantValue).longValue());
            break;
          default:
            // throw new IllegalArgumentException("signature "
            // + signature);
            statics.setObject(staticsIdx, fd.constantValue);
            break;
        }
      }
      fs.setRuntimeAnnotations(fd.rVisAnn);
      fs.setRawAnnotations(fd.rawAnnotations);
    }

    // Align the instance fields for minimal object size.
    if ((pragmaFlags & TypePragmaFlags.NO_FIELD_ALIGNMENT) == 0) {
      objectSize = alignInstanceFields(ftable, slotSize);
    }

    cls.setFieldTable(ftable);
    if (objectSize > 0) {
      ((VmNormalClass<?>) cls).setObjectSize(objectSize);
    }
  }