History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/reflect/ReflectionFactory.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/reflect/ReflectionFactory.java+418−0
@@ -0,0 +1,418 @@
1+/*
2+ * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.reflect;
27+
28+import java.lang.reflect.Field;
29+import java.lang.reflect.Method;
30+import java.lang.reflect.Constructor;
31+import java.lang.reflect.Modifier;
32+import java.security.AccessController;
33+import java.security.Permission;
34+import java.security.PrivilegedAction;
35+
36+/** <P> The master factory for all reflective objects, both those in
37+ java.lang.reflect (Fields, Methods, Constructors) as well as their
38+ delegates (FieldAccessors, MethodAccessors, ConstructorAccessors).
39+ </P>
40+
41+ <P> The methods in this class are extremely unsafe and can cause
42+ subversion of both the language and the verifier. For this reason,
43+ they are all instance methods, and access to the constructor of
44+ this factory is guarded by a security check, in similar style to
45+ {@link sun.misc.Unsafe}. </P>
46+*/
47+
48+public class ReflectionFactory {
49+
50+ private static boolean initted = false;
51+ private static Permission reflectionFactoryAccessPerm
52+ = new RuntimePermission("reflectionFactoryAccess");
53+ private static ReflectionFactory soleInstance = new ReflectionFactory();
54+ // Provides access to package-private mechanisms in java.lang.reflect
55+ private static volatile LangReflectAccess langReflectAccess;
56+
57+ //
58+ // "Inflation" mechanism. Loading bytecodes to implement
59+ // Method.invoke() and Constructor.newInstance() currently costs
60+ // 3-4x more than an invocation via native code for the first
61+ // invocation (though subsequent invocations have been benchmarked
62+ // to be over 20x faster). Unfortunately this cost increases
63+ // startup time for certain applications that use reflection
64+ // intensively (but only once per class) to bootstrap themselves.
65+ // To avoid this penalty we reuse the existing JVM entry points
66+ // for the first few invocations of Methods and Constructors and
67+ // then switch to the bytecode-based implementations.
68+ //
69+ // Package-private to be accessible to NativeMethodAccessorImpl
70+ // and NativeConstructorAccessorImpl
71+ private static boolean noInflation = false;
72+ private static int inflationThreshold = 15;
73+
74+ private ReflectionFactory() {
75+ }
76+
77+ /**
78+ * A convenience class for acquiring the capability to instantiate
79+ * reflective objects. Use this instead of a raw call to {@link
80+ * #getReflectionFactory} in order to avoid being limited by the
81+ * permissions of your callers.
82+ *
83+ * <p>An instance of this class can be used as the argument of
84+ * <code>AccessController.doPrivileged</code>.
85+ */
86+ public static final class GetReflectionFactoryAction
87+ implements PrivilegedAction<ReflectionFactory> {
88+ public ReflectionFactory run() {
89+ return getReflectionFactory();
90+ }
91+ }
92+
93+ /**
94+ * Provides the caller with the capability to instantiate reflective
95+ * objects.
96+ *
97+ * <p> First, if there is a security manager, its
98+ * <code>checkPermission</code> method is called with a {@link
99+ * java.lang.RuntimePermission} with target
100+ * <code>"reflectionFactoryAccess"</code>. This may result in a
101+ * security exception.
102+ *
103+ * <p> The returned <code>ReflectionFactory</code> object should be
104+ * carefully guarded by the caller, since it can be used to read and
105+ * write private data and invoke private methods, as well as to load
106+ * unverified bytecodes. It must never be passed to untrusted code.
107+ *
108+ * @exception SecurityException if a security manager exists and its
109+ * <code>checkPermission</code> method doesn't allow
110+ * access to the RuntimePermission "reflectionFactoryAccess". */
111+ public static ReflectionFactory getReflectionFactory() {
112+ SecurityManager security = System.getSecurityManager();
113+ if (security != null) {
114+ // TO DO: security.checkReflectionFactoryAccess();
115+ security.checkPermission(reflectionFactoryAccessPerm);
116+ }
117+ return soleInstance;
118+ }
119+
120+ //--------------------------------------------------------------------------
121+ //
122+ // Routines used by java.lang.reflect
123+ //
124+ //
125+
126+ /** Called only by java.lang.reflect.Modifier's static initializer */
127+ public void setLangReflectAccess(LangReflectAccess access) {
128+ langReflectAccess = access;
129+ }
130+
131+ /**
132+ * Note: this routine can cause the declaring class for the field
133+ * be initialized and therefore must not be called until the
134+ * first get/set of this field.
135+ * @param field the field
136+ * @param override true if caller has overridden aaccessibility
137+ */
138+ public FieldAccessor newFieldAccessor(Field field, boolean override) {
139+ checkInitted();
140+ return UnsafeFieldAccessorFactory.newFieldAccessor(field, override);
141+ }
142+
143+ public MethodAccessor newMethodAccessor(Method method) {
144+ checkInitted();
145+
146+ if (noInflation) {
147+ return new MethodAccessorGenerator().
148+ generateMethod(method.getDeclaringClass(),
149+ method.getName(),
150+ method.getParameterTypes(),
151+ method.getReturnType(),
152+ method.getExceptionTypes(),
153+ method.getModifiers());
154+ } else {
155+ NativeMethodAccessorImpl acc =
156+ new NativeMethodAccessorImpl(method);
157+ DelegatingMethodAccessorImpl res =
158+ new DelegatingMethodAccessorImpl(acc);
159+ acc.setParent(res);
160+ return res;
161+ }
162+ }
163+
164+ public ConstructorAccessor newConstructorAccessor(Constructor c) {
165+ checkInitted();
166+
167+ Class<?> declaringClass = c.getDeclaringClass();
168+ if (Modifier.isAbstract(declaringClass.getModifiers())) {
169+ return new InstantiationExceptionConstructorAccessorImpl(null);
170+ }
171+ if (declaringClass == Class.class) {
172+ return new InstantiationExceptionConstructorAccessorImpl
173+ ("Can not instantiate java.lang.Class");
174+ }
175+ // Bootstrapping issue: since we use Class.newInstance() in
176+ // the ConstructorAccessor generation process, we have to
177+ // break the cycle here.
178+ if (Reflection.isSubclassOf(declaringClass,
179+ ConstructorAccessorImpl.class)) {
180+ return new BootstrapConstructorAccessorImpl(c);
181+ }
182+
183+ if (noInflation) {
184+ return new MethodAccessorGenerator().
185+ generateConstructor(c.getDeclaringClass(),
186+ c.getParameterTypes(),
187+ c.getExceptionTypes(),
188+ c.getModifiers());
189+ } else {
190+ NativeConstructorAccessorImpl acc =
191+ new NativeConstructorAccessorImpl(c);
192+ DelegatingConstructorAccessorImpl res =
193+ new DelegatingConstructorAccessorImpl(acc);
194+ acc.setParent(res);
195+ return res;
196+ }
197+ }
198+
199+ //--------------------------------------------------------------------------
200+ //
201+ // Routines used by java.lang
202+ //
203+ //
204+
205+ /** Creates a new java.lang.reflect.Field. Access checks as per
206+ java.lang.reflect.AccessibleObject are not overridden. */
207+ public Field newField(Class<?> declaringClass,
208+ String name,
209+ Class<?> type,
210+ int modifiers,
211+ int slot,
212+ String signature,
213+ byte[] annotations)
214+ {
215+ return langReflectAccess().newField(declaringClass,
216+ name,
217+ type,
218+ modifiers,
219+ slot,
220+ signature,
221+ annotations);
222+ }
223+
224+ /** Creates a new java.lang.reflect.Method. Access checks as per
225+ java.lang.reflect.AccessibleObject are not overridden. */
226+ public Method newMethod(Class<?> declaringClass,
227+ String name,
228+ Class<?>[] parameterTypes,
229+ Class<?> returnType,
230+ Class<?>[] checkedExceptions,
231+ int modifiers,
232+ int slot,
233+ String signature,
234+ byte[] annotations,
235+ byte[] parameterAnnotations,
236+ byte[] annotationDefault)
237+ {
238+ return langReflectAccess().newMethod(declaringClass,
239+ name,
240+ parameterTypes,
241+ returnType,
242+ checkedExceptions,
243+ modifiers,
244+ slot,
245+ signature,
246+ annotations,
247+ parameterAnnotations,
248+ annotationDefault);
249+ }
250+
251+ /** Creates a new java.lang.reflect.Constructor. Access checks as
252+ per java.lang.reflect.AccessibleObject are not overridden. */
253+ public Constructor newConstructor(Class<?> declaringClass,
254+ Class<?>[] parameterTypes,
255+ Class<?>[] checkedExceptions,
256+ int modifiers,
257+ int slot,
258+ String signature,
259+ byte[] annotations,
260+ byte[] parameterAnnotations)
261+ {
262+ return langReflectAccess().newConstructor(declaringClass,
263+ parameterTypes,
264+ checkedExceptions,
265+ modifiers,
266+ slot,
267+ signature,
268+ annotations,
269+ parameterAnnotations);
270+ }
271+
272+ /** Gets the MethodAccessor object for a java.lang.reflect.Method */
273+ public MethodAccessor getMethodAccessor(Method m) {
274+ return langReflectAccess().getMethodAccessor(m);
275+ }
276+
277+ /** Sets the MethodAccessor object for a java.lang.reflect.Method */
278+ public void setMethodAccessor(Method m, MethodAccessor accessor) {
279+ langReflectAccess().setMethodAccessor(m, accessor);
280+ }
281+
282+ /** Gets the ConstructorAccessor object for a
283+ java.lang.reflect.Constructor */
284+ public ConstructorAccessor getConstructorAccessor(Constructor c) {
285+ return langReflectAccess().getConstructorAccessor(c);
286+ }
287+
288+ /** Sets the ConstructorAccessor object for a
289+ java.lang.reflect.Constructor */
290+ public void setConstructorAccessor(Constructor c,
291+ ConstructorAccessor accessor)
292+ {
293+ langReflectAccess().setConstructorAccessor(c, accessor);
294+ }
295+
296+ /** Makes a copy of the passed method. The returned method is a
297+ "child" of the passed one; see the comments in Method.java for
298+ details. */
299+ public Method copyMethod(Method arg) {
300+ return langReflectAccess().copyMethod(arg);
301+ }
302+
303+ /** Makes a copy of the passed field. The returned field is a
304+ "child" of the passed one; see the comments in Field.java for
305+ details. */
306+ public Field copyField(Field arg) {
307+ return langReflectAccess().copyField(arg);
308+ }
309+
310+ /** Makes a copy of the passed constructor. The returned
311+ constructor is a "child" of the passed one; see the comments
312+ in Constructor.java for details. */
313+ public <T> Constructor<T> copyConstructor(Constructor<T> arg) {
314+ return langReflectAccess().copyConstructor(arg);
315+ }
316+
317+ //--------------------------------------------------------------------------
318+ //
319+ // Routines used by serialization
320+ //
321+ //
322+
323+ public Constructor newConstructorForSerialization
324+ (Class<?> classToInstantiate, Constructor constructorToCall)
325+ {
326+ // Fast path
327+ if (constructorToCall.getDeclaringClass() == classToInstantiate) {
328+ return constructorToCall;
329+ }
330+
331+ ConstructorAccessor acc = new MethodAccessorGenerator().
332+ generateSerializationConstructor(classToInstantiate,
333+ constructorToCall.getParameterTypes(),
334+ constructorToCall.getExceptionTypes(),
335+ constructorToCall.getModifiers(),
336+ constructorToCall.getDeclaringClass());
337+ Constructor c = newConstructor(constructorToCall.getDeclaringClass(),
338+ constructorToCall.getParameterTypes(),
339+ constructorToCall.getExceptionTypes(),
340+ constructorToCall.getModifiers(),
341+ langReflectAccess().
342+ getConstructorSlot(constructorToCall),
343+ langReflectAccess().
344+ getConstructorSignature(constructorToCall),
345+ langReflectAccess().
346+ getConstructorAnnotations(constructorToCall),
347+ langReflectAccess().
348+ getConstructorParameterAnnotations(constructorToCall));
349+ setConstructorAccessor(c, acc);
350+ return c;
351+ }
352+
353+ //--------------------------------------------------------------------------
354+ //
355+ // Internals only below this point
356+ //
357+
358+ static int inflationThreshold() {
359+ return inflationThreshold;
360+ }
361+
362+ /** We have to defer full initialization of this class until after
363+ the static initializer is run since java.lang.reflect.Method's
364+ static initializer (more properly, that for
365+ java.lang.reflect.AccessibleObject) causes this class's to be
366+ run, before the system properties are set up. */
367+ private static void checkInitted() {
368+ if (initted) return;
369+ AccessController.doPrivileged(
370+ new PrivilegedAction<Void>() {
371+ public Void run() {
372+ // Tests to ensure the system properties table is fully
373+ // initialized. This is needed because reflection code is
374+ // called very early in the initialization process (before
375+ // command-line arguments have been parsed and therefore
376+ // these user-settable properties installed.) We assume that
377+ // if System.out is non-null then the System class has been
378+ // fully initialized and that the bulk of the startup code
379+ // has been run.
380+
381+ if (System.out == null) {
382+ // java.lang.System not yet fully initialized
383+ return null;
384+ }
385+
386+ String val = System.getProperty("sun.reflect.noInflation");
387+ if (val != null && val.equals("true")) {
388+ noInflation = true;
389+ }
390+
391+ val = System.getProperty("sun.reflect.inflationThreshold");
392+ if (val != null) {
393+ try {
394+ inflationThreshold = Integer.parseInt(val);
395+ } catch (NumberFormatException e) {
396+ throw (RuntimeException)
397+ new RuntimeException("Unable to parse property sun.reflect.inflationThreshold").
398+ initCause(e);
399+ }
400+ }
401+
402+ initted = true;
403+ return null;
404+ }
405+ });
406+ }
407+
408+ private static LangReflectAccess langReflectAccess() {
409+ if (langReflectAccess == null) {
410+ // Call a static method to get class java.lang.reflect.Modifier
411+ // initialized. Its static initializer will cause
412+ // setLangReflectAccess() to be called from the context of the
413+ // java.lang.reflect package.
414+ Modifier.isPublic(Modifier.PUBLIC);
415+ }
416+ return langReflectAccess;
417+ }
418+}