protected final RVMType getRVMTypeForClassWithAppCL(String className) {
   Atom descriptor =
       Atom.findOrCreateAsciiAtom(className.replace('.', '/')).descriptorFromClassName();
   TypeReference tRef =
       TypeReference.findOrCreate(ApplicationClassLoader.getSystemClassLoader(), descriptor);
   return tRef.peekType();
 }
Beispiel #2
0
 private static Class<?> forNameInternal(
     String className, boolean initialize, ClassLoader classLoader)
     throws ClassNotFoundException, LinkageError, ExceptionInInitializerError {
   try {
     if (className.startsWith("[")) {
       if (!validArrayDescriptor(className)) {
         throw new ClassNotFoundException(className);
       }
     }
     Atom descriptor =
         Atom.findOrCreateAsciiAtom(className.replace('.', '/')).descriptorFromClassName();
     TypeReference tRef = TypeReference.findOrCreate(classLoader, descriptor);
     RVMType ans = tRef.resolve();
     Callbacks.notifyForName(ans);
     if (initialize && !ans.isInitialized()) {
       ans.resolve();
       ans.instantiate();
       ans.initialize();
     }
     return ans.getClassForType();
   } catch (NoClassDefFoundError ncdfe) {
     Throwable cause2 = ncdfe.getCause();
     ClassNotFoundException cnf;
     // If we get a NCDFE that was caused by a CNFE, throw the original CNFE.
     if (cause2 instanceof ClassNotFoundException) cnf = (ClassNotFoundException) cause2;
     else cnf = new ClassNotFoundException(className, ncdfe);
     throw cnf;
   }
 }
Beispiel #3
0
 public Class<?> getEnclosingClass() {
   if (type.isClassType()) {
     TypeReference enclosingClass = type.asClass().getEnclosingClass();
     if (enclosingClass != null) {
       return enclosingClass.resolve().getClassForType();
     } else {
       return null;
     }
   } else {
     return null;
   }
 }
 /** What would be the appropriate return bytecode for the given type reference? */
 private static int typeRefToReturnBytecode(TypeReference tr) {
   if (!tr.isPrimitiveType()) {
     return JBC_areturn;
   } else {
     Primitive pt = (Primitive) tr.peekType();
     if ((pt == RVMType.BooleanType)
         || (pt == RVMType.ByteType)
         || (pt == RVMType.ShortType)
         || (pt == RVMType.CharType)
         || (pt == RVMType.IntType)) {
       return JBC_ireturn;
     } else if (pt == RVMType.LongType) {
       return JBC_lreturn;
     } else if (pt == RVMType.FloatType) {
       return JBC_freturn;
     } else if (pt == RVMType.DoubleType) {
       return JBC_dreturn;
     } else {
       if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED);
       return -1;
     }
   }
 }
Beispiel #5
0
  public Class<?>[] getClasses() throws SecurityException {
    checkMemberAccess(Member.PUBLIC);
    if (!type.isClassType()) return new Class[0];

    ArrayList<Class<?>> publicClasses = new ArrayList<Class<?>>();
    for (Class<?> c = this; c != null; c = c.getSuperclass()) {
      c.checkMemberAccess(Member.PUBLIC);
      TypeReference[] declaredClasses = c.type.asClass().getDeclaredClasses();
      if (declaredClasses != null) {
        for (TypeReference declaredClass : declaredClasses) {
          if (declaredClass != null) {
            RVMClass dc = declaredClass.resolve().asClass();
            if (dc.isPublic()) {
              publicClasses.add(dc.getClassForType());
            }
          }
        }
      }
    }
    Class<?>[] result = new Class[publicClasses.size()];
    result = publicClasses.toArray(result);
    return result;
  }
  public SpecializedScanMethod(int id, TypeReference specializedTrace) {
    super(id);
    this.specializedSignature =
        new TypeReference[] {TypeReference.JavaLangObject, specializedTrace};

    if (!VM.BuildWithBaseBootImageCompiler) {
      /* Compile our specialized methods when we are opt compiling */
      RVMClass myClass = specializedScanMethodType.peekType().asClass();
      for (int i = 0; i < PATTERNS; i++) {
        RVMMethod method =
            myClass.findStaticMethod(templateMethodName(i), specializedMethodDescriptor);
        specializedMethods[i] = compileSpecializedMethod(method, specializedSignature);
      }
    }
  }
/**
 * A method that scan objects and is specialized to a specific MMTk TransitiveClosure type.
 *
 * <p>In general as there may not be a 1-1 mapping between objects and the specialized methods this
 * class is responsible for performing the mapping.
 *
 * <p>Specialized methods must have a static 'invoke' method that matches the given signature and
 * return type.
 */
@Uninterruptible
public final class SpecializedScanMethod extends SpecializedMethod
    implements SizeConstants, JavaHeaderConstants {

  /** Use specialized scanning ? */
  public static final boolean ENABLED = true;

  /** This method's signature: the object to be scanned and the trace to use */
  private static final TypeReference[] signature =
      new TypeReference[] {
        TypeReference.JavaLangObject, TypeReference.findOrCreate(TransitiveClosure.class)
      };

  /** The return type of this method: void */
  private static final TypeReference returnType = TypeReference.Void;

  /** Our type reference */
  private static final TypeReference specializedScanMethodType =
      TypeReference.findOrCreate(SpecializedScanMethod.class);

  /** Objects with no references or primitive arrays */
  private static final int NULL_PATTERN = 0;
  /** Number of patterns we will specialize */
  private static final int SPECIALIZED_PATTERNS = 64;
  /** Reference arrays */
  private static final int REFARRAY_PATTERN = 64;
  /** Fallback to a slower path that is not specialized */
  private static final int FALLBACK_PATTERN = 65;
  /** The total number of patterns */
  private static final int PATTERNS = 66;
  /** Maximum field offset we can deal with */
  private static final int MAX_SPECIALIZED_OFFSET = 6 << LOG_BYTES_IN_ADDRESS;

  /** We keep the specialized methods for key object reference patterns here. */
  private final CompiledMethod[] specializedMethods = new CompiledMethod[PATTERNS];

  /** The specialized signature of the method */
  private final TypeReference[] specializedSignature;

  public SpecializedScanMethod(int id, TypeReference specializedTrace) {
    super(id);
    this.specializedSignature =
        new TypeReference[] {TypeReference.JavaLangObject, specializedTrace};

    if (!VM.BuildWithBaseBootImageCompiler) {
      /* Compile our specialized methods when we are opt compiling */
      RVMClass myClass = specializedScanMethodType.peekType().asClass();
      for (int i = 0; i < PATTERNS; i++) {
        RVMMethod method =
            myClass.findStaticMethod(templateMethodName(i), specializedMethodDescriptor);
        specializedMethods[i] = compileSpecializedMethod(method, specializedSignature);
      }
    }
  }

  /** Get the pattern index for a given type */
  @Interruptible
  private static int getPattern(RVMType type) {
    /* Handle array types */
    if (type.isArrayType()) {
      if (type.asArray().getElementType().isReferenceType()) {
        return REFARRAY_PATTERN;
      }
      return NULL_PATTERN;
    }

    /* Build a bitmap if the object is compact enough and is not a reference array */
    int[] offsets = type.asClass().getReferenceOffsets();

    if (offsets.length == 0) {
      return NULL_PATTERN;
    }
    if ((offsets.length << LOG_BYTES_IN_ADDRESS) > SPECIALIZED_PATTERNS) {
      return FALLBACK_PATTERN;
    }

    int base = FIELD_ZERO_OFFSET.toInt();
    int pattern = 0;

    for (int i = 0; i < offsets.length; i++) {
      int reference = (offsets[i] - base);
      if (reference > MAX_SPECIALIZED_OFFSET) {
        return FALLBACK_PATTERN;
      }
      pattern |= 1 << (reference >> LOG_BYTES_IN_ADDRESS);
    }

    if (pattern < 0 || pattern > 63) {
      pattern = FALLBACK_PATTERN;
    }

    return pattern;
  }

  /**
   * Return the specialized method for the given type.
   *
   * <p>TODO: Lazily compile specialized methods?
   */
  @Interruptible
  public synchronized CodeArray specializeMethod(RVMType type) {
    /* Work out which pattern this type uses */
    int pattern = getPattern(type);

    if (VM.BuildWithBaseBootImageCompiler) {
      /* There is no point specializing if we aren't opt compiling */
      return null;
    }

    /* Ensure we have a compiled method cached. */
    if (VM.VerifyAssertions) VM._assert(specializedMethods[pattern] != null);

    /* Return the code entry array */
    return specializedMethods[pattern].getEntryCodeArray();
  }

  /** @return the method signature of the specialized method's invoke. */
  public TypeReference[] getSignature() {
    return signature;
  }

  /** @return the return type of the specialized method's invoke */
  public TypeReference getReturnType() {
    return returnType;
  }

  /**
   * This method peforms the scanning of a given object.
   *
   * <p>This is the method that (may) be hijacked by the compiler to call the specialized method.
   *
   * <p>It is safe for a compiler to ignore the potential gains and just use this method directly.
   *
   * @param id The specialized method id
   * @param object The object to scan
   * @param trace The trace to scan
   */
  @SpecializedMethodInvoke
  @NoInline
  public static void invoke(int id, Object object, TransitiveClosure trace) {
    /* By default we call a non-specialized fallback */
    fallback(object, trace);
  }

  /** Fallback */
  public static void fallback(Object object, TransitiveClosure trace) {
    ObjectReference objectRef = ObjectReference.fromObject(object);
    RVMType type = ObjectModel.getObjectType(objectRef.toObject());
    if (type.isClassType()) {
      RVMClass klass = type.asClass();
      int[] offsets = klass.getReferenceOffsets();
      for (int i = 0; i < offsets.length; i++) {
        trace.processEdge(objectRef, objectRef.toAddress().plus(offsets[i]));
      }
    } else if (type.isArrayType() && type.asArray().getElementType().isReferenceType()) {
      for (int i = 0; i < ObjectModel.getArrayLength(objectRef.toObject()); i++) {
        trace.processEdge(objectRef, objectRef.toAddress().plus(i << LOG_BYTES_IN_ADDRESS));
      }
    }
  }

  /** All Scalars */
  public static void scalar(Object object, TransitiveClosure trace) {
    Address base = Magic.objectAsAddress(object);
    int[] offsets = ObjectModel.getObjectType(object).asClass().getReferenceOffsets();
    for (int i = 0; i < offsets.length; i++) {
      trace.processEdge(ObjectReference.fromObject(object), base.plus(offsets[i]));
    }
  }

  /** Reference Arrays */
  public static void referenceArray(Object object, TransitiveClosure trace) {
    Address base = Magic.objectAsAddress(object);
    int length = ObjectModel.getArrayLength(object);
    for (int i = 0; i < length; i++) {
      trace.processEdge(ObjectReference.fromObject(object), base.plus(i << LOG_BYTES_IN_ADDRESS));
    }
  }

  /** No Reference fields / Primitive Arrays */
  public static void noReferences(Object object, TransitiveClosure trace) {}

  /** All patterns bottom out here */
  @Inline
  public static void pattern(int pattern, Object object, TransitiveClosure trace) {
    Address base = Magic.objectAsAddress(object).plus(FIELD_ZERO_OFFSET);
    if ((pattern & 1) != 0) {
      trace.processEdge(ObjectReference.fromObject(object), base.plus(0));
    }
    if ((pattern & 2) != 0) {
      trace.processEdge(ObjectReference.fromObject(object), base.plus(1 << LOG_BYTES_IN_ADDRESS));
    }
    if ((pattern & 4) != 0) {
      trace.processEdge(ObjectReference.fromObject(object), base.plus(2 << LOG_BYTES_IN_ADDRESS));
    }
    if ((pattern & 8) != 0) {
      trace.processEdge(ObjectReference.fromObject(object), base.plus(3 << LOG_BYTES_IN_ADDRESS));
    }
    if ((pattern & 16) != 0) {
      trace.processEdge(ObjectReference.fromObject(object), base.plus(4 << LOG_BYTES_IN_ADDRESS));
    }
    if ((pattern & 32) != 0) {
      trace.processEdge(ObjectReference.fromObject(object), base.plus(5 << LOG_BYTES_IN_ADDRESS));
    }
  }

  /**
   * Find the template method name for a given pattern.
   *
   * @param pattern The pattern to look for
   * @return The method name that will be used.
   */
  private Atom templateMethodName(int pattern) {
    switch (pattern) {
      case 1:
        return Names.scalarRNNNNN;
      case 2:
        return Names.scalarNRNNNN;
      case 3:
        return Names.scalarRRNNNN;
      case 4:
        return Names.scalarNNRNNN;
      case 5:
        return Names.scalarRNRNNN;
      case 6:
        return Names.scalarNRRNNN;
      case 7:
        return Names.scalarRRRNNN;
      case 8:
        return Names.scalarNNNRNN;
      case 9:
        return Names.scalarRNNRNN;
      case 10:
        return Names.scalarNRNRNN;
      case 11:
        return Names.scalarRRNRNN;
      case 12:
        return Names.scalarNNRRNN;
      case 13:
        return Names.scalarRNRRNN;
      case 14:
        return Names.scalarNRRRNN;
      case 15:
        return Names.scalarRRRRNN;
      case 16:
        return Names.scalarNNNNRN;
      case 17:
        return Names.scalarRNNNRN;
      case 18:
        return Names.scalarNRNNRN;
      case 19:
        return Names.scalarRRNNRN;
      case 20:
        return Names.scalarNNRNRN;
      case 21:
        return Names.scalarRNRNRN;
      case 22:
        return Names.scalarNRRNRN;
      case 23:
        return Names.scalarRRRNRN;
      case 24:
        return Names.scalarNNNRRN;
      case 25:
        return Names.scalarRNNRRN;
      case 26:
        return Names.scalarNRNRRN;
      case 27:
        return Names.scalarRRNRRN;
      case 28:
        return Names.scalarNNRRRN;
      case 29:
        return Names.scalarRNRRRN;
      case 30:
        return Names.scalarNRRRRN;
      case 31:
        return Names.scalarRRRRRN;
      case 32:
        return Names.scalarNNNNNR;
      case 33:
        return Names.scalarRNNNNR;
      case 34:
        return Names.scalarNRNNNR;
      case 35:
        return Names.scalarRRNNNR;
      case 36:
        return Names.scalarNNRNNR;
      case 37:
        return Names.scalarRNRNNR;
      case 38:
        return Names.scalarNRRNNR;
      case 39:
        return Names.scalarRRRNNR;
      case 40:
        return Names.scalarNNNRNR;
      case 41:
        return Names.scalarRNNRNR;
      case 42:
        return Names.scalarNRNRNR;
      case 43:
        return Names.scalarRRNRNR;
      case 44:
        return Names.scalarNNRRNR;
      case 45:
        return Names.scalarRNRRNR;
      case 46:
        return Names.scalarNRRRNR;
      case 47:
        return Names.scalarRRRRNR;
      case 48:
        return Names.scalarNNNNRR;
      case 49:
        return Names.scalarRNNNRR;
      case 50:
        return Names.scalarNRNNRR;
      case 51:
        return Names.scalarRRNNRR;
      case 52:
        return Names.scalarNNRNRR;
      case 53:
        return Names.scalarRNRNRR;
      case 54:
        return Names.scalarNRRNRR;
      case 55:
        return Names.scalarRRRNRR;
      case 56:
        return Names.scalarNNNRRR;
      case 57:
        return Names.scalarRNNRRR;
      case 58:
        return Names.scalarNRNRRR;
      case 59:
        return Names.scalarRRNRRR;
      case 60:
        return Names.scalarNNRRRR;
      case 61:
        return Names.scalarRNRRRR;
      case 62:
        return Names.scalarNRRRRR;
      case 63:
        return Names.scalarRRRRRR;
      case NULL_PATTERN:
        return Names.noReferences;
      case REFARRAY_PATTERN:
        return Names.referenceArray;
      case FALLBACK_PATTERN:
      default:
        return Names.scalar;
    }
  }

  /** The generic descriptor for the specialized methods */
  private static final Atom specializedMethodDescriptor =
      Atom.findOrCreateAsciiAtom("(Ljava/lang/Object;Lorg/mmtk/plan/TransitiveClosure;)V");

  /** The atoms for the names of the specialized methods */
  private static final class Names {
    static final Atom fallback = Atom.findOrCreateAsciiAtom("fallback");
    static final Atom referenceArray = Atom.findOrCreateAsciiAtom("referenceArray");
    static final Atom scalar = Atom.findOrCreateAsciiAtom("scalar");
    static final Atom noReferences = Atom.findOrCreateAsciiAtom("noReferences");
    static final Atom scalarRNNNNN = Atom.findOrCreateAsciiAtom("scalarRNNNNN");
    static final Atom scalarNRNNNN = Atom.findOrCreateAsciiAtom("scalarNRNNNN");
    static final Atom scalarRRNNNN = Atom.findOrCreateAsciiAtom("scalarRRNNNN");
    static final Atom scalarNNRNNN = Atom.findOrCreateAsciiAtom("scalarNNRNNN");
    static final Atom scalarRNRNNN = Atom.findOrCreateAsciiAtom("scalarRNRNNN");
    static final Atom scalarNRRNNN = Atom.findOrCreateAsciiAtom("scalarNRRNNN");
    static final Atom scalarRRRNNN = Atom.findOrCreateAsciiAtom("scalarRRRNNN");
    static final Atom scalarNNNRNN = Atom.findOrCreateAsciiAtom("scalarNNNRNN");
    static final Atom scalarRNNRNN = Atom.findOrCreateAsciiAtom("scalarRNNRNN");
    static final Atom scalarNRNRNN = Atom.findOrCreateAsciiAtom("scalarNRNRNN");
    static final Atom scalarRRNRNN = Atom.findOrCreateAsciiAtom("scalarRRNRNN");
    static final Atom scalarNNRRNN = Atom.findOrCreateAsciiAtom("scalarNNRRNN");
    static final Atom scalarRNRRNN = Atom.findOrCreateAsciiAtom("scalarRNRRNN");
    static final Atom scalarNRRRNN = Atom.findOrCreateAsciiAtom("scalarNRRRNN");
    static final Atom scalarRRRRNN = Atom.findOrCreateAsciiAtom("scalarRRRRNN");
    static final Atom scalarNNNNRN = Atom.findOrCreateAsciiAtom("scalarNNNNRN");
    static final Atom scalarRNNNRN = Atom.findOrCreateAsciiAtom("scalarRNNNRN");
    static final Atom scalarNRNNRN = Atom.findOrCreateAsciiAtom("scalarNRNNRN");
    static final Atom scalarRRNNRN = Atom.findOrCreateAsciiAtom("scalarRRNNRN");
    static final Atom scalarNNRNRN = Atom.findOrCreateAsciiAtom("scalarNNRNRN");
    static final Atom scalarRNRNRN = Atom.findOrCreateAsciiAtom("scalarRNRNRN");
    static final Atom scalarNRRNRN = Atom.findOrCreateAsciiAtom("scalarNRRNRN");
    static final Atom scalarRRRNRN = Atom.findOrCreateAsciiAtom("scalarRRRNRN");
    static final Atom scalarNNNRRN = Atom.findOrCreateAsciiAtom("scalarNNNRRN");
    static final Atom scalarRNNRRN = Atom.findOrCreateAsciiAtom("scalarRNNRRN");
    static final Atom scalarNRNRRN = Atom.findOrCreateAsciiAtom("scalarNRNRRN");
    static final Atom scalarRRNRRN = Atom.findOrCreateAsciiAtom("scalarRRNRRN");
    static final Atom scalarNNRRRN = Atom.findOrCreateAsciiAtom("scalarNNRRRN");
    static final Atom scalarRNRRRN = Atom.findOrCreateAsciiAtom("scalarRNRRRN");
    static final Atom scalarNRRRRN = Atom.findOrCreateAsciiAtom("scalarNRRRRN");
    static final Atom scalarRRRRRN = Atom.findOrCreateAsciiAtom("scalarRRRRRN");
    static final Atom scalarNNNNNR = Atom.findOrCreateAsciiAtom("scalarNNNNNR");
    static final Atom scalarRNNNNR = Atom.findOrCreateAsciiAtom("scalarRNNNNR");
    static final Atom scalarNRNNNR = Atom.findOrCreateAsciiAtom("scalarNRNNNR");
    static final Atom scalarRRNNNR = Atom.findOrCreateAsciiAtom("scalarRRNNNR");
    static final Atom scalarNNRNNR = Atom.findOrCreateAsciiAtom("scalarNNRNNR");
    static final Atom scalarRNRNNR = Atom.findOrCreateAsciiAtom("scalarRNRNNR");
    static final Atom scalarNRRNNR = Atom.findOrCreateAsciiAtom("scalarNRRNNR");
    static final Atom scalarRRRNNR = Atom.findOrCreateAsciiAtom("scalarRRRNNR");
    static final Atom scalarNNNRNR = Atom.findOrCreateAsciiAtom("scalarNNNRNR");
    static final Atom scalarRNNRNR = Atom.findOrCreateAsciiAtom("scalarRNNRNR");
    static final Atom scalarNRNRNR = Atom.findOrCreateAsciiAtom("scalarNRNRNR");
    static final Atom scalarRRNRNR = Atom.findOrCreateAsciiAtom("scalarRRNRNR");
    static final Atom scalarNNRRNR = Atom.findOrCreateAsciiAtom("scalarNNRRNR");
    static final Atom scalarRNRRNR = Atom.findOrCreateAsciiAtom("scalarRNRRNR");
    static final Atom scalarNRRRNR = Atom.findOrCreateAsciiAtom("scalarNRRRNR");
    static final Atom scalarRRRRNR = Atom.findOrCreateAsciiAtom("scalarRRRRNR");
    static final Atom scalarNNNNRR = Atom.findOrCreateAsciiAtom("scalarNNNNRR");
    static final Atom scalarRNNNRR = Atom.findOrCreateAsciiAtom("scalarRNNNRR");
    static final Atom scalarNRNNRR = Atom.findOrCreateAsciiAtom("scalarNRNNRR");
    static final Atom scalarRRNNRR = Atom.findOrCreateAsciiAtom("scalarRRNNRR");
    static final Atom scalarNNRNRR = Atom.findOrCreateAsciiAtom("scalarNNRNRR");
    static final Atom scalarRNRNRR = Atom.findOrCreateAsciiAtom("scalarRNRNRR");
    static final Atom scalarNRRNRR = Atom.findOrCreateAsciiAtom("scalarNRRNRR");
    static final Atom scalarRRRNRR = Atom.findOrCreateAsciiAtom("scalarRRRNRR");
    static final Atom scalarNNNRRR = Atom.findOrCreateAsciiAtom("scalarNNNRRR");
    static final Atom scalarRNNRRR = Atom.findOrCreateAsciiAtom("scalarRNNRRR");
    static final Atom scalarNRNRRR = Atom.findOrCreateAsciiAtom("scalarNRNRRR");
    static final Atom scalarRRNRRR = Atom.findOrCreateAsciiAtom("scalarRRNRRR");
    static final Atom scalarNNRRRR = Atom.findOrCreateAsciiAtom("scalarNNRRRR");
    static final Atom scalarRNRRRR = Atom.findOrCreateAsciiAtom("scalarRNRRRR");
    static final Atom scalarNRRRRR = Atom.findOrCreateAsciiAtom("scalarNRRRRR");
    static final Atom scalarRRRRRR = Atom.findOrCreateAsciiAtom("scalarRRRRRR");
  }

  // CHECKSTYLE:OFF

  public static void scalarRNNNNN(Object object, TransitiveClosure trace) {
    pattern(1, object, trace);
  }

  public static void scalarNRNNNN(Object object, TransitiveClosure trace) {
    pattern(2, object, trace);
  }

  public static void scalarRRNNNN(Object object, TransitiveClosure trace) {
    pattern(3, object, trace);
  }

  public static void scalarNNRNNN(Object object, TransitiveClosure trace) {
    pattern(4, object, trace);
  }

  public static void scalarRNRNNN(Object object, TransitiveClosure trace) {
    pattern(5, object, trace);
  }

  public static void scalarNRRNNN(Object object, TransitiveClosure trace) {
    pattern(6, object, trace);
  }

  public static void scalarRRRNNN(Object object, TransitiveClosure trace) {
    pattern(7, object, trace);
  }

  public static void scalarNNNRNN(Object object, TransitiveClosure trace) {
    pattern(8, object, trace);
  }

  public static void scalarRNNRNN(Object object, TransitiveClosure trace) {
    pattern(9, object, trace);
  }

  public static void scalarNRNRNN(Object object, TransitiveClosure trace) {
    pattern(10, object, trace);
  }

  public static void scalarRRNRNN(Object object, TransitiveClosure trace) {
    pattern(11, object, trace);
  }

  public static void scalarNNRRNN(Object object, TransitiveClosure trace) {
    pattern(12, object, trace);
  }

  public static void scalarRNRRNN(Object object, TransitiveClosure trace) {
    pattern(13, object, trace);
  }

  public static void scalarNRRRNN(Object object, TransitiveClosure trace) {
    pattern(14, object, trace);
  }

  public static void scalarRRRRNN(Object object, TransitiveClosure trace) {
    pattern(15, object, trace);
  }

  public static void scalarNNNNRN(Object object, TransitiveClosure trace) {
    pattern(16, object, trace);
  }

  public static void scalarRNNNRN(Object object, TransitiveClosure trace) {
    pattern(17, object, trace);
  }

  public static void scalarNRNNRN(Object object, TransitiveClosure trace) {
    pattern(18, object, trace);
  }

  public static void scalarRRNNRN(Object object, TransitiveClosure trace) {
    pattern(19, object, trace);
  }

  public static void scalarNNRNRN(Object object, TransitiveClosure trace) {
    pattern(20, object, trace);
  }

  public static void scalarRNRNRN(Object object, TransitiveClosure trace) {
    pattern(21, object, trace);
  }

  public static void scalarNRRNRN(Object object, TransitiveClosure trace) {
    pattern(22, object, trace);
  }

  public static void scalarRRRNRN(Object object, TransitiveClosure trace) {
    pattern(23, object, trace);
  }

  public static void scalarNNNRRN(Object object, TransitiveClosure trace) {
    pattern(24, object, trace);
  }

  public static void scalarRNNRRN(Object object, TransitiveClosure trace) {
    pattern(25, object, trace);
  }

  public static void scalarNRNRRN(Object object, TransitiveClosure trace) {
    pattern(26, object, trace);
  }

  public static void scalarRRNRRN(Object object, TransitiveClosure trace) {
    pattern(27, object, trace);
  }

  public static void scalarNNRRRN(Object object, TransitiveClosure trace) {
    pattern(28, object, trace);
  }

  public static void scalarRNRRRN(Object object, TransitiveClosure trace) {
    pattern(29, object, trace);
  }

  public static void scalarNRRRRN(Object object, TransitiveClosure trace) {
    pattern(30, object, trace);
  }

  public static void scalarRRRRRN(Object object, TransitiveClosure trace) {
    pattern(31, object, trace);
  }

  public static void scalarNNNNNR(Object object, TransitiveClosure trace) {
    pattern(32, object, trace);
  }

  public static void scalarRNNNNR(Object object, TransitiveClosure trace) {
    pattern(33, object, trace);
  }

  public static void scalarNRNNNR(Object object, TransitiveClosure trace) {
    pattern(34, object, trace);
  }

  public static void scalarRRNNNR(Object object, TransitiveClosure trace) {
    pattern(35, object, trace);
  }

  public static void scalarNNRNNR(Object object, TransitiveClosure trace) {
    pattern(36, object, trace);
  }

  public static void scalarRNRNNR(Object object, TransitiveClosure trace) {
    pattern(37, object, trace);
  }

  public static void scalarNRRNNR(Object object, TransitiveClosure trace) {
    pattern(38, object, trace);
  }

  public static void scalarRRRNNR(Object object, TransitiveClosure trace) {
    pattern(39, object, trace);
  }

  public static void scalarNNNRNR(Object object, TransitiveClosure trace) {
    pattern(40, object, trace);
  }

  public static void scalarRNNRNR(Object object, TransitiveClosure trace) {
    pattern(41, object, trace);
  }

  public static void scalarNRNRNR(Object object, TransitiveClosure trace) {
    pattern(42, object, trace);
  }

  public static void scalarRRNRNR(Object object, TransitiveClosure trace) {
    pattern(43, object, trace);
  }

  public static void scalarNNRRNR(Object object, TransitiveClosure trace) {
    pattern(44, object, trace);
  }

  public static void scalarRNRRNR(Object object, TransitiveClosure trace) {
    pattern(45, object, trace);
  }

  public static void scalarNRRRNR(Object object, TransitiveClosure trace) {
    pattern(46, object, trace);
  }

  public static void scalarRRRRNR(Object object, TransitiveClosure trace) {
    pattern(47, object, trace);
  }

  public static void scalarNNNNRR(Object object, TransitiveClosure trace) {
    pattern(48, object, trace);
  }

  public static void scalarRNNNRR(Object object, TransitiveClosure trace) {
    pattern(49, object, trace);
  }

  public static void scalarNRNNRR(Object object, TransitiveClosure trace) {
    pattern(50, object, trace);
  }

  public static void scalarRRNNRR(Object object, TransitiveClosure trace) {
    pattern(51, object, trace);
  }

  public static void scalarNNRNRR(Object object, TransitiveClosure trace) {
    pattern(52, object, trace);
  }

  public static void scalarRNRNRR(Object object, TransitiveClosure trace) {
    pattern(53, object, trace);
  }

  public static void scalarNRRNRR(Object object, TransitiveClosure trace) {
    pattern(54, object, trace);
  }

  public static void scalarRRRNRR(Object object, TransitiveClosure trace) {
    pattern(55, object, trace);
  }

  public static void scalarNNNRRR(Object object, TransitiveClosure trace) {
    pattern(56, object, trace);
  }

  public static void scalarRNNRRR(Object object, TransitiveClosure trace) {
    pattern(57, object, trace);
  }

  public static void scalarNRNRRR(Object object, TransitiveClosure trace) {
    pattern(58, object, trace);
  }

  public static void scalarRRNRRR(Object object, TransitiveClosure trace) {
    pattern(59, object, trace);
  }

  public static void scalarNNRRRR(Object object, TransitiveClosure trace) {
    pattern(60, object, trace);
  }

  public static void scalarRNRRRR(Object object, TransitiveClosure trace) {
    pattern(61, object, trace);
  }

  public static void scalarNRRRRR(Object object, TransitiveClosure trace) {
    pattern(62, object, trace);
  }

  public static void scalarRRRRRR(Object object, TransitiveClosure trace) {
    pattern(63, object, trace);
  }

  // CHECKSTYLE:ON
}
 /**
  * Create a method for reflectively invoking this method
  *
  * @param reflectionClass the class this method will belong to
  * @param constantPool for the class
  * @param memRef the member reference corresponding to this method
  * @return the created method
  */
 RVMMethod createReflectionMethod(
     TypeReference reflectionClass, int[] constantPool, MethodReference memRef) {
   TypeReference[] parameters = getParameterTypes();
   int numParams = parameters.length;
   byte[] bytecodes;
   boolean interfaceCall = false;
   int curBC = 0;
   if (!isStatic()) {
     if (!getDeclaringClass().isInterface()) {
       // virtual call
       bytecodes = new byte[8 * numParams + 8];
     } else {
       // interface call
       bytecodes = new byte[8 * numParams + 10];
       interfaceCall = true;
     }
     bytecodes[curBC] = JBC_aload_1;
     curBC++;
   } else {
     // static call
     bytecodes = new byte[8 * numParams + 7];
   }
   for (int i = 0; i < numParams; i++) {
     if (parameters[i].isVoidType()) {
       bytecodes[curBC] =
           bytecodes[curBC + 1] =
               bytecodes[curBC + 2] =
                   bytecodes[curBC + 3] =
                       bytecodes[curBC + 4] =
                           bytecodes[curBC + 5] =
                               bytecodes[curBC + 6] = bytecodes[curBC + 7] = (byte) JBC_nop;
       continue;
     }
     bytecodes[curBC] = (byte) JBC_aload_2;
     bytecodes[curBC + 1] = (byte) JBC_sipush;
     bytecodes[curBC + 2] = (byte) (i >>> 8);
     bytecodes[curBC + 3] = (byte) i;
     bytecodes[curBC + 4] = (byte) JBC_aaload;
     if (!parameters[i].isPrimitiveType()) {
       bytecodes[curBC + 5] = (byte) JBC_checkcast;
       if (VM.VerifyAssertions) VM._assert(parameters[i].getId() != 0);
       constantPool[i + 1] = ClassFileReader.packCPEntry(CP_CLASS, parameters[i].getId());
       bytecodes[curBC + 6] = (byte) ((i + 1) >>> 8);
       bytecodes[curBC + 7] = (byte) (i + 1);
     } else if (parameters[i].isWordLikeType()) {
       bytecodes[curBC + 5] = bytecodes[curBC + 6] = bytecodes[curBC + 7] = (byte) JBC_nop;
     } else {
       bytecodes[curBC + 5] = (byte) JBC_invokestatic;
       MemberReference unboxMethod;
       if (parameters[i].isBooleanType()) {
         unboxMethod =
             MethodReference.findOrCreate(
                 baseReflectionClass,
                 Atom.findOrCreateUnicodeAtom("unboxAsBoolean"),
                 Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)Z"));
       } else if (parameters[i].isByteType()) {
         unboxMethod =
             MethodReference.findOrCreate(
                 baseReflectionClass,
                 Atom.findOrCreateUnicodeAtom("unboxAsByte"),
                 Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)B"));
       } else if (parameters[i].isShortType()) {
         unboxMethod =
             MethodReference.findOrCreate(
                 baseReflectionClass,
                 Atom.findOrCreateUnicodeAtom("unboxAsShort"),
                 Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)S"));
       } else if (parameters[i].isCharType()) {
         unboxMethod =
             MethodReference.findOrCreate(
                 baseReflectionClass,
                 Atom.findOrCreateUnicodeAtom("unboxAsChar"),
                 Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)C"));
       } else if (parameters[i].isIntType()) {
         unboxMethod =
             MethodReference.findOrCreate(
                 baseReflectionClass,
                 Atom.findOrCreateUnicodeAtom("unboxAsInt"),
                 Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)I"));
       } else if (parameters[i].isLongType()) {
         unboxMethod =
             MethodReference.findOrCreate(
                 baseReflectionClass,
                 Atom.findOrCreateUnicodeAtom("unboxAsLong"),
                 Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)J"));
       } else if (parameters[i].isFloatType()) {
         unboxMethod =
             MethodReference.findOrCreate(
                 baseReflectionClass,
                 Atom.findOrCreateUnicodeAtom("unboxAsFloat"),
                 Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)F"));
       } else {
         if (VM.VerifyAssertions) VM._assert(parameters[i].isDoubleType());
         unboxMethod =
             MethodReference.findOrCreate(
                 baseReflectionClass,
                 Atom.findOrCreateUnicodeAtom("unboxAsDouble"),
                 Atom.findOrCreateUnicodeAtom("(Ljava/lang/Object;)D"));
       }
       constantPool[i + 1] = ClassFileReader.packCPEntry(CP_MEMBER, unboxMethod.getId());
       bytecodes[curBC + 6] = (byte) ((i + 1) >>> 8);
       bytecodes[curBC + 7] = (byte) (i + 1);
     }
     curBC += 8;
   }
   if (isStatic()) {
     bytecodes[curBC] = (byte) JBC_invokestatic;
   } else if (isObjectInitializer() || isPrivate()) {
     bytecodes[curBC] = (byte) JBC_invokespecial;
   } else if (interfaceCall) {
     bytecodes[curBC] = (byte) JBC_invokeinterface;
   } else {
     bytecodes[curBC] = (byte) JBC_invokevirtual;
   }
   constantPool[numParams + 1] = ClassFileReader.packCPEntry(CP_MEMBER, getId());
   bytecodes[curBC + 1] = (byte) ((numParams + 1) >>> 8);
   bytecodes[curBC + 2] = (byte) (numParams + 1);
   if (interfaceCall) {
     // invokeinterface bytecodes are historically longer than others
     curBC += 2;
   }
   TypeReference returnType = getReturnType();
   if (!returnType.isPrimitiveType() || returnType.isWordLikeType()) {
     bytecodes[curBC + 3] = (byte) JBC_nop;
     bytecodes[curBC + 4] = (byte) JBC_nop;
     bytecodes[curBC + 5] = (byte) JBC_nop;
   } else if (returnType.isVoidType()) {
     bytecodes[curBC + 3] = (byte) JBC_aconst_null;
     bytecodes[curBC + 4] = (byte) JBC_nop;
     bytecodes[curBC + 5] = (byte) JBC_nop;
   } else {
     MemberReference boxMethod;
     if (returnType.isBooleanType()) {
       boxMethod =
           MethodReference.findOrCreate(
               baseReflectionClass,
               Atom.findOrCreateUnicodeAtom("boxAsBoolean"),
               Atom.findOrCreateUnicodeAtom("(Z)Ljava/lang/Object;"));
     } else if (returnType.isByteType()) {
       boxMethod =
           MethodReference.findOrCreate(
               baseReflectionClass,
               Atom.findOrCreateUnicodeAtom("boxAsByte"),
               Atom.findOrCreateUnicodeAtom("(B)Ljava/lang/Object;"));
     } else if (returnType.isShortType()) {
       boxMethod =
           MethodReference.findOrCreate(
               baseReflectionClass,
               Atom.findOrCreateUnicodeAtom("boxAsShort"),
               Atom.findOrCreateUnicodeAtom("(S)Ljava/lang/Object;"));
     } else if (returnType.isCharType()) {
       boxMethod =
           MethodReference.findOrCreate(
               baseReflectionClass,
               Atom.findOrCreateUnicodeAtom("boxAsChar"),
               Atom.findOrCreateUnicodeAtom("(C)Ljava/lang/Object;"));
     } else if (returnType.isIntType()) {
       boxMethod =
           MethodReference.findOrCreate(
               baseReflectionClass,
               Atom.findOrCreateUnicodeAtom("boxAsInt"),
               Atom.findOrCreateUnicodeAtom("(I)Ljava/lang/Object;"));
     } else if (returnType.isLongType()) {
       boxMethod =
           MethodReference.findOrCreate(
               baseReflectionClass,
               Atom.findOrCreateUnicodeAtom("boxAsLong"),
               Atom.findOrCreateUnicodeAtom("(J)Ljava/lang/Object;"));
     } else if (returnType.isFloatType()) {
       boxMethod =
           MethodReference.findOrCreate(
               baseReflectionClass,
               Atom.findOrCreateUnicodeAtom("boxAsFloat"),
               Atom.findOrCreateUnicodeAtom("(F)Ljava/lang/Object;"));
     } else {
       if (VM.VerifyAssertions) VM._assert(returnType.isDoubleType());
       boxMethod =
           MethodReference.findOrCreate(
               baseReflectionClass,
               Atom.findOrCreateUnicodeAtom("boxAsDouble"),
               Atom.findOrCreateUnicodeAtom("(D)Ljava/lang/Object;"));
     }
     constantPool[numParams + 2] = ClassFileReader.packCPEntry(CP_MEMBER, boxMethod.getId());
     bytecodes[curBC + 3] = (byte) JBC_invokestatic;
     bytecodes[curBC + 4] = (byte) ((numParams + 2) >>> 8);
     bytecodes[curBC + 5] = (byte) (numParams + 2);
   }
   bytecodes[curBC + 6] = (byte) JBC_areturn;
   return new NormalMethod(
       reflectionClass,
       memRef,
       (short) (ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC),
       null,
       (short) 3,
       (short) (getParameterWords() + 2),
       bytecodes,
       null,
       null,
       null,
       constantPool,
       null,
       null,
       null,
       null);
 }
  /**
   * Called from {@link ClassFileReader#readClass(TypeReference,DataInputStream)} to create an
   * instance of a RVMMethod by reading the relevant data from the argument bytecode stream.
   *
   * @param declaringClass the TypeReference of the class being loaded
   * @param constantPool the constantPool of the RVMClass object that's being constructed
   * @param memRef the canonical memberReference for this member.
   * @param modifiers modifiers associated with this member.
   * @param input the DataInputStream to read the method's attributes from
   */
  static RVMMethod readMethod(
      TypeReference declaringClass,
      int[] constantPool,
      MemberReference memRef,
      short modifiers,
      DataInputStream input)
      throws IOException {
    short tmp_localWords = 0;
    short tmp_operandWords = 0;
    byte[] tmp_bytecodes = null;
    ExceptionHandlerMap tmp_exceptionHandlerMap = null;
    TypeReference[] tmp_exceptionTypes = null;
    int[] tmp_lineNumberMap = null;
    LocalVariableTable tmp_localVariableTable = null;
    Atom tmp_signature = null;
    RVMAnnotation[] annotations = null;
    RVMAnnotation[][] parameterAnnotations = null;
    Object tmp_annotationDefault = null;

    // Read the attributes
    for (int i = 0, n = input.readUnsignedShort(); i < n; i++) {
      Atom attName = ClassFileReader.getUtf(constantPool, input.readUnsignedShort());
      int attLength = input.readInt();

      // Only bother to interpret non-boring Method attributes
      if (attName == RVMClassLoader.codeAttributeName) {
        tmp_operandWords = input.readShort();
        tmp_localWords = input.readShort();
        tmp_bytecodes = new byte[input.readInt()];
        input.readFully(tmp_bytecodes);
        tmp_exceptionHandlerMap = ExceptionHandlerMap.readExceptionHandlerMap(input, constantPool);

        // Read the attributes portion of the code attribute
        for (int j = 0, n2 = input.readUnsignedShort(); j < n2; j++) {
          attName = ClassFileReader.getUtf(constantPool, input.readUnsignedShort());
          attLength = input.readInt();

          if (attName == RVMClassLoader.lineNumberTableAttributeName) {
            int cnt = input.readUnsignedShort();
            if (cnt != 0) {
              tmp_lineNumberMap = new int[cnt];
              for (int k = 0; k < cnt; k++) {
                int startPC = input.readUnsignedShort();
                int lineNumber = input.readUnsignedShort();
                tmp_lineNumberMap[k] = (lineNumber << BITS_IN_SHORT) | startPC;
              }
            }
          } else if (attName == RVMClassLoader.localVariableTableAttributeName) {
            tmp_localVariableTable = LocalVariableTable.readLocalVariableTable(input, constantPool);
          } else {
            // All other entries in the attribute portion of the code attribute are boring.
            int skippedAmount = input.skipBytes(attLength);
            if (skippedAmount != attLength) {
              throw new IOException("Unexpected short skip");
            }
          }
        }
      } else if (attName == RVMClassLoader.exceptionsAttributeName) {
        int cnt = input.readUnsignedShort();
        if (cnt != 0) {
          tmp_exceptionTypes = new TypeReference[cnt];
          for (int j = 0, m = tmp_exceptionTypes.length; j < m; ++j) {
            tmp_exceptionTypes[j] =
                ClassFileReader.getTypeRef(constantPool, input.readUnsignedShort());
          }
        }
      } else if (attName == RVMClassLoader.syntheticAttributeName) {
        modifiers |= ACC_SYNTHETIC;
      } else if (attName == RVMClassLoader.signatureAttributeName) {
        tmp_signature = ClassFileReader.getUtf(constantPool, input.readUnsignedShort());
      } else if (attName == RVMClassLoader.runtimeVisibleAnnotationsAttributeName) {
        annotations =
            AnnotatedElement.readAnnotations(constantPool, input, declaringClass.getClassLoader());
      } else if (attName == RVMClassLoader.runtimeVisibleParameterAnnotationsAttributeName) {
        int numParameters = input.readByte() & 0xFF;
        parameterAnnotations = new RVMAnnotation[numParameters][];
        for (int a = 0; a < numParameters; ++a) {
          parameterAnnotations[a] =
              AnnotatedElement.readAnnotations(
                  constantPool, input, declaringClass.getClassLoader());
        }
      } else if (attName == RVMClassLoader.annotationDefaultAttributeName) {
        try {
          tmp_annotationDefault =
              RVMAnnotation.readValue(
                  memRef.asMethodReference().getReturnType(),
                  constantPool,
                  input,
                  declaringClass.getClassLoader());
        } catch (ClassNotFoundException e) {
          throw new Error(e);
        }
      } else {
        // all other method attributes are boring
        int skippedAmount = input.skipBytes(attLength);
        if (skippedAmount != attLength) {
          throw new IOException("Unexpected short skip");
        }
      }
    }
    RVMMethod method;
    if ((modifiers & ACC_NATIVE) != 0) {
      method =
          new NativeMethod(
              declaringClass,
              memRef,
              modifiers,
              tmp_exceptionTypes,
              tmp_signature,
              annotations,
              parameterAnnotations,
              tmp_annotationDefault);
    } else if ((modifiers & ACC_ABSTRACT) != 0) {
      method =
          new AbstractMethod(
              declaringClass,
              memRef,
              modifiers,
              tmp_exceptionTypes,
              tmp_signature,
              annotations,
              parameterAnnotations,
              tmp_annotationDefault);

    } else {
      method =
          new NormalMethod(
              declaringClass,
              memRef,
              modifiers,
              tmp_exceptionTypes,
              tmp_localWords,
              tmp_operandWords,
              tmp_bytecodes,
              tmp_exceptionHandlerMap,
              tmp_lineNumberMap,
              tmp_localVariableTable,
              constantPool,
              tmp_signature,
              annotations,
              parameterAnnotations,
              tmp_annotationDefault);
    }
    return method;
  }
  /**
   * Do a quick pass over the IR, and return types that are candidates for redundant load
   * elimination. Algorithm: return those types T where 1) there's a load L(i) of type T 2) there's
   * another load or store M(j) of type T, M!=L and V(i) == V(j)
   *
   * <p>The result contains objects of type RVMField and TypeReference, whose narrowest common
   * ancestor is Object.
   */
  @SuppressWarnings("unchecked")
  public static HashSet<Object> getCandidates(IR ir) {
    GlobalValueNumberState valueNumbers = ir.HIRInfo.valueNumbers;
    // which types have we seen loads for?
    HashSet<Object> seenLoad = new HashSet<Object>(10);
    // which static fields have we seen stores for?
    HashSet<RVMField> seenStore = new HashSet<RVMField>(10);
    HashSet<Object> resultSet = new HashSet<Object>(10);
    HashSet<FieldReference> forbidden = new HashSet<FieldReference>(10);
    // for each type T, indices(T) gives the set of value number (pairs)
    // that identify the indices seen in memory accesses to type T.
    HashMap indices = new HashMap(10);

    for (Enumeration be = ir.getBasicBlocks(); be.hasMoreElements(); ) {
      BasicBlock bb = (BasicBlock) be.nextElement();
      if (!ir.options.FREQ_FOCUS_EFFORT || !bb.getInfrequent()) {
        for (InstructionEnumeration e = bb.forwardInstrEnumerator(); e.hasMoreElements(); ) {
          Instruction s = e.next();
          switch (s.operator().opcode) {
            case GETFIELD_opcode:
              {
                Operand ref = GetField.getRef(s);
                FieldReference fr = GetField.getLocation(s).getFieldRef();
                RVMField f = fr.peekResolvedField();
                if (f == null) {
                  forbidden.add(fr);
                } else {
                  HashSet<Integer> numbers = findOrCreateIndexSet(indices, f);
                  int v = valueNumbers.getValueNumber(ref);
                  Integer V = v;
                  if (numbers.contains(V)) {
                    resultSet.add(f);
                  } else {
                    numbers.add(V);
                  }
                  seenLoad.add(f);
                }
              }
              break;
            case PUTFIELD_opcode:
              {
                Operand ref = PutField.getRef(s);
                FieldReference fr = PutField.getLocation(s).getFieldRef();
                RVMField f = fr.peekResolvedField();
                if (f == null) {
                  forbidden.add(fr);
                } else {
                  HashSet<Integer> numbers = findOrCreateIndexSet(indices, f);
                  int v = valueNumbers.getValueNumber(ref);
                  Integer V = v;
                  if (numbers.contains(V)) {
                    if (seenLoad.contains(f)) {
                      resultSet.add(f);
                    }
                  } else {
                    numbers.add(V);
                  }
                }
              }
              break;
            case GETSTATIC_opcode:
              {
                FieldReference fr = GetStatic.getLocation(s).getFieldRef();
                RVMField f = fr.peekResolvedField();
                if (f == null) {
                  forbidden.add(fr);
                } else {
                  if (seenLoad.contains(f) || seenStore.contains(f)) {
                    resultSet.add(f);
                  }
                  seenLoad.add(f);
                }
              }
              break;
            case PUTSTATIC_opcode:
              {
                FieldReference fr = PutStatic.getLocation(s).getFieldRef();
                RVMField f = fr.peekResolvedField();
                if (f == null) {
                  forbidden.add(fr);
                } else {
                  if (seenLoad.contains(f)) {
                    resultSet.add(f);
                  }
                  seenStore.add(f);
                }
              }
              break;
            case INT_ALOAD_opcode:
            case LONG_ALOAD_opcode:
            case FLOAT_ALOAD_opcode:
            case DOUBLE_ALOAD_opcode:
            case REF_ALOAD_opcode:
            case BYTE_ALOAD_opcode:
            case UBYTE_ALOAD_opcode:
            case USHORT_ALOAD_opcode:
            case SHORT_ALOAD_opcode:
              {
                Operand ref = ALoad.getArray(s);
                TypeReference type = ref.getType();
                if (type.isArrayType()) {
                  if (!type.getArrayElementType().isPrimitiveType()) {
                    type = TypeReference.JavaLangObjectArray;
                  }
                }
                Operand index = ALoad.getIndex(s);

                HashSet<ValueNumberPair> numbers = findOrCreateIndexSet(indices, type);
                int v1 = valueNumbers.getValueNumber(ref);
                int v2 = valueNumbers.getValueNumber(index);
                ValueNumberPair V = new ValueNumberPair(v1, v2);
                if (numbers.contains(V)) {
                  resultSet.add(type);
                } else {
                  numbers.add(V);
                }
                seenLoad.add(type);
              }

              break;

            case INT_ASTORE_opcode:
            case LONG_ASTORE_opcode:
            case FLOAT_ASTORE_opcode:
            case DOUBLE_ASTORE_opcode:
            case REF_ASTORE_opcode:
            case BYTE_ASTORE_opcode:
            case SHORT_ASTORE_opcode:
              {
                Operand ref = AStore.getArray(s);
                TypeReference type = ref.getType();
                if (type.isArrayType()) {
                  if (!type.getArrayElementType().isPrimitiveType()) {
                    type = TypeReference.JavaLangObjectArray;
                  }
                }
                Operand index = AStore.getIndex(s);

                HashSet<ValueNumberPair> numbers = findOrCreateIndexSet(indices, type);
                int v1 = valueNumbers.getValueNumber(ref);
                int v2 = valueNumbers.getValueNumber(index);
                ValueNumberPair V = new ValueNumberPair(v1, v2);

                if (numbers.contains(V)) {
                  if (seenLoad.contains(type)) {
                    resultSet.add(type);
                  }
                } else {
                  numbers.add(V);
                }
              }
              break;

            default:
              break;
          }
        }
      }
    }

    // If we have found an unresolved field reference, then conservatively
    // remove all fields that it might refer to from the resultSet.
    for (final FieldReference fieldReference : forbidden) {
      for (Iterator i2 = resultSet.iterator(); i2.hasNext(); ) {
        Object it = i2.next();
        if (it instanceof RVMField) {
          final RVMField field = (RVMField) it;
          if (!fieldReference.definitelyDifferent(field.getMemberRef().asFieldReference())) {
            i2.remove();
          }
        }
      }
    }

    return resultSet;
  }
Beispiel #11
0
 public Class<?> getDeclaringClass() {
   if (!type.isClassType()) return null;
   TypeReference dc = type.asClass().getDeclaringClass();
   if (dc == null) return null;
   return dc.resolve().getClassForType();
 }