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 jdk.internal.reflect;
27
28 import java.security.AccessController;
29 import java.security.PrivilegedAction;
30
31
32 /** Generator for jdk.internal.reflect.SerializationConstructorAccessorImpl
33 objects using bytecodes to implement a constructor for serialization
34 returned by ReflectionFactory::newConstructorForSerialization. */
35
36 class SerializationConstructorAccessorGenerator extends AccessorGenerator {
37
38 private static final short NUM_BASE_CPOOL_ENTRIES = (short) 12;
39 // One for invoke() plus one for constructor
40 private static final short NUM_METHODS = (short) 2;
41 // Only used if forSerialization is true
42 private static final short NUM_SERIALIZATION_CPOOL_ENTRIES = (short) 2;
43
44 private static volatile int methodSymnum;
45 private static volatile int constructorSymnum;
46 private static volatile int serializationConstructorSymnum;
47
48 private Class<?> declaringClass;
49 private Class<?>[] parameterTypes;
50 private Class<?> returnType;
51 private boolean isConstructor;
52 private boolean forSerialization;
53
54 private short targetMethodRef;
55 private short invokeIdx;
56 private short invokeDescriptorIdx;
57 // Constant pool index of CONSTANT_Class_info for first
58 // non-primitive parameter type. Should be incremented by 2.
59 private short nonPrimitiveParametersBaseIdx;
60
61 SerializationConstructorAccessorGenerator() {
62 }
63
64 /** This routine is not thread-safe */
65 public SerializationConstructorAccessorImpl
66 generateSerializationConstructor(Class<?> declaringClass,
67 Class<?>[] parameterTypes,
68 int modifiers,
69 Class<?> targetConstructorClass)
70 {
71 return (SerializationConstructorAccessorImpl)
72 generate(declaringClass,
73 "<init>",
74 parameterTypes,
75 Void.TYPE,
76 modifiers,
77 true,
78 true,
79 targetConstructorClass);
80 }
81
82 /** This routine is not thread-safe */
83 @SuppressWarnings("removal")
84 private MagicAccessorImpl generate(final Class<?> declaringClass,
85 String name,
86 Class<?>[] parameterTypes,
87 Class<?> returnType,
88 int modifiers,
89 boolean isConstructor,
90 boolean forSerialization,
91 Class<?> serializationTargetClass)
92 {
93 ByteVector vec = ByteVectorFactory.create();
94 asm = new ClassFileAssembler(vec);
95 this.declaringClass = declaringClass;
96 this.parameterTypes = parameterTypes;
97 this.returnType = returnType;
98 this.modifiers = modifiers;
99 this.isConstructor = isConstructor;
100 this.forSerialization = forSerialization;
101
102 asm.emitMagicAndVersion();
103
104 // Constant pool entries:
105 // ( * = Boxing information: optional)
106 // (+ = Shared entries provided by AccessorGenerator)
107 // (^ = Only present if generating SerializationConstructorAccessor)
108 // [UTF-8] [This class's name]
109 // [CONSTANT_Class_info] for above
110 // [UTF-8] "jdk/internal/reflect/{MethodAccessorImpl,ConstructorAccessorImpl,SerializationConstructorAccessorImpl}"
111 // [CONSTANT_Class_info] for above
112 // [UTF-8] [Target class's name]
113 // [CONSTANT_Class_info] for above
114 // ^ [UTF-8] [Serialization: Class's name in which to invoke constructor]
115 // ^ [CONSTANT_Class_info] for above
116 // [UTF-8] target method or constructor name
117 // [UTF-8] target method or constructor signature
118 // [CONSTANT_NameAndType_info] for above
119 // [CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info] for target method
282 targetMethodRef = asm.cpi();
283 if (isConstructor) {
284 asm.emitConstantPoolUTF8("newInstance");
285 } else {
286 asm.emitConstantPoolUTF8("invoke");
287 }
288 invokeIdx = asm.cpi();
289 if (isConstructor) {
290 asm.emitConstantPoolUTF8("([Ljava/lang/Object;)Ljava/lang/Object;");
291 } else {
292 asm.emitConstantPoolUTF8
293 ("(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
294 }
295 invokeDescriptorIdx = asm.cpi();
296
297 // Output class information for non-primitive parameter types
298 nonPrimitiveParametersBaseIdx = add(asm.cpi(), S2);
299 for (int i = 0; i < parameterTypes.length; i++) {
300 Class<?> c = parameterTypes[i];
301 if (!isPrimitive(c)) {
302 asm.emitConstantPoolUTF8(getClassName(c, false));
303 asm.emitConstantPoolClass(asm.cpi());
304 }
305 }
306
307 // Entries common to FieldAccessor, MethodAccessor and ConstructorAccessor
308 emitCommonConstantPoolEntries();
309
310 // Boxing entries
311 if (usesPrimitives) {
312 emitBoxingContantPoolEntries();
313 }
314
315 if (asm.cpi() != numCPEntries) {
316 throw new InternalError("Adjust this code (cpi = " + asm.cpi() +
317 ", numCPEntries = " + numCPEntries + ")");
318 }
319
320 // Access flags
321 asm.emitShort(ACC_PUBLIC);
322
372 private void emitInvoke() {
373 // NOTE that this code will only handle 65535 parameters since we
374 // use the sipush instruction to get the array index on the
375 // operand stack.
376 if (parameterTypes.length > 65535) {
377 throw new InternalError("Can't handle more than 65535 parameters");
378 }
379
380 // Generate code into fresh code buffer
381 ClassFileAssembler cb = new ClassFileAssembler();
382 if (isConstructor) {
383 // 1 incoming argument
384 cb.setMaxLocals(2);
385 } else {
386 // 2 incoming arguments
387 cb.setMaxLocals(3);
388 }
389
390 short illegalArgStartPC = 0;
391
392 if (isConstructor) {
393 // Instantiate target class before continuing
394 // new <target class type>
395 // dup
396 cb.opc_new(targetClass);
397 cb.opc_dup();
398 } else {
399 // Get target object on operand stack if necessary.
400
401 // We need to do an explicit null check here; we won't see
402 // NullPointerExceptions from the invoke bytecode, since it's
403 // covered by an exception handler.
404 if (!isStatic()) {
405 // aload_1
406 // ifnonnull <checkcast label>
407 // new <NullPointerException>
408 // dup
409 // invokespecial <NullPointerException ctor>
410 // athrow
411 // <checkcast label:>
412 // aload_1
562 l.bind();
563 cb.opc_new(illegalArgumentClass);
564 cb.opc_dup();
565 cb.opc_invokespecial(illegalArgumentCtorIdx, 0, 0);
566 cb.opc_athrow();
567 } else {
568 // Emit appropriate checkcast
569 cb.opc_checkcast(paramTypeCPIdx);
570 paramTypeCPIdx = add(paramTypeCPIdx, S2);
571 // Fall through to next argument
572 }
573 }
574 // Bind last goto if present
575 if (nextParamLabel != null) {
576 nextParamLabel.bind();
577 }
578
579 short invokeStartPC = cb.getLength();
580
581 // OK, ready to perform the invocation.
582 if (isConstructor) {
583 cb.opc_invokespecial(targetMethodRef, count, 0);
584 } else {
585 if (isStatic()) {
586 cb.opc_invokestatic(targetMethodRef,
587 count,
588 typeSizeInStackSlots(returnType));
589 } else {
590 if (isInterface()) {
591 cb.opc_invokeinterface(targetMethodRef,
592 count,
593 count,
594 typeSizeInStackSlots(returnType));
595 } else {
596 cb.opc_invokevirtual(targetMethodRef,
597 count,
598 typeSizeInStackSlots(returnType));
599 }
600 }
601 }
602
|
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 jdk.internal.reflect;
27
28 import jdk.internal.value.PrimitiveClass;
29
30 import java.security.AccessController;
31 import java.security.PrivilegedAction;
32
33
34 /** Generator for jdk.internal.reflect.SerializationConstructorAccessorImpl
35 objects using bytecodes to implement a constructor for serialization
36 returned by ReflectionFactory::newConstructorForSerialization. */
37
38 class SerializationConstructorAccessorGenerator extends AccessorGenerator {
39
40 private static final short NUM_BASE_CPOOL_ENTRIES = (short) 12;
41 // One for invoke() plus one for constructor
42 private static final short NUM_METHODS = (short) 2;
43 // Only used if forSerialization is true
44 private static final short NUM_SERIALIZATION_CPOOL_ENTRIES = (short) 2;
45
46 private static volatile int methodSymnum;
47 private static volatile int constructorSymnum;
48 private static volatile int serializationConstructorSymnum;
49
50 private Class<?> declaringClass;
51 private Class<?>[] parameterTypes;
52 private Class<?> returnType;
53 private boolean isConstructor;
54 private boolean isStaticFactory;
55 private boolean forSerialization;
56
57 private short targetMethodRef;
58 private short invokeIdx;
59 private short invokeDescriptorIdx;
60 // Constant pool index of CONSTANT_Class_info for first
61 // non-primitive parameter type. Should be incremented by 2.
62 private short nonPrimitiveParametersBaseIdx;
63
64 SerializationConstructorAccessorGenerator() {
65 }
66
67 /** This routine is not thread-safe */
68 public SerializationConstructorAccessorImpl
69 generateSerializationConstructor(Class<?> declaringClass,
70 Class<?>[] parameterTypes,
71 int modifiers,
72 Class<?> targetConstructorClass)
73 {
74 boolean isStaticFactory = declaringClass.isValue();
75 return (SerializationConstructorAccessorImpl)
76 generate(declaringClass,
77 "<init>",
78 parameterTypes,
79 isStaticFactory ? PrimitiveClass.asValueType(declaringClass) : Void.TYPE,
80 modifiers,
81 true,
82 isStaticFactory,
83 true,
84 targetConstructorClass);
85 }
86
87 /** This routine is not thread-safe */
88 @SuppressWarnings("removal")
89 private MagicAccessorImpl generate(final Class<?> declaringClass,
90 String name,
91 Class<?>[] parameterTypes,
92 Class<?> returnType,
93 int modifiers,
94 boolean isConstructor,
95 boolean isStaticFactory,
96 boolean forSerialization,
97 Class<?> serializationTargetClass)
98 {
99 ByteVector vec = ByteVectorFactory.create();
100 asm = new ClassFileAssembler(vec);
101 this.declaringClass = declaringClass;
102 this.parameterTypes = parameterTypes;
103 this.returnType = returnType;
104 this.modifiers = modifiers;
105 this.isConstructor = isConstructor;
106 this.isStaticFactory = isStaticFactory;
107 this.forSerialization = forSerialization;
108
109 asm.emitMagicAndVersion();
110
111 // Constant pool entries:
112 // ( * = Boxing information: optional)
113 // (+ = Shared entries provided by AccessorGenerator)
114 // (^ = Only present if generating SerializationConstructorAccessor)
115 // [UTF-8] [This class's name]
116 // [CONSTANT_Class_info] for above
117 // [UTF-8] "jdk/internal/reflect/{MethodAccessorImpl,ConstructorAccessorImpl,SerializationConstructorAccessorImpl}"
118 // [CONSTANT_Class_info] for above
119 // [UTF-8] [Target class's name]
120 // [CONSTANT_Class_info] for above
121 // ^ [UTF-8] [Serialization: Class's name in which to invoke constructor]
122 // ^ [CONSTANT_Class_info] for above
123 // [UTF-8] target method or constructor name
124 // [UTF-8] target method or constructor signature
125 // [CONSTANT_NameAndType_info] for above
126 // [CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info] for target method
289 targetMethodRef = asm.cpi();
290 if (isConstructor) {
291 asm.emitConstantPoolUTF8("newInstance");
292 } else {
293 asm.emitConstantPoolUTF8("invoke");
294 }
295 invokeIdx = asm.cpi();
296 if (isConstructor) {
297 asm.emitConstantPoolUTF8("([Ljava/lang/Object;)Ljava/lang/Object;");
298 } else {
299 asm.emitConstantPoolUTF8
300 ("(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
301 }
302 invokeDescriptorIdx = asm.cpi();
303
304 // Output class information for non-primitive parameter types
305 nonPrimitiveParametersBaseIdx = add(asm.cpi(), S2);
306 for (int i = 0; i < parameterTypes.length; i++) {
307 Class<?> c = parameterTypes[i];
308 if (!isPrimitive(c)) {
309 asm.emitConstantPoolUTF8(getClassName(c, true));
310 asm.emitConstantPoolClass(asm.cpi());
311 }
312 }
313
314 // Entries common to FieldAccessor, MethodAccessor and ConstructorAccessor
315 emitCommonConstantPoolEntries();
316
317 // Boxing entries
318 if (usesPrimitives) {
319 emitBoxingContantPoolEntries();
320 }
321
322 if (asm.cpi() != numCPEntries) {
323 throw new InternalError("Adjust this code (cpi = " + asm.cpi() +
324 ", numCPEntries = " + numCPEntries + ")");
325 }
326
327 // Access flags
328 asm.emitShort(ACC_PUBLIC);
329
379 private void emitInvoke() {
380 // NOTE that this code will only handle 65535 parameters since we
381 // use the sipush instruction to get the array index on the
382 // operand stack.
383 if (parameterTypes.length > 65535) {
384 throw new InternalError("Can't handle more than 65535 parameters");
385 }
386
387 // Generate code into fresh code buffer
388 ClassFileAssembler cb = new ClassFileAssembler();
389 if (isConstructor) {
390 // 1 incoming argument
391 cb.setMaxLocals(2);
392 } else {
393 // 2 incoming arguments
394 cb.setMaxLocals(3);
395 }
396
397 short illegalArgStartPC = 0;
398
399 if (isConstructor && !isStaticFactory) {
400 // Instantiate target class before continuing
401 // new <target class type>
402 // dup
403 cb.opc_new(targetClass);
404 cb.opc_dup();
405 } else {
406 // Get target object on operand stack if necessary.
407
408 // We need to do an explicit null check here; we won't see
409 // NullPointerExceptions from the invoke bytecode, since it's
410 // covered by an exception handler.
411 if (!isStatic()) {
412 // aload_1
413 // ifnonnull <checkcast label>
414 // new <NullPointerException>
415 // dup
416 // invokespecial <NullPointerException ctor>
417 // athrow
418 // <checkcast label:>
419 // aload_1
569 l.bind();
570 cb.opc_new(illegalArgumentClass);
571 cb.opc_dup();
572 cb.opc_invokespecial(illegalArgumentCtorIdx, 0, 0);
573 cb.opc_athrow();
574 } else {
575 // Emit appropriate checkcast
576 cb.opc_checkcast(paramTypeCPIdx);
577 paramTypeCPIdx = add(paramTypeCPIdx, S2);
578 // Fall through to next argument
579 }
580 }
581 // Bind last goto if present
582 if (nextParamLabel != null) {
583 nextParamLabel.bind();
584 }
585
586 short invokeStartPC = cb.getLength();
587
588 // OK, ready to perform the invocation.
589 if (isConstructor && !isStaticFactory) {
590 cb.opc_invokespecial(targetMethodRef, count, 0);
591 } else {
592 if (isStatic()) {
593 cb.opc_invokestatic(targetMethodRef,
594 count,
595 typeSizeInStackSlots(returnType));
596 } else {
597 if (isInterface()) {
598 cb.opc_invokeinterface(targetMethodRef,
599 count,
600 count,
601 typeSizeInStackSlots(returnType));
602 } else {
603 cb.opc_invokevirtual(targetMethodRef,
604 count,
605 typeSizeInStackSlots(returnType));
606 }
607 }
608 }
609
|