/** Get an instance of an object capable of reflectively invoking this method */ @RuntimePure @SuppressWarnings("unchecked") public synchronized ReflectionBase getInvoker() { if (!VM.runningVM) { return null; } ReflectionBase invoker; if (invokeMethods != null) { synchronized (RVMMethod.class) { invoker = invokeMethods.get(this); } } else { invoker = null; } if (invoker == null) { Class<ReflectionBase> reflectionClass = (Class<ReflectionBase>) RVMClass.createReflectionClass(this); if (reflectionClass != null) { try { invoker = reflectionClass.newInstance(); } catch (Throwable e) { throw new Error(e); } } else { invoker = ReflectionBase.nullInvoker; } if (invokeMethods != null) { synchronized (RVMMethod.class) { invokeMethods.put(this, invoker); } } } return invoker; }
/** Returns the parameter annotations for this method. */ @Pure public final Annotation[][] getDeclaredParameterAnnotations() { Annotation[][] result; synchronized (declaredParameterAnnotations) { result = declaredParameterAnnotations.get(this); } if (result == null) { RVMAnnotation[][] parameterAnnotations = getParameterAnnotations(); result = new Annotation[parameterAnnotations.length][]; for (int a = 0; a < result.length; ++a) { result[a] = toAnnotations(parameterAnnotations[a]); } synchronized (declaredParameterAnnotations) { declaredParameterAnnotations.put(this, result); } } return result; }
/** * This is the findOrCreate() method through which all Atoms are ultimately created. The * constructor for Atom is a private method, so someone has to call one of the public * findOrCreate() methods to get a new one. And they all feed through here. */ private static Atom findOrCreate(byte[] bytes, boolean create, String str) { Atom val = new Atom(bytes, -1, str); val = dictionary.get(val); if (val != null || !create) return val; synchronized (Atom.class) { val = new Atom(bytes, nextId++, str); int column = val.id >> LOG_ROW_SIZE; if (column == atoms.length) { Atom[][] tmp = new Atom[column + 1][]; for (int i = 0; i < column; i++) { tmp[i] = atoms[i]; } atoms = tmp; atoms[column] = new Atom[1 << LOG_ROW_SIZE]; } atoms[column][val.id & ROW_MASK] = val; dictionary.put(val, val); } return val; }
/** Get the offset used to hold a JTOC addressable version of the current entry code array */ @Pure private Offset getJtocOffset() { Integer offAsInt; synchronized (jtocOffsets) { offAsInt = jtocOffsets.get(this); } if (offAsInt == null) { return Offset.zero(); } else { return Offset.fromIntSignExtend(offAsInt.intValue()); } }
/** Find or create a JTOC offset for this method */ public final synchronized Offset findOrCreateJtocOffset() { if (VM.VerifyAssertions) VM._assert(!isStatic() && !isObjectInitializer()); Offset jtocOffset = getJtocOffset(); ; if (jtocOffset.EQ(Offset.zero())) { jtocOffset = Statics.allocateReferenceSlot(true); Statics.setSlotContents(jtocOffset, getCurrentEntryCodeArray()); synchronized (jtocOffsets) { jtocOffsets.put(this, Integer.valueOf(jtocOffset.toInt())); } } return jtocOffset; }
/** * Find an atom from the subsequence of another * * @param utf8 byte backing of atom * @param off offset of new atom * @param len length of new atom * @param str possible string encoding of atom or null * @return atom */ private static Atom findOrCreate(byte[] utf8, int off, int len, String str) { if (str != null) { // string substring is cheap, so try to find using this if possible Atom val = new Atom(null, -1, str.substring(off, off + len)); val = dictionary.get(val); if (val != null) return val; } byte[] val = new byte[len]; for (int i = 0; i < len; ++i) { val[i] = utf8[off++]; } return findOrCreate(val, true, null); }
/** * Read an annotation attribute from the class file * * @param constantPool from constant pool being loaded * @param input the data being read */ static RVMAnnotation readAnnotation( int[] constantPool, DataInputStream input, ClassLoader classLoader) throws IOException, ClassNotFoundException { TypeReference type; // Read type int typeIndex = input.readUnsignedShort(); type = TypeReference.findOrCreate(classLoader, RVMClass.getUtf(constantPool, typeIndex)); // Read values int numAnnotationMembers = input.readUnsignedShort(); AnnotationMember[] elementValuePairs = new AnnotationMember[numAnnotationMembers]; for (int i = 0; i < numAnnotationMembers; i++) { elementValuePairs[i] = AnnotationMember.readAnnotationMember(type, constantPool, input, classLoader); } // Arrays.sort(elementValuePairs); RVMAnnotation result = new RVMAnnotation(type, elementValuePairs); RVMAnnotation unique = uniqueMap.get(result); if (unique != null) { return unique; } else { uniqueMap.put(result, result); return result; } }
/** * Exceptions thrown by this method - something like { "java/lang/IOException", * "java/lang/EOFException" } * * @return info (null --> method doesn't throw any exceptions) */ @Pure public final TypeReference[] getExceptionTypes() { synchronized (exceptionTypes) { return exceptionTypes.get(this); } }
/** Get the parameter annotations for this method */ @Pure private RVMAnnotation[][] getParameterAnnotations() { synchronized (parameterAnnotations) { return parameterAnnotations.get(this); } }