f.setObjectValue(newObj, f.getObjectValue(obj));
f.setObjectValueUnchecked(newObj, f.getObjectValueUnchecked(obj));
  public static Object clone (Object obj)    throws OutOfMemoryError, CloneNotSupportedException {    VM_Type type = VM_Magic.getObjectType(obj);    int allocator = VM_Interface.pickAllocator(type);    if (type.isArrayType()) {      VM_Array ary   = type.asArray();      int      nelts = VM_ObjectModel.getArrayLength(obj);      int      size  = ary.getInstanceSize(nelts);      Object[] tib   = ary.getTypeInformationBlock();      Object newObj  = resolvedNewArray(nelts, size, tib, allocator);      System.arraycopy(obj, 0, newObj, 0, nelts);      return newObj;    } else {      if (!(obj instanceof Cloneable))	throw new CloneNotSupportedException();      VM_Class cls   = type.asClass();      int      size  = cls.getInstanceSize();      Object[] tib   = cls.getTypeInformationBlock();      Object newObj  = resolvedNewScalar(size, tib, cls.hasFinalizer(), allocator);      VM_Field[] instanceFields = cls.getInstanceFields();      for (int i=0; i<instanceFields.length; i++) {	VM_Field f = instanceFields[i];	VM_TypeReference ft = f.getType();	if (ft.isReferenceType()) {	  // Do via slower "pure" reflection to enable	  // collectors to do the right thing wrt reference counting	  // and write barriers.	  f.setObjectValue(newObj, f.getObjectValue(obj));	} else if (ft.isLongType() || ft.isDoubleType()) {	  int offset = f.getOffset();	  long bits = VM_Magic.getLongAtOffset(obj, offset);	  VM_Magic.setLongAtOffset(newObj, offset, bits);	} else {	  // NOTE: assumes that all other types get 32 bits.	  //       This is currently true, but may change in the future.	  int offset = f.getOffset();	  int bits = VM_Magic.getIntAtOffset(obj, offset);	  VM_Magic.setIntAtOffset(newObj, offset, bits);	}      }      return newObj;    }  }