Mercurial > hg > graal-jvmci-8
annotate src/share/vm/runtime/reflection.cpp @ 7432:0b3d19153cc6
8001028: Improve GC option handling
Summary: If there are not enough native resources to create the ReferenceHandler or Finalizer Java threads, the VM will attempt to throw an OOME before the java.lang.Class class has been initialized. This can result in assertion failures and other crashes. Move the initialization of the java.lang.Class class to just before the initialization of the java.lang.ref.Finalizer class.
Reviewed-by: jwilhelm, dholmes, coleenp
author | johnc |
---|---|
date | Wed, 12 Dec 2012 12:07:32 -0800 |
parents | 070d523b96a7 |
children | 35431a769282 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 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. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1152
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1152
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1152
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/javaClasses.hpp" | |
27 #include "classfile/symbolTable.hpp" | |
28 #include "classfile/systemDictionary.hpp" | |
29 #include "classfile/verifier.hpp" | |
30 #include "classfile/vmSymbols.hpp" | |
31 #include "interpreter/linkResolver.hpp" | |
32 #include "memory/oopFactory.hpp" | |
33 #include "memory/resourceArea.hpp" | |
34 #include "memory/universe.inline.hpp" | |
35 #include "oops/instanceKlass.hpp" | |
36 #include "oops/objArrayKlass.hpp" | |
37 #include "oops/objArrayOop.hpp" | |
38 #include "prims/jvm.h" | |
39 #include "runtime/arguments.hpp" | |
40 #include "runtime/handles.inline.hpp" | |
41 #include "runtime/javaCalls.hpp" | |
42 #include "runtime/reflection.hpp" | |
43 #include "runtime/reflectionUtils.hpp" | |
44 #include "runtime/signature.hpp" | |
45 #include "runtime/vframe.hpp" | |
0 | 46 |
47 #define JAVA_1_5_VERSION 49 | |
48 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
49 static void trace_class_resolution(Klass* to_class) { |
0 | 50 ResourceMark rm; |
51 int line_number = -1; | |
52 const char * source_file = NULL; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
53 Klass* caller = NULL; |
0 | 54 JavaThread* jthread = JavaThread::current(); |
55 if (jthread->has_last_Java_frame()) { | |
56 vframeStream vfst(jthread); | |
57 // skip over any frames belonging to java.lang.Class | |
58 while (!vfst.at_end() && | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
59 vfst.method()->method_holder()->name() == vmSymbols::java_lang_Class()) { |
0 | 60 vfst.next(); |
61 } | |
62 if (!vfst.at_end()) { | |
63 // this frame is a likely suspect | |
64 caller = vfst.method()->method_holder(); | |
65 line_number = vfst.method()->line_number_from_bci(vfst.bci()); | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
66 Symbol* s = vfst.method()->method_holder()->source_file_name(); |
0 | 67 if (s != NULL) { |
68 source_file = s->as_C_string(); | |
69 } | |
70 } | |
71 } | |
72 if (caller != NULL) { | |
6983 | 73 const char * from = caller->external_name(); |
74 const char * to = to_class->external_name(); | |
0 | 75 // print in a single call to reduce interleaving between threads |
76 if (source_file != NULL) { | |
77 tty->print("RESOLVE %s %s %s:%d (reflection)\n", from, to, source_file, line_number); | |
78 } else { | |
79 tty->print("RESOLVE %s %s (reflection)\n", from, to); | |
80 } | |
81 } | |
82 } | |
83 | |
84 | |
85 oop Reflection::box(jvalue* value, BasicType type, TRAPS) { | |
86 if (type == T_VOID) { | |
87 return NULL; | |
88 } | |
89 if (type == T_OBJECT || type == T_ARRAY) { | |
90 // regular objects are not boxed | |
91 return (oop) value->l; | |
92 } | |
93 oop result = java_lang_boxing_object::create(type, value, CHECK_NULL); | |
94 if (result == NULL) { | |
95 THROW_(vmSymbols::java_lang_IllegalArgumentException(), result); | |
96 } | |
97 return result; | |
98 } | |
99 | |
100 | |
101 BasicType Reflection::unbox_for_primitive(oop box, jvalue* value, TRAPS) { | |
102 if (box == NULL) { | |
103 THROW_(vmSymbols::java_lang_IllegalArgumentException(), T_ILLEGAL); | |
104 } | |
105 return java_lang_boxing_object::get_value(box, value); | |
106 } | |
107 | |
108 BasicType Reflection::unbox_for_regular_object(oop box, jvalue* value) { | |
109 // Note: box is really the unboxed oop. It might even be a Short, etc.! | |
110 value->l = (jobject) box; | |
111 return T_OBJECT; | |
112 } | |
113 | |
114 | |
115 void Reflection::widen(jvalue* value, BasicType current_type, BasicType wide_type, TRAPS) { | |
116 assert(wide_type != current_type, "widen should not be called with identical types"); | |
117 switch (wide_type) { | |
118 case T_BOOLEAN: | |
119 case T_BYTE: | |
120 case T_CHAR: | |
121 break; // fail | |
122 case T_SHORT: | |
123 switch (current_type) { | |
124 case T_BYTE: | |
125 value->s = (jshort) value->b; | |
126 return; | |
127 } | |
128 break; // fail | |
129 case T_INT: | |
130 switch (current_type) { | |
131 case T_BYTE: | |
132 value->i = (jint) value->b; | |
133 return; | |
134 case T_CHAR: | |
135 value->i = (jint) value->c; | |
136 return; | |
137 case T_SHORT: | |
138 value->i = (jint) value->s; | |
139 return; | |
140 } | |
141 break; // fail | |
142 case T_LONG: | |
143 switch (current_type) { | |
144 case T_BYTE: | |
145 value->j = (jlong) value->b; | |
146 return; | |
147 case T_CHAR: | |
148 value->j = (jlong) value->c; | |
149 return; | |
150 case T_SHORT: | |
151 value->j = (jlong) value->s; | |
152 return; | |
153 case T_INT: | |
154 value->j = (jlong) value->i; | |
155 return; | |
156 } | |
157 break; // fail | |
158 case T_FLOAT: | |
159 switch (current_type) { | |
160 case T_BYTE: | |
161 value->f = (jfloat) value->b; | |
162 return; | |
163 case T_CHAR: | |
164 value->f = (jfloat) value->c; | |
165 return; | |
166 case T_SHORT: | |
167 value->f = (jfloat) value->s; | |
168 return; | |
169 case T_INT: | |
170 value->f = (jfloat) value->i; | |
171 return; | |
172 case T_LONG: | |
173 value->f = (jfloat) value->j; | |
174 return; | |
175 } | |
176 break; // fail | |
177 case T_DOUBLE: | |
178 switch (current_type) { | |
179 case T_BYTE: | |
180 value->d = (jdouble) value->b; | |
181 return; | |
182 case T_CHAR: | |
183 value->d = (jdouble) value->c; | |
184 return; | |
185 case T_SHORT: | |
186 value->d = (jdouble) value->s; | |
187 return; | |
188 case T_INT: | |
189 value->d = (jdouble) value->i; | |
190 return; | |
191 case T_FLOAT: | |
192 value->d = (jdouble) value->f; | |
193 return; | |
194 case T_LONG: | |
195 value->d = (jdouble) value->j; | |
196 return; | |
197 } | |
198 break; // fail | |
199 default: | |
200 break; // fail | |
201 } | |
202 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); | |
203 } | |
204 | |
205 | |
206 BasicType Reflection::array_get(jvalue* value, arrayOop a, int index, TRAPS) { | |
207 if (!a->is_within_bounds(index)) { | |
208 THROW_(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), T_ILLEGAL); | |
209 } | |
210 if (a->is_objArray()) { | |
211 value->l = (jobject) objArrayOop(a)->obj_at(index); | |
212 return T_OBJECT; | |
213 } else { | |
214 assert(a->is_typeArray(), "just checking"); | |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
215 BasicType type = TypeArrayKlass::cast(a->klass())->element_type(); |
0 | 216 switch (type) { |
217 case T_BOOLEAN: | |
218 value->z = typeArrayOop(a)->bool_at(index); | |
219 break; | |
220 case T_CHAR: | |
221 value->c = typeArrayOop(a)->char_at(index); | |
222 break; | |
223 case T_FLOAT: | |
224 value->f = typeArrayOop(a)->float_at(index); | |
225 break; | |
226 case T_DOUBLE: | |
227 value->d = typeArrayOop(a)->double_at(index); | |
228 break; | |
229 case T_BYTE: | |
230 value->b = typeArrayOop(a)->byte_at(index); | |
231 break; | |
232 case T_SHORT: | |
233 value->s = typeArrayOop(a)->short_at(index); | |
234 break; | |
235 case T_INT: | |
236 value->i = typeArrayOop(a)->int_at(index); | |
237 break; | |
238 case T_LONG: | |
239 value->j = typeArrayOop(a)->long_at(index); | |
240 break; | |
241 default: | |
242 return T_ILLEGAL; | |
243 } | |
244 return type; | |
245 } | |
246 } | |
247 | |
248 | |
249 void Reflection::array_set(jvalue* value, arrayOop a, int index, BasicType value_type, TRAPS) { | |
250 if (!a->is_within_bounds(index)) { | |
251 THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); | |
252 } | |
253 if (a->is_objArray()) { | |
254 if (value_type == T_OBJECT) { | |
255 oop obj = (oop) value->l; | |
256 if (obj != NULL) { | |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
257 Klass* element_klass = ObjArrayKlass::cast(a->klass())->element_klass(); |
0 | 258 if (!obj->is_a(element_klass)) { |
259 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "array element type mismatch"); | |
260 } | |
261 } | |
262 objArrayOop(a)->obj_at_put(index, obj); | |
263 } | |
264 } else { | |
265 assert(a->is_typeArray(), "just checking"); | |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
266 BasicType array_type = TypeArrayKlass::cast(a->klass())->element_type(); |
0 | 267 if (array_type != value_type) { |
268 // The widen operation can potentially throw an exception, but cannot block, | |
269 // so typeArrayOop a is safe if the call succeeds. | |
270 widen(value, value_type, array_type, CHECK); | |
271 } | |
272 switch (array_type) { | |
273 case T_BOOLEAN: | |
274 typeArrayOop(a)->bool_at_put(index, value->z); | |
275 break; | |
276 case T_CHAR: | |
277 typeArrayOop(a)->char_at_put(index, value->c); | |
278 break; | |
279 case T_FLOAT: | |
280 typeArrayOop(a)->float_at_put(index, value->f); | |
281 break; | |
282 case T_DOUBLE: | |
283 typeArrayOop(a)->double_at_put(index, value->d); | |
284 break; | |
285 case T_BYTE: | |
286 typeArrayOop(a)->byte_at_put(index, value->b); | |
287 break; | |
288 case T_SHORT: | |
289 typeArrayOop(a)->short_at_put(index, value->s); | |
290 break; | |
291 case T_INT: | |
292 typeArrayOop(a)->int_at_put(index, value->i); | |
293 break; | |
294 case T_LONG: | |
295 typeArrayOop(a)->long_at_put(index, value->j); | |
296 break; | |
297 default: | |
298 THROW(vmSymbols::java_lang_IllegalArgumentException()); | |
299 } | |
300 } | |
301 } | |
302 | |
303 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
304 Klass* Reflection::basic_type_mirror_to_arrayklass(oop basic_type_mirror, TRAPS) { |
0 | 305 assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking"); |
306 BasicType type = java_lang_Class::primitive_type(basic_type_mirror); | |
307 if (type == T_VOID) { | |
308 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
309 } else { | |
310 return Universe::typeArrayKlassObj(type); | |
311 } | |
312 } | |
313 | |
314 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
315 oop Reflection:: basic_type_arrayklass_to_mirror(Klass* basic_type_arrayklass, TRAPS) { |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
316 BasicType type = TypeArrayKlass::cast(basic_type_arrayklass)->element_type(); |
0 | 317 return Universe::java_mirror(type); |
318 } | |
319 | |
320 | |
321 arrayOop Reflection::reflect_new_array(oop element_mirror, jint length, TRAPS) { | |
322 if (element_mirror == NULL) { | |
323 THROW_0(vmSymbols::java_lang_NullPointerException()); | |
324 } | |
325 if (length < 0) { | |
326 THROW_0(vmSymbols::java_lang_NegativeArraySizeException()); | |
327 } | |
328 if (java_lang_Class::is_primitive(element_mirror)) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
329 Klass* tak = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL); |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
330 return TypeArrayKlass::cast(tak)->allocate(length, THREAD); |
0 | 331 } else { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
332 Klass* k = java_lang_Class::as_Klass(element_mirror); |
6983 | 333 if (k->oop_is_array() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) { |
0 | 334 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); |
335 } | |
336 return oopFactory::new_objArray(k, length, THREAD); | |
337 } | |
338 } | |
339 | |
340 | |
341 arrayOop Reflection::reflect_new_multi_array(oop element_mirror, typeArrayOop dim_array, TRAPS) { | |
342 assert(dim_array->is_typeArray(), "just checking"); | |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
343 assert(TypeArrayKlass::cast(dim_array->klass())->element_type() == T_INT, "just checking"); |
0 | 344 |
345 if (element_mirror == NULL) { | |
346 THROW_0(vmSymbols::java_lang_NullPointerException()); | |
347 } | |
348 | |
349 int len = dim_array->length(); | |
350 if (len <= 0 || len > MAX_DIM) { | |
351 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
352 } | |
353 | |
354 jint dimensions[MAX_DIM]; // C array copy of intArrayOop | |
355 for (int i = 0; i < len; i++) { | |
356 int d = dim_array->int_at(i); | |
357 if (d < 0) { | |
358 THROW_0(vmSymbols::java_lang_NegativeArraySizeException()); | |
359 } | |
360 dimensions[i] = d; | |
361 } | |
362 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
363 Klass* klass; |
0 | 364 int dim = len; |
365 if (java_lang_Class::is_primitive(element_mirror)) { | |
366 klass = basic_type_mirror_to_arrayklass(element_mirror, CHECK_NULL); | |
367 } else { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
368 klass = java_lang_Class::as_Klass(element_mirror); |
6983 | 369 if (klass->oop_is_array()) { |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
370 int k_dim = ArrayKlass::cast(klass)->dimension(); |
0 | 371 if (k_dim + len > MAX_DIM) { |
372 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
373 } | |
374 dim += k_dim; | |
375 } | |
376 } | |
6983 | 377 klass = klass->array_klass(dim, CHECK_NULL); |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
378 oop obj = ArrayKlass::cast(klass)->multi_allocate(len, dimensions, THREAD); |
0 | 379 assert(obj->is_array(), "just checking"); |
380 return arrayOop(obj); | |
381 } | |
382 | |
383 | |
384 oop Reflection::array_component_type(oop mirror, TRAPS) { | |
385 if (java_lang_Class::is_primitive(mirror)) { | |
386 return NULL; | |
387 } | |
388 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
389 Klass* klass = java_lang_Class::as_Klass(mirror); |
6983 | 390 if (!klass->oop_is_array()) { |
0 | 391 return NULL; |
392 } | |
393 | |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
394 oop result = ArrayKlass::cast(klass)->component_mirror(); |
0 | 395 #ifdef ASSERT |
396 oop result2 = NULL; | |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
397 if (ArrayKlass::cast(klass)->dimension() == 1) { |
6983 | 398 if (klass->oop_is_typeArray()) { |
0 | 399 result2 = basic_type_arrayklass_to_mirror(klass, CHECK_NULL); |
400 } else { | |
6983 | 401 result2 = ObjArrayKlass::cast(klass)->element_klass()->java_mirror(); |
0 | 402 } |
403 } else { | |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
404 Klass* lower_dim = ArrayKlass::cast(klass)->lower_dimension(); |
6983 | 405 assert(lower_dim->oop_is_array(), "just checking"); |
406 result2 = lower_dim->java_mirror(); | |
0 | 407 } |
408 assert(result == result2, "results must be consistent"); | |
409 #endif //ASSERT | |
410 return result; | |
411 } | |
412 | |
413 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
414 bool Reflection::reflect_check_access(Klass* field_class, AccessFlags acc, Klass* target_class, bool is_method_invoke, TRAPS) { |
0 | 415 // field_class : declaring class |
416 // acc : declared field access | |
417 // target_class : for protected | |
418 | |
419 // Check if field or method is accessible to client. Throw an | |
420 // IllegalAccessException and return false if not. | |
421 | |
422 // The "client" is the class associated with the nearest real frame | |
423 // getCallerClass already skips Method.invoke frames, so pass 0 in | |
424 // that case (same as classic). | |
425 ResourceMark rm(THREAD); | |
426 assert(THREAD->is_Java_thread(), "sanity check"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
427 Klass* client_class = ((JavaThread *)THREAD)->security_get_caller_class(is_method_invoke ? 0 : 1); |
0 | 428 |
429 if (client_class != field_class) { | |
430 if (!verify_class_access(client_class, field_class, false) | |
431 || !verify_field_access(client_class, | |
432 field_class, | |
433 field_class, | |
434 acc, | |
435 false)) { | |
436 THROW_(vmSymbols::java_lang_IllegalAccessException(), false); | |
437 } | |
438 } | |
439 | |
440 // Additional test for protected members: JLS 6.6.2 | |
441 | |
442 if (acc.is_protected()) { | |
443 if (target_class != client_class) { | |
444 if (!is_same_class_package(client_class, field_class)) { | |
6983 | 445 if (!target_class->is_subclass_of(client_class)) { |
0 | 446 THROW_(vmSymbols::java_lang_IllegalAccessException(), false); |
447 } | |
448 } | |
449 } | |
450 } | |
451 | |
452 // Passed all tests | |
453 return true; | |
454 } | |
455 | |
456 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
457 bool Reflection::verify_class_access(Klass* current_class, Klass* new_class, bool classloader_only) { |
0 | 458 // Verify that current_class can access new_class. If the classloader_only |
459 // flag is set, we automatically allow any accesses in which current_class | |
460 // doesn't have a classloader. | |
461 if ((current_class == NULL) || | |
462 (current_class == new_class) || | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
463 (InstanceKlass::cast(new_class)->is_public()) || |
0 | 464 is_same_class_package(current_class, new_class)) { |
465 return true; | |
466 } | |
467 // New (1.4) reflection implementation. Allow all accesses from | |
468 // sun/reflect/MagicAccessorImpl subclasses to succeed trivially. | |
469 if ( JDK_Version::is_gte_jdk14x_version() | |
470 && UseNewReflection | |
6983 | 471 && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) { |
0 | 472 return true; |
473 } | |
474 | |
6934 | 475 // Also allow all accesses from |
476 // java/lang/invoke/MagicLambdaImpl subclasses to succeed trivially. | |
477 if (current_class->is_subclass_of(SystemDictionary::lambda_MagicLambdaImpl_klass())) { | |
478 return true; | |
479 } | |
480 | |
0 | 481 return can_relax_access_check_for(current_class, new_class, classloader_only); |
482 } | |
483 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
484 static bool under_host_klass(InstanceKlass* ik, Klass* host_klass) { |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
485 DEBUG_ONLY(int inf_loop_check = 1000 * 1000 * 1000); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
486 for (;;) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
487 Klass* hc = (Klass*) ik->host_klass(); |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
488 if (hc == NULL) return false; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
489 if (hc == host_klass) return true; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
490 ik = InstanceKlass::cast(hc); |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
491 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
492 // There's no way to make a host class loop short of patching memory. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
493 // Therefore there cannot be a loop here unles there's another bug. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
494 // Still, let's check for it. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
495 assert(--inf_loop_check > 0, "no host_klass loop"); |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
496 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
497 } |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
498 |
0 | 499 bool Reflection::can_relax_access_check_for( |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
500 Klass* accessor, Klass* accessee, bool classloader_only) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
501 InstanceKlass* accessor_ik = InstanceKlass::cast(accessor); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
502 InstanceKlass* accessee_ik = InstanceKlass::cast(accessee); |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
503 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
504 // If either is on the other's host_klass chain, access is OK, |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
505 // because one is inside the other. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
506 if (under_host_klass(accessor_ik, accessee) || |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
507 under_host_klass(accessee_ik, accessor)) |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
508 return true; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
509 |
0 | 510 if (RelaxAccessControlCheck || |
511 (accessor_ik->major_version() < JAVA_1_5_VERSION && | |
512 accessee_ik->major_version() < JAVA_1_5_VERSION)) { | |
513 return classloader_only && | |
514 Verifier::relax_verify_for(accessor_ik->class_loader()) && | |
515 accessor_ik->protection_domain() == accessee_ik->protection_domain() && | |
516 accessor_ik->class_loader() == accessee_ik->class_loader(); | |
517 } else { | |
518 return false; | |
519 } | |
520 } | |
521 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
522 bool Reflection::verify_field_access(Klass* current_class, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
523 Klass* resolved_class, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
524 Klass* field_class, |
0 | 525 AccessFlags access, |
526 bool classloader_only, | |
527 bool protected_restriction) { | |
528 // Verify that current_class can access a field of field_class, where that | |
529 // field's access bits are "access". We assume that we've already verified | |
530 // that current_class can access field_class. | |
531 // | |
532 // If the classloader_only flag is set, we automatically allow any accesses | |
533 // in which current_class doesn't have a classloader. | |
534 // | |
535 // "resolved_class" is the runtime type of "field_class". Sometimes we don't | |
536 // need this distinction (e.g. if all we have is the runtime type, or during | |
537 // class file parsing when we only care about the static type); in that case | |
538 // callers should ensure that resolved_class == field_class. | |
539 // | |
540 if ((current_class == NULL) || | |
541 (current_class == field_class) || | |
542 access.is_public()) { | |
543 return true; | |
544 } | |
545 | |
546 if (access.is_protected()) { | |
547 if (!protected_restriction) { | |
548 // See if current_class is a subclass of field_class | |
6983 | 549 if (current_class->is_subclass_of(field_class)) { |
115 | 550 if (access.is_static() || // static fields are ok, see 6622385 |
551 current_class == resolved_class || | |
0 | 552 field_class == resolved_class || |
6983 | 553 current_class->is_subclass_of(resolved_class) || |
554 resolved_class->is_subclass_of(current_class)) { | |
0 | 555 return true; |
556 } | |
557 } | |
558 } | |
559 } | |
560 | |
561 if (!access.is_private() && is_same_class_package(current_class, field_class)) { | |
562 return true; | |
563 } | |
564 | |
565 // New (1.4) reflection implementation. Allow all accesses from | |
566 // sun/reflect/MagicAccessorImpl subclasses to succeed trivially. | |
567 if ( JDK_Version::is_gte_jdk14x_version() | |
568 && UseNewReflection | |
6983 | 569 && current_class->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) { |
0 | 570 return true; |
571 } | |
572 | |
6934 | 573 // Also allow all accesses from |
574 // java/lang/invoke/MagicLambdaImpl subclasses to succeed trivially. | |
575 if (current_class->is_subclass_of(SystemDictionary::lambda_MagicLambdaImpl_klass())) { | |
576 return true; | |
577 } | |
578 | |
0 | 579 return can_relax_access_check_for( |
580 current_class, field_class, classloader_only); | |
581 } | |
582 | |
583 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
584 bool Reflection::is_same_class_package(Klass* class1, Klass* class2) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
585 return InstanceKlass::cast(class1)->is_same_class_package(class2); |
0 | 586 } |
587 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
588 bool Reflection::is_same_package_member(Klass* class1, Klass* class2, TRAPS) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
589 return InstanceKlass::cast(class1)->is_same_package_member(class2, THREAD); |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
590 } |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
591 |
0 | 592 |
593 // Checks that the 'outer' klass has declared 'inner' as being an inner klass. If not, | |
594 // throw an incompatible class change exception | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
595 // If inner_is_member, require the inner to be a member of the outer. |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
596 // If !inner_is_member, require the inner to be anonymous (a non-member). |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
597 // Caller is responsible for figuring out in advance which case must be true. |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
598 void Reflection::check_for_inner_class(instanceKlassHandle outer, instanceKlassHandle inner, |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
599 bool inner_is_member, TRAPS) { |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
3895
diff
changeset
|
600 InnerClassesIterator iter(outer); |
0 | 601 constantPoolHandle cp (THREAD, outer->constants()); |
5967
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
3895
diff
changeset
|
602 for (; !iter.done(); iter.next()) { |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
3895
diff
changeset
|
603 int ioff = iter.inner_class_info_index(); |
f7c4174b33ba
7109878: The instanceKlass EnclosingMethhod attribute fields can be folded into the _inner_class field.
jiangli
parents:
3895
diff
changeset
|
604 int ooff = iter.outer_class_info_index(); |
0 | 605 |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
606 if (inner_is_member && ioff != 0 && ooff != 0) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
607 Klass* o = cp->klass_at(ooff, CHECK); |
0 | 608 if (o == outer()) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
609 Klass* i = cp->klass_at(ioff, CHECK); |
0 | 610 if (i == inner()) { |
611 return; | |
612 } | |
613 } | |
614 } | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
615 if (!inner_is_member && ioff != 0 && ooff == 0 && |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
616 cp->klass_name_at_matches(inner, ioff)) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
617 Klass* i = cp->klass_at(ioff, CHECK); |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
618 if (i == inner()) { |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
619 return; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
620 } |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
621 } |
0 | 622 } |
623 | |
624 // 'inner' not declared as an inner klass in outer | |
625 ResourceMark rm(THREAD); | |
626 Exceptions::fthrow( | |
627 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
628 vmSymbols::java_lang_IncompatibleClassChangeError(), |
0 | 629 "%s and %s disagree on InnerClasses attribute", |
630 outer->external_name(), | |
631 inner->external_name() | |
632 ); | |
633 } | |
634 | |
635 // Utility method converting a single SignatureStream element into java.lang.Class instance | |
636 | |
637 oop get_mirror_from_signature(methodHandle method, SignatureStream* ss, TRAPS) { | |
638 switch (ss->type()) { | |
639 default: | |
640 assert(ss->type() != T_VOID || ss->at_return_type(), "T_VOID should only appear as return type"); | |
641 return java_lang_Class::primitive_mirror(ss->type()); | |
642 case T_OBJECT: | |
643 case T_ARRAY: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
644 Symbol* name = ss->as_symbol(CHECK_NULL); |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
645 oop loader = method->method_holder()->class_loader(); |
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
646 oop protection_domain = method->method_holder()->protection_domain(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
647 Klass* k = SystemDictionary::resolve_or_fail( |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
648 name, |
0 | 649 Handle(THREAD, loader), |
650 Handle(THREAD, protection_domain), | |
651 true, CHECK_NULL); | |
652 if (TraceClassResolution) { | |
653 trace_class_resolution(k); | |
654 } | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2177
diff
changeset
|
655 return k->java_mirror(); |
0 | 656 }; |
657 } | |
658 | |
659 | |
660 objArrayHandle Reflection::get_parameter_types(methodHandle method, int parameter_count, oop* return_type, TRAPS) { | |
661 // Allocate array holding parameter types (java.lang.Class instances) | |
1142 | 662 objArrayOop m = oopFactory::new_objArray(SystemDictionary::Class_klass(), parameter_count, CHECK_(objArrayHandle())); |
0 | 663 objArrayHandle mirrors (THREAD, m); |
664 int index = 0; | |
665 // Collect parameter types | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
666 ResourceMark rm(THREAD); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
667 Symbol* signature = method->signature(); |
0 | 668 SignatureStream ss(signature); |
669 while (!ss.at_return_type()) { | |
670 oop mirror = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle())); | |
671 mirrors->obj_at_put(index++, mirror); | |
672 ss.next(); | |
673 } | |
674 assert(index == parameter_count, "invalid parameter count"); | |
675 if (return_type != NULL) { | |
676 // Collect return type as well | |
677 assert(ss.at_return_type(), "return type should be present"); | |
678 *return_type = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle())); | |
679 } | |
680 return mirrors; | |
681 } | |
682 | |
683 objArrayHandle Reflection::get_exception_types(methodHandle method, TRAPS) { | |
684 return method->resolved_checked_exceptions(CHECK_(objArrayHandle())); | |
685 } | |
686 | |
687 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
688 Handle Reflection::new_type(Symbol* signature, KlassHandle k, TRAPS) { |
0 | 689 // Basic types |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
690 BasicType type = vmSymbols::signature_type(signature); |
0 | 691 if (type != T_OBJECT) { |
692 return Handle(THREAD, Universe::java_mirror(type)); | |
693 } | |
694 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
695 oop loader = InstanceKlass::cast(k())->class_loader(); |
6983 | 696 oop protection_domain = k()->protection_domain(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
697 Klass* result = SystemDictionary::resolve_or_fail(signature, |
0 | 698 Handle(THREAD, loader), |
699 Handle(THREAD, protection_domain), | |
700 true, CHECK_(Handle())); | |
701 | |
702 if (TraceClassResolution) { | |
703 trace_class_resolution(result); | |
704 } | |
705 | |
6983 | 706 oop nt = result->java_mirror(); |
0 | 707 return Handle(THREAD, nt); |
708 } | |
709 | |
710 | |
711 oop Reflection::new_method(methodHandle method, bool intern_name, bool for_constant_pool_access, TRAPS) { | |
712 // In jdk1.2.x, getMethods on an interface erroneously includes <clinit>, thus the complicated assert. | |
713 // Also allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods. | |
714 assert(!method()->is_initializer() || | |
715 (for_constant_pool_access && method()->is_static()) || | |
716 (method()->name() == vmSymbols::class_initializer_name() | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
717 && method()->method_holder()->is_interface() && JDK_Version::is_jdk12x_version()), "should call new_constructor instead"); |
0 | 718 instanceKlassHandle holder (THREAD, method->method_holder()); |
719 int slot = method->method_idnum(); | |
720 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
721 Symbol* signature = method->signature(); |
0 | 722 int parameter_count = ArgumentCount(signature).size(); |
723 oop return_type_oop = NULL; | |
724 objArrayHandle parameter_types = get_parameter_types(method, parameter_count, &return_type_oop, CHECK_NULL); | |
725 if (parameter_types.is_null() || return_type_oop == NULL) return NULL; | |
726 | |
727 Handle return_type(THREAD, return_type_oop); | |
728 | |
729 objArrayHandle exception_types = get_exception_types(method, CHECK_NULL); | |
730 | |
731 if (exception_types.is_null()) return NULL; | |
732 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
733 Symbol* method_name = method->name(); |
0 | 734 Handle name; |
735 if (intern_name) { | |
736 // intern_name is only true with UseNewReflection | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
737 oop name_oop = StringTable::intern(method_name, CHECK_NULL); |
0 | 738 name = Handle(THREAD, name_oop); |
739 } else { | |
740 name = java_lang_String::create_from_symbol(method_name, CHECK_NULL); | |
741 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
742 if (name == NULL) return NULL; |
0 | 743 |
744 int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; | |
745 | |
746 Handle mh = java_lang_reflect_Method::create(CHECK_NULL); | |
747 | |
748 java_lang_reflect_Method::set_clazz(mh(), holder->java_mirror()); | |
749 java_lang_reflect_Method::set_slot(mh(), slot); | |
750 java_lang_reflect_Method::set_name(mh(), name()); | |
751 java_lang_reflect_Method::set_return_type(mh(), return_type()); | |
752 java_lang_reflect_Method::set_parameter_types(mh(), parameter_types()); | |
753 java_lang_reflect_Method::set_exception_types(mh(), exception_types()); | |
754 java_lang_reflect_Method::set_modifiers(mh(), modifiers); | |
755 java_lang_reflect_Method::set_override(mh(), false); | |
756 if (java_lang_reflect_Method::has_signature_field() && | |
757 method->generic_signature() != NULL) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
758 Symbol* gs = method->generic_signature(); |
0 | 759 Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL); |
760 java_lang_reflect_Method::set_signature(mh(), sig()); | |
761 } | |
762 if (java_lang_reflect_Method::has_annotations_field()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
763 typeArrayOop an_oop = Annotations::make_java_array(method->annotations(), CHECK_NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
764 java_lang_reflect_Method::set_annotations(mh(), an_oop); |
0 | 765 } |
766 if (java_lang_reflect_Method::has_parameter_annotations_field()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
767 typeArrayOop an_oop = Annotations::make_java_array(method->parameter_annotations(), CHECK_NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
768 java_lang_reflect_Method::set_parameter_annotations(mh(), an_oop); |
0 | 769 } |
770 if (java_lang_reflect_Method::has_annotation_default_field()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
771 typeArrayOop an_oop = Annotations::make_java_array(method->annotation_default(), CHECK_NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
772 java_lang_reflect_Method::set_annotation_default(mh(), an_oop); |
0 | 773 } |
774 return mh(); | |
775 } | |
776 | |
777 | |
778 oop Reflection::new_constructor(methodHandle method, TRAPS) { | |
779 assert(method()->is_initializer(), "should call new_method instead"); | |
780 | |
781 instanceKlassHandle holder (THREAD, method->method_holder()); | |
782 int slot = method->method_idnum(); | |
783 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
784 Symbol* signature = method->signature(); |
0 | 785 int parameter_count = ArgumentCount(signature).size(); |
786 objArrayHandle parameter_types = get_parameter_types(method, parameter_count, NULL, CHECK_NULL); | |
787 if (parameter_types.is_null()) return NULL; | |
788 | |
789 objArrayHandle exception_types = get_exception_types(method, CHECK_NULL); | |
790 if (exception_types.is_null()) return NULL; | |
791 | |
792 int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; | |
793 | |
794 Handle ch = java_lang_reflect_Constructor::create(CHECK_NULL); | |
795 | |
796 java_lang_reflect_Constructor::set_clazz(ch(), holder->java_mirror()); | |
797 java_lang_reflect_Constructor::set_slot(ch(), slot); | |
798 java_lang_reflect_Constructor::set_parameter_types(ch(), parameter_types()); | |
799 java_lang_reflect_Constructor::set_exception_types(ch(), exception_types()); | |
800 java_lang_reflect_Constructor::set_modifiers(ch(), modifiers); | |
801 java_lang_reflect_Constructor::set_override(ch(), false); | |
802 if (java_lang_reflect_Constructor::has_signature_field() && | |
803 method->generic_signature() != NULL) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
804 Symbol* gs = method->generic_signature(); |
0 | 805 Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL); |
806 java_lang_reflect_Constructor::set_signature(ch(), sig()); | |
807 } | |
808 if (java_lang_reflect_Constructor::has_annotations_field()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
809 typeArrayOop an_oop = Annotations::make_java_array(method->annotations(), CHECK_NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
810 java_lang_reflect_Constructor::set_annotations(ch(), an_oop); |
0 | 811 } |
812 if (java_lang_reflect_Constructor::has_parameter_annotations_field()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
813 typeArrayOop an_oop = Annotations::make_java_array(method->parameter_annotations(), CHECK_NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
814 java_lang_reflect_Constructor::set_parameter_annotations(ch(), an_oop); |
0 | 815 } |
816 return ch(); | |
817 } | |
818 | |
819 | |
820 oop Reflection::new_field(fieldDescriptor* fd, bool intern_name, TRAPS) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
821 Symbol* field_name = fd->name(); |
0 | 822 Handle name; |
823 if (intern_name) { | |
824 // intern_name is only true with UseNewReflection | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
825 oop name_oop = StringTable::intern(field_name, CHECK_NULL); |
0 | 826 name = Handle(THREAD, name_oop); |
827 } else { | |
828 name = java_lang_String::create_from_symbol(field_name, CHECK_NULL); | |
829 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
830 Symbol* signature = fd->signature(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
831 instanceKlassHandle holder (THREAD, fd->field_holder()); |
0 | 832 Handle type = new_type(signature, holder, CHECK_NULL); |
833 Handle rh = java_lang_reflect_Field::create(CHECK_NULL); | |
834 | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
835 java_lang_reflect_Field::set_clazz(rh(), fd->field_holder()->java_mirror()); |
0 | 836 java_lang_reflect_Field::set_slot(rh(), fd->index()); |
837 java_lang_reflect_Field::set_name(rh(), name()); | |
838 java_lang_reflect_Field::set_type(rh(), type()); | |
839 // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here. | |
840 java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS); | |
841 java_lang_reflect_Field::set_override(rh(), false); | |
842 if (java_lang_reflect_Field::has_signature_field() && | |
6176
634b8615a6ba
7177409: Perf regression in JVM_GetClassDeclaredFields after generic signature changes.
jiangli
parents:
5967
diff
changeset
|
843 fd->has_generic_signature()) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
844 Symbol* gs = fd->generic_signature(); |
0 | 845 Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL); |
846 java_lang_reflect_Field::set_signature(rh(), sig()); | |
847 } | |
848 if (java_lang_reflect_Field::has_annotations_field()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
849 typeArrayOop an_oop = Annotations::make_java_array(fd->annotations(), CHECK_NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
850 java_lang_reflect_Field::set_annotations(rh(), an_oop); |
0 | 851 } |
852 return rh(); | |
853 } | |
854 | |
855 | |
856 methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, methodHandle method, | |
857 KlassHandle recv_klass, Handle receiver, TRAPS) { | |
858 assert(!method.is_null() , "method should not be null"); | |
859 | |
860 CallInfo info; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
861 Symbol* signature = method->signature(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
862 Symbol* name = method->name(); |
0 | 863 LinkResolver::resolve_interface_call(info, receiver, recv_klass, klass, |
864 name, signature, | |
865 KlassHandle(), false, true, | |
866 CHECK_(methodHandle())); | |
867 return info.selected_method(); | |
868 } | |
869 | |
870 | |
871 oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method, | |
872 Handle receiver, bool override, objArrayHandle ptypes, | |
873 BasicType rtype, objArrayHandle args, bool is_method_invoke, TRAPS) { | |
874 ResourceMark rm(THREAD); | |
875 | |
876 methodHandle method; // actual method to invoke | |
877 KlassHandle target_klass; // target klass, receiver's klass for non-static | |
878 | |
879 // Ensure klass is initialized | |
880 klass->initialize(CHECK_NULL); | |
881 | |
882 bool is_static = reflected_method->is_static(); | |
883 if (is_static) { | |
884 // ignore receiver argument | |
885 method = reflected_method; | |
886 target_klass = klass; | |
887 } else { | |
888 // check for null receiver | |
889 if (receiver.is_null()) { | |
890 THROW_0(vmSymbols::java_lang_NullPointerException()); | |
891 } | |
892 // Check class of receiver against class declaring method | |
893 if (!receiver->is_a(klass())) { | |
894 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class"); | |
895 } | |
896 // target klass is receiver's klass | |
897 target_klass = KlassHandle(THREAD, receiver->klass()); | |
898 // no need to resolve if method is private or <init> | |
899 if (reflected_method->is_private() || reflected_method->name() == vmSymbols::object_initializer_name()) { | |
900 method = reflected_method; | |
901 } else { | |
902 // resolve based on the receiver | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
903 if (reflected_method->method_holder()->is_interface()) { |
0 | 904 // resolve interface call |
905 if (ReflectionWrapResolutionErrors) { | |
906 // new default: 6531596 | |
907 // Match resolution errors with those thrown due to reflection inlining | |
908 // Linktime resolution & IllegalAccessCheck already done by Class.getMethod() | |
909 method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD); | |
910 if (HAS_PENDING_EXCEPTION) { | |
911 // Method resolution threw an exception; wrap it in an InvocationTargetException | |
912 oop resolution_exception = PENDING_EXCEPTION; | |
913 CLEAR_PENDING_EXCEPTION; | |
914 JavaCallArguments args(Handle(THREAD, resolution_exception)); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
915 THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
916 vmSymbols::throwable_void_signature(), |
0 | 917 &args); |
918 } | |
919 } else { | |
920 method = resolve_interface_call(klass, reflected_method, target_klass, receiver, CHECK_(NULL)); | |
921 } | |
922 } else { | |
923 // if the method can be overridden, we resolve using the vtable index. | |
924 int index = reflected_method->vtable_index(); | |
925 method = reflected_method; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
926 if (index != Method::nonvirtual_vtable_index) { |
0 | 927 // target_klass might be an arrayKlassOop but all vtables start at |
928 // the same place. The cast is to avoid virtual call and assertion. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
929 InstanceKlass* inst = (InstanceKlass*)target_klass(); |
0 | 930 method = methodHandle(THREAD, inst->method_at_vtable(index)); |
931 } | |
932 if (!method.is_null()) { | |
933 // Check for abstract methods as well | |
934 if (method->is_abstract()) { | |
935 // new default: 6531596 | |
936 if (ReflectionWrapResolutionErrors) { | |
937 ResourceMark rm(THREAD); | |
938 Handle h_origexception = Exceptions::new_exception(THREAD, | |
939 vmSymbols::java_lang_AbstractMethodError(), | |
6983 | 940 Method::name_and_sig_as_C_string(target_klass(), |
0 | 941 method->name(), |
942 method->signature())); | |
943 JavaCallArguments args(h_origexception); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
944 THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
945 vmSymbols::throwable_void_signature(), |
0 | 946 &args); |
947 } else { | |
948 ResourceMark rm(THREAD); | |
949 THROW_MSG_0(vmSymbols::java_lang_AbstractMethodError(), | |
6983 | 950 Method::name_and_sig_as_C_string(target_klass(), |
0 | 951 method->name(), |
952 method->signature())); | |
953 } | |
954 } | |
955 } | |
956 } | |
957 } | |
958 } | |
959 | |
960 // I believe this is a ShouldNotGetHere case which requires | |
961 // an internal vtable bug. If you ever get this please let Karen know. | |
962 if (method.is_null()) { | |
963 ResourceMark rm(THREAD); | |
964 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), | |
6983 | 965 Method::name_and_sig_as_C_string(klass(), |
0 | 966 reflected_method->name(), |
967 reflected_method->signature())); | |
968 } | |
969 | |
970 // In the JDK 1.4 reflection implementation, the security check is | |
971 // done at the Java level | |
972 if (!(JDK_Version::is_gte_jdk14x_version() && UseNewReflection)) { | |
973 | |
974 // Access checking (unless overridden by Method) | |
975 if (!override) { | |
976 if (!(klass->is_public() && reflected_method->is_public())) { | |
977 bool access = Reflection::reflect_check_access(klass(), reflected_method->access_flags(), target_klass(), is_method_invoke, CHECK_NULL); | |
978 if (!access) { | |
979 return NULL; // exception | |
980 } | |
981 } | |
982 } | |
983 | |
984 } // !(Universe::is_gte_jdk14x_version() && UseNewReflection) | |
985 | |
986 assert(ptypes->is_objArray(), "just checking"); | |
987 int args_len = args.is_null() ? 0 : args->length(); | |
988 // Check number of arguments | |
989 if (ptypes->length() != args_len) { | |
990 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "wrong number of arguments"); | |
991 } | |
992 | |
993 // Create object to contain parameters for the JavaCall | |
994 JavaCallArguments java_args(method->size_of_parameters()); | |
995 | |
996 if (!is_static) { | |
997 java_args.push_oop(receiver); | |
998 } | |
999 | |
1000 for (int i = 0; i < args_len; i++) { | |
1001 oop type_mirror = ptypes->obj_at(i); | |
1002 oop arg = args->obj_at(i); | |
1003 if (java_lang_Class::is_primitive(type_mirror)) { | |
1004 jvalue value; | |
1005 BasicType ptype = basic_type_mirror_to_basic_type(type_mirror, CHECK_NULL); | |
1006 BasicType atype = unbox_for_primitive(arg, &value, CHECK_NULL); | |
1007 if (ptype != atype) { | |
1008 widen(&value, atype, ptype, CHECK_NULL); | |
1009 } | |
1010 switch (ptype) { | |
1011 case T_BOOLEAN: java_args.push_int(value.z); break; | |
1012 case T_CHAR: java_args.push_int(value.c); break; | |
1013 case T_BYTE: java_args.push_int(value.b); break; | |
1014 case T_SHORT: java_args.push_int(value.s); break; | |
1015 case T_INT: java_args.push_int(value.i); break; | |
1016 case T_LONG: java_args.push_long(value.j); break; | |
1017 case T_FLOAT: java_args.push_float(value.f); break; | |
1018 case T_DOUBLE: java_args.push_double(value.d); break; | |
1019 default: | |
1020 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); | |
1021 } | |
1022 } else { | |
1023 if (arg != NULL) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1024 Klass* k = java_lang_Class::as_Klass(type_mirror); |
0 | 1025 if (!arg->is_a(k)) { |
1026 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); | |
1027 } | |
1028 } | |
1029 Handle arg_handle(THREAD, arg); // Create handle for argument | |
1030 java_args.push_oop(arg_handle); // Push handle | |
1031 } | |
1032 } | |
1033 | |
1034 assert(java_args.size_of_parameters() == method->size_of_parameters(), "just checking"); | |
1035 | |
1036 // All oops (including receiver) is passed in as Handles. An potential oop is returned as an | |
1037 // oop (i.e., NOT as an handle) | |
1038 JavaValue result(rtype); | |
1039 JavaCalls::call(&result, method, &java_args, THREAD); | |
1040 | |
1041 if (HAS_PENDING_EXCEPTION) { | |
1042 // Method threw an exception; wrap it in an InvocationTargetException | |
1043 oop target_exception = PENDING_EXCEPTION; | |
1044 CLEAR_PENDING_EXCEPTION; | |
1045 JavaCallArguments args(Handle(THREAD, target_exception)); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1046 THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1047 vmSymbols::throwable_void_signature(), |
0 | 1048 &args); |
1049 } else { | |
1050 if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT) | |
1051 narrow((jvalue*) result.get_value_addr(), rtype, CHECK_NULL); | |
1052 return box((jvalue*) result.get_value_addr(), rtype, CHECK_NULL); | |
1053 } | |
1054 } | |
1055 | |
1056 | |
1057 void Reflection::narrow(jvalue* value, BasicType narrow_type, TRAPS) { | |
1058 switch (narrow_type) { | |
1059 case T_BOOLEAN: | |
1060 value->z = (jboolean) value->i; | |
1061 return; | |
1062 case T_BYTE: | |
1063 value->b = (jbyte) value->i; | |
1064 return; | |
1065 case T_CHAR: | |
1066 value->c = (jchar) value->i; | |
1067 return; | |
1068 case T_SHORT: | |
1069 value->s = (jshort) value->i; | |
1070 return; | |
1071 default: | |
1072 break; // fail | |
1073 } | |
1074 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); | |
1075 } | |
1076 | |
1077 | |
1078 BasicType Reflection::basic_type_mirror_to_basic_type(oop basic_type_mirror, TRAPS) { | |
1079 assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking"); | |
1080 return java_lang_Class::primitive_type(basic_type_mirror); | |
1081 } | |
1082 | |
1083 // This would be nicer if, say, java.lang.reflect.Method was a subclass | |
1084 // of java.lang.reflect.Constructor | |
1085 | |
1086 oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS) { | |
1087 oop mirror = java_lang_reflect_Method::clazz(method_mirror); | |
1088 int slot = java_lang_reflect_Method::slot(method_mirror); | |
1089 bool override = java_lang_reflect_Method::override(method_mirror) != 0; | |
1090 objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Method::parameter_types(method_mirror))); | |
1091 | |
1092 oop return_type_mirror = java_lang_reflect_Method::return_type(method_mirror); | |
1093 BasicType rtype; | |
1094 if (java_lang_Class::is_primitive(return_type_mirror)) { | |
1095 rtype = basic_type_mirror_to_basic_type(return_type_mirror, CHECK_NULL); | |
1096 } else { | |
1097 rtype = T_OBJECT; | |
1098 } | |
1099 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1100 instanceKlassHandle klass(THREAD, java_lang_Class::as_Klass(mirror)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1101 Method* m = klass->method_with_idnum(slot); |
51
1ffa5cdd0b7e
6667089: 3/3 multiple redefinitions of a class break reflection
dcubed
parents:
0
diff
changeset
|
1102 if (m == NULL) { |
0 | 1103 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke"); |
1104 } | |
51
1ffa5cdd0b7e
6667089: 3/3 multiple redefinitions of a class break reflection
dcubed
parents:
0
diff
changeset
|
1105 methodHandle method(THREAD, m); |
0 | 1106 |
1107 return invoke(klass, method, receiver, override, ptypes, rtype, args, true, THREAD); | |
1108 } | |
1109 | |
1110 | |
1111 oop Reflection::invoke_constructor(oop constructor_mirror, objArrayHandle args, TRAPS) { | |
1112 oop mirror = java_lang_reflect_Constructor::clazz(constructor_mirror); | |
1113 int slot = java_lang_reflect_Constructor::slot(constructor_mirror); | |
1114 bool override = java_lang_reflect_Constructor::override(constructor_mirror) != 0; | |
1115 objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror))); | |
1116 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1117 instanceKlassHandle klass(THREAD, java_lang_Class::as_Klass(mirror)); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1118 Method* m = klass->method_with_idnum(slot); |
51
1ffa5cdd0b7e
6667089: 3/3 multiple redefinitions of a class break reflection
dcubed
parents:
0
diff
changeset
|
1119 if (m == NULL) { |
0 | 1120 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke"); |
1121 } | |
51
1ffa5cdd0b7e
6667089: 3/3 multiple redefinitions of a class break reflection
dcubed
parents:
0
diff
changeset
|
1122 methodHandle method(THREAD, m); |
0 | 1123 assert(method->name() == vmSymbols::object_initializer_name(), "invalid constructor"); |
1124 | |
1125 // Make sure klass gets initialize | |
1126 klass->initialize(CHECK_NULL); | |
1127 | |
1128 // Create new instance (the receiver) | |
1129 klass->check_valid_for_instantiation(false, CHECK_NULL); | |
1130 Handle receiver = klass->allocate_instance_handle(CHECK_NULL); | |
1131 | |
1132 // Ignore result from call and return receiver | |
1133 invoke(klass, method, receiver, override, ptypes, T_VOID, args, false, CHECK_NULL); | |
1134 return receiver(); | |
1135 } |