Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
+++ new/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
1 1 /*
2 2 * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 *
5 5 * This code is free software; you can redistribute it and/or modify it
6 6 * under the terms of the GNU General Public License version 2 only, as
7 7 * published by the Free Software Foundation. Oracle designates this
8 8 * particular file as subject to the "Classpath" exception as provided
9 9 * by Oracle in the LICENSE file that accompanied this code.
10 10 *
11 11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 14 * version 2 for more details (a copy is included in the LICENSE file that
15 15 * accompanied this code).
16 16 *
17 17 * You should have received a copy of the GNU General Public License version
18 18 * 2 along with this work; if not, write to the Free Software Foundation,
19 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 20 *
21 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 22 * or visit www.oracle.com if you need additional information or have any
23 23 * questions.
24 24 */
25 25
26 26 package java.lang.invoke;
27 27
28 28 import java.lang.invoke.MethodHandles.Lookup;
29 29 import java.lang.reflect.AccessibleObject;
30 30 import java.lang.reflect.Field;
31 31 import static java.lang.invoke.MethodHandleNatives.Constants.*;
32 32 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
33 33
34 34 /**
35 35 * The JVM interface for the method handles package is all here.
36 36 * This is an interface internal and private to an implemetantion of JSR 292.
37 37 * <em>This class is not part of the JSR 292 standard.</em>
38 38 * @author jrose
39 39 */
40 40 class MethodHandleNatives {
41 41
42 42 private MethodHandleNatives() { } // static only
43 43
44 44 /// MethodName support
45 45
46 46 static native void init(MemberName self, Object ref);
47 47 static native void expand(MemberName self);
48 48 static native void resolve(MemberName self, Class<?> caller);
49 49 static native int getMembers(Class<?> defc, String matchName, String matchSig,
50 50 int matchFlags, Class<?> caller, int skip, MemberName[] results);
51 51
52 52 /// MethodHandle support
53 53
↓ open down ↓ |
53 lines elided |
↑ open up ↑ |
54 54 /** Initialize the method handle to adapt the call. */
55 55 static native void init(AdapterMethodHandle self, MethodHandle target, int argnum);
56 56 /** Initialize the method handle to call the correct method, directly. */
57 57 static native void init(BoundMethodHandle self, Object target, int argnum);
58 58 /** Initialize the method handle to call as if by an invoke* instruction. */
59 59 static native void init(DirectMethodHandle self, Object ref, boolean doDispatch, Class<?> caller);
60 60
61 61 /** Initialize a method type, once per form. */
62 62 static native void init(MethodType self);
63 63
64 - /** Tell the JVM about a class's bootstrap method. */
65 - static native void registerBootstrap(Class<?> caller, MethodHandle bootstrapMethod);
66 -
67 - /** Ask the JVM about a class's bootstrap method. */
68 - static native MethodHandle getBootstrap(Class<?> caller);
69 -
70 - /** Tell the JVM that we need to change the target of an invokedynamic. */
71 - static native void setCallSiteTarget(CallSite site, MethodHandle target);
72 -
73 64 /** Fetch the vmtarget field.
74 65 * It will be sanitized as necessary to avoid exposing non-Java references.
75 66 * This routine is for debugging and reflection.
76 67 */
77 68 static native Object getTarget(MethodHandle self, int format);
78 69
79 70 /** Fetch the name of the handled method, if available.
80 71 * This routine is for debugging and reflection.
81 72 */
82 73 static MemberName getMethodName(MethodHandle self) {
83 74 return (MemberName) getTarget(self, ETF_METHOD_NAME);
84 75 }
85 76
86 77 /** Fetch the reflective version of the handled method, if available.
87 78 */
88 79 static AccessibleObject getTargetMethod(MethodHandle self) {
89 80 return (AccessibleObject) getTarget(self, ETF_REFLECT_METHOD);
90 81 }
91 82
92 83 /** Fetch the target of this method handle.
93 84 * If it directly targets a method, return a MemberName for the method.
94 85 * If it is chained to another method handle, return that handle.
95 86 */
96 87 static Object getTargetInfo(MethodHandle self) {
97 88 return getTarget(self, ETF_HANDLE_OR_METHOD_NAME);
98 89 }
99 90
100 91 static Object[] makeTarget(Class<?> defc, String name, String sig, int mods, Class<?> refc) {
101 92 return new Object[] { defc, name, sig, mods, refc };
102 93 }
103 94
104 95 /** Fetch MH-related JVM parameter.
105 96 * which=0 retrieves MethodHandlePushLimit
106 97 * which=1 retrieves stack slot push size (in address units)
107 98 */
108 99 static native int getConstant(int which);
109 100
110 101 /** Java copy of MethodHandlePushLimit in range 2..255. */
111 102 static final int JVM_PUSH_LIMIT;
112 103 /** JVM stack motion (in words) after one slot is pushed, usually -1.
113 104 */
114 105 static final int JVM_STACK_MOVE_UNIT;
↓ open down ↓ |
32 lines elided |
↑ open up ↑ |
115 106
116 107 /** Which conv-ops are implemented by the JVM? */
117 108 static final int CONV_OP_IMPLEMENTED_MASK;
118 109 /** Derived mode flag. Only false on some old JVM implementations. */
119 110 static final boolean HAVE_RICOCHET_FRAMES;
120 111
121 112 static final int OP_ROT_ARGS_DOWN_LIMIT_BIAS;
122 113
123 114 static final boolean COUNT_GWT;
124 115
116 + /// CallSite support
117 +
118 + /** Tell the JVM that we need to change the target of a CallSite. */
119 + static native void setCallSiteTargetNormal(CallSite site, MethodHandle target);
120 + static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target);
121 +
125 122 private static native void registerNatives();
126 123 static {
127 124 registerNatives();
128 125 int k;
129 126 JVM_PUSH_LIMIT = getConstant(Constants.GC_JVM_PUSH_LIMIT);
130 127 JVM_STACK_MOVE_UNIT = getConstant(Constants.GC_JVM_STACK_MOVE_UNIT);
131 128 k = getConstant(Constants.GC_CONV_OP_IMPLEMENTED_MASK);
132 129 CONV_OP_IMPLEMENTED_MASK = (k != 0) ? k : DEFAULT_CONV_OP_IMPLEMENTED_MASK;
133 130 k = getConstant(Constants.GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS);
134 131 OP_ROT_ARGS_DOWN_LIMIT_BIAS = (k != 0) ? (byte)k : -1;
135 132 HAVE_RICOCHET_FRAMES = (CONV_OP_IMPLEMENTED_MASK & (1<<OP_COLLECT_ARGS)) != 0;
136 133 COUNT_GWT = getConstant(Constants.GC_COUNT_GWT) != 0;
137 134 //sun.reflect.Reflection.registerMethodsToFilter(MethodHandleImpl.class, "init");
138 135 }
139 136
140 137 // All compile-time constants go here.
141 138 // There is an opportunity to check them against the JVM's idea of them.
142 139 static class Constants {
143 140 Constants() { } // static only
144 141 // MethodHandleImpl
145 142 static final int // for getConstant
146 143 GC_JVM_PUSH_LIMIT = 0,
147 144 GC_JVM_STACK_MOVE_UNIT = 1,
148 145 GC_CONV_OP_IMPLEMENTED_MASK = 2,
149 146 GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS = 3,
150 147 GC_COUNT_GWT = 4;
151 148 static final int
152 149 ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method)
153 150 ETF_DIRECT_HANDLE = 1, // ultimate method handle (will be a DMH, may be self)
154 151 ETF_METHOD_NAME = 2, // ultimate method as MemberName
155 152 ETF_REFLECT_METHOD = 3; // ultimate method as java.lang.reflect object (sans refClass)
156 153
157 154 // MemberName
158 155 // The JVM uses values of -2 and above for vtable indexes.
159 156 // Field values are simple positive offsets.
160 157 // Ref: src/share/vm/oops/methodOop.hpp
161 158 // This value is negative enough to avoid such numbers,
162 159 // but not too negative.
163 160 static final int
164 161 MN_IS_METHOD = 0x00010000, // method (not constructor)
165 162 MN_IS_CONSTRUCTOR = 0x00020000, // constructor
166 163 MN_IS_FIELD = 0x00040000, // field
167 164 MN_IS_TYPE = 0x00080000, // nested type
168 165 MN_SEARCH_SUPERCLASSES = 0x00100000, // for MHN.getMembers
169 166 MN_SEARCH_INTERFACES = 0x00200000, // for MHN.getMembers
170 167 VM_INDEX_UNINITIALIZED = -99;
171 168
172 169 // BoundMethodHandle
173 170 /** Constants for decoding the vmargslot field, which contains 2 values. */
174 171 static final int
175 172 ARG_SLOT_PUSH_SHIFT = 16,
176 173 ARG_SLOT_MASK = (1<<ARG_SLOT_PUSH_SHIFT)-1;
177 174
178 175 // AdapterMethodHandle
179 176 /** Conversions recognized by the JVM.
180 177 * They must align with the constants in java.lang.invoke.AdapterMethodHandle,
181 178 * in the JVM file hotspot/src/share/vm/classfile/javaClasses.hpp.
182 179 */
183 180 static final int
184 181 OP_RETYPE_ONLY = 0x0, // no argument changes; straight retype
185 182 OP_RETYPE_RAW = 0x1, // straight retype, trusted (void->int, Object->T)
186 183 OP_CHECK_CAST = 0x2, // ref-to-ref conversion; requires a Class argument
187 184 OP_PRIM_TO_PRIM = 0x3, // converts from one primitive to another
188 185 OP_REF_TO_PRIM = 0x4, // unboxes a wrapper to produce a primitive
189 186 OP_PRIM_TO_REF = 0x5, // boxes a primitive into a wrapper
190 187 OP_SWAP_ARGS = 0x6, // swap arguments (vminfo is 2nd arg)
191 188 OP_ROT_ARGS = 0x7, // rotate arguments (vminfo is displaced arg)
192 189 OP_DUP_ARGS = 0x8, // duplicates one or more arguments (at TOS)
193 190 OP_DROP_ARGS = 0x9, // remove one or more argument slots
194 191 OP_COLLECT_ARGS = 0xA, // combine arguments using an auxiliary function
195 192 OP_SPREAD_ARGS = 0xB, // expand in place a varargs array (of known size)
196 193 OP_FOLD_ARGS = 0xC, // combine but do not remove arguments; prepend result
197 194 //OP_UNUSED_13 = 0xD, // unused code, perhaps for reified argument lists
198 195 CONV_OP_LIMIT = 0xE; // limit of CONV_OP enumeration
199 196 /** Shift and mask values for decoding the AMH.conversion field.
200 197 * These numbers are shared with the JVM for creating AMHs.
201 198 */
202 199 static final int
203 200 CONV_OP_MASK = 0xF00, // this nybble contains the conversion op field
204 201 CONV_TYPE_MASK = 0x0F, // fits T_ADDRESS and below
205 202 CONV_VMINFO_MASK = 0x0FF, // LSB is reserved for JVM use
206 203 CONV_VMINFO_SHIFT = 0, // position of bits in CONV_VMINFO_MASK
207 204 CONV_OP_SHIFT = 8, // position of bits in CONV_OP_MASK
208 205 CONV_DEST_TYPE_SHIFT = 12, // byte 2 has the adapter BasicType (if needed)
209 206 CONV_SRC_TYPE_SHIFT = 16, // byte 2 has the source BasicType (if needed)
210 207 CONV_STACK_MOVE_SHIFT = 20, // high 12 bits give signed SP change
211 208 CONV_STACK_MOVE_MASK = (1 << (32 - CONV_STACK_MOVE_SHIFT)) - 1;
212 209
213 210 /** Which conv-ops are implemented by the JVM? */
214 211 static final int DEFAULT_CONV_OP_IMPLEMENTED_MASK =
215 212 // Value to use if the corresponding JVM query fails.
216 213 ((1<<OP_RETYPE_ONLY)
217 214 |(1<<OP_RETYPE_RAW)
218 215 |(1<<OP_CHECK_CAST)
219 216 |(1<<OP_PRIM_TO_PRIM)
220 217 |(1<<OP_REF_TO_PRIM)
221 218 |(1<<OP_SWAP_ARGS)
222 219 |(1<<OP_ROT_ARGS)
223 220 |(1<<OP_DUP_ARGS)
224 221 |(1<<OP_DROP_ARGS)
225 222 //|(1<<OP_SPREAD_ARGS)
226 223 );
227 224
228 225 /**
229 226 * Basic types as encoded in the JVM. These code values are not
230 227 * intended for use outside this class. They are used as part of
231 228 * a private interface between the JVM and this class.
232 229 */
233 230 static final int
234 231 T_BOOLEAN = 4,
235 232 T_CHAR = 5,
236 233 T_FLOAT = 6,
237 234 T_DOUBLE = 7,
238 235 T_BYTE = 8,
239 236 T_SHORT = 9,
240 237 T_INT = 10,
241 238 T_LONG = 11,
242 239 T_OBJECT = 12,
243 240 //T_ARRAY = 13
244 241 T_VOID = 14,
245 242 //T_ADDRESS = 15
246 243 T_ILLEGAL = 99;
247 244
248 245 /**
249 246 * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
250 247 */
251 248 static final int
252 249 REF_getField = 1,
253 250 REF_getStatic = 2,
254 251 REF_putField = 3,
255 252 REF_putStatic = 4,
256 253 REF_invokeVirtual = 5,
257 254 REF_invokeStatic = 6,
258 255 REF_invokeSpecial = 7,
259 256 REF_newInvokeSpecial = 8,
260 257 REF_invokeInterface = 9;
261 258 }
262 259
263 260 private static native int getNamedCon(int which, Object[] name);
264 261 static boolean verifyConstants() {
265 262 Object[] box = { null };
266 263 for (int i = 0; ; i++) {
267 264 box[0] = null;
268 265 int vmval = getNamedCon(i, box);
269 266 if (box[0] == null) break;
270 267 String name = (String) box[0];
271 268 try {
272 269 Field con = Constants.class.getDeclaredField(name);
273 270 int jval = con.getInt(null);
274 271 if (jval == vmval) continue;
275 272 String err = (name+": JVM has "+vmval+" while Java has "+jval);
276 273 if (name.equals("CONV_OP_LIMIT")) {
277 274 System.err.println("warning: "+err);
278 275 continue;
279 276 }
280 277 throw new InternalError(err);
281 278 } catch (Exception ex) {
282 279 if (ex instanceof NoSuchFieldException) {
283 280 String err = (name+": JVM has "+vmval+" which Java does not define");
284 281 // ignore exotic ops the JVM cares about; we just wont issue them
285 282 if (name.startsWith("OP_") || name.startsWith("GC_")) {
286 283 System.err.println("warning: "+err);
287 284 continue;
288 285 }
289 286 }
290 287 throw new InternalError(name+": access failed, got "+ex);
291 288 }
292 289 }
293 290 return true;
294 291 }
295 292 static {
296 293 assert(verifyConstants());
297 294 }
298 295
299 296 // Up-calls from the JVM.
300 297 // These must NOT be public.
301 298
302 299 /**
303 300 * The JVM is linking an invokedynamic instruction. Create a reified call site for it.
304 301 */
305 302 static CallSite makeDynamicCallSite(MethodHandle bootstrapMethod,
306 303 String name, MethodType type,
307 304 Object info,
308 305 MemberName callerMethod, int callerBCI) {
309 306 return CallSite.makeSite(bootstrapMethod, name, type, info, callerMethod, callerBCI);
310 307 }
311 308
312 309 /**
313 310 * Called by the JVM to check the length of a spread array.
314 311 */
315 312 static void checkSpreadArgument(Object av, int n) {
316 313 MethodHandleStatics.checkSpreadArgument(av, n);
317 314 }
318 315
319 316 /**
320 317 * The JVM wants a pointer to a MethodType. Oblige it by finding or creating one.
321 318 */
322 319 static MethodType findMethodHandleType(Class<?> rtype, Class<?>[] ptypes) {
323 320 return MethodType.makeImpl(rtype, ptypes, true);
324 321 }
325 322
326 323 /**
327 324 * The JVM wants to use a MethodType with inexact invoke. Give the runtime fair warning.
328 325 */
329 326 static void notifyGenericMethodType(MethodType type) {
330 327 type.form().notifyGenericMethodType();
331 328 }
332 329
333 330 /**
334 331 * The JVM wants to raise an exception. Here's the path.
335 332 */
336 333 static void raiseException(int code, Object actual, Object required) {
337 334 String message = null;
338 335 switch (code) {
339 336 case 190: // arraylength
340 337 try {
341 338 String reqLength = "";
342 339 if (required instanceof AdapterMethodHandle) {
343 340 int conv = ((AdapterMethodHandle)required).getConversion();
344 341 int spChange = AdapterMethodHandle.extractStackMove(conv);
345 342 reqLength = " of length "+(spChange+1);
346 343 }
347 344 int actualLength = actual == null ? 0 : java.lang.reflect.Array.getLength(actual);
348 345 message = "required array"+reqLength+", but encountered wrong length "+actualLength;
349 346 break;
350 347 } catch (IllegalArgumentException ex) {
351 348 }
352 349 required = Object[].class; // should have been an array
353 350 code = 192; // checkcast
354 351 break;
355 352 case 191: // athrow
356 353 // JVM is asking us to wrap an exception which happened during resolving
357 354 if (required == BootstrapMethodError.class) {
358 355 throw new BootstrapMethodError((Throwable) actual);
359 356 }
360 357 break;
361 358 }
362 359 // disregard the identity of the actual object, if it is not a class:
363 360 if (message == null) {
364 361 if (!(actual instanceof Class) && !(actual instanceof MethodType))
365 362 actual = actual.getClass();
366 363 if (actual != null)
367 364 message = "required "+required+" but encountered "+actual;
368 365 else
369 366 message = "required "+required;
370 367 }
371 368 switch (code) {
372 369 case 190: // arraylength
373 370 throw new ArrayIndexOutOfBoundsException(message);
374 371 case 50: //_aaload
375 372 throw new ClassCastException(message);
376 373 case 192: // checkcast
377 374 throw new ClassCastException(message);
378 375 default:
379 376 throw new InternalError("unexpected code "+code+": "+message);
380 377 }
381 378 }
382 379
383 380 /**
384 381 * The JVM is resolving a CONSTANT_MethodHandle CP entry. And it wants our help.
385 382 * It will make an up-call to this method. (Do not change the name or signature.)
386 383 */
387 384 static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
388 385 Class<?> defc, String name, Object type) {
389 386 try {
390 387 Lookup lookup = IMPL_LOOKUP.in(callerClass);
391 388 return lookup.linkMethodHandleConstant(refKind, defc, name, type);
392 389 } catch (ReflectiveOperationException ex) {
393 390 Error err = new IncompatibleClassChangeError();
394 391 err.initCause(ex);
395 392 throw err;
396 393 }
397 394 }
398 395 }
↓ open down ↓ |
264 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX