Bridge.java revision 807:408c9c621938
1/*
2 * Copyright (c) 2004, 2016, 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
26package sun.corba ;
27
28import java.io.OptionalDataException;
29import java.lang.invoke.MethodHandle;
30import java.lang.reflect.Field ;
31import java.lang.reflect.Constructor ;
32
33import java.security.AccessController;
34import java.security.Permission;
35import java.security.PrivilegedAction;
36
37import sun.misc.Unsafe;
38import sun.reflect.ReflectionFactory;
39
40/** This class provides the methods for fundamental JVM operations
41 * needed in the ORB that are not part of the public Java API.  This includes:
42 * <ul>
43 * <li>throwException, which can throw undeclared checked exceptions.
44 * This is needed to handle throwing arbitrary exceptions across a standardized
45 * OMG interface that (incorrectly) does not specify appropriate exceptions.</li>
46 * <li>putXXX/getXXX methods that allow unchecked access to fields of objects.
47 * This is used for setting uninitialzed non-static final fields (which is
48 * impossible with reflection) and for speed.</li>
49 * <li>objectFieldOffset to obtain the field offsets for use in the putXXX/getXXX methods</li>
50 * <li>newConstructorForSerialization to get the special constructor required for a
51 * Serializable class</li>
52 * <li>latestUserDefinedLoader to get the latest user defined class loader from
53 * the call stack as required by the RMI-IIOP specification (really from the
54 * JDK 1.1 days)</li>
55 * </ul>
56 * The code that calls Bridge.get() must have the following Permissions:
57 * <ul>
58 * <li>RuntimePermission "reflectionFactoryAccess"</li>
59 * <li>BridgePermission "getBridge"</li>
60 * <li>ReflectPermission "suppressAccessChecks"</li>
61 * </ul>
62 * <p>
63 * All of these permissions are required to obtain and correctly initialize
64 * the instance of Bridge.  No security checks are performed on calls
65 * made to Bridge instance methods, so access to the Bridge instance
66 * must be protected.
67 * <p>
68 * This class is a singleton (per ClassLoader of course).  Access to the
69 * instance is obtained through the Bridge.get() method.
70 */
71public final class Bridge
72{
73    private static final Permission getBridgePermission =
74            new BridgePermission("getBridge");
75    private static Bridge bridge = null ;
76
77    /** Access to Unsafe to read/write fields. */
78    private static final Unsafe unsafe = AccessController.doPrivileged(
79            (PrivilegedAction<Unsafe>)() -> {
80                try {
81                    Field field = Unsafe.class.getDeclaredField("theUnsafe");
82                    field.setAccessible(true);
83                    return (Unsafe)field.get(null);
84
85                } catch (NoSuchFieldException |IllegalAccessException ex) {
86                    throw new InternalError("Unsafe.theUnsafe field not available", ex);
87                }
88            }
89    ) ;
90
91    private final ReflectionFactory reflectionFactory ;
92
93    private Bridge() {
94        reflectionFactory = ReflectionFactory.getReflectionFactory();
95    }
96
97    /** Fetch the Bridge singleton.  This requires the following
98     * permissions:
99     * <ul>
100     * <li>RuntimePermission "reflectionFactoryAccess"</li>
101     * <li>BridgePermission "getBridge"</li>
102     * <li>ReflectPermission "suppressAccessChecks"</li>
103     * </ul>
104     * @return The singleton instance of the Bridge class
105     * @throws SecurityException if the caller does not have the
106     * required permissions and the caller has a non-null security manager.
107     */
108    public static final synchronized Bridge get()
109    {
110        SecurityManager sman = System.getSecurityManager() ;
111        if (sman != null)
112            sman.checkPermission( getBridgePermission ) ;
113
114        if (bridge == null) {
115            bridge = new Bridge() ;
116        }
117
118        return bridge ;
119    }
120
121    /** Obtain the latest user defined ClassLoader from the call stack.
122     * This is required by the RMI-IIOP specification.
123     */
124    public final ClassLoader getLatestUserDefinedLoader() {
125        return jdk.internal.misc.VM.latestUserDefinedLoader();
126    }
127
128    /**
129     * Fetches a field element within the given
130     * object <code>o</code> at the given offset.
131     * The result is undefined unless the offset was obtained from
132     * {@link #objectFieldOffset} on the {@link java.lang.reflect.Field}
133     * of some Java field and the object referred to by <code>o</code>
134     * is of a class compatible with that field's class.
135     * @param o Java heap object in which the field from which the offset
136     * was obtained resides
137     * @param offset indication of where the field resides in a Java heap
138     *        object
139     * @return the value fetched from the indicated Java field
140     * @throws RuntimeException No defined exceptions are thrown, not even
141     *         {@link NullPointerException}
142     */
143    public final int getInt(Object o, long offset)
144    {
145        return unsafe.getInt( o, offset ) ;
146    }
147
148    /**
149     * Stores a value into a given Java field.
150     * <p>
151     * The first two parameters are interpreted exactly as with
152     * {@link #getInt(Object, long)} to refer to a specific
153     * Java field.  The given value is stored into that field.
154     * <p>
155     * The field must be of the same type as the method
156     * parameter <code>x</code>.
157     *
158     * @param o Java heap object in which the field resides, if any, else
159     *        null
160     * @param offset indication of where the field resides in a Java heap
161     *        object.
162     * @param x the value to store into the indicated Java field
163     * @throws RuntimeException No defined exceptions are thrown, not even
164     *         {@link NullPointerException}
165     */
166    public final void putInt(Object o, long offset, int x)
167    {
168        unsafe.putInt( o, offset, x ) ;
169    }
170
171    /**
172     * @see #getInt(Object, long)
173     */
174    public final Object getObject(Object o, long offset)
175    {
176        return unsafe.getObject( o, offset ) ;
177    }
178
179    /**
180     * @see #putInt(Object, long, int)
181     */
182    public final void putObject(Object o, long offset, Object x)
183    {
184        unsafe.putObject( o, offset, x ) ;
185    }
186
187    /** @see #getInt(Object, long) */
188    public final boolean getBoolean(Object o, long offset)
189    {
190        return unsafe.getBoolean( o, offset ) ;
191    }
192    /** @see #putInt(Object, long, int) */
193    public final void    putBoolean(Object o, long offset, boolean x)
194    {
195        unsafe.putBoolean( o, offset, x ) ;
196    }
197    /** @see #getInt(Object, long) */
198    public final byte    getByte(Object o, long offset)
199    {
200        return unsafe.getByte( o, offset ) ;
201    }
202    /** @see #putInt(Object, long, int) */
203    public final void    putByte(Object o, long offset, byte x)
204    {
205        unsafe.putByte( o, offset, x ) ;
206    }
207    /** @see #getInt(Object, long) */
208    public final short   getShort(Object o, long offset)
209    {
210        return unsafe.getShort( o, offset ) ;
211    }
212    /** @see #putInt(Object, long, int) */
213    public final void    putShort(Object o, long offset, short x)
214    {
215        unsafe.putShort( o, offset, x ) ;
216    }
217    /** @see #getInt(Object, long) */
218    public final char    getChar(Object o, long offset)
219    {
220        return unsafe.getChar( o, offset ) ;
221    }
222    /** @see #putInt(Object, long, int) */
223    public final void    putChar(Object o, long offset, char x)
224    {
225        unsafe.putChar( o, offset, x ) ;
226    }
227    /** @see #getInt(Object, long) */
228    public final long    getLong(Object o, long offset)
229    {
230        return unsafe.getLong( o, offset ) ;
231    }
232    /** @see #putInt(Object, long, int) */
233    public final void    putLong(Object o, long offset, long x)
234    {
235        unsafe.putLong( o, offset, x ) ;
236    }
237    /** @see #getInt(Object, long) */
238    public final float   getFloat(Object o, long offset)
239    {
240        return unsafe.getFloat( o, offset ) ;
241    }
242    /** @see #putInt(Object, long, int) */
243    public final void    putFloat(Object o, long offset, float x)
244    {
245        unsafe.putFloat( o, offset, x ) ;
246    }
247    /** @see #getInt(Object, long) */
248    public final double  getDouble(Object o, long offset)
249    {
250        return unsafe.getDouble( o, offset ) ;
251    }
252    /** @see #putInt(Object, long, int) */
253    public final void    putDouble(Object o, long offset, double x)
254    {
255        unsafe.putDouble( o, offset, x ) ;
256    }
257
258    /**
259     * This constant differs from all results that will ever be returned from
260     * {@link #objectFieldOffset}.
261     */
262    public static final long INVALID_FIELD_OFFSET   = -1;
263
264    /**
265     * Returns the offset of a non-static field.
266     */
267    public final long objectFieldOffset(Field f)
268    {
269        return unsafe.objectFieldOffset( f ) ;
270    }
271
272    /**
273     * Returns the offset of a static field.
274     */
275    public final long staticFieldOffset(Field f)
276    {
277        return unsafe.staticFieldOffset( f ) ;
278    }
279
280    /**
281     * Ensure that the class has been initalized.
282     * @param cl the class to ensure is initialized
283     */
284    public final void ensureClassInitialized(Class<?> cl) {
285        unsafe.ensureClassInitialized(cl);
286    }
287
288
289    /** Throw the exception.
290     * The exception may be an undeclared checked exception.
291     */
292    public final void throwException(Throwable ee)
293    {
294        unsafe.throwException( ee ) ;
295    }
296
297    /**
298     * Obtain a constructor for Class cl.
299     * This is used to create a constructor for Serializable classes that
300     * construct an instance of the Serializable class using the
301     * no args constructor of the first non-Serializable superclass
302     * of the Serializable class.
303     */
304    public final Constructor<?> newConstructorForSerialization( Class<?> cl ) {
305        return reflectionFactory.newConstructorForSerialization( cl ) ;
306    }
307
308    public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
309        return reflectionFactory.newConstructorForExternalization( cl ) ;
310    }
311
312    /**
313     * Returns true if the given class defines a static initializer method,
314     * false otherwise.
315     */
316    public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
317        return reflectionFactory.hasStaticInitializerForSerialization(cl);
318    }
319
320    public final MethodHandle writeObjectForSerialization(Class<?> cl) {
321        return reflectionFactory.writeObjectForSerialization(cl);
322    }
323
324    public final MethodHandle readObjectForSerialization(Class<?> cl) {
325        return reflectionFactory.readObjectForSerialization(cl);
326    }
327
328    public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
329        return reflectionFactory.readObjectNoDataForSerialization(cl);
330    }
331
332    public final MethodHandle readResolveForSerialization(Class<?> cl) {
333        return reflectionFactory.readResolveForSerialization(cl);
334    }
335
336    public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
337        return reflectionFactory.writeReplaceForSerialization(cl);
338    }
339
340    /**
341     * Return a new OptionalDataException instance.
342     * @return a new OptionalDataException instance
343     */
344    public final OptionalDataException newOptionalDataExceptionForSerialization(boolean bool) {
345        return reflectionFactory.newOptionalDataExceptionForSerialization(bool);
346    }
347
348}
349