text:
package org.jikesrvm.classloader;

import java.io.DataInputStream;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.annotation.Inherited;
import org.jikesrvm.VM;
import org.jikesrvm.Callbacks;
import org.jikesrvm.Constants;
import org.jikesrvm.compilers.common.CompiledMethod;
import org.jikesrvm.compilers.opt.inlining.ClassLoadingDependencyManager;
import org.jikesrvm.mm.mminterface.MemoryManager;
import org.jikesrvm.objectmodel.FieldLayoutContext;
import org.jikesrvm.objectmodel.IMT;
import org.jikesrvm.objectmodel.ObjectModel;
import org.jikesrvm.objectmodel.TIB;
import org.jikesrvm.runtime.Magic;
import org.jikesrvm.runtime.RuntimeEntrypoints;
import org.jikesrvm.runtime.StackBrowser;
import org.jikesrvm.runtime.Statics;
import org.jikesrvm.util.LinkedListRVM;
import org.vmmagic.pragma.NonMoving;
import org.vmmagic.pragma.Pure;
import org.vmmagic.pragma.Uninterruptible;
import org.vmmagic.unboxed.Offset;

/**
 * Description of a java "class" type.

 *
 * This description is read from a ".class" file as classes/field/methods
 * referenced by the running program need to be bound in to the running image.
 *
 * @see RVMType
 * @see RVMArray
 * @see Primitive
 */
@NonMoving
public final class RVMClass extends RVMType implements Constants, ClassLoaderConstants {

  /** Flag for closed world testing */
  public static boolean classLoadingDisabled = false;

  /** Constant pool entry for a UTF-8 encoded atom */
  public static final byte CP_UTF = 0;

  /** Constant pool entry for int literal */
  public static final byte CP_INT = 1;

  /** Constant pool entry for long literal */
  public static final byte CP_LONG = 2;

  /** Constant pool entry for float literal */
  public static final byte CP_FLOAT = 3;

  /** Constant pool entry for double literal */
  public static final byte CP_DOUBLE = 4;

  /** Constant pool entry for string literal (for annotations, may be other objects) */
  public static final byte CP_STRING = 5;

  /** Constant pool entry for member (field or method) reference */
  public static final byte CP_MEMBER = 6;

  /** Constant pool entry for type reference or class literal */
  public static final byte CP_CLASS = 7;

  /**
   * The constant pool holds constants used by the class and the Java
   * bytecodes in the methods associated with this class. This
   * constant pool isn't that from the class file, instead it has been
   * processed during class loading (see {@link #readClass}). The loaded
   * class' constant pool has 3 bits of type information (such as
   * (see {@link #CP_INT})), the rest of the int holds data as follows:
   *
   *

   *
utf: value is a UTF atom identifier

   *
int, long, float, double, string: value is an offset in the
   *     JTOC

   *
member: value is a member reference identifier

   *
class: value is a type reference identifier. NB this means
   *     that class literal bytecodes must first convert the identifier
   *     in to a JTOC offset.

   *

   */
  private final int[] constantPool;
  /** {@link ClassLoaderConstants} */
  private final short modifiers;
  /** Super class of this class */
  private final RVMClass superClass;
  /**
   * Non-final list of sub-classes. Classes added as sub-classes are
   * loaded.
   */
  private RVMClass[] subClasses;
  /** Interfaces supported by this class */
  private final RVMClass[] declaredInterfaces;
  /** Fields of this class */
  private final RVMField[] declaredFields;
  /** Methods of this class */
  private final RVMMethod[] declaredMethods;
  /** Declared inner classes, may be null */
  private final TypeReference[] declaredClasses;
  /** The outer class, or null if this is not a inner/nested class */
  private final TypeReference declaringClass;
  /** The enclosing class if this is a local class */
  private final TypeReference enclosingClass;
  /** The enclosing method if this is a local class */
  private final MethodReference enclosingMethod;
  /** Name of file .class file was compiled from, may be null */
  private final Atom sourceName;
  /**
   * The signature is a string representing the generic type for this
   * class declaration, may be null
   */
  private final Atom signature;
  /**
   * Class initializer method, null if no method or if class is
   * initialized (ie class initializer method has been run)
   */
  private RVMMethod classInitializerMethod;

  /**
   * current class-loading stage (loaded, resolved, instantiated,
   * initializing or initialized)
   */
  private byte state;

  //
  // The following are valid only when "state >= CLASS_RESOLVED".
  //

  // --- Field size and offset information --- //

  /** fields shared by all instances of class  */
  private RVMField[] staticFields;

  /** fields distinct for each instance of class */
  private RVMField[] instanceFields;

  /** offsets of reference-containing instance fields */
  private int[] referenceOffsets;

  /** Total size of per-instance data, in bytes  */
  private int instanceSize;

  /** The desired alignment for instances of this type. */
  private int alignment;

  /**
   * A field layout helper - used to keep context regarding field layouts.
   * Managed by the field layout objects in the ObjectModel.
   */
  private FieldLayoutContext fieldLayoutContext = null;

  // --- Method-dispatching information --- //

  /** static methods of class */
  private RVMMethod[] staticMethods;

  /** constructor methods of class  */
  private RVMMethod[] constructorMethods;

  /** virtual methods of class */
  private RVMMethod[] virtualMethods;

  /**
   * method that overrides java.lang.Object.finalize()
   * null => class does not have a finalizer
   */
  private RVMMethod finalizeMethod;

  /** type and virtual method dispatch table for class */
  private TIB typeInformationBlock;

  // --- Memory manager support --- //

  /**
   * Is this class type in the bootimage? Types in the boot image can
   * be initialized prior to execution (therefore removing runtime
   * resolution).
   */
  private boolean inBootImage;

  /**
   * At what offset is the thin lock word to be found in instances of
   * objects of this type?  A value of -1 indicates that the instances of
   * this type do not have inline thin locks.
   */
  private Offset thinLockOffset;

  /** Reference Count GC: is this type acyclic?  */
  private boolean acyclic;

  /** Cached set of inherited and declared annotations. */
  private Annotation[] annotations;

  /** Set of objects that are cached here to ensure they are not collected by GC **/
  private final LinkedListRVM<Object> objectCache;

  /** The imt for this class **/
  private IMT imt;

  // --- Assertion support --- //
  /**
   * Are assertions enabled on this class?
   */
  private final boolean desiredAssertionStatus;

  // --- General purpose functions --- //

  /**
   * Name - something like "java.lang.String".
   */
  @Override
  @Pure
  public String toString() {
    return getDescriptor().classNameFromDescriptor();
  }

  /**
   * Package name - something like "java.lang".
   * Returns the empty string if the class is a member of the unnamed package.
   */
  public String getPackageName() {
    String className = toString();
    int lastDot = className.lastIndexOf(".");
    return (lastDot >= 0) ? className.substring(0, lastDot) : "";
  }

  /**
   * Stack space requirement in words.
   */
  @Override
  @Pure
  @Uninterruptible
  public int getStackWords() {
    return 1;
  }

  /**
   * Space required in memory in bytes.
   */
  @Override
  @Pure
  @Uninterruptible
  public int getMemoryBytes() {
    return BYTES_IN_ADDRESS;
  }

  /**
   * An "interface" description rather than a "class" description?
   */
  @Uninterruptible
  public boolean isInterface() {
    return (modifiers & ACC_INTERFACE) != 0;
  }

  /**
   * Usable from other packages?
   */
  @Uninterruptible
  public boolean isPublic() {
    return (modifiers & ACC_PUBLIC) != 0;
  }

  /**
   * Non-subclassable?
   */
  @Uninterruptible
  public boolean isFinal() {
    return (modifiers & ACC_FINAL) != 0;
  }

  /**
   * Non-instantiable?
   */
  @Uninterruptible
  public boolean isAbstract() {
    return (modifiers & ACC_ABSTRACT) != 0;
  }

  /**
   * Use new-style "invokespecial" semantics for method calls in this class?
   */
  @Uninterruptible
  public boolean isSpecial() {
    return (modifiers & ACC_SUPER) != 0;
  }

  /**
   * Not present in source code file?
   */
  public boolean isSynthetic() {
    return (modifiers & ACC_SYNTHETIC) != 0;
  }

  /**
   * Is enumeration?
   */
  public boolean isEnum() {
    return (modifiers & ACC_ENUM) != 0;
  }

  /**
   * Annotation type
   */
  public boolean isAnnotation() {
    return (modifiers & ACC_ANNOTATION) != 0;
  }

  /**
   * @return true if this is a representation of an anonymous class
   */
  public boolean isAnonymousClass() {
    return (enclosingClass != null) && (enclosingMethod == null);
  }

  /**
   * @return true if this is a representation of a local class, ie
   * local to a block of code.
   */
  public boolean isLocalClass() {
    return enclosingMethod != null;
  }

  /**
   * @return true if this is a representation of a member class
   */
  public boolean isMemberClass() {
    return ((declaringClass != null) && ((modifiers & ACC_STATIC) == 0));
  }
  /**
   * @return true if this an object of this class could be assigned to Throwable
   */
  public boolean isThrowable() {
    return (getTypeRef() == TypeReference.JavaLangThrowable) ||
    RuntimeEntrypoints.isAssignableWith(TypeReference.JavaLangThrowable.resolve(), this);
  }
  /**
   * Get the modifiers associated with this class {@link
   * ClassLoaderConstants}.
   */
  public int getModifiers() {
    return modifiers & APPLICABLE_TO_CLASSES;
  }

  /**
   * Generic type information for class
   */
  public Atom getSignature() {
    return signature;
  }

  /**
   * Name of source file from which class was compiled -
   * something like "c:\java\src\java\lang\Object.java".
   * (null --> "unknown - wasn't recorded by compiler").
   */
  public Atom getSourceName() {
    return sourceName;
  }

  /**
   * Superclass of this class (null means "no superclass",
   * ie. class is "java/lang/Object").
   */
  @Uninterruptible
  public RVMClass getSuperClass() {
    return superClass;
  }

  /**
   * Currently loaded classes that "extend" this class.
   */
  @Uninterruptible
  public RVMClass[] getSubClasses() {
    return subClasses;
  }

  /**
   * Interfaces implemented directly by this class
   * (ie. not including superclasses).
   */
  @Uninterruptible
  public RVMClass[] getDeclaredInterfaces() {
    return declaredInterfaces;
  }

  /**
   * Fields defined directly by this class (ie. not including superclasses).
   */
  @Uninterruptible
  public RVMField[] getDeclaredFields() {
    return declaredFields;
  }

  /**
   * Does this class directly define a final instance field (has implications for JMM).
   */
  public boolean declaresFinalInstanceField() {
    for (RVMField f : declaredFields) {
      if (f.isFinal() && !f.isStatic()) return true;
    }
    return false;
  }

  /**
   * Methods defined directly by this class (ie. not including superclasses).
   */
  @Uninterruptible
  public RVMMethod[] getDeclaredMethods() {
    return declaredMethods;
  }

  /**
   * Declared inner and static member classes.
   */
  public TypeReference[] getDeclaredClasses() {
    return declaredClasses;
  }

  /**
   * Class that declared this class, or null if this is not an
   * inner/nested class.
   */
  public TypeReference getDeclaringClass() {
    return declaringClass;
  }

  /**
   * Class that immediately encloses this class, or null if this is not an
   * inner/nested class.
   */
  public TypeReference getEnclosingClass() {
    return enclosingClass;
  }

  /**
   * Set the resolvedMember in all declared members.
   */
  void setResolvedMembers() {
    for(RVMField field: declaredFields) {
      /* Make all declared fields appear resolved */
      field.getMemberRef().asFieldReference().setResolvedMember(field);
    }
    for(RVMMethod method: declaredMethods) {
      /* Make all declared methods appear resolved */
      method.getMemberRef().asMethodReference().setResolvedMember(method);
    }
    if (virtualMethods != null) {
      /* Possibly created Miranda methods */
      for(RVMMethod method: virtualMethods) {
        if (method.getDeclaringClass() == this) {
          method.getMemberRef().asMethodReference().setResolvedMember(method);
        }
      }
    }
  }

  /**
   * Static initializer method for this class (null -> no static initializer
   *  or initializer already been run).
   */
  @Uninterruptible
  public RVMMethod getClassInitializerMethod() {
    return classInitializerMethod;
  }

  @Override
  Annotation[] getAnnotationsInternal() {
    final RVMClass parent = getSuperClass();
    if (parent == null) {
      return super.getAnnotationsInternal();
    }
    if (annotations == null) {
      final Annotation[] declared = getDeclaredAnnotations();
      // Not synchronized as it does not matter if occasionally we create two cached copies
      final Annotation[] parentAnnotations = parent.getAnnotations();
      int rejected = 0;
      for (int i = 0; i < parentAnnotations.length; i++) {
        final Annotation pa = parentAnnotations[i];
        final Class<? extends Annotation> paType = pa.annotationType();
        if (!paType.isAnnotationPresent(Inherited.class)) {
          parentAnnotations[i] = null;
          rejected++;
        } else {
          for (final Annotation a : declared) {
            if (a.annotationType().equals(paType)) {
              parentAnnotations[i] = null;
              rejected++;
              break;
            }
          }
        }
      }
      final Annotation[] cache = new Annotation[declared.length + parentAnnotations.length - rejected];
      System.arraycopy(declared, 0, cache, 0, declared.length);
      int index = declared.length;
      for (final Annotation pa : parentAnnotations) {
        if (pa != null) cache[index++] = pa;
      }
      annotations = cache;
    }
    return annotations;
  }

  /**
   * Find description of a field of this class.
   * @param fieldName field name - something like "foo"
   * @param fieldDescriptor field descriptor - something like "I"
   * @return description (null --> not found)
   */
  public RVMField findDeclaredField(Atom fieldName, Atom fieldDescriptor) {
    for (RVMField field : declaredFields) {
      if (field.getName() == fieldName && field.getDescriptor() == fieldDescriptor) {
        return field;
      }
    }
    return null;
  }

  /**
   * Find description of a field of this class. NB. ignores descriptor.
   * @param fieldName field name - something like "foo"
   * @return description (null --> not found)
   */
  public RVMField findDeclaredField(Atom fieldName) {
    for (RVMField field : declaredFields) {
      if (field.getName() == fieldName) {
        return field;
      }
    }
    return null;
  }

  /**
   * Find description of a method of this class.
   * @param methodName method name - something like "foo"
   * @param methodDescriptor method descriptor - something like "()I"
   * @return description (null --> not found)
   */
  public RVMMethod findDeclaredMethod(Atom methodName, Atom methodDescriptor) {
    for (RVMMethod method : declaredMethods) {
      if (method.getName() == methodName && method.getDescriptor() == methodDescriptor) {
        return method;
      }
    }
    return null;
  }

  /**
   * Find the first description of a method of this class.
   * @param methodName method name - something like "foo"
   * @return description (null --> not found)
   */
  public RVMMethod findDeclaredMethod(Atom methodName) {
    for (RVMMethod method : declaredMethods) {
      if (method.getName() == methodName) {
        return method;
      }
    }
    return null;
  }

  /**
   * Find description of "public static void main(String[])"
   * method of this class.
   * @return description (null --> not found)
   */
  public RVMMethod findMainMethod() {
    Atom mainName = Atom.findOrCreateAsciiAtom(("main"));
    Atom mainDescriptor = Atom.findOrCreateAsciiAtom(("([Ljava/lang/String;)V"));
    RVMMethod mainMethod = this.findDeclaredMethod(mainName, mainDescriptor);

    if (mainMethod == null || !mainMethod.isPublic() || !mainMethod.isStatic()) {
      // no such method
      return null;
    }
    return mainMethod;
  }

  /**
   * Add the given cached object.
   */
  public synchronized void addCachedObject(Object o) {
    objectCache.add(o);
  }

  /**
   * Set the imt object.
   */
  public void setIMT(IMT imt) {
    this.imt = imt;
  }

  //
  // Constant pool accessors.
  //
  // The constant pool holds literals and external references used by
  // the bytecodes of this class's methods.
  // Items are fetched by specifying their "constant pool index".
  //

  @Uninterruptible
  private static int packCPEntry(byte type, int value) {
    return (type << 29) | (value & 0x1fffffff);
  }

  @Uninterruptible
  private static byte unpackCPType(int cpValue) {
    return (byte) (cpValue >>> 29);
  }

  @Uninterruptible
  private static int unpackSignedCPValue(int cpValue) {
    return (cpValue << 3) >> 3;
  }

  @Uninterruptible
  private static int unpackUnsignedCPValue(int cpValue) {
    return cpValue & 0x1fffffff;
  }

  @Uninterruptible
  private static boolean packedCPTypeIsClassType(int cpValue) {
    return (cpValue & (7 << 29)) == (CP_CLASS << 29);
  }

  @Uninterruptible
  private static int packTempCPEntry(int index1, int index2) {
    return (index1 << 16) | (index2 & 0xffff);
  }

  @Uninterruptible
  private static int unpackTempCPIndex1(int cpValue) {
    return cpValue >>> 16;
  }

  @Uninterruptible
  private static int unpackTempCPIndex2(int cpValue) {
    return cpValue & 0xffff;
  }

  static int getLiteralSize(int[] constantPool, int constantPoolIndex) {
    int cpValue = constantPool[constantPoolIndex];
    switch (unpackCPType(cpValue)) {
      case CP_INT:
      case CP_FLOAT:
        return BYTES_IN_INT;
      case CP_LONG:
      case CP_DOUBLE:
        return BYTES_IN_LONG;
      case CP_CLASS:
      case CP_STRING:
        return BYTES_IN_ADDRESS;
      default:
        VM._assert(NOT_REACHED);
        return 0;
    }
  }

  /**
   * Get offset of a literal constant, in bytes.
   * Offset is with respect to virtual machine's "table of contents" (jtoc).
   */
  public Offset getLiteralOffset(int constantPoolIndex) {
    return getLiteralOffset(this.constantPool, constantPoolIndex);
  }

  /**
   * Get offset of a literal constant, in bytes.
   * Offset is with respect to virtual machine's "table of contents" (jtoc).
   */
  static Offset getLiteralOffset(int[] constantPool, int constantPoolIndex) {
    int cpValue = constantPool[constantPoolIndex];
    if (VM.VerifyAssertions) {
      int value = unpackSignedCPValue(cpValue);
      byte type = unpackCPType(cpValue);
      switch (type) {
        case CP_INT:
        case CP_FLOAT:
        case CP_LONG:
        case CP_DOUBLE:
        case CP_STRING:
          return Offset.fromIntSignExtend(value);
        case CP_CLASS: {
          int typeId = unpackUnsignedCPValue(cpValue);
          Class<?> literalAsClass = TypeReference.getTypeRef(typeId).resolve().getClassForType();
          return Offset.fromIntSignExtend(Statics.findOrCreateObjectLiteral(literalAsClass));
        }
        default:
          VM._assert(NOT_REACHED);
          return Offset.fromIntSignExtend(0xebad0ff5);
      }
    } else {
      if (packedCPTypeIsClassType(cpValue)) {
        int typeId = unpackUnsignedCPValue(cpValue);
        Class<?> literalAsClass = TypeReference.getTypeRef(typeId).resolve().getClassForType();
        return Offset.fromIntSignExtend(Statics.findOrCreateObjectLiteral(literalAsClass));
      } else {
        int value = unpackSignedCPValue(cpValue);
        return Offset.fromIntSignExtend(value);
      }
    }
  }

  /**
   * Get description of a literal constant.
   */
  static byte getLiteralDescription(int[] constantPool, int constantPoolIndex) {
    int cpValue = constantPool[constantPoolIndex];
    byte type = unpackCPType(cpValue);
    return type;
  }

  /**
   * Get description of a literal constant.
   */
  public byte getLiteralDescription(int constantPoolIndex) {
    int cpValue = constantPool[constantPoolIndex];
    byte type = unpackCPType(cpValue);
    return type;
  }

  /**
   * Get contents of a "typeRef" constant pool entry.
   * @return type that was referenced
   */
  @Uninterruptible
  public TypeReference getTypeRef(int constantPoolIndex) {
    return getTypeRef(constantPool, constantPoolIndex);
  }

  /**
   * Get contents of a "typeRef" constant pool entry.
   * @return type that was referenced
   */
  @Uninterruptible
  static TypeReference getTypeRef(int[] constantPool, int constantPoolIndex) {
    if (constantPoolIndex != 0) {
      int cpValue = constantPool[constantPoolIndex];
      if (VM.VerifyAssertions) VM._assert(unpackCPType(cpValue) == CP_CLASS);
      return TypeReference.getTypeRef(unpackUnsignedCPValue(cpValue));
    } else {
      return null;
    }
  }

  /**
   * Get contents of a "methodRef" constant pool entry.
   */
  @Uninterruptible
  public MethodReference getMethodRef(int constantPoolIndex) {
    return getMethodRef(constantPool, constantPoolIndex);
  }

  /**
   * Get contents of a "methodRef" constant pool entry.
   */
  @Uninterruptible
  static MethodReference getMethodRef(int[] constantPool, int constantPoolIndex) {
    int cpValue = constantPool[constantPoolIndex];
    if (VM.VerifyAssertions) VM._assert(unpackCPType(cpValue) == CP_MEMBER);
    return (MethodReference) MemberReference.getMemberRef(unpackUnsignedCPValue(cpValue));
  }

  /**
   * Get contents of a "fieldRef" constant pool entry.
   */
  @Uninterruptible
  public FieldReference getFieldRef(int constantPoolIndex) {
    int cpValue = constantPool[constantPoolIndex];
    if (VM.VerifyAssertions) VM._assert(unpackCPType(cpValue) == CP_MEMBER);
    return (FieldReference) MemberReference.getMemberRef(unpackUnsignedCPValue(cpValue));
  }

  /**
   * Get contents of a "methodRef" constant pool entry.
   */
  @Uninterruptible
  static FieldReference getFieldRef(int[] constantPool, int constantPoolIndex) {
    int cpValue = constantPool[constantPoolIndex];
    if (VM.VerifyAssertions) VM._assert(unpackCPType(cpValue) == CP_MEMBER);
    return (FieldReference) MemberReference.getMemberRef(unpackUnsignedCPValue(cpValue));
  }

  /**
   * Get contents of a "utf" constant pool entry.
   */
  @Uninterruptible
  Atom getUtf(int constantPoolIndex) {
    int cpValue = constantPool[constantPoolIndex];
    if (VM.VerifyAssertions) VM._assert(unpackCPType(cpValue) == CP_UTF);
    return Atom.getAtom(unpackUnsignedCPValue(cpValue));
  }

  /**
   * Get contents of a "utf" from a constant pool entry.
   */
  @Uninterruptible
  static Atom getUtf(int[] constantPool, int constantPoolIndex) {
    int cpValue = constantPool[constantPoolIndex];
    if (VM.VerifyAssertions) VM._assert(unpackCPType(cpValue) == CP_UTF);
    return Atom.getAtom(unpackUnsignedCPValue(cpValue));
  }

  /**
   * Return true if the SynchronizedObject annotation is present.
   * @see org.vmmagic.pragma.SynchronizedObject
   */
  boolean hasSynchronizedObjectAnnotation() {
    return isAnnotationDeclared(TypeReference.SynchronizedObject);
  }

  /**
   * Should the methods of this class be compiled with special
   * register save/restore logic?
   * @see org.vmmagic.pragma.DynamicBridge
   */
  @Uninterruptible
  public boolean hasDynamicBridgeAnnotation() {
    return isAnnotationDeclared(TypeReference.DynamicBridge);
  }

  /**
   * The methods of this class are only called from native code,
   * they are compiled with
   * a special prolog to interface with the native stack frame.
   */
  @Uninterruptible
  public boolean hasBridgeFromNativeAnnotation() {
    return isAnnotationDeclared(TypeReference.NativeBridge);
  }

  /**
   * Should the methods of this class save incoming registers ?
   * @see org.vmmagic.pragma.SaveVolatile
   */
  public boolean hasSaveVolatileAnnotation() {
    return isAnnotationDeclared(TypeReference.SaveVolatile);
  }

  //--------------------------------------------------------------------//
  // The following are available after the class has been "resolved".   //
  //--------------------------------------------------------------------//

  /**
   * Does this class override java.lang.Object.finalize()?
   */
  @Override
  @Pure
  @Uninterruptible
  public boolean hasFinalizer() {
    if (VM.VerifyAssertions) VM._assert(isResolved());
    return (finalizeMethod != null);
  }

  /**
   * Get finalize method that overrides java.lang.Object.finalize(),
   * if one exists
   */
  @Uninterruptible
  public RVMMethod getFinalizer() {
    if (VM.VerifyAssertions) VM._assert(isResolved());
    return finalizeMethod;
  }

  /**
   * Static fields of this class.
   * Values in these fields are shared by all class instances.
   */
  @Override
  @Pure
  public RVMField[] getStaticFields() {
    if (VM.VerifyAssertions) VM._assert(isResolved());
    return staticFields;
  }

  /**
   * Non-static fields of this class (composed with supertypes, if any).
   * Values in these fields are distinct for each class instance.
   */
  @Override
  @Pure
  public RVMField[] getInstanceFields() {
    if (VM.VerifyAssertions) VM._assert(isResolved());
    return instanceFields;
  }

  /**
   * Statically dispatched methods of this class.
   */
  @Override
  @Pure
  public RVMMethod[] getStaticMethods() {
    if (VM.VerifyAssertions) VM._assert(isResolved());
    return staticMethods;
  }

  /**
   * Constructors (<init>) methods of this class.
   */
  @Pure
  public RVMMethod[] getConstructorMethods() {
    if (VM.VerifyAssertions) VM._assert(isResolved(), "Error class " + this + " is not resolved but " + state);
    return constructorMethods;
  }

  /**
   * Virtually dispatched methods of this class
   * (composed with supertypes, if any).
   */
  @Override
  @Pure
  public RVMMethod[] getVirtualMethods() {
    if (VM.VerifyAssertions) VM._assert(isResolved());
    return virtualMethods;
  }

  /**
   * @return All of the interfaces implemented by this class either
   * directly or by inheritance from superclass and superinterfaces
   * recursively.
   */
  @Pure
  public RVMClass[] getAllImplementedInterfaces() {
    if (VM.VerifyAssertions) VM._assert(isResolved());
    int count = 0;
    int[] doesImplement = getDoesImplement();
    for (int mask : doesImplement) {
      while (mask != 0) {
        count++;
        mask &= (mask - 1); // clear lsb 1 bit
      }
    }
    if (count == 0) return emptyVMClass;
    RVMClass[] ans = new RVMClass[count];
    for (int i = 0, idx = 0; i < doesImplement.length; i++) {
      int mask = doesImplement[i];
      if (mask != 0) {
        for (int j = 0; j < 32; j++) {
          if ((mask & (1 << j)) != 0) {
            int id = 32 * i + j;
            ans[idx++] = RVMClass.getInterface(id);
          }
        }
      }
    }
    return ans;
  }

  /**
   * Total size, in bytes, of an instance of this class
   * (including object header).
   */
  @Uninterruptible
  public int getInstanceSize() {
    if (VM.VerifyAssertions) VM._assert(isResolved());
    return instanceSize;
  }

  /**
   * Total size, in bytes, of an instance of this class (including
   * object header). Doesn't perform any verification.
   */
  @Uninterruptible
  public int getInstanceSizeInternal() {
    return instanceSize;
  }

  /**
   * Set the size of the instance. Only meant to be called from
   * ObjectModel et al. must be called when lock on class object
   * is already held (ie from resolve).
   */
  @Uninterruptible
  public void setInstanceSizeInternal(int size) {
    instanceSize = size;
  }

  /**
   * Offsets of reference-containing instance fields of this class type.
   * Offsets are with respect to object pointer -- see RVMField.getOffset().
   */
  @Uninterruptible
  public int[] getReferenceOffsets() {
    if (VM.VerifyAssertions) VM._assert(isResolved());
    return referenceOffsets;
  }

  /**
   * @return number of fields that are non-final
   */
  public int getNumberOfNonFinalReferences() {
    int count = 0;
    for(RVMField field: declaredFields) {
      if (!field.isFinal()) {
        count++;
      }
    }
    return count;
  }

  /**
   * Set object representing available holes in the field layout
   */
  public FieldLayoutContext getFieldLayoutContext() {
    return fieldLayoutContext;
  }

  /**
   * Set object representing available holes in the field layout
   */
  public void setFieldLayoutContext(FieldLayoutContext newLayout) {
    fieldLayoutContext = isFinal() ? null : newLayout;
  }

  /**
   * @return alignment for instances of this class type
   */
  @Uninterruptible
  public int getAlignment() {
    if (BYTES_IN_ADDRESS == BYTES_IN_DOUBLE) {
      return BYTES_IN_ADDRESS;
    } else {
      return alignment;
    }
  }

  /**
   * Set the alignment for instances of this class type
   */
  public void setAlignment(int align) {
    if (BYTES_IN_ADDRESS != BYTES_IN_DOUBLE) {
      if (VM.VerifyAssertions) VM._assert(align >= alignment);
      alignment = align;
    }
  }

  /**
   * Find specified static method description.
   * @param memberName method name - something like "foo"
   * @param memberDescriptor method descriptor - something like "I" or "()I"
   * @return method description (null --> not found)
   */
  @Pure
  public RVMMethod findStaticMethod(Atom memberName, Atom memberDescriptor) {
    if (VM.VerifyAssertions) VM._assert(isResolved());
    RVMMethod[] methods = getStaticMethods();
    for (int i = 0, n = methods.length; i < n; ++i) {
      RVMMethod method = methods[i];
      if (method.getName() == memberName && method.getDescriptor() == memberDescriptor) {
        return method;
      }
    }
    return null;
  }

  /**
   * Find specified initializer method description.
   * @param  memberDescriptor  init method descriptor - something like "(I)V"
   * @return method description (null --> not found)
   */
  @Pure
  public RVMMethod findInitializerMethod(Atom memberDescriptor) {
    if (VM.VerifyAssertions) VM._assert(isResolved());
    RVMMethod[] methods = getConstructorMethods();
    for (int i = 0, n = methods.length; i < n; ++i) {
      RVMMethod method = methods[i];
      if (method.getDescriptor() == memberDescriptor) {
        return method;
      }
    }
    return null;
  }

  /**
   * Runtime type information for this class type.
   */
  @Override
  @Uninterruptible
  public TIB getTypeInformationBlock() {
    if (VM.VerifyAssertions) VM._assert(isResolved());
    return typeInformationBlock;
  }

  //--------------------------------------------------------------------//
  //                     Miscellaneous queries.                         //
  //---------------------------------------------------------------------//

  /**
   * Support for user-written class loaders:
   * It's required to find the classloader of the class
   * whose method requires another class to be loaded;
   * the initiating loader of the required class is the
   * defining loader of the requiring class.
   *
   *
   * @param skip specifies the number of frames back from the
   *             caller to the method whose class's loader is required
   */
  public static ClassLoader getClassLoaderFromStackFrame(int skip) {
    skip++; // account for stack frame of this function
    StackBrowser browser = new StackBrowser();
    VM.disableGC();
    browser.init();
    while (skip-- > 0) browser.up();
    VM.enableGC();
    return browser.getClassLoader();
  }

  /**
   * Used for accessibility checks in reflection code.
   * Find the class of the method that corresponds to the requested frame.
   *
   * @param skip   Specifies the number of frames back from the
   *               caller to the method whose class is required
   */
  public static RVMClass getClassFromStackFrame(int skip) {
    skip++; // account for stack frame of this function
    StackBrowser browser = new StackBrowser();
    VM.disableGC();
    browser.init();
    while (skip-- > 0) browser.up();
    VM.enableGC();
    return browser.getCurrentClass();
  }

  /**
   * Should assertions be enabled on this type?
   */
  @Override
  @Pure
  public boolean getDesiredAssertionStatus() {
    return desiredAssertionStatus;
  }

  //--------------------------------------------------------------------//
  //      Load, Resolve, Instantiate, and Initialize                    //
  //--------------------------------------------------------------------//

  /**
   * Construct a class from its constituent loaded parts
   *
   * @param typeRef the type reference that was resolved to this class
   * @param constantPool array of ints encoding constant value
   * @param modifiers {@link org.jikesrvm.classloader.ClassLoaderConstants}
   * @param superClass parent of this class
   * @param declaredInterfaces array of interfaces this class implements
   * @param declaredFields fields of the class
   * @param declaredMethods methods of the class
   * @param declaredClasses declared inner classes
   * @param declaringClass outer class if an inner class
   * @param sourceName source file name
   * @param classInitializerMethod handle to class initializer method
   * @param signature the generic type name for this class
   * @param annotations array of runtime visible annotations
   */
  private RVMClass(TypeReference typeRef, int[] constantPool, short modifiers, RVMClass superClass,
                   RVMClass[] declaredInterfaces, RVMField[] declaredFields, RVMMethod[] declaredMethods,
                   TypeReference[] declaredClasses, TypeReference declaringClass, TypeReference enclosingClass,
                   MethodReference enclosingMethod, Atom sourceName, RVMMethod classInitializerMethod,
                   Atom signature, RVMAnnotation[] annotations) {
    super(typeRef, 0, annotations);
    if (VM.VerifyAssertions) VM._assert(!getTypeRef().isUnboxedType());
    if (VM.VerifyAssertions && null != superClass) VM._assert(!superClass.getTypeRef().isUnboxedType());

    // final fields
    this.constantPool = constantPool;
    this.modifiers = modifiers;
    this.superClass = superClass;
    this.declaredInterfaces = declaredInterfaces;
    this.declaredFields = declaredFields;
    this.declaredMethods = declaredMethods;
    this.declaredClasses = declaredClasses;
    this.declaringClass = declaringClass;
    this.enclosingClass = enclosingClass;
    this.enclosingMethod = enclosingMethod;
    this.sourceName = sourceName;
    this.classInitializerMethod = classInitializerMethod;
    this.signature = signature;
    this.objectCache = new LinkedListRVM<Object>();

    // non-final fields
    this.subClasses = emptyVMClass;
    state = CLASS_LOADED;

    // we're about to leak a reference to 'this' force memory to be
    // consistent
    Magic.sync();

    if (superClass != null) {
      // MUST wait until end of constructor to 'publish' the subclass link.
      // If we do this earlier, then people can see an incomplete RVMClass object
      // by traversing the subclasses of our superclass!
      superClass.addSubClass(this);
    }

    this.desiredAssertionStatus = RVMClassLoader.getDesiredAssertionStatus(this);

    Callbacks.notifyClassLoaded(this);

    if (VM.TraceClassLoading && VM.runningVM) {
      VM.sysWriteln("RVMClass: (end)   load file " + typeRef.getName());
    }
    if (VM.verboseClassLoading) VM.sysWrite("[Loaded " + toString() + "]\n");
  }

  /**
   * Create an instance of a RVMClass.
   * @param typeRef the cannonical type reference for this type.
   * @param input the data stream from which to read the class's description.
   */
  static RVMClass readClass(TypeReference typeRef, DataInputStream input) throws ClassFormatError, IOException {

    if (classLoadingDisabled) {
      throw new RuntimeException("ClassLoading Disabled : " + typeRef);
    }

    if (VM.TraceClassLoading && VM.runningVM) {
      VM.sysWrite("RVMClass: (begin) load file " + typeRef.getName() + "\n");
    }

    int magic = input.readInt();
    if (magic != 0xCAFEBABE) {
      throw new ClassFormatError("bad magic number " + Integer.toHexString(magic));
    }

    // Get the class file version number and check to see if it is a version
    // that we support.
    int minor = input.readUnsignedShort();
    int major = input.readUnsignedShort();
    switch (major) {
      case 45:
      case 46:
      case 47:
      case 48:
      case 49: // we support all variants of these major versions so the minor number doesn't matter.
        break;
      case 50: // we only support up to 50.0 (ie Java 1.6.0)
        if (minor == 0) break;
      default:
        throw new UnsupportedClassVersionError("unsupported class file version " + major + "." + minor);
    }

    //
    // pass 1: read constant pool
    //
    int[] constantPool = new int[input.readUnsignedShort()];
    byte[] tmpTags = new byte[constantPool.length];

    // note: slot 0 is unused
    for (int i = 1; i < constantPool.length; i++) {
      tmpTags[i] = input.readByte();
      switch (tmpTags[i]) {
        case TAG_UTF: {
          byte[] utf = new byte[input.readUnsignedShort()];
          input.readFully(utf);
          int atomId = Atom.findOrCreateUtf8Atom(utf).getId();
          constantPool[i] = packCPEntry(CP_UTF, atomId);
          break;
        }
        case TAG_UNUSED:
          if (VM.VerifyAssertions) VM._assert(NOT_REACHED);
          break;

        case TAG_INT: {
          int literal = input.readInt();
          int offset = Statics.findOrCreateIntSizeLiteral(literal);
          constantPool[i] = packCPEntry(CP_INT, offset);
          break;
        }
        case TAG_FLOAT: {
          int literal = input.readInt();
          int offset = Statics.findOrCreateIntSizeLiteral(literal);
          constantPool[i] = packCPEntry(CP_FLOAT, offset);
          break;
        }
        case TAG_LONG: {
          long literal = input.readLong();
          int offset = Statics.findOrCreateLongSizeLiteral(literal);
          constantPool[i] = packCPEntry(CP_LONG, offset);
          i++;
          break;
        }
        case TAG_DOUBLE: {
          long literal = input.readLong();
          int offset = Statics.findOrCreateLongSizeLiteral(literal);
          constantPool[i] = packCPEntry(CP_DOUBLE, offset);
          i++;
          break;
        }
        case TAG_TYPEREF:
          constantPool[i] = input.readUnsignedShort();
          break;

        case TAG_STRING:
          constantPool[i] = input.readUnsignedShort();
          break;

        case TAG_FIELDREF:
        case TAG_METHODREF:
        case TAG_INTERFACE_METHODREF: {
          int classDescriptorIndex = input.readUnsignedShort();
          int memberNameAndDescriptorIndex = input.readUnsignedShort();
          constantPool[i] = packTempCPEntry(classDescriptorIndex, memberNameAndDescriptorIndex);
          break;
        }

        case TAG_MEMBERNAME_AND_DESCRIPTOR: {
          int memberNameIndex = input.readUnsignedShort();
          int descriptorIndex = input.readUnsignedShort();
          constantPool[i] = packTempCPEntry(memberNameIndex, descriptorIndex);
          break;
        }

        default:
          throw new ClassFormatError("bad constant pool");
      }
    }

    //
    // pass 2: post-process type and string constant pool entries
    // (we must do this in a second pass because of forward references)
    //
    try {
      for (int i = 1; i < constantPool.length; i++) {
        switch (tmpTags[i]) {
          case TAG_LONG:
          case TAG_DOUBLE:
            ++i;
            break;

          case TAG_TYPEREF: { // in: utf index
            Atom typeName = getUtf(constantPool, constantPool[i]);
            int typeRefId =
                TypeReference.findOrCreate(typeRef.getClassLoader(), typeName.descriptorFromClassName()).getId();
            constantPool[i] = packCPEntry(CP_CLASS, typeRefId);
            break;
          } // out: type reference id

          case TAG_STRING: { // in: utf index
            Atom literal = getUtf(constantPool, constantPool[i]);
            int offset = literal.getStringLiteralOffset();
            constantPool[i] = packCPEntry(CP_STRING, offset);
            break;
          } // out: jtoc slot number
        }
      }
    } catch (java.io.UTFDataFormatException x) {
      throw new ClassFormatError(x.toString());
    }

    //
    // pass 3: post-process type field and method constant pool entries
    //
    for (int i = 1; i < constantPool.length; i++) {
      switch (tmpTags[i]) {
        case TAG_LONG:
        case TAG_DOUBLE:
          ++i;
          break;

        case TAG_FIELDREF:
        case TAG_METHODREF:
        case TAG_INTERFACE_METHODREF: { // in: classname+membername+memberdescriptor indices
          int bits = constantPool[i];
          int classNameIndex = unpackTempCPIndex1(bits);
          int memberNameAndDescriptorIndex = unpackTempCPIndex2(bits);
          int memberNameAndDescriptorBits = constantPool[memberNameAndDescriptorIndex];
          int memberNameIndex = unpackTempCPIndex1(memberNameAndDescriptorBits);
          int memberDescriptorIndex = unpackTempCPIndex2(memberNameAndDescriptorBits);

          TypeReference tref = getTypeRef(constantPool, classNameIndex);
          Atom memberName = getUtf(constantPool, memberNameIndex);
          Atom memberDescriptor = getUtf(constantPool, memberDescriptorIndex);
          MemberReference mr = MemberReference.findOrCreate(tref, memberName, memberDescriptor);
          int mrId = mr.getId();
          constantPool[i] = packCPEntry(CP_MEMBER, mrId);
          break;
        } // out: MemberReference id
      }
    }

    short modifiers = input.readShort();
    int myTypeIndex = input.readUnsignedShort();
    TypeReference myTypeRef = getTypeRef(constantPool, myTypeIndex);
    if (myTypeRef != typeRef) {
      // eg. file contains a different class than would be
      // expected from its .class file name
      if (!VM.VerifyAssertions) {
        throw new ClassFormatError("expected class \"" +
                                   typeRef.getName() +
                                   "\" but found \"" +
                                   myTypeRef.getName() +
                                   "\"");
      } else {
        throw new ClassFormatError("expected class \"" +
                                   typeRef.getName() +
                                   "\" but found \"" +
                                   myTypeRef.getName() +
                                   "\"\n" + typeRef + " != " + myTypeRef);
      }
    }

    TypeReference superType = getTypeRef(constantPool, input.readUnsignedShort()); // possibly null
    RVMClass superClass = null;
    if (((modifiers & ACC_INTERFACE) == 0) && (superType != null)) {
      superClass = superType.resolve().asClass();
    }

    int numInterfaces = input.readUnsignedShort();
    RVMClass[] declaredInterfaces;
    if (numInterfaces == 0) {
      declaredInterfaces = emptyVMClass;
    } else {
      declaredInterfaces = new RVMClass[numInterfaces];
      for (int i = 0; i < numInterfaces; ++i) {
        TypeReference inTR = getTypeRef(constantPool, input.readUnsignedShort());
        declaredInterfaces[i] = inTR.resolve().asClass();
      }
    }

    int numFields = input.readUnsignedShort();
    RVMField[] declaredFields;
    if (numFields == 0) {
      declaredFields = emptyVMField;
    } else {
      declaredFields = new RVMField[numFields];
      for (int i = 0; i < numFields; i++) {
        short fmodifiers = input.readShort();
        Atom fieldName = getUtf(constantPool, input.readUnsignedShort());
        Atom fieldDescriptor = getUtf(constantPool, input.readUnsignedShort());
        MemberReference memRef = MemberReference.findOrCreate(typeRef, fieldName, fieldDescriptor);
        declaredFields[i] = RVMField.readField(typeRef, constantPool, memRef, fmodifiers, input);
      }
    }

    int numMethods = input.readUnsignedShort();
    RVMMethod[] declaredMethods;
    RVMMethod classInitializerMethod = null;
    if (numMethods == 0) {
      declaredMethods = emptyVMMethod;
    } else {
      declaredMethods = new RVMMethod[numMethods];
      for (int i = 0; i < numMethods; i++) {
        short mmodifiers = input.readShort();
        Atom methodName = getUtf(constantPool, input.readUnsignedShort());
        Atom methodDescriptor = getUtf(constantPool, input.readUnsignedShort());
        MemberReference memRef = MemberReference.findOrCreate(typeRef, methodName, methodDescriptor);
        RVMMethod method = RVMMethod.readMethod(typeRef, constantPool, memRef, mmodifiers, input);
        declaredMethods[i] = method;
        if (method.isClassInitializer()) {
          classInitializerMethod = method;
        }
      }
    }
    TypeReference[] declaredClasses = null;
    Atom sourceName = null;
    TypeReference declaringClass = null;
    Atom signature = null;
    RVMAnnotation[] annotations = null;
    TypeReference enclosingClass = null;
    MethodReference enclosingMethod = null;
    // Read attributes.
    for (int i = 0, n = input.readUnsignedShort(); i < n; ++i) {
      Atom attName = getUtf(constantPool, input.readUnsignedShort());
      int attLength = input.readInt();

      // Class attributes
      if (attName == RVMClassLoader.sourceFileAttributeName && attLength == 2) {
        sourceName = getUtf(constantPool, input.readUnsignedShort());
      } else if (attName == RVMClassLoader.innerClassesAttributeName) {
        // Parse InnerClasses attribute, and use the information to populate
        // the list of declared member classes.  We do this so we can
        // support the java.lang.Class.getDeclaredClasses()
        // and java.lang.Class.getDeclaredClass methods.

        int numberOfClasses = input.readUnsignedShort();
        declaredClasses = new TypeReference[numberOfClasses];

        for (int j = 0; j < numberOfClasses; ++j) {
          int innerClassInfoIndex = input.readUnsignedShort();
          int outerClassInfoIndex = input.readUnsignedShort();
          int innerNameIndex = input.readUnsignedShort();
          int innerClassAccessFlags = input.readUnsignedShort();

          if (innerClassInfoIndex != 0 && outerClassInfoIndex == myTypeIndex && innerNameIndex != 0) {
            // This looks like a declared inner class.
            declaredClasses[j] = getTypeRef(constantPool, innerClassInfoIndex);
          }

          if (innerClassInfoIndex == myTypeIndex) {
            if (outerClassInfoIndex != 0) {
              declaringClass = getTypeRef(constantPool, outerClassInfoIndex);
              if (enclosingClass == null) {
                // TODO: is this the null test necessary?
                enclosingClass = declaringClass;
              }
            }
            if ((innerClassAccessFlags & (ACC_PRIVATE | ACC_PROTECTED)) != 0) {
              modifiers &= ~(ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
            }
            modifiers |= innerClassAccessFlags;
          }
        }
      } else if (attName == RVMClassLoader.syntheticAttributeName) {
        modifiers |= ACC_SYNTHETIC;
      } else if (attName == RVMClassLoader.enclosingMethodAttributeName) {
        int enclosingClassIndex = input.readUnsignedShort();
        enclosingClass = getTypeRef(constantPool, enclosingClassIndex);

        int enclosingMethodIndex = input.readUnsignedShort();
        if (enclosingMethodIndex != 0) {
          int memberNameIndex = constantPool[enclosingMethodIndex] >>> BITS_IN_SHORT;
          int memberDescriptorIndex = constantPool[enclosingMethodIndex] & ((1 << BITS_IN_SHORT) - 1);
          Atom memberName = getUtf(constantPool, memberNameIndex);
          Atom memberDescriptor = getUtf(constantPool, memberDescriptorIndex);
          enclosingMethod =
              MemberReference.findOrCreate(enclosingClass, memberName, memberDescriptor).asMethodReference();
        }
      } else if (attName == RVMClassLoader.signatureAttributeName) {
        signature = RVMClass.getUtf(constantPool, input.readUnsignedShort());
      } else if (attName == RVMClassLoader.runtimeVisibleAnnotationsAttributeName) {
        annotations = AnnotatedElement.readAnnotations(constantPool, input, typeRef.getClassLoader());
      } else {
        int skippedAmount = input.skipBytes(attLength);
        if (skippedAmount != attLength) {
          throw new IOException("Unexpected short skip");
        }
      }
    }

    return new RVMClass(typeRef,
                        constantPool,
                        modifiers,
                        superClass,
                        declaredInterfaces,
                        declaredFields,
                        declaredMethods,
                        declaredClasses,
                        declaringClass,
                        enclosingClass,
                        enclosingMethod,
                        sourceName,
                        classInitializerMethod,
                        signature,
                        annotations);
  }

  /**
   * Generate size and offset information for members of this class and
   * allocate space in jtoc for static fields, static methods, and virtual
   * method table.
   * Side effects: superclasses and superinterfaces are resolved.
   */
  @Override
  public synchronized void resolve() {
    if (isResolved()) return;
    if (VM.TraceClassLoading && VM.runningVM) VM.sysWriteln("RVMClass: (begin) resolve " + this);
    if (VM.VerifyAssertions) VM._assert(state == CLASS_LOADED);

    // Resolve superclass and super interfaces
    //
    if (superClass != null) {
      superClass.resolve();
    }
    for (RVMClass declaredInterface : declaredInterfaces) {
      declaredInterface.resolve();
    }

    if (isInterface()) {
      if (VM.VerifyAssertions) VM._assert(superClass == null);
      depth = 1;
      thinLockOffset = Offset.max();
    } else if (superClass == null) {
      if (VM.VerifyAssertions) VM._assert(isJavaLangObjectType());
      instanceSize = ObjectModel.computeScalarHeaderSize(this);
      alignment = BYTES_IN_ADDRESS;
      thinLockOffset = ObjectModel.defaultThinLockOffset();
      depth=0;
    } else {
      depth = superClass.depth + 1;
      thinLockOffset = superClass.thinLockOffset;
      instanceSize = superClass.instanceSize;
      fieldLayoutContext = superClass.fieldLayoutContext;
      alignment = superClass.alignment;
    }

    if (hasSynchronizedObjectAnnotation() || this == RVMType.JavaLangClassType) {
      ObjectModel.allocateThinLock(this);
    }

    if (superClass != null && superClass.isNonMoving() && !isNonMoving()) {
      VM.sysWriteln("WARNING: movable " + this + " extends non-moving " + superClass);
    }

    if (VM.verboseClassLoading) VM.sysWrite("[Preparing " + this + "]\n");

    // build field and method lists for this class
    //
    {
      FieldVector staticFields = new FieldVector();
      FieldVector instanceFields = new FieldVector();
      MethodVector staticMethods = new MethodVector();
      MethodVector constructorMethods = new MethodVector();
      MethodVector virtualMethods = new MethodVector();

      // start with fields and methods of superclass
      //
      if (superClass != null) {
        RVMField[] fields = superClass.getInstanceFields();
        for (int i = 0, n = fields.length; i < n; ++i) {
          instanceFields.addElement(fields[i]);
        }

        RVMMethod[] methods = superClass.getVirtualMethods();
        for (int i = 0, n = methods.length; i < n; ++i) {
          virtualMethods.addElement(methods[i]);
        }
      }

      // append fields defined by this class
      //
      RVMField[] fields = getDeclaredFields();
      for (int i = 0, n = fields.length; i < n; ++i) {
        RVMField field = fields[i];
        if (field.isStatic()) {
          staticFields.addElement(field);
        } else {
          instanceFields.addElement(field);
        }
      }

      // append/overlay methods defined by this class
      //
      RVMMethod[] methods = getDeclaredMethods();
      for (int i = 0, n = methods.length; i < n; ++i) {
        RVMMethod method = methods[i];

        if (VM.VerifyUnint) {
          if (method.isSynchronized() && method.isUninterruptible()) {
            if (VM.ParanoidVerifyUnint || !method.hasLogicallyUninterruptibleAnnotation()) {
              VM.sysWriteln("WARNING: " + method + " cannot be both uninterruptible and synchronized");
            }
          }
        }

        if (method.isObjectInitializer()) {
          Callbacks.notifyMethodOverride(method, null);
          constructorMethods.addElement(method);
        } else if (method.isStatic()) {
          if (!method.isClassInitializer()) {
            Callbacks.notifyMethodOverride(method, null);
            staticMethods.addElement(method);
          }
        } else { // Virtual method

          if (method.isSynchronized()) {
            ObjectModel.allocateThinLock(this);
          }

          // method could override something in superclass - check for it
          //
          int superclassMethodIndex = -1;
          for (int j = 0, m = virtualMethods.size(); j < m; ++j) {
            RVMMethod alreadyDefinedMethod = virtualMethods.elementAt(j);
            if (alreadyDefinedMethod.getName() == method.getName() &&
                alreadyDefinedMethod.getDescriptor() == method.getDescriptor()) {
              // method already defined in superclass
              superclassMethodIndex = j;
              break;
            }
          }

          if (superclassMethodIndex == -1) {
            Callbacks.notifyMethodOverride(method, null);
            virtualMethods.addElement(method);                          // append
          } else {
            RVMMethod superc = virtualMethods.elementAt(superclassMethodIndex);
            if (VM.VerifyUnint) {
              if (!superc.isInterruptible() && method.isInterruptible()) {
                VM.sysWriteln("WARNING: interruptible " + method + " overrides uninterruptible " + superc);
              }
            }
            Callbacks.notifyMethodOverride(method, superc);
            virtualMethods.setElementAt(method, superclassMethodIndex); // override
          }
        }
      }

      // Deal with Miranda methods.
      // If this is an abstract class, then for each
      // interface that this class implements, ensure that a corresponding virtual
      // method is declared.  If one is not, then create an abstract method to fill the void.
      if (!isInterface() && isAbstract()) {
        for (RVMClass I : declaredInterfaces) {
          RVMMethod[] iMeths = I.getVirtualMethods();
          outer:
          for (RVMMethod iMeth : iMeths) {
            Atom iName = iMeth.getName();
            Atom iDesc = iMeth.getDescriptor();
            for (int k = 0; k < virtualMethods.size(); k++) {
              RVMMethod vMeth = virtualMethods.elementAt(k);
              if (vMeth.getName() == iName && vMeth.getDescriptor() == iDesc) continue outer;
            }
            MemberReference mRef = MemberReference.findOrCreate(typeRef, iName, iDesc);
            virtualMethods.addElement(new AbstractMethod(getTypeRef(),
                                                            mRef,
                                                            (short) (ACC_ABSTRACT | ACC_PUBLIC),
                                                            iMeth.getExceptionTypes(),
                                                            null,
                                                            null,
                                                            null,
                                                            null));
          }
        }
      }

      // If this is an interface, inherit methods from its superinterfaces
      if (isInterface()) {
        for (RVMClass declaredInterface : declaredInterfaces) {
          RVMMethod[] meths = declaredInterface.getVirtualMethods();
          for (RVMMethod meth : meths) {
            virtualMethods.addUniqueElement(meth);
          }
        }
      }

      this.staticFields = staticFields.finish();
      this.instanceFields = instanceFields.finish();
      this.staticMethods = staticMethods.finish();
      this.constructorMethods = constructorMethods.finish();
      this.virtualMethods = virtualMethods.finish();
    }

    // allocate space for class fields
    //
    for (int i = 0, n = staticFields.length; i < n; ++i) {
      RVMField field = staticFields[i];
      if (field.isReferenceType()) {
        field.setOffset(Statics.allocateReferenceSlot(true));
      } else if (field.getSize() <= BYTES_IN_INT) {
        field.setOffset(Statics.allocateNumericSlot(BYTES_IN_INT, true));
      } else {
        field.setOffset(Statics.allocateNumericSlot(BYTES_IN_LONG, true));
      }

      // (SJF): Serialization nastily accesses even final private static
      //           fields via pseudo-reflection! So, we must shove the
      //           values of final static fields into the JTOC.  Now
      //           seems to be a good time.
      if (field.isFinal()) {
        setFinalStaticJTOCEntry(field, field.getOffset());
      }
    }

    // lay out instance fields
    //
    ObjectModel.layoutInstanceFields(this);

    // count reference fields
    int referenceFieldCount = 0;
    for (int i = 0, n = instanceFields.length; i < n; ++i) {
      RVMField field = instanceFields[i];
      if (field.isTraced()) {
        referenceFieldCount += 1;
      }
    }

    // record offsets of those instance fields that contain references
    //
    if (typeRef.isRuntimeTable()) {
      referenceOffsets = MemoryManager.newNonMovingIntArray(0);
    } else {
      referenceOffsets = MemoryManager.newNonMovingIntArray(referenceFieldCount);
      for (int i = 0, j = 0, n = instanceFields.length; i < n; ++i) {
        RVMField field = instanceFields[i];
        if (field.isTraced()) {
          referenceOffsets[j++] = field.getOffset().toInt();
        }
      }
    }

    // Allocate space for <init> method pointers
    //
    for (int i = 0, n = constructorMethods.length; i < n; ++i) {
      RVMMethod method = constructorMethods[i];
      method.setOffset(Statics.allocateReferenceSlot(true));
    }

    // Allocate space for static method pointers
    //
    for (int i = 0, n = staticMethods.length; i < n; ++i) {
      RVMMethod method = staticMethods[i];
      if (method.isClassInitializer()) {
        method.setOffset(Offset.fromIntZeroExtend(0xebad0ff5)); // should never be used.
      } else {
        method.setOffset(Statics.allocateReferenceSlot(true));
      }
    }

    if (!isInterface()) {
      // lay out virtual method section of type information block
      // (to be filled in by instantiate)
      for (int i = 0, n = virtualMethods.length; i < n; ++i) {
        RVMMethod method = virtualMethods[i];
        method.setOffset(TIB.getVirtualMethodOffset(i));
      }
    }

    // RCGC: Determine if class is inherently acyclic
    acyclic = false;    // must initially be false for recursive types
    boolean foundCyclic = false;
    for (RVMField instanceField : instanceFields) {
      TypeReference ft = instanceField.getType();
      if (!ft.isResolved() || !ft.peekType().isAcyclicReference()) {
        foundCyclic = true;
        break;
      }
    }
    if (!foundCyclic) {
      acyclic = true;
    }

    // allocate "type information block"
    TIB allocatedTib;
    if (isInterface()) {
      allocatedTib = MemoryManager.newTIB(0);
    } else {
      allocatedTib = MemoryManager.newTIB(virtualMethods.length);
    }

    superclassIds = DynamicTypeCheck.buildSuperclassIds(this);
    doesImplement = DynamicTypeCheck.buildDoesImplement(this);

    // can't move this beyond "finalize" code block as findVirtualMethod
    // assumes state >= RESOLVED, no allocation occurs until
    // state >= CLASS_INITIALIZING
    publishResolved(allocatedTib, superclassIds, doesImplement);

    // TODO: Make this into a more general listener interface
    if (VM.BuildForOptCompiler && VM.writingBootImage) {
      classLoadListener.classInitialized(this, true);
    }

    Callbacks.notifyClassResolved(this);
    MemoryManager.notifyClassResolved(this);

    // check for a "finalize" method that overrides the one in java.lang.Object
    //
    finalizeMethod = null;
    if (!isInterface()) {
      final RVMMethod method =
          findVirtualMethod(RVMClassLoader.StandardObjectFinalizerMethodName,
                            RVMClassLoader.StandardObjectFinalizerMethodDescriptor);
      if (!method.getDeclaringClass().isJavaLangObjectType()) {
        finalizeMethod = method;
      }
    }

    if (VM.TraceClassLoading && VM.runningVM) VM.sysWriteln("RVMClass: (end)   resolve " + this);
  }

  /**
   * Atomically initialize the important parts of the TIB and let the world know this type is
   * resolved.
   *
   * @param allocatedTib The TIB that has been allocated for this type
   * @param superclassIds The calculated superclass ids array
   * @param doesImplement The calculated does implement array
   */
  @Uninterruptible
  private void publishResolved(TIB allocatedTib, short[] superclassIds, int[] doesImplement) {
    Statics.setSlotContents(getTibOffset(), allocatedTib);
    allocatedTib.setType(this);
    allocatedTib.setSuperclassIds(superclassIds);
    allocatedTib.setDoesImplement(doesImplement);
    typeInformationBlock = allocatedTib;
    state = CLASS_RESOLVED;
  }

  @Override
  public void allBootImageTypesResolved() {
    for (RVMMethod method : declaredMethods) {
      if (method instanceof NormalMethod) {
        ((NormalMethod)method).recomputeSummary(constantPool);
      }
    }
  }

  // RCGC: A reference to class is acyclic if the class is acyclic and
  // final (otherwise the reference could be to a subsequently loaded
  // cyclic subclass).
  //
  @Override
  @Uninterruptible
  public boolean isAcyclicReference() {
    return acyclic && isFinal();
  }

  /**
   * Insert the value of a final static field into the JTOC
   */
  private void setFinalStaticJTOCEntry(RVMField field, Offset fieldOffset) {
    if (!field.isFinal()) return;

    // value Index: index into the classes constant pool.
    int valueIndex = field.getConstantValueIndex();

    // if there's no value in the constant pool, bail out
    if (valueIndex <= 0) return;

    Offset literalOffset = field.getDeclaringClass().getLiteralOffset(valueIndex);

    if (Statics.isReference(Statics.offsetAsSlot(fieldOffset))) {
      Object obj = Statics.getSlotContentsAsObject(literalOffset);
      Statics.setSlotContents(fieldOffset, obj);
    } else if (field.getSize() <= BYTES_IN_INT) {
      // copy one word from constant pool to JTOC
      int value = Statics.getSlotContentsAsInt(literalOffset);
      Statics.setSlotContents(fieldOffset, value);
    } else {
      // copy two words from constant pool to JTOC
      long value = Statics.getSlotContentsAsLong(literalOffset);
      Statics.setSlotContents(fieldOffset, value);
    }
  }

  /**
   * Compile this class's methods, build type information block, populate jtoc.
   * Side effects: superclasses are instantiated.
   */
  @Override
  public synchronized void instantiate() {
    if (isInstantiated()) {
      return;
    }

    if (VM.TraceClassLoading && VM.runningVM) VM.sysWriteln("RVMClass: (begin) instantiate " + this);
    if (VM.VerifyAssertions) VM._assert(state == CLASS_RESOLVED);

    // instantiate superclass
    //
    if (superClass != null) {
      superClass.instantiate();
    }
    if (VM.runningVM) {
      // can't instantiate if building bootimage, since this can cause
      // class initializer to be lost (when interface is not included in bootimage).
      // since we don't need to instantiate/initialize for the purposes of
      // dynamic type checking and interface invocation, defer it until runtime
      // and the class actually refers to a static field of the interface.
      for (RVMClass declaredInterface : declaredInterfaces) {
        declaredInterface.instantiate();
      }
    }

    if (!isInterface()) {
      // Create the internal lazy method invoker trampoline
      typeInformationBlock.initializeInternalLazyCompilationTrampoline();

      // Initialize slots in the TIB for virtual methods
      for(int i=0; i < virtualMethods.length; i++) {
        RVMMethod method = virtualMethods[i];
        if (method.isPrivate() && method.getDeclaringClass() != this) {
          typeInformationBlock.setVirtualMethod(i, null); // an inherited private method....will never be invoked via this TIB
        } else {
          typeInformationBlock.setVirtualMethod(i, method.getCurrentEntryCodeArray());
        }
      }

      // compile <init> methods and put their addresses into jtoc
      for (int i = 0, n = constructorMethods.length; i < n; ++i) {
        RVMMethod method = constructorMethods[i];
        Statics.setSlotContents(method.getOffset(), method.getCurrentEntryCodeArray());
      }

      // compile static methods and put their addresses into jtoc
      for (int i = 0, n = staticMethods.length; i < n; ++i) {
        // don't bother compiling <clinit> here;
        // compile it right before we invoke it in initialize.
        // This also avoids putting <clinit>s in the bootimage.
        RVMMethod method = staticMethods[i];
        if (!method.isClassInitializer()) {
          Statics.setSlotContents(method.getOffset(), method.getCurrentEntryCodeArray());
        }
      }
    }

    InterfaceInvocation.initializeDispatchStructures(this);
    SpecializedMethodManager.notifyTypeInstantiated(this);

    if (VM.writingBootImage) {
      state = CLASS_INITIALIZED;
      // Mark final fields as literals as class initializer won't have been called
      markFinalFieldsAsLiterals();
    } else {
      state = CLASS_INSTANTIATED;
    }

    Callbacks.notifyClassInstantiated(this);
    if (VM.writingBootImage) {
      Callbacks.notifyClassInitialized(this);
    }

    if (VM.TraceClassLoading && VM.runningVM) VM.sysWriteln("RVMClass: (end)   instantiate " + this);
  }

  /**
   * Make the passed field a traced field by garbage collection. Also affects all
   * subclasses.
   */
  public synchronized void makeFieldTraced(RVMField field) {
    int[] oldOffsets = referenceOffsets;
    int fieldOffset = field.getOffset().toInt();
    referenceOffsets = MemoryManager.newNonMovingIntArray(oldOffsets.length + 1);
    int i;
    for(i=0; i < oldOffsets.length && oldOffsets[i] < fieldOffset; i++) {
      referenceOffsets[i] = oldOffsets[i];
    }
    if (VM.VerifyAssertions) VM._assert(oldOffsets[i] != fieldOffset, "Field is already traced!");
    referenceOffsets[i++] = fieldOffset;
    while(i < referenceOffsets.length) {
      referenceOffsets[i] = oldOffsets[i-1];
      i++;
    }
    SpecializedMethodManager.refreshSpecializedMethods(this);

    for(RVMClass klass: subClasses) {
      klass.makeFieldTraced(field);
    }
  }

  /**
   * Execute this class's static initializer, <clinit>.
   * Side effects: superclasses are initialized, static fields receive
   * initial values.
   */
  @Override
  public synchronized void initialize()
    // Doesn't really need declaring.
      throws ExceptionInInitializerError {
    if (isInitialized()) {
      return;
    }

    if (state == CLASS_INITIALIZING) {
      return;
    }

    if (VM.TraceClassLoading && VM.runningVM) VM.sysWriteln("RVMClass: (begin) initialize " + this);
    if (VM.VerifyAssertions) VM._assert(state == CLASS_INSTANTIATED);
    state = CLASS_INITIALIZING;
    if (VM.verboseClassLoading) VM.sysWrite("[Initializing " + this + "]\n");

    // run super <clinit>
    //
    if (superClass != null) {
      superClass.initialize();
    }

    // run <clinit>
    //
    if (classInitializerMethod != null) {
      CompiledMethod cm = classInitializerMethod.getCurrentCompiledMethod();
      while (cm == null) {
        classInitializerMethod.compile();
        cm = classInitializerMethod.getCurrentCompiledMethod();
      }

      if (VM.verboseClassLoading) VM.sysWrite("[Running static initializer for " + this + "]\n");

      try {
        Magic.invokeClassInitializer(cm.getEntryCodeArray());
      } catch (Error e) {
        throw e;
      } catch (Throwable t) {
        ExceptionInInitializerError eieio = new ExceptionInInitializerError("While initializing " + this);
        if (VM.verboseClassLoading) {
          VM.sysWriteln("[Exception in initializer error caused by:");
          t.printStackTrace();
          VM.sysWriteln("]");
        }
        throw eieio;
      }

      // <clinit> is no longer needed: reclaim space by removing references to it
      classInitializerMethod.invalidateCompiledMethod(cm);
      classInitializerMethod = null;
    }

    if (VM.BuildForOptCompiler) {
      // report that a class is about to be marked initialized to
      // the opt compiler so it can invalidate speculative CHA optimizations
      // before an instance of this class could actually be created.
      classLoadListener.classInitialized(this, false);
    }

    state = CLASS_INITIALIZED;

    Callbacks.notifyClassInitialized(this);

    markFinalFieldsAsLiterals();

    if (VM.verboseClassLoading) VM.sysWrite("[Initialized " + this + "]\n");
    if (VM.TraceClassLoading && VM.runningVM) VM.sysWriteln("RVMClass: (end)   initialize " + this);
  }

  /**
   * Mark final fields as being available as literals
   */
  private void markFinalFieldsAsLiterals() {
    for (RVMField f : getStaticFields()) {
      if (f.isFinal()) {
        Offset fieldOffset = f.getOffset();
        if (Statics.isReference(Statics.offsetAsSlot(fieldOffset))) {
          Statics.markAsReferenceLiteral(fieldOffset);
        } else {
          Statics.markAsNumericLiteral(f.getSize(), fieldOffset);
        }
      }
    }
  }

  /**
   * Copy the values of all static final fields into
   * the JTOC.  Note: This method should only be run AFTER
   * the class initializer has run.
   */
  public void setAllFinalStaticJTOCEntries() {
    if (VM.VerifyAssertions) VM._assert(isInitialized());
    for (RVMField f : getStaticFields()) {
      if (f.isFinal()) {
        setFinalStaticJTOCEntry(f, f.getOffset());
      }
    }
  }

  void resolveNativeMethods() {
    if (VM.VerifyAssertions) VM._assert(isInitialized());
    resolveNativeMethodsInternal(getStaticMethods());
    resolveNativeMethodsInternal(getVirtualMethods());
  }

  private void resolveNativeMethodsInternal(RVMMethod[] methods) {
    for (RVMMethod m : methods) {
      if (m.isNative()) {
        m.replaceCompiledMethod(null);
      }
    }
  }

  /**
   * Unregisters all native methods
   */
  public void unregisterNativeMethods() {
    if (VM.VerifyAssertions) VM._assert(isInitialized());
    for (RVMMethod m : declaredMethods) {
      if (m.isNative()) {
        NativeMethod nm = (NativeMethod) m;
        nm.unregisterNativeSymbol();
        m.replaceCompiledMethod(null);
      }
    }
  }

  /**
   * Add to list of classes that derive from this one.
   */
  private void addSubClass(RVMClass sub) {
    int n = subClasses.length;
    RVMClass[] tmp = new RVMClass[n + 1];

    for (int i = 0; i < n; ++i) {
      tmp[i] = subClasses[i];
    }
    tmp[n] = sub;

    subClasses = tmp;
  }

  //------------------------------------------------------------//
  // Support for speculative optimizations that may need to
  // invalidate compiled code when new classes are loaded.
  //
  // TODO: Make this into a more general listener API
  //------------------------------------------------------------//
  public static final ClassLoadingListener classLoadListener =
      VM.BuildForOptCompiler ? new ClassLoadingDependencyManager() : null;

  /**
   * Given a method declared by this class, update all
   * dispatching tables to refer to the current compiled
   * code for the method.
   */
  public void updateMethod(RVMMethod m) {
    if (VM.VerifyAssertions) VM._assert(isResolved());
    if (VM.VerifyAssertions) VM._assert(m.getDeclaringClass() == this);
    if (m.isClassInitializer()) return; // we never put this method in the jtoc anyways!

    if (m.isStatic() || m.isObjectInitializer()) {
      updateJTOCEntry(m);
    } else {
      updateVirtualMethod(m);
    }
  }

  /**
   * Update the JTOC slot for the given static method to point to
   * the current compiled code for the given method.
   * NOTE: This method is intentionally not synchronized to avoid deadlocks.
   *       We instead rely on the fact that we are always updating the JTOC with
   *       the most recent instructions for the method.
   */
  public void updateJTOCEntry(RVMMethod m) {
    if (VM.VerifyAssertions) VM._assert(m.getDeclaringClass() == this);
    if (VM.VerifyAssertions) VM._assert(isResolved());
    if (VM.VerifyAssertions) VM._assert(m.isStatic() || m.isObjectInitializer());
    Statics.setSlotContents(m.getOffset(), m.getCurrentEntryCodeArray());
  }

  /**
   * Update this class's TIB entry for the given method to point to
   * the current compiled code for the given method.
   * NOTE: This method is intentionally not synchronized to avoid deadlocks.
   *       We instead rely on the fact that we are always updating the JTOC with
   *       the most recent instructions for the method.
   */
  public void updateTIBEntry(RVMMethod m) {
    if (VM.VerifyAssertions) {
      RVMMethod vm = findVirtualMethod(m.getName(), m.getDescriptor());
      VM._assert(vm == m);
    }
    typeInformationBlock.setVirtualMethod(m.getOffset(), m.getCurrentEntryCodeArray());
    InterfaceInvocation.updateTIBEntry(this, m);
  }

  /**
   * Update the TIB entry's for all classes that inherit the given method
   * to point to the current compiled code for the given method.
   * NOTE: This method is intentionally not synchronized to avoid deadlocks.
   *       We instead rely on the fact that we are always updating the JTOC with
   *       the most recent instructions for the method.
   */
  public void updateVirtualMethod(RVMMethod m) {
    RVMMethod dm = findDeclaredMethod(m.getName(), m.getDescriptor());
    if (dm != null && dm != m) return;  // this method got overridden
    updateTIBEntry(m);
    if (m.isPrivate()) return; // can't override
    for (RVMClass sc : getSubClasses()) {
      if (sc.isResolved()) {
        sc.updateVirtualMethod(m);
      }
    }
  }

  //------------------------------------------------------------//
  // Additional fields and methods for Interfaces               //
  //------------------------------------------------------------//

  private static final Object interfaceCountLock = new Object();
  private static int interfaceCount = 0;
  private static RVMClass[] interfaces;
  private int interfaceId = -1;
  RVMMethod[] noIMTConflictMap; // used by InterfaceInvocation to support resetTIB

  /**
   * Classes used as Interfaces get assigned an interface id.
   *   If the class is not an interface, attempting to use this
   *   id will cause an IncompatibleClassChangeError to be thrown
   */
  public int getInterfaceId() {
    if (interfaceId == -1) {
      assignInterfaceId();
    }
    return interfaceId;
  }

  public int getDoesImplementIndex() {
    return getInterfaceId() >>> 5;
  }

  public int getDoesImplementBitMask() {
    return 1 << (getInterfaceId() & 31);
  }

  public static RVMClass getInterface(int id) {
    return interfaces[id];
  }

  private synchronized void assignInterfaceId() {
    if (interfaceId == -1) {
      if (interfaceCountLock != null && interfaces != null) {
        synchronized (interfaceCountLock) {
          interfaceId = interfaceCount++;
          if (interfaceId == interfaces.length) {
            RVMClass[] tmp = new RVMClass[interfaces.length * 2];
            System.arraycopy(interfaces, 0, tmp, 0, interfaces.length);
            interfaces = tmp;
          }
          interfaces[interfaceId] = this;
        }
      } else {
        interfaceId = interfaceCount++;
        if (interfaces == null) {
          interfaces = new RVMClass[200];
        }
        interfaces[interfaceId] = this;
      }
    }
  }

  /**
   * Number of [ in descriptor for arrays; -1 for primitives; 0 for
   * classes
   * @return 0
   */
  @Override
  @Pure
  @Uninterruptible
  public int getDimensionality() {
    return 0;
  }

  /**
   * Resolution status.
   */
  @Override
  @Uninterruptible
  public boolean isResolved() {
    return state >= CLASS_RESOLVED;
  }

  /**
   * Instantiation status.
   */
  @Override
  @Uninterruptible
  public boolean isInstantiated() {
    return state >= CLASS_INSTANTIATED;
  }

  /**
   * Initialization status.
   */
  @Override
  @Uninterruptible
  public boolean isInitialized() {
    return state == CLASS_INITIALIZED;
  }

  /**
   * Only intended to be used by the BootImageWriter
   */
  @Override
  public void markAsBootImageClass() {
    inBootImage = true;
  }

  /**
   * Is this class part of the virtual machine's boot image?
   */
  @Override
  @Uninterruptible
  public boolean isInBootImage() {
    return inBootImage;
  }

  /**
   * Get the offset in instances of this type assigned to the thin lock word.
   * Offset.max() if instances of this type do not have thin lock words.
   * Is only known after class has been resolved.
   */
  @Override
  @Uninterruptible
  public Offset getThinLockOffset() {
    if (VM.VerifyAssertions) VM._assert(isResolved());
    return thinLockOffset;
  }

 /**
   * Set the thin lock offset for instances of this type. Can be called at most once.
   * and is invoked from ObjectModel.allocateThinLock (in object models which
   * do not allocate thin locks for all scalar object types).
   */
  public void setThinLockOffset(Offset offset) {
    if (VM.VerifyAssertions) VM._assert(thinLockOffset.isMax());
    if (VM.VerifyAssertions) VM._assert(!offset.isMax());
    thinLockOffset = offset;
  }

  /**
   * get number of superclasses to Object
   */
  @Override
  @Pure
  @Uninterruptible
  public int getTypeDepth() {
    return depth;
  }

  /**
   * Whether or not this is an instance of RVMClass?
   * @return false
   */
  @Override
  @Pure
  @Uninterruptible
  public boolean isClassType() {
    return true;
  }

  /**
   * Whether or not this is an instance of RVMArray?
   * @return true
   */
  @Override
  @Pure
  @Uninterruptible
  public boolean isArrayType() {
    return false;
  }

  /**
   * Whether or not this is a primitive type
   * @return false
   */
  @Override
  @Pure
  @Uninterruptible
  public boolean isPrimitiveType() {
    return false;
  }

  /**
   * @return whether or not this is a reference (ie non-primitive) type.
   */
  @Override
  @Pure
  @Uninterruptible
  public boolean isReferenceType() {
    return true;
  }
}


text:
Biakło (na mapie Geoportalu Brodło, 361 m) – wzgórze ostańcowe w miejscowości Olsztyn w województwie śląskim, w powiecie częstochowskim. Wzniesienie ma formę bezleśnego, skalnego grzebienia. Od północnej strony sąsiaduje ze skalistym grzebieniem Lipówek, od południowej opada na płaskie i porośnięte lasem obniżenie oddzielające go od Sokolich Gór. Wzgórze zbudowane jest z wapieni pochodzących z okresu jurajskiego. Na południowym krańcu grzebienia znajduje się okno skalne, natomiast na wschód od szczytu – iglica wapienna. Liczne formy krasowe: jamy, żłobki i żebra. Z wszystkich stron otoczone jest łąkami.

Wzgórze, dzięki kształtowi przypominającemu tatrzański Giewont nazywane jest małym Giewontem. Podobnie jak na Giewoncie, na Biakle znajduje się krzyż, pozostawiony na początku lat 90. XX wieku przez pielgrzymkę pracowników przemysłu metalowego z Zawiercia. Wzgórze jest popularne wśród turystów i wspinaczy i zaliczane do grupy tzw. Skał Olsztyńskich. Wspinacze wyróżnili na nim kilka skał wspinaczkowych:
 Biakło
 Garb,
 Mnich,
 Sfinks, Blin, Okręt, Z Jałowcem.

Drogi wspinaczkowe
Większość dróg wspinaczkowych jest łatwa, jednowyciągowa, ale jak na Jurę długa. Szczytowa skała Biakło ma wysokość 16-20 m. Wspinacze poprowadzili na niej 13 dróg wspinaczkowych o trudności III – VI.4+ w skali Kurtyki. Drogi wspinaczkowe o wystawie zachodniej lub północno-zachodniej. Tylko część z nich ma zamontowane stałe punkty asekuracyjne: ringi (r), spiny (s) i dwa ringi zjazdowe (drz).

Szlaki turystyczne
Obok wzgórza Biakło  prowadzą dwa szlaki turystyczne.
  szlak św. Idziego: Olsztyn – Biakło – rezerwat przyrody Sokole Góry – Zrębice
  Olsztyn – Biakło – rezerwat przyrody Sokole Góry – Knieje – Zrębice

Przypisy

Wzgórza Wyżyny Częstochowskiej
Formacje skalne Wyżyny Krakowsko-Częstochowskiej
Geografia Olsztyna (województwo śląskie)

redpajama_set_name: RedPajamaWikipedia


There are 1 blog entries for November 2017.
Friday, November 17th, 2017 at 12:29am.
Sales of Orlando homes posted positive increases in October, just one month after Hurricane Irma hit the pause button on housing transactions. Sales increased by 7 percent in October when compared to October of last year, and increased by 14 percent when compared to last month. The median price rose in October as well, by 6 percent year-over-year. >>Read more.


This week Northland Age and New Zealand Herald online featured a recent trip Dame Valerie Adams made to Kaikohe in New Zealand's north.
Dame Valerie Adams speaks to a crowd of over 350 people at the Kaikohe Stake Centre of The Church of Jesus Christ of Latter-day Saints - September 2018.© 2018 by Intellectual Reserve, Inc. All rights reserved.
"The more than 350 people who crowded into the Church of Jesus Christ of Latter-day Saints' Kaikohe Stake Centre to hear Dame Valerie Adams were given an insight into the life of one of New Zealand's sports champions," the article begins.
"They learned a good deal too, including that Dame Valerie's lunch with the Queen had been awkward, the best part of the Olympics was the food tent, and one did not need to come from ideal circumstances to be a champion.
The double Olympic gold medal shot putter, a member of the Church of Jesus Christ of Latter-day Saints, was speaking as part of an event organised by the Church to inspire youth and parents in the North.
She and her husband, Gabriel Price, spent the morning working alongside members of the community in Paihia, picking up rubbish from a beach and pulling weeds from a bush track being restored by Project Island Song."


text:
Bio - Gordon Rogers, Riverkeeper and Executive Director, Fayetteville
Gordon Rogers
Gordon Rogers is Executive Director & Flint Riverkeeper®. He lives in the lower portion of the upper Flint in Talbot County. A native of South Georgia, Rogers attended college at Oxford College of Emory University, the University of Georgia–Athens, and Skidaway Institute of Oceanography. Following his formal schooling, he was employed for ten years by the Georgia Department of Natural Resources at the Coastal Resources Division in Brunswick, first as a fisheries statistician and later as a marine biologist and analyst. There he conducted basic research, management-oriented research, and marine policy development. Rogers then entered the private sector, as owner-operator of a Brunswick-based waste and recycling facility.
A professional fisherman, he has participated in tournaments, provided instruction and conducted fishing charters. He was formerly Executive Director of Satilla Riverwatch Alliance, Inc. and the Satilla Riverkeeper® from 2004 to 2009. He became Riverkeeper® and Executive Director of Flint Riverkeeper®, Inc., in 2009.

redpajama_set_name: RedPajamaCommonCrawl


Buy it with 90° rotator, and sigma 8mm f/3.5 ring clamp for your appropriate brand. Set to 7.5° tilt.
Buy it with 7.5° tilt angle, 90° rotator, and sigma 8mm f/3.5 ring clamp for your appropriate brand.
This entry was posted on Thursday, July 19th, 2012 at 5:28 PM. You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.


text:
India selected
Profile: Kailash Satyarthi
Image caption Kailash Satyarthi and former child slaves in India
Indian child rights activist Kailash Satyarthi was awarded the Nobel Peace Prize for his campaign for the rights of children and young people.
He was honoured along with Pakistani activist Malala Yousafzai.
Accepting the prize in Oslo on 10 December, Mr Satyarthi declined to deliver a lecture, saying instead: "I represent here the sound of silence. The cry of innocence. And, the face of invisibility.
"I have come here to share the voices and dreams of our children, our children, because they are all our children."
Mr Satyarthi, who turned 60 in January, has long campaigned against child labour and rescued children from servitude. His efforts have seen tens of thousands of children rescued from hazardous industries and rehabilitated.
Mr Satyarthi, who says his mission is to "wipe away the blot of human slavery", has often staged dangerous and daring dawn raids on factories - sometimes manned by armed guards - which employed children.
Culprit companies, he said, included carpet makers, diamond miners and even firms that made footballs.
For his work, he has endured death threats and attempts at incarceration, and two of his colleagues were even murdered. But he continues with his campaign because, he has said, "somebody has to accept the challenge whatever dangers are there".
Meeting Kailash Satyarthi: Shilpa Kannan, BBC News, Delhi
In February, I met Mr Satyarthi at a shelter he runs just outside Delhi for rescued child workers.
He was sitting surrounded by anxious parents who had come from tea gardens in north-east India looking for their missing daughters.
He spoke patiently with each family, trying to devise a strategy to find their child.
"It's a risky job," he says. He is often threatened by unscrupulous middlemen who kidnap children to work in garment factories and was injured badly while rescuing child slaves from stone quarries in Rajasthan.
Helped by an army of volunteers, Mr Satyarthi has been campaigning against the exploitation of children for more than three decades.
I ask him if he has seen any improvement in the situation in all these years?
"It's only become worse," he says.
Nearly 30 years ago he left a promising career as an electrical engineer to set up Bachpan Bachao Andolan (Save Childhood Movement) and since then, by his own count, he has rescued more than 80,000 children.
He also heads the Global March Against Child Labour, which represents about 2,000 social groups and union organisations in 140 countries.
His campaigns over the years have ensured that India's carpet industry has stopped using child labour.
He also successfully led a movement to bring in a new law in 2012 to make employment of children under the age of 14 illegal - a law he considers his big achievement.
But India still has millions of child labourers - official estimates put the number at five million; Mr Satyarthi says it is as high as 60 million.
Many parents say poverty forces them to send their young children to work, while campaigners say child servitude is a reality in India and that it will continue.
But Mr Satyarthi has described that point of view as "absolutely pessimistic".
"We must all be totally against child labour. I want to see in my lifetime that there is no child slavery in the world," he told the BBC in an earlier interview.
The Nobel Committee made clear that this was why he was selected: "Showing great personal courage, Kailash Satyarthi, maintaining Gandhi's tradition, has headed various forms of protests and demonstrations, all peaceful, focusing on the grave exploitation of children for financial gain."
Malala and Kailash Satyarthi receive joint Nobel award


text:
Total value of customer's worldwide deployments now exceeds $11.5 million
May. 2, 2017 7:00 am
AUSTIN, Texas, May 02, 2017 (GLOBE NEWSWIRE) -- Xplore Technologies Corp. (NASDAQ:XPLR) today announced that one of the world's leading automotive manufacturers has equipped workers in one of its new U.S. body shops with Xplore's ultra-rugged XC6 tablet PCs as part of a multi-year, multi-million-dollar mobility initiative. The long-time global customer is utilizing the vibration-proof, shock-proof, waterproof, and dustproof industrial-grade tablets on forklifts in support of multiple logistics activities, including materials handling, shop floor tasks, and maintenance. They have also installed Xplore's secure vehicle docking systems third-party forklift mounts and DC power converters as part of the total Xplore-engineered mobility solution. Additional screen black-out software has been installed for safe rugged tablet use while the forklifts are in transit.
"The XC6 is the most rugged Windows® tablet on the market, which is exactly what auto manufacturers' need in fast-paced body shop facilities where workers' tools – and heavy hands – have been known to wreak havoc on electronic devices," explained Mark Holleran, president and CEO, Xplore. "Not only does the XC6 boast a less than 1 percent annualized failure rate, but it comes standard with an extensive number of high-performance features that augment existing industrial IT systems to eliminate production downtime. In fact, the XC-series tablet platform has proven to be the perfect computing solution for this customer's quality-driven, mass volume manufacturing operations for more than five product generations."
Over the last several years, thousands of Xplore's rugged tablet-based forklift terminal solutions have been deployed across the automotive leader's manufacturing and warehousing facilities worldwide to facilitate work orders completion, inventory tracking and data collection. Other Xplore rugged tablets, including the XSLATE B10, R12, F5 and CL920 models, are also in use by mobile workers and forklift operators in the manufacturer's plants and body shops worldwide. The tablets are used on order picking carts for parts delivery, as well as on the assembly line to confirm the accuracy of vehicle parts prior to installation. They're also used to conduct vehicle inspections and quality tests prior to customer delivery, among other logistical tasks.
"Workers like the XC6 because it's easy to use, and supervisors claim that its use has directly contributed to operational efficiency gains," Holleran continued. "Plus, the modular design of this custom-developed forklift solution provides the manufacturer with greater usage and servicing flexibility than the older technology of permanently installed forklift terminals. Not only does that translate to a lower investment cost upfront, but a lower maintenance cost over the life of the mobile computer. The same tablet model can be removed from the forklift and used to complete any mobile workflow application in and around the manufacturing shop floor, and it can easily be upgraded to higher computing standards as needed to accommodate the evolving technology requirements of cutting edge smart factories. As such, an investment in Xplore's mobility solutions protect the ROI of customers' entire IT investment."
The Xplore XC6 ultra-rugged tablet PC is specifically configured to support factory-related workflows, including those conducted primarily by forklift and cart operators. The IP67 mobile computer can survive a 7-foot drop – the highest of any rugged computer on the market today – and is reinforced internally and externally to tolerate a number of other industrial hazards such as extreme temperature variations that occur between storage areas and loading docks. The XC6 ultra-rugged tablet also features a direct sunlight readable, resistive multi-touch display that supports glove touch, finger, and stylus interface for easy data input and access on the move.
To learn about Xplore's mobile computing solutions for manufacturing, please visit www.xploretech.com/manufacturing. More information about Xplore's ultra-rugged tablets can be found at www.xploretech.com/us/xc6-series-rugged-tablets/xc6-dmsr-rugged-tablet-pc/.
This news release contains forward-looking statements that involve risks and uncertainties, which may cause actual results to differ materially from the statements made. When used in this document, the words "may", "would", "could", "will", "intend", "plan", "anticipate", "believe", "estimate", "expect" and similar expressions are intended to identify forward-looking statements. Such statements reflect Xplore's current views with respect to future events and are subject to such risks and uncertainties. Many factors could cause actual results to differ materially from the statements made including those factors detailed from time to time in filings made by Xplore with securities regulatory authorities. Should one or more of these risks or uncertainties materialize, or should assumptions underlying the forward-looking statements prove incorrect, actual results may vary materially from those described herein as intended, planned, anticipated or expected. Xplore does not intend and does not assume any obligation to update these forward-looking statements.
Xplore Contact Information:
Debbie Russo
outboundmarketing@xploretech.com
Email: twilkinson@xploretech.com
Email: xplr@darrowir.com
May 2, 2017 - 7:00 AM EDT


text:
// This file is generated from PrimVector.template. DO NOT EDIT!
// Copyright (c) 2001, 2002, 2015  Per M.A. Bothner and Brainfood Inc.
// This is free software;  for terms and warranty disclaimer see ./COPYING.

package gnu.lists;
import java.io.*;

/** Simple adjustable-length vector of 64-bit doubles. */

public  class F64Vector extends SimpleVector<Double>
    implements Comparable
{
    double[] data;
    protected static double[] empty = new double[0];

    public F64Vector() {
        data = empty;
    }

    public F64Vector(int size, double value) {
        double[] array = new double[size];
        data = array;
        if (value != 0) {
            while (--size >= 0)
                array[size] = value;
        }
    }

    public F64Vector(int size) {
        this(new double[size]);
    }

    /** Reuses the argument without making a copy. */
    public F64Vector(double[] data) {
        this.data = data;
    }

    /*
    public F64Vector(Sequence seq) {
        data = new double[seq.size()];
        addAll(seq);
    }
    */

    public F64Vector(double[] data, IntSequence indexes) {
        this.data = data;
        this.indexes = indexes;
    }

    /** Makes a copy of (part of) the argument array. */
    public F64Vector(double[] values, int offset, int length) {
        this(length);
        System.arraycopy(values, offset, data, 0, length);
    }

    /** Get the allocated length of the data buffer. */
    public int getBufferLength() {
        return data.length;
    }

    public void setBufferLength(int length) {
        int oldLength = data.length;
        if (oldLength != length) {
            double[] tmp = new double[length];
            System.arraycopy(data, 0, tmp, 0,
                             oldLength < length ? oldLength : length);
            data = tmp;
        }
    }

    public double[] getBuffer() { return data; }

    protected void setBuffer(Object buffer) { data = (double[]) buffer; }

    public final double doubleAt(int index) {
        if (indexes != null)
            index = indexes.intAt(index);
        return data[index];
    }

    public final double doubleAtBuffer(int index) {
        return data[index];
    }

    public final Double get(int index) {
        if (indexes != null)
            index = indexes.intAt(index);
        return Double.valueOf(data[index]);
    }

    public final Double getBuffer(int index) {
        return Double.valueOf(data[index]);
    }

    public final void setDoubleAt(int index, double value) {
        checkCanWrite(); // FIXME maybe inline and fold into following
        if (indexes != null)
            index = indexes.intAt(index);
        data[index] = value;
    }

    public final void setDoubleAtBuffer(int index, double value) {
        data[index] = value;
    }

    @Override
    public final void setBuffer(int index, Double value) {
        data[index] = value.doubleValue();
    }

    public void add(double v) {
        int sz = size();
        addSpace(sz, 1);
        setDoubleAt(sz, v);
    }

    protected void clearBuffer(int start, int count) {
        double[] d = data;
        while (--count >= 0)
            d[start++] = 0;
    }

    @Override
    protected F64Vector withIndexes(IntSequence ind) {
        return new F64Vector(data, ind);
    }

    @Override
    public F64Vector subList(int fromIx, int toIx) {
        return new F64Vector(data, indexesSubList(fromIx, toIx));
    }

    public int getElementKind() { return DOUBLE_VALUE; }

    public String getTag() { return "f64"; }

    public void consumePosRange(int iposStart, int iposEnd, Consumer out) {
        if (out.ignoring())
            return;
        int i = nextIndex(iposStart);
        int end = nextIndex(iposEnd);
        for (;  i < end;  i++)
            out.writeDouble(doubleAt(i));
    }

    public int compareTo(Object obj) {
        F64Vector vec2 = (F64Vector) obj;
        double[] arr1 = data;
        double[] arr2 = vec2.data;
        int n1 = size();
        int n2 = vec2.size();
        IntSequence inds1 = getIndexesForce();
        IntSequence inds2 = vec2.getIndexesForce();
        int n = n1 > n2 ? n2 : n1;
        for (int i = 0;  i < n;  i++) {
            double v1 = arr1[inds1.intAt(i)];
            double v2 = arr2[inds2.intAt(i)];
            if (v1 != v2)
                return v1 > v2 ? 1 : -1;
        }
        return n1 - n2;
    }

}

redpajama_set_name: RedPajamaGithub


give a strong hydrophobicity to the treated surface.
• Transpiration: The product does not change the normal transpiration of the material.
moss. The processed materials are more 'easy cleaning.
• Duration: The product has a shelf life of 4 years.
Apply with a brush on the surface, wait for the drying.
small portion: if you do not detect the effect will have to wait for another time.
effect will be a normal hydrophobic effect.
nanoparticles (or the bond could be weak) the effect will be lower than the expectations.
The special feature of NANOS SM is to keep the fabric or skin washable even if they have owned hydro and oleophobic properties.