예제 #1
0
 /** Are two annotations equal? */
 private boolean annotationEquals(Annotation a, Annotation b) {
   if (a == b) {
     return true;
   } else if (a.getClass() != b.getClass()) {
     return false;
   } else {
     RVMClass annotationInterface = type.resolve().asClass();
     RVMMethod[] annotationMethods = annotationInterface.getDeclaredMethods();
     AnnotationFactory afB = (AnnotationFactory) Proxy.getInvocationHandler(b);
     try {
       for (RVMMethod method : annotationMethods) {
         String name = method.getName().toUnicodeString();
         Object objA = getElementValue(name, method.getReturnType().resolve().getClassForType());
         Object objB = afB.getValue(name, method.getReturnType().resolve().getClassForType());
         if (!objA.getClass().isArray()) {
           if (!objA.equals(objB)) {
             return false;
           }
         } else {
           if (!Arrays.equals((Object[]) objA, (Object[]) objB)) {
             return false;
           }
         }
       }
     } catch (java.io.UTFDataFormatException e) {
       throw new Error(e);
     }
     return true;
   }
 }
  /** Is a finalizer method extended from Object: {@code protected void finalize()} */
  @Pure
  public static boolean isFinalizer(final RVMMethod method) {
    if (!method.isProtected()) return false;

    // is the method name "finalize"
    byte[] name = method.getName().getBytes();
    if (name.length != 8) return false;
    // is the desc "()V"?
    byte[] desc = method.getDescriptor().getBytes();
    if (desc.length != 3) return false;

    if (name[0] != 'f'
        || name[1] != 'i'
        || name[2] != 'n'
        || name[3] != 'a'
        || name[4] != 'l'
        || name[5] != 'i'
        || name[6] != 'z'
        || name[7] != 'e'
        || desc[8] != '('
        || desc[9] != ')'
        || desc[10] != 'V') return false;

    return true;
  }
 private boolean match(RVMMethod method) {
   if (excludePattern == null) return true;
   RVMClass cls = method.getDeclaringClass();
   String clsName = cls.toString();
   if (clsName.compareTo("org.jikesrvm.compilers.opt.runtimesupport.OptSaveVolatile") == 0)
     return true;
   String methodName = method.getName().toString();
   String fullName = clsName + "." + methodName;
   return (fullName.indexOf(excludePattern)) < 0;
 }
예제 #4
0
  public Method[] getDeclaredMethods() throws SecurityException {
    checkMemberAccess(Member.DECLARED);
    if (!type.isClassType()) return new Method[0];

    RVMMethod[] methods = type.asClass().getDeclaredMethods();
    ArrayList<Method> coll = new ArrayList<Method>(methods.length);
    for (RVMMethod meth : methods) {
      if (!meth.isClassInitializer() && !meth.isObjectInitializer()) {
        coll.add(JikesRVMSupport.createMethod(meth));
      }
    }
    return coll.toArray(new Method[coll.size()]);
  }
예제 #5
0
 @Pure
 private RVMMethod getDefaultConstructor() {
   if (this.defaultConstructor == null) {
     RVMMethod defaultConstructor = null;
     RVMMethod[] methods = type.asClass().getConstructorMethods();
     for (RVMMethod method : methods) {
       if (method.getParameterTypes().length == 0) {
         defaultConstructor = method;
         break;
       }
     }
     this.defaultConstructor = defaultConstructor;
   }
   return this.defaultConstructor;
 }
예제 #6
0
  public Constructor<?>[] getConstructors() throws SecurityException {
    checkMemberAccess(Member.PUBLIC);
    if (!type.isClassType()) return new Constructor[0];

    RVMMethod[] methods = type.asClass().getConstructorMethods();
    ArrayList<Constructor<T>> coll = new ArrayList<Constructor<T>>(methods.length);
    for (RVMMethod method : methods) {
      if (method.isPublic()) {
        @SuppressWarnings("unchecked")
        Constructor<T> x = (Constructor<T>) JikesRVMSupport.createConstructor(method);
        coll.add(x);
      }
    }
    return coll.toArray(new Constructor[coll.size()]);
  }
  /* generate yieldpoint without checking threadSwith request
   */
  private static void expandUnconditionalYieldpoint(Instruction s, IR ir, RVMMethod meth) {
    // split the basic block after the yieldpoint, create a new
    // block at the end of the IR to hold the yieldpoint,
    // remove the yieldpoint (to prepare to out it in the new block at the end)
    BasicBlock thisBlock = s.getBasicBlock();
    BasicBlock nextBlock = thisBlock.splitNodeWithLinksAt(s, ir);
    BasicBlock yieldpoint = thisBlock.createSubBlock(s.getBytecodeIndex(), ir);
    thisBlock.insertOut(yieldpoint);
    yieldpoint.insertOut(nextBlock);
    ir.cfg.addLastInCodeOrder(yieldpoint);
    s.remove();

    // change thread switch instruction into call to thread switch routine
    // NOTE: must make s the call instruction: it is the GC point!
    //       must also inform the GCMap that s has been moved!!!
    Offset offset = meth.getOffset();
    LocationOperand loc = new LocationOperand(offset);
    Operand guard = TG();
    Operand target = MemoryOperand.D(Magic.getTocPointer().plus(offset), (byte) 4, loc, guard);
    MIR_Call.mutate0(s, CALL_SAVE_VOLATILE, null, null, target, MethodOperand.STATIC(meth));
    yieldpoint.appendInstruction(s);
    ir.MIRInfo.gcIRMap.moveToEnd(s);

    yieldpoint.appendInstruction(MIR_Branch.create(IA32_JMP, nextBlock.makeJumpTarget()));

    // make a jump to yield block
    thisBlock.appendInstruction(MIR_Branch.create(IA32_JMP, yieldpoint.makeJumpTarget()));
  }
 /**
  * Create a copy of the method that occurs in the annotation interface. The method body will
  * contain a read of the field at the constant pool index specified.
  *
  * @param annotationClass the class this method belongs to
  * @param constantPool for the class
  * @param memRef the member reference corresponding to this method
  * @param interfaceMethod the interface method that will copied to produce the annotation method
  * @param constantPoolIndex the index of the field that will be returned by this method
  * @return the created method
  */
 static RVMMethod createAnnotationMethod(
     TypeReference annotationClass,
     int[] constantPool,
     MemberReference memRef,
     RVMMethod interfaceMethod,
     int constantPoolIndex) {
   byte[] bytecodes =
       new byte[] {
         (byte) JBC_aload_0,
         (byte) JBC_getfield,
         (byte) (constantPoolIndex >>> 8),
         (byte) constantPoolIndex,
         // Xreturn
         (byte) typeRefToReturnBytecode(interfaceMethod.getReturnType())
       };
   return new NormalMethod(
       annotationClass,
       memRef,
       (short) (ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC),
       null,
       (short) 1,
       (short) 2,
       bytecodes,
       null,
       null,
       null,
       constantPool,
       null,
       null,
       null,
       null);
 }
예제 #9
0
 Class<?>[] getExceptionTypes() {
   TypeReference[] exceptionTypes = method.getExceptionTypes();
   if (exceptionTypes == null) {
     return new Class[0];
   } else {
     return VMCommonLibrarySupport.typesToClasses(exceptionTypes);
   }
 }
예제 #10
0
 // For use by JikesRVMSupport
 VMMethod(RVMMethod m) {
   method = m;
   if (Reflection.cacheInvokerInJavaLangReflect) {
     invoker = m.getInvoker();
   } else {
     invoker = null;
   }
 }
예제 #11
0
  public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
      throws NoSuchMethodException, SecurityException {
    checkMemberAccess(Member.DECLARED);

    if (!type.isClassType()) throwNoSuchMethodException(name, parameterTypes);

    if (name == null) {
      throwNoSuchMethodException(name, parameterTypes);
    }
    Atom aName = Atom.findOrCreateUnicodeAtom(name);
    if (aName == RVMClassLoader.StandardClassInitializerMethodName
        || aName == RVMClassLoader.StandardObjectInitializerMethodName) {
      // <init> and <clinit> are not methods.
      throwNoSuchMethodException(name, parameterTypes);
    }

    RVMMethod[] methods = type.asClass().getDeclaredMethods();
    RVMMethod answer = null;
    for (RVMMethod meth : methods) {
      if (meth.getName() == aName && parametersMatch(meth.getParameterTypes(), parameterTypes)) {
        if (answer == null) {
          answer = meth;
        } else {
          RVMMethod m2 = meth;
          if (answer.getReturnType().resolve().isAssignableFrom(m2.getReturnType().resolve())) {
            answer = m2;
          }
        }
      }
    }
    if (answer == null) {
      throwNoSuchMethodException(name, parameterTypes);
    }
    return JikesRVMSupport.createMethod(answer);
  }
예제 #12
0
  public Method[] getMethods() throws SecurityException {
    checkMemberAccess(Member.PUBLIC);

    RVMMethod[] static_methods = type.getStaticMethods();
    RVMMethod[] virtual_methods = type.getVirtualMethods();
    ArrayList<Method> coll = new ArrayList<Method>(static_methods.length + virtual_methods.length);
    for (RVMMethod meth : static_methods) {
      if (meth.isPublic()) {
        coll.add(JikesRVMSupport.createMethod(meth));
      }
    }
    for (RVMMethod meth : virtual_methods) {
      if (meth.isPublic()) {
        coll.add(JikesRVMSupport.createMethod(meth));
      }
    }
    return coll.toArray(new Method[coll.size()]);
  }
예제 #13
0
 /**
  * Is this a special exception-raising method that must be invisible in stack traces?
  *
  * <p>In some configurations, the optimizing compiler may insert calls to special exception
  * raising methods in RuntimeEntrypoints if it recognizes that code throws unconditional
  * exceptions. Those calls must not appear in the stack trace.
  *
  * @param m a method
  * @return {@code true} when the given me is a special exception-raising method that must be
  *     invisible in stack traces, {@code false} otherwise
  */
 public static final boolean isInvisibleRaiseMethod(RVMMethod m) {
   if (!m.isRuntimeServiceMethod()) {
     return false;
   }
   NormalMethod nm = (NormalMethod) m;
   return nm == raiseAbstractMethodError
       || nm == raiseArithmeticException
       || nm == raiseArithmeticException
       || nm == raiseNullPointerException
       || nm == raiseIllegalAccessError;
 }
예제 #14
0
 /** Hash code for annotation value */
 private int annotationHashCode() {
   RVMClass annotationInterface = type.resolve().asClass();
   RVMMethod[] annotationMethods = annotationInterface.getDeclaredMethods();
   String typeString = type.toString();
   int result = typeString.substring(1, typeString.length() - 1).hashCode();
   try {
     for (RVMMethod method : annotationMethods) {
       String name = method.getName().toUnicodeString();
       Object value = getElementValue(name, method.getReturnType().resolve().getClassForType());
       int part_result = name.hashCode() * 127;
       if (value.getClass().isArray()) {
         if (value instanceof Object[]) {
           part_result ^= Arrays.hashCode((Object[]) value);
         } else if (value instanceof boolean[]) {
           part_result ^= Arrays.hashCode((boolean[]) value);
         } else if (value instanceof byte[]) {
           part_result ^= Arrays.hashCode((byte[]) value);
         } else if (value instanceof char[]) {
           part_result ^= Arrays.hashCode((char[]) value);
         } else if (value instanceof short[]) {
           part_result ^= Arrays.hashCode((short[]) value);
         } else if (value instanceof int[]) {
           part_result ^= Arrays.hashCode((int[]) value);
         } else if (value instanceof long[]) {
           part_result ^= Arrays.hashCode((long[]) value);
         } else if (value instanceof float[]) {
           part_result ^= Arrays.hashCode((float[]) value);
         } else if (value instanceof double[]) {
           part_result ^= Arrays.hashCode((double[]) value);
         }
       } else {
         part_result ^= value.hashCode();
       }
       result += part_result;
     }
   } catch (java.io.UTFDataFormatException e) {
     throw new Error(e);
   }
   return result;
 }
예제 #15
0
  public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
      throws NoSuchMethodException, SecurityException {
    checkMemberAccess(Member.DECLARED);
    if (!type.isClassType()) throwNoSuchMethodException("<init>", parameterTypes);

    RVMMethod answer = null;
    if (parameterTypes == null || parameterTypes.length == 0) {
      answer = getDefaultConstructor();
    } else {
      RVMMethod[] methods = type.asClass().getConstructorMethods();
      for (RVMMethod method : methods) {
        if (parametersMatch(method.getParameterTypes(), parameterTypes)) {
          answer = method;
          break;
        }
      }
    }
    if (answer == null) {
      throwNoSuchMethodException("<init>", parameterTypes);
    }
    return JikesRVMSupport.createConstructor(answer);
  }
예제 #16
0
  @Inline(
      value = Inline.When.ArgumentsAreConstant,
      arguments = {0})
  public T newInstance()
      throws IllegalAccessException, InstantiationException, ExceptionInInitializerError,
          SecurityException {

    // Basic checks
    checkMemberAccess(Member.PUBLIC);
    if (!type.isClassType()) throw new InstantiationException();

    RVMClass cls = type.asClass();

    if (cls.isAbstract() || cls.isInterface()) throw new InstantiationException();

    // Ensure that the class is initialized
    if (!cls.isInitialized()) {
      RuntimeEntrypoints.initializeClassForDynamicLink(cls);
    }

    // Find the defaultConstructor
    RVMMethod defaultConstructor = getDefaultConstructor();
    if (defaultConstructor == null) throw new InstantiationException();

    // Check that caller is allowed to access it
    if (!defaultConstructor.isPublic()) {
      RVMClass accessingClass = RVMClass.getClassFromStackFrame(1);
      VMCommonLibrarySupport.checkAccess(defaultConstructor, accessingClass);
    }

    // Allocate an uninitialized instance;
    @SuppressWarnings("unchecked") // yes, we're giving an anonymous object a type.
    T obj = (T) RuntimeEntrypoints.resolvedNewScalar(cls);

    // Run the default constructor on the it.
    Reflection.invoke(defaultConstructor, null, obj, null, true);

    return obj;
  }
예제 #17
0
 @Pure
 private RVMMethod getMethodInternal2(Atom aName, Class<?>... parameterTypes) {
   RVMMethod answer = null;
   RVMMethod[] methods = type.asClass().getVirtualMethods();
   for (RVMMethod meth : methods) {
     if (meth.getName() == aName
         && meth.isPublic()
         && parametersMatch(meth.getParameterTypes(), parameterTypes)) {
       if (answer == null) {
         answer = meth;
       } else {
         RVMMethod m2 = meth;
         if (answer.getReturnType().resolve().isAssignableFrom(m2.getReturnType().resolve())) {
           answer = m2;
         }
       }
     }
   }
   return answer;
 }
  private static void expandYieldpoint(
      Instruction s, IR ir, RVMMethod meth, IA32ConditionOperand ypCond) {
    // split the basic block after the yieldpoint, create a new
    // block at the end of the IR to hold the yieldpoint,
    // remove the yieldpoint (to prepare to out it in the new block at the end)
    BasicBlock thisBlock = s.getBasicBlock();
    BasicBlock nextBlock = thisBlock.splitNodeWithLinksAt(s, ir);
    BasicBlock yieldpoint = thisBlock.createSubBlock(s.getBytecodeIndex(), ir, 0);
    thisBlock.insertOut(yieldpoint);
    yieldpoint.insertOut(nextBlock);
    ir.cfg.addLastInCodeOrder(yieldpoint);
    s.remove();

    // change thread switch instruction into call to thread switch routine
    // NOTE: must make s the call instruction: it is the GC point!
    //       must also inform the GCMap that s has been moved!!!
    Offset offset = meth.getOffset();
    LocationOperand loc = new LocationOperand(offset);
    Operand guard = TG();
    Operand target;
    if (JTOC_REGISTER == null) {
      target = MemoryOperand.D(Magic.getTocPointer().plus(offset), (byte) 4, loc, guard);
    } else {
      target = MemoryOperand.BD(ir.regpool.makeTocOp().asRegister(), offset, (byte) 8, loc, guard);
    }

    MIR_Call.mutate0(s, CALL_SAVE_VOLATILE, null, null, target, MethodOperand.STATIC(meth));
    yieldpoint.appendInstruction(s);
    ir.MIRInfo.gcIRMap.moveToEnd(s);

    yieldpoint.appendInstruction(MIR_Branch.create(IA32_JMP, nextBlock.makeJumpTarget()));

    // Check to see if threadSwitch requested
    Offset tsr = Entrypoints.takeYieldpointField.getOffset();
    MemoryOperand M = MemoryOperand.BD(ir.regpool.makeTROp(), tsr, (byte) 4, null, null);
    thisBlock.appendInstruction(MIR_Compare.create(IA32_CMP, M, IC(0)));
    thisBlock.appendInstruction(
        MIR_CondBranch.create(
            IA32_JCC, ypCond, yieldpoint.makeJumpTarget(), BranchProfileOperand.never()));
  }
예제 #19
0
 @Pure
 private RVMMethod getMethodInternal1(Atom aName, Class<?>... parameterTypes) {
   RVMMethod answer = null;
   for (RVMClass current = type.asClass();
       current != null && answer == null;
       current = current.getSuperClass()) {
     RVMMethod[] methods = current.getDeclaredMethods();
     for (RVMMethod meth : methods) {
       if (meth.getName() == aName
           && meth.isPublic()
           && parametersMatch(meth.getParameterTypes(), parameterTypes)) {
         if (answer == null) {
           answer = meth;
         } else {
           RVMMethod m2 = meth;
           if (answer.getReturnType().resolve().isAssignableFrom(m2.getReturnType().resolve())) {
             answer = m2;
           }
         }
       }
     }
   }
   return answer;
 }
예제 #20
0
 Object getDefaultValue() {
   return method.getAnnotationDefault();
 }
예제 #21
0
 Annotation[][] getParameterAnnotations() {
   return method.getDeclaredParameterAnnotations();
 }
예제 #22
0
 public Class<?> getDeclaringClass() {
   return method.getDeclaringClass().getClassForType();
 }
예제 #23
0
 int getModifiersInternal() {
   return method.getModifiers();
 }
예제 #24
0
 public String getName() {
   return method.getName().toString();
 }
예제 #25
0
 Class<?>[] getParameterTypes() {
   return VMCommonLibrarySupport.typesToClasses(method.getParameterTypes());
 }
예제 #26
0
 Class<?> getReturnType() {
   return method.getReturnType().resolve().getClassForType();
 }
예제 #27
0
 Annotation[] getDeclaredAnnotations() {
   return method.getDeclaredAnnotations();
 }
예제 #28
0
 <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
   return method.getAnnotation(annotationClass);
 }
예제 #29
0
 String getSignature() {
   return method.getSignature().toString();
 }