Mercurial > hg > truffle
annotate src/share/vm/runtime/reflection.cpp @ 6862:8a5ea0a9ccc4
7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author | johnc |
---|---|
date | Sat, 06 Oct 2012 01:17:44 -0700 |
parents | da91efe96a93 |
children | d8ce2825b193 |
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() && | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
59 InstanceKlass::cast(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()); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
66 Symbol* s = InstanceKlass::cast(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) { | |
73 const char * from = Klass::cast(caller)->external_name(); | |
74 const char * to = Klass::cast(to_class)->external_name(); | |
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"); | |
215 BasicType type = typeArrayKlass::cast(a->klass())->element_type(); | |
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) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
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"); | |
266 BasicType array_type = typeArrayKlass::cast(a->klass())->element_type(); | |
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) { |
0 | 316 BasicType type = typeArrayKlass::cast(basic_type_arrayklass)->element_type(); |
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); |
0 | 330 return typeArrayKlass::cast(tak)->allocate(length, THREAD); |
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); |
0 | 333 if (Klass::cast(k)->oop_is_array() && arrayKlass::cast(k)->dimension() >= MAX_DIM) { |
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"); | |
343 assert(typeArrayKlass::cast(dim_array->klass())->element_type() == T_INT, "just checking"); | |
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); |
0 | 369 if (Klass::cast(klass)->oop_is_array()) { |
370 int k_dim = arrayKlass::cast(klass)->dimension(); | |
371 if (k_dim + len > MAX_DIM) { | |
372 THROW_0(vmSymbols::java_lang_IllegalArgumentException()); | |
373 } | |
374 dim += k_dim; | |
375 } | |
376 } | |
377 klass = Klass::cast(klass)->array_klass(dim, CHECK_NULL); | |
378 oop obj = arrayKlass::cast(klass)->multi_allocate(len, dimensions, THREAD); | |
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); |
0 | 390 if (!Klass::cast(klass)->oop_is_array()) { |
391 return NULL; | |
392 } | |
393 | |
394 oop result = arrayKlass::cast(klass)->component_mirror(); | |
395 #ifdef ASSERT | |
396 oop result2 = NULL; | |
397 if (arrayKlass::cast(klass)->dimension() == 1) { | |
398 if (Klass::cast(klass)->oop_is_typeArray()) { | |
399 result2 = basic_type_arrayklass_to_mirror(klass, CHECK_NULL); | |
400 } else { | |
401 result2 = Klass::cast(objArrayKlass::cast(klass)->element_klass())->java_mirror(); | |
402 } | |
403 } else { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
404 Klass* lower_dim = arrayKlass::cast(klass)->lower_dimension(); |
0 | 405 assert(Klass::cast(lower_dim)->oop_is_array(), "just checking"); |
406 result2 = Klass::cast(lower_dim)->java_mirror(); | |
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)) { | |
445 if (!Klass::cast(target_class)->is_subclass_of(client_class)) { | |
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 | |
1142 | 471 && Klass::cast(current_class)->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) { |
0 | 472 return true; |
473 } | |
474 | |
475 return can_relax_access_check_for(current_class, new_class, classloader_only); | |
476 } | |
477 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
478 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
|
479 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
|
480 for (;;) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
481 Klass* hc = (Klass*) ik->host_klass(); |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
482 if (hc == NULL) return false; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
483 if (hc == host_klass) return true; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
484 ik = InstanceKlass::cast(hc); |
431
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
485 |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
486 // 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
|
487 // 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
|
488 // Still, let's check for it. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
489 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
|
490 } |
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 |
0 | 493 bool Reflection::can_relax_access_check_for( |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
494 Klass* accessor, Klass* accessee, bool classloader_only) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
495 InstanceKlass* accessor_ik = InstanceKlass::cast(accessor); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
496 InstanceKlass* accessee_ik = InstanceKlass::cast(accessee); |
431
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 // 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
|
499 // because one is inside the other. |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
500 if (under_host_klass(accessor_ik, accessee) || |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
501 under_host_klass(accessee_ik, accessor)) |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
502 return true; |
a45484ea312d
6653858: dynamic languages need to be able to load anonymous classes
jrose
parents:
196
diff
changeset
|
503 |
0 | 504 if (RelaxAccessControlCheck || |
505 (accessor_ik->major_version() < JAVA_1_5_VERSION && | |
506 accessee_ik->major_version() < JAVA_1_5_VERSION)) { | |
507 return classloader_only && | |
508 Verifier::relax_verify_for(accessor_ik->class_loader()) && | |
509 accessor_ik->protection_domain() == accessee_ik->protection_domain() && | |
510 accessor_ik->class_loader() == accessee_ik->class_loader(); | |
511 } else { | |
512 return false; | |
513 } | |
514 } | |
515 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
516 bool Reflection::verify_field_access(Klass* current_class, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
517 Klass* resolved_class, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
518 Klass* field_class, |
0 | 519 AccessFlags access, |
520 bool classloader_only, | |
521 bool protected_restriction) { | |
522 // Verify that current_class can access a field of field_class, where that | |
523 // field's access bits are "access". We assume that we've already verified | |
524 // that current_class can access field_class. | |
525 // | |
526 // If the classloader_only flag is set, we automatically allow any accesses | |
527 // in which current_class doesn't have a classloader. | |
528 // | |
529 // "resolved_class" is the runtime type of "field_class". Sometimes we don't | |
530 // need this distinction (e.g. if all we have is the runtime type, or during | |
531 // class file parsing when we only care about the static type); in that case | |
532 // callers should ensure that resolved_class == field_class. | |
533 // | |
534 if ((current_class == NULL) || | |
535 (current_class == field_class) || | |
536 access.is_public()) { | |
537 return true; | |
538 } | |
539 | |
540 if (access.is_protected()) { | |
541 if (!protected_restriction) { | |
542 // See if current_class is a subclass of field_class | |
543 if (Klass::cast(current_class)->is_subclass_of(field_class)) { | |
115 | 544 if (access.is_static() || // static fields are ok, see 6622385 |
545 current_class == resolved_class || | |
0 | 546 field_class == resolved_class || |
547 Klass::cast(current_class)->is_subclass_of(resolved_class) || | |
548 Klass::cast(resolved_class)->is_subclass_of(current_class)) { | |
549 return true; | |
550 } | |
551 } | |
552 } | |
553 } | |
554 | |
555 if (!access.is_private() && is_same_class_package(current_class, field_class)) { | |
556 return true; | |
557 } | |
558 | |
559 // New (1.4) reflection implementation. Allow all accesses from | |
560 // sun/reflect/MagicAccessorImpl subclasses to succeed trivially. | |
561 if ( JDK_Version::is_gte_jdk14x_version() | |
562 && UseNewReflection | |
1142 | 563 && Klass::cast(current_class)->is_subclass_of(SystemDictionary::reflect_MagicAccessorImpl_klass())) { |
0 | 564 return true; |
565 } | |
566 | |
567 return can_relax_access_check_for( | |
568 current_class, field_class, classloader_only); | |
569 } | |
570 | |
571 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
572 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
|
573 return InstanceKlass::cast(class1)->is_same_class_package(class2); |
0 | 574 } |
575 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
576 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
|
577 return InstanceKlass::cast(class1)->is_same_package_member(class2, THREAD); |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
578 } |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
579 |
0 | 580 |
581 // Checks that the 'outer' klass has declared 'inner' as being an inner klass. If not, | |
582 // throw an incompatible class change exception | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
583 // 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
|
584 // 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
|
585 // 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
|
586 void Reflection::check_for_inner_class(instanceKlassHandle outer, instanceKlassHandle inner, |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
587 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
|
588 InnerClassesIterator iter(outer); |
0 | 589 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
|
590 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
|
591 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
|
592 int ooff = iter.outer_class_info_index(); |
0 | 593 |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
594 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
|
595 Klass* o = cp->klass_at(ooff, CHECK); |
0 | 596 if (o == outer()) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
597 Klass* i = cp->klass_at(ioff, CHECK); |
0 | 598 if (i == inner()) { |
599 return; | |
600 } | |
601 } | |
602 } | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
603 if (!inner_is_member && ioff != 0 && ooff == 0 && |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
604 cp->klass_name_at_matches(inner, ioff)) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
605 Klass* i = cp->klass_at(ioff, CHECK); |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
606 if (i == inner()) { |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
607 return; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
608 } |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
431
diff
changeset
|
609 } |
0 | 610 } |
611 | |
612 // 'inner' not declared as an inner klass in outer | |
613 ResourceMark rm(THREAD); | |
614 Exceptions::fthrow( | |
615 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
616 vmSymbols::java_lang_IncompatibleClassChangeError(), |
0 | 617 "%s and %s disagree on InnerClasses attribute", |
618 outer->external_name(), | |
619 inner->external_name() | |
620 ); | |
621 } | |
622 | |
623 // Utility method converting a single SignatureStream element into java.lang.Class instance | |
624 | |
625 oop get_mirror_from_signature(methodHandle method, SignatureStream* ss, TRAPS) { | |
626 switch (ss->type()) { | |
627 default: | |
628 assert(ss->type() != T_VOID || ss->at_return_type(), "T_VOID should only appear as return type"); | |
629 return java_lang_Class::primitive_mirror(ss->type()); | |
630 case T_OBJECT: | |
631 case T_ARRAY: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
632 Symbol* name = ss->as_symbol(CHECK_NULL); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
633 oop loader = InstanceKlass::cast(method->method_holder())->class_loader(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
634 oop protection_domain = InstanceKlass::cast(method->method_holder())->protection_domain(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
635 Klass* k = SystemDictionary::resolve_or_fail( |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
636 name, |
0 | 637 Handle(THREAD, loader), |
638 Handle(THREAD, protection_domain), | |
639 true, CHECK_NULL); | |
640 if (TraceClassResolution) { | |
641 trace_class_resolution(k); | |
642 } | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2177
diff
changeset
|
643 return k->java_mirror(); |
0 | 644 }; |
645 } | |
646 | |
647 | |
648 objArrayHandle Reflection::get_parameter_types(methodHandle method, int parameter_count, oop* return_type, TRAPS) { | |
649 // Allocate array holding parameter types (java.lang.Class instances) | |
1142 | 650 objArrayOop m = oopFactory::new_objArray(SystemDictionary::Class_klass(), parameter_count, CHECK_(objArrayHandle())); |
0 | 651 objArrayHandle mirrors (THREAD, m); |
652 int index = 0; | |
653 // Collect parameter types | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
654 ResourceMark rm(THREAD); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
655 Symbol* signature = method->signature(); |
0 | 656 SignatureStream ss(signature); |
657 while (!ss.at_return_type()) { | |
658 oop mirror = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle())); | |
659 mirrors->obj_at_put(index++, mirror); | |
660 ss.next(); | |
661 } | |
662 assert(index == parameter_count, "invalid parameter count"); | |
663 if (return_type != NULL) { | |
664 // Collect return type as well | |
665 assert(ss.at_return_type(), "return type should be present"); | |
666 *return_type = get_mirror_from_signature(method, &ss, CHECK_(objArrayHandle())); | |
667 } | |
668 return mirrors; | |
669 } | |
670 | |
671 objArrayHandle Reflection::get_exception_types(methodHandle method, TRAPS) { | |
672 return method->resolved_checked_exceptions(CHECK_(objArrayHandle())); | |
673 } | |
674 | |
675 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
676 Handle Reflection::new_type(Symbol* signature, KlassHandle k, TRAPS) { |
0 | 677 // Basic types |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
678 BasicType type = vmSymbols::signature_type(signature); |
0 | 679 if (type != T_OBJECT) { |
680 return Handle(THREAD, Universe::java_mirror(type)); | |
681 } | |
682 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
683 oop loader = InstanceKlass::cast(k())->class_loader(); |
0 | 684 oop protection_domain = Klass::cast(k())->protection_domain(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
685 Klass* result = SystemDictionary::resolve_or_fail(signature, |
0 | 686 Handle(THREAD, loader), |
687 Handle(THREAD, protection_domain), | |
688 true, CHECK_(Handle())); | |
689 | |
690 if (TraceClassResolution) { | |
691 trace_class_resolution(result); | |
692 } | |
693 | |
694 oop nt = Klass::cast(result)->java_mirror(); | |
695 return Handle(THREAD, nt); | |
696 } | |
697 | |
698 | |
699 oop Reflection::new_method(methodHandle method, bool intern_name, bool for_constant_pool_access, TRAPS) { | |
700 // In jdk1.2.x, getMethods on an interface erroneously includes <clinit>, thus the complicated assert. | |
701 // Also allow sun.reflect.ConstantPool to refer to <clinit> methods as java.lang.reflect.Methods. | |
702 assert(!method()->is_initializer() || | |
703 (for_constant_pool_access && method()->is_static()) || | |
704 (method()->name() == vmSymbols::class_initializer_name() | |
705 && Klass::cast(method()->method_holder())->is_interface() && JDK_Version::is_jdk12x_version()), "should call new_constructor instead"); | |
706 instanceKlassHandle holder (THREAD, method->method_holder()); | |
707 int slot = method->method_idnum(); | |
708 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
709 Symbol* signature = method->signature(); |
0 | 710 int parameter_count = ArgumentCount(signature).size(); |
711 oop return_type_oop = NULL; | |
712 objArrayHandle parameter_types = get_parameter_types(method, parameter_count, &return_type_oop, CHECK_NULL); | |
713 if (parameter_types.is_null() || return_type_oop == NULL) return NULL; | |
714 | |
715 Handle return_type(THREAD, return_type_oop); | |
716 | |
717 objArrayHandle exception_types = get_exception_types(method, CHECK_NULL); | |
718 | |
719 if (exception_types.is_null()) return NULL; | |
720 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
721 Symbol* method_name = method->name(); |
0 | 722 Handle name; |
723 if (intern_name) { | |
724 // intern_name is only true with UseNewReflection | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
725 oop name_oop = StringTable::intern(method_name, CHECK_NULL); |
0 | 726 name = Handle(THREAD, name_oop); |
727 } else { | |
728 name = java_lang_String::create_from_symbol(method_name, CHECK_NULL); | |
729 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
730 if (name == NULL) return NULL; |
0 | 731 |
732 int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; | |
733 | |
734 Handle mh = java_lang_reflect_Method::create(CHECK_NULL); | |
735 | |
736 java_lang_reflect_Method::set_clazz(mh(), holder->java_mirror()); | |
737 java_lang_reflect_Method::set_slot(mh(), slot); | |
738 java_lang_reflect_Method::set_name(mh(), name()); | |
739 java_lang_reflect_Method::set_return_type(mh(), return_type()); | |
740 java_lang_reflect_Method::set_parameter_types(mh(), parameter_types()); | |
741 java_lang_reflect_Method::set_exception_types(mh(), exception_types()); | |
742 java_lang_reflect_Method::set_modifiers(mh(), modifiers); | |
743 java_lang_reflect_Method::set_override(mh(), false); | |
744 if (java_lang_reflect_Method::has_signature_field() && | |
745 method->generic_signature() != NULL) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
746 Symbol* gs = method->generic_signature(); |
0 | 747 Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL); |
748 java_lang_reflect_Method::set_signature(mh(), sig()); | |
749 } | |
750 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
|
751 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
|
752 java_lang_reflect_Method::set_annotations(mh(), an_oop); |
0 | 753 } |
754 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
|
755 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
|
756 java_lang_reflect_Method::set_parameter_annotations(mh(), an_oop); |
0 | 757 } |
758 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
|
759 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
|
760 java_lang_reflect_Method::set_annotation_default(mh(), an_oop); |
0 | 761 } |
762 return mh(); | |
763 } | |
764 | |
765 | |
766 oop Reflection::new_constructor(methodHandle method, TRAPS) { | |
767 assert(method()->is_initializer(), "should call new_method instead"); | |
768 | |
769 instanceKlassHandle holder (THREAD, method->method_holder()); | |
770 int slot = method->method_idnum(); | |
771 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
772 Symbol* signature = method->signature(); |
0 | 773 int parameter_count = ArgumentCount(signature).size(); |
774 objArrayHandle parameter_types = get_parameter_types(method, parameter_count, NULL, CHECK_NULL); | |
775 if (parameter_types.is_null()) return NULL; | |
776 | |
777 objArrayHandle exception_types = get_exception_types(method, CHECK_NULL); | |
778 if (exception_types.is_null()) return NULL; | |
779 | |
780 int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; | |
781 | |
782 Handle ch = java_lang_reflect_Constructor::create(CHECK_NULL); | |
783 | |
784 java_lang_reflect_Constructor::set_clazz(ch(), holder->java_mirror()); | |
785 java_lang_reflect_Constructor::set_slot(ch(), slot); | |
786 java_lang_reflect_Constructor::set_parameter_types(ch(), parameter_types()); | |
787 java_lang_reflect_Constructor::set_exception_types(ch(), exception_types()); | |
788 java_lang_reflect_Constructor::set_modifiers(ch(), modifiers); | |
789 java_lang_reflect_Constructor::set_override(ch(), false); | |
790 if (java_lang_reflect_Constructor::has_signature_field() && | |
791 method->generic_signature() != NULL) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
792 Symbol* gs = method->generic_signature(); |
0 | 793 Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL); |
794 java_lang_reflect_Constructor::set_signature(ch(), sig()); | |
795 } | |
796 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
|
797 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
|
798 java_lang_reflect_Constructor::set_annotations(ch(), an_oop); |
0 | 799 } |
800 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
|
801 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
|
802 java_lang_reflect_Constructor::set_parameter_annotations(ch(), an_oop); |
0 | 803 } |
804 return ch(); | |
805 } | |
806 | |
807 | |
808 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
|
809 Symbol* field_name = fd->name(); |
0 | 810 Handle name; |
811 if (intern_name) { | |
812 // intern_name is only true with UseNewReflection | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
813 oop name_oop = StringTable::intern(field_name, CHECK_NULL); |
0 | 814 name = Handle(THREAD, name_oop); |
815 } else { | |
816 name = java_lang_String::create_from_symbol(field_name, CHECK_NULL); | |
817 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
818 Symbol* signature = fd->signature(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
819 instanceKlassHandle holder (THREAD, fd->field_holder()); |
0 | 820 Handle type = new_type(signature, holder, CHECK_NULL); |
821 Handle rh = java_lang_reflect_Field::create(CHECK_NULL); | |
822 | |
823 java_lang_reflect_Field::set_clazz(rh(), Klass::cast(fd->field_holder())->java_mirror()); | |
824 java_lang_reflect_Field::set_slot(rh(), fd->index()); | |
825 java_lang_reflect_Field::set_name(rh(), name()); | |
826 java_lang_reflect_Field::set_type(rh(), type()); | |
827 // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here. | |
828 java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS); | |
829 java_lang_reflect_Field::set_override(rh(), false); | |
830 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
|
831 fd->has_generic_signature()) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
832 Symbol* gs = fd->generic_signature(); |
0 | 833 Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL); |
834 java_lang_reflect_Field::set_signature(rh(), sig()); | |
835 } | |
836 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
|
837 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
|
838 java_lang_reflect_Field::set_annotations(rh(), an_oop); |
0 | 839 } |
840 return rh(); | |
841 } | |
842 | |
843 | |
844 methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, methodHandle method, | |
845 KlassHandle recv_klass, Handle receiver, TRAPS) { | |
846 assert(!method.is_null() , "method should not be null"); | |
847 | |
848 CallInfo info; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
849 Symbol* signature = method->signature(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
850 Symbol* name = method->name(); |
0 | 851 LinkResolver::resolve_interface_call(info, receiver, recv_klass, klass, |
852 name, signature, | |
853 KlassHandle(), false, true, | |
854 CHECK_(methodHandle())); | |
855 return info.selected_method(); | |
856 } | |
857 | |
858 | |
859 oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method, | |
860 Handle receiver, bool override, objArrayHandle ptypes, | |
861 BasicType rtype, objArrayHandle args, bool is_method_invoke, TRAPS) { | |
862 ResourceMark rm(THREAD); | |
863 | |
864 methodHandle method; // actual method to invoke | |
865 KlassHandle target_klass; // target klass, receiver's klass for non-static | |
866 | |
867 // Ensure klass is initialized | |
868 klass->initialize(CHECK_NULL); | |
869 | |
870 bool is_static = reflected_method->is_static(); | |
871 if (is_static) { | |
872 // ignore receiver argument | |
873 method = reflected_method; | |
874 target_klass = klass; | |
875 } else { | |
876 // check for null receiver | |
877 if (receiver.is_null()) { | |
878 THROW_0(vmSymbols::java_lang_NullPointerException()); | |
879 } | |
880 // Check class of receiver against class declaring method | |
881 if (!receiver->is_a(klass())) { | |
882 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class"); | |
883 } | |
884 // target klass is receiver's klass | |
885 target_klass = KlassHandle(THREAD, receiver->klass()); | |
886 // no need to resolve if method is private or <init> | |
887 if (reflected_method->is_private() || reflected_method->name() == vmSymbols::object_initializer_name()) { | |
888 method = reflected_method; | |
889 } else { | |
890 // resolve based on the receiver | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
891 if (InstanceKlass::cast(reflected_method->method_holder())->is_interface()) { |
0 | 892 // resolve interface call |
893 if (ReflectionWrapResolutionErrors) { | |
894 // new default: 6531596 | |
895 // Match resolution errors with those thrown due to reflection inlining | |
896 // Linktime resolution & IllegalAccessCheck already done by Class.getMethod() | |
897 method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD); | |
898 if (HAS_PENDING_EXCEPTION) { | |
899 // Method resolution threw an exception; wrap it in an InvocationTargetException | |
900 oop resolution_exception = PENDING_EXCEPTION; | |
901 CLEAR_PENDING_EXCEPTION; | |
902 JavaCallArguments args(Handle(THREAD, resolution_exception)); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
903 THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
904 vmSymbols::throwable_void_signature(), |
0 | 905 &args); |
906 } | |
907 } else { | |
908 method = resolve_interface_call(klass, reflected_method, target_klass, receiver, CHECK_(NULL)); | |
909 } | |
910 } else { | |
911 // if the method can be overridden, we resolve using the vtable index. | |
912 int index = reflected_method->vtable_index(); | |
913 method = reflected_method; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
914 if (index != Method::nonvirtual_vtable_index) { |
0 | 915 // target_klass might be an arrayKlassOop but all vtables start at |
916 // 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
|
917 InstanceKlass* inst = (InstanceKlass*)target_klass(); |
0 | 918 method = methodHandle(THREAD, inst->method_at_vtable(index)); |
919 } | |
920 if (!method.is_null()) { | |
921 // Check for abstract methods as well | |
922 if (method->is_abstract()) { | |
923 // new default: 6531596 | |
924 if (ReflectionWrapResolutionErrors) { | |
925 ResourceMark rm(THREAD); | |
926 Handle h_origexception = Exceptions::new_exception(THREAD, | |
927 vmSymbols::java_lang_AbstractMethodError(), | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
928 Method::name_and_sig_as_C_string(Klass::cast(target_klass()), |
0 | 929 method->name(), |
930 method->signature())); | |
931 JavaCallArguments args(h_origexception); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
932 THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
933 vmSymbols::throwable_void_signature(), |
0 | 934 &args); |
935 } else { | |
936 ResourceMark rm(THREAD); | |
937 THROW_MSG_0(vmSymbols::java_lang_AbstractMethodError(), | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
938 Method::name_and_sig_as_C_string(Klass::cast(target_klass()), |
0 | 939 method->name(), |
940 method->signature())); | |
941 } | |
942 } | |
943 } | |
944 } | |
945 } | |
946 } | |
947 | |
948 // I believe this is a ShouldNotGetHere case which requires | |
949 // an internal vtable bug. If you ever get this please let Karen know. | |
950 if (method.is_null()) { | |
951 ResourceMark rm(THREAD); | |
952 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
953 Method::name_and_sig_as_C_string(Klass::cast(klass()), |
0 | 954 reflected_method->name(), |
955 reflected_method->signature())); | |
956 } | |
957 | |
958 // In the JDK 1.4 reflection implementation, the security check is | |
959 // done at the Java level | |
960 if (!(JDK_Version::is_gte_jdk14x_version() && UseNewReflection)) { | |
961 | |
962 // Access checking (unless overridden by Method) | |
963 if (!override) { | |
964 if (!(klass->is_public() && reflected_method->is_public())) { | |
965 bool access = Reflection::reflect_check_access(klass(), reflected_method->access_flags(), target_klass(), is_method_invoke, CHECK_NULL); | |
966 if (!access) { | |
967 return NULL; // exception | |
968 } | |
969 } | |
970 } | |
971 | |
972 } // !(Universe::is_gte_jdk14x_version() && UseNewReflection) | |
973 | |
974 assert(ptypes->is_objArray(), "just checking"); | |
975 int args_len = args.is_null() ? 0 : args->length(); | |
976 // Check number of arguments | |
977 if (ptypes->length() != args_len) { | |
978 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "wrong number of arguments"); | |
979 } | |
980 | |
981 // Create object to contain parameters for the JavaCall | |
982 JavaCallArguments java_args(method->size_of_parameters()); | |
983 | |
984 if (!is_static) { | |
985 java_args.push_oop(receiver); | |
986 } | |
987 | |
988 for (int i = 0; i < args_len; i++) { | |
989 oop type_mirror = ptypes->obj_at(i); | |
990 oop arg = args->obj_at(i); | |
991 if (java_lang_Class::is_primitive(type_mirror)) { | |
992 jvalue value; | |
993 BasicType ptype = basic_type_mirror_to_basic_type(type_mirror, CHECK_NULL); | |
994 BasicType atype = unbox_for_primitive(arg, &value, CHECK_NULL); | |
995 if (ptype != atype) { | |
996 widen(&value, atype, ptype, CHECK_NULL); | |
997 } | |
998 switch (ptype) { | |
999 case T_BOOLEAN: java_args.push_int(value.z); break; | |
1000 case T_CHAR: java_args.push_int(value.c); break; | |
1001 case T_BYTE: java_args.push_int(value.b); break; | |
1002 case T_SHORT: java_args.push_int(value.s); break; | |
1003 case T_INT: java_args.push_int(value.i); break; | |
1004 case T_LONG: java_args.push_long(value.j); break; | |
1005 case T_FLOAT: java_args.push_float(value.f); break; | |
1006 case T_DOUBLE: java_args.push_double(value.d); break; | |
1007 default: | |
1008 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); | |
1009 } | |
1010 } else { | |
1011 if (arg != NULL) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1012 Klass* k = java_lang_Class::as_Klass(type_mirror); |
0 | 1013 if (!arg->is_a(k)) { |
1014 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); | |
1015 } | |
1016 } | |
1017 Handle arg_handle(THREAD, arg); // Create handle for argument | |
1018 java_args.push_oop(arg_handle); // Push handle | |
1019 } | |
1020 } | |
1021 | |
1022 assert(java_args.size_of_parameters() == method->size_of_parameters(), "just checking"); | |
1023 | |
1024 // All oops (including receiver) is passed in as Handles. An potential oop is returned as an | |
1025 // oop (i.e., NOT as an handle) | |
1026 JavaValue result(rtype); | |
1027 JavaCalls::call(&result, method, &java_args, THREAD); | |
1028 | |
1029 if (HAS_PENDING_EXCEPTION) { | |
1030 // Method threw an exception; wrap it in an InvocationTargetException | |
1031 oop target_exception = PENDING_EXCEPTION; | |
1032 CLEAR_PENDING_EXCEPTION; | |
1033 JavaCallArguments args(Handle(THREAD, target_exception)); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1034 THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1035 vmSymbols::throwable_void_signature(), |
0 | 1036 &args); |
1037 } else { | |
1038 if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT) | |
1039 narrow((jvalue*) result.get_value_addr(), rtype, CHECK_NULL); | |
1040 return box((jvalue*) result.get_value_addr(), rtype, CHECK_NULL); | |
1041 } | |
1042 } | |
1043 | |
1044 | |
1045 void Reflection::narrow(jvalue* value, BasicType narrow_type, TRAPS) { | |
1046 switch (narrow_type) { | |
1047 case T_BOOLEAN: | |
1048 value->z = (jboolean) value->i; | |
1049 return; | |
1050 case T_BYTE: | |
1051 value->b = (jbyte) value->i; | |
1052 return; | |
1053 case T_CHAR: | |
1054 value->c = (jchar) value->i; | |
1055 return; | |
1056 case T_SHORT: | |
1057 value->s = (jshort) value->i; | |
1058 return; | |
1059 default: | |
1060 break; // fail | |
1061 } | |
1062 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); | |
1063 } | |
1064 | |
1065 | |
1066 BasicType Reflection::basic_type_mirror_to_basic_type(oop basic_type_mirror, TRAPS) { | |
1067 assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking"); | |
1068 return java_lang_Class::primitive_type(basic_type_mirror); | |
1069 } | |
1070 | |
1071 // This would be nicer if, say, java.lang.reflect.Method was a subclass | |
1072 // of java.lang.reflect.Constructor | |
1073 | |
1074 oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS) { | |
1075 oop mirror = java_lang_reflect_Method::clazz(method_mirror); | |
1076 int slot = java_lang_reflect_Method::slot(method_mirror); | |
1077 bool override = java_lang_reflect_Method::override(method_mirror) != 0; | |
1078 objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Method::parameter_types(method_mirror))); | |
1079 | |
1080 oop return_type_mirror = java_lang_reflect_Method::return_type(method_mirror); | |
1081 BasicType rtype; | |
1082 if (java_lang_Class::is_primitive(return_type_mirror)) { | |
1083 rtype = basic_type_mirror_to_basic_type(return_type_mirror, CHECK_NULL); | |
1084 } else { | |
1085 rtype = T_OBJECT; | |
1086 } | |
1087 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1088 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
|
1089 Method* m = klass->method_with_idnum(slot); |
51
1ffa5cdd0b7e
6667089: 3/3 multiple redefinitions of a class break reflection
dcubed
parents:
0
diff
changeset
|
1090 if (m == NULL) { |
0 | 1091 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke"); |
1092 } | |
51
1ffa5cdd0b7e
6667089: 3/3 multiple redefinitions of a class break reflection
dcubed
parents:
0
diff
changeset
|
1093 methodHandle method(THREAD, m); |
0 | 1094 |
1095 return invoke(klass, method, receiver, override, ptypes, rtype, args, true, THREAD); | |
1096 } | |
1097 | |
1098 | |
1099 oop Reflection::invoke_constructor(oop constructor_mirror, objArrayHandle args, TRAPS) { | |
1100 oop mirror = java_lang_reflect_Constructor::clazz(constructor_mirror); | |
1101 int slot = java_lang_reflect_Constructor::slot(constructor_mirror); | |
1102 bool override = java_lang_reflect_Constructor::override(constructor_mirror) != 0; | |
1103 objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror))); | |
1104 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1105 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
|
1106 Method* m = klass->method_with_idnum(slot); |
51
1ffa5cdd0b7e
6667089: 3/3 multiple redefinitions of a class break reflection
dcubed
parents:
0
diff
changeset
|
1107 if (m == NULL) { |
0 | 1108 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke"); |
1109 } | |
51
1ffa5cdd0b7e
6667089: 3/3 multiple redefinitions of a class break reflection
dcubed
parents:
0
diff
changeset
|
1110 methodHandle method(THREAD, m); |
0 | 1111 assert(method->name() == vmSymbols::object_initializer_name(), "invalid constructor"); |
1112 | |
1113 // Make sure klass gets initialize | |
1114 klass->initialize(CHECK_NULL); | |
1115 | |
1116 // Create new instance (the receiver) | |
1117 klass->check_valid_for_instantiation(false, CHECK_NULL); | |
1118 Handle receiver = klass->allocate_instance_handle(CHECK_NULL); | |
1119 | |
1120 // Ignore result from call and return receiver | |
1121 invoke(klass, method, receiver, override, ptypes, T_VOID, args, false, CHECK_NULL); | |
1122 return receiver(); | |
1123 } |