Mercurial > hg > graal-compiler
annotate src/share/vm/runtime/reflection.cpp @ 7588:f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
Summary: This patch addresses an alignment trap due to the storage format of method parameters data in constMethod. It also adds code to validate constant pool indexes for method parameters data.
Reviewed-by: jrose, dholmes
Contributed-by: eric.mccorkle@oracle.com
author | coleenp |
---|---|
date | Mon, 14 Jan 2013 11:01:39 -0500 |
parents | ade95d680b42 |
children | a589c78a8811 |
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 } |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
6983
diff
changeset
|
774 if (java_lang_reflect_Method::has_type_annotations_field()) { |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
6983
diff
changeset
|
775 typeArrayOop an_oop = Annotations::make_java_array(method->type_annotations(), CHECK_NULL); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
6983
diff
changeset
|
776 java_lang_reflect_Method::set_type_annotations(mh(), an_oop); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
6983
diff
changeset
|
777 } |
0 | 778 return mh(); |
779 } | |
780 | |
781 | |
782 oop Reflection::new_constructor(methodHandle method, TRAPS) { | |
783 assert(method()->is_initializer(), "should call new_method instead"); | |
784 | |
785 instanceKlassHandle holder (THREAD, method->method_holder()); | |
786 int slot = method->method_idnum(); | |
787 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
788 Symbol* signature = method->signature(); |
0 | 789 int parameter_count = ArgumentCount(signature).size(); |
790 objArrayHandle parameter_types = get_parameter_types(method, parameter_count, NULL, CHECK_NULL); | |
791 if (parameter_types.is_null()) return NULL; | |
792 | |
793 objArrayHandle exception_types = get_exception_types(method, CHECK_NULL); | |
794 if (exception_types.is_null()) return NULL; | |
795 | |
796 int modifiers = method->access_flags().as_int() & JVM_RECOGNIZED_METHOD_MODIFIERS; | |
797 | |
798 Handle ch = java_lang_reflect_Constructor::create(CHECK_NULL); | |
799 | |
800 java_lang_reflect_Constructor::set_clazz(ch(), holder->java_mirror()); | |
801 java_lang_reflect_Constructor::set_slot(ch(), slot); | |
802 java_lang_reflect_Constructor::set_parameter_types(ch(), parameter_types()); | |
803 java_lang_reflect_Constructor::set_exception_types(ch(), exception_types()); | |
804 java_lang_reflect_Constructor::set_modifiers(ch(), modifiers); | |
805 java_lang_reflect_Constructor::set_override(ch(), false); | |
806 if (java_lang_reflect_Constructor::has_signature_field() && | |
807 method->generic_signature() != NULL) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
808 Symbol* gs = method->generic_signature(); |
0 | 809 Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL); |
810 java_lang_reflect_Constructor::set_signature(ch(), sig()); | |
811 } | |
812 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
|
813 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
|
814 java_lang_reflect_Constructor::set_annotations(ch(), an_oop); |
0 | 815 } |
816 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
|
817 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
|
818 java_lang_reflect_Constructor::set_parameter_annotations(ch(), an_oop); |
0 | 819 } |
820 return ch(); | |
821 } | |
822 | |
823 | |
824 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
|
825 Symbol* field_name = fd->name(); |
0 | 826 Handle name; |
827 if (intern_name) { | |
828 // intern_name is only true with UseNewReflection | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
829 oop name_oop = StringTable::intern(field_name, CHECK_NULL); |
0 | 830 name = Handle(THREAD, name_oop); |
831 } else { | |
832 name = java_lang_String::create_from_symbol(field_name, CHECK_NULL); | |
833 } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
834 Symbol* signature = fd->signature(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
835 instanceKlassHandle holder (THREAD, fd->field_holder()); |
0 | 836 Handle type = new_type(signature, holder, CHECK_NULL); |
837 Handle rh = java_lang_reflect_Field::create(CHECK_NULL); | |
838 | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
839 java_lang_reflect_Field::set_clazz(rh(), fd->field_holder()->java_mirror()); |
0 | 840 java_lang_reflect_Field::set_slot(rh(), fd->index()); |
841 java_lang_reflect_Field::set_name(rh(), name()); | |
842 java_lang_reflect_Field::set_type(rh(), type()); | |
843 // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here. | |
844 java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS); | |
845 java_lang_reflect_Field::set_override(rh(), false); | |
846 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
|
847 fd->has_generic_signature()) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
848 Symbol* gs = fd->generic_signature(); |
0 | 849 Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL); |
850 java_lang_reflect_Field::set_signature(rh(), sig()); | |
851 } | |
852 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
|
853 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
|
854 java_lang_reflect_Field::set_annotations(rh(), an_oop); |
0 | 855 } |
7457
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
6983
diff
changeset
|
856 if (java_lang_reflect_Field::has_type_annotations_field()) { |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
6983
diff
changeset
|
857 typeArrayOop an_oop = Annotations::make_java_array(fd->type_annotations(), CHECK_NULL); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
6983
diff
changeset
|
858 java_lang_reflect_Field::set_type_annotations(rh(), an_oop); |
35431a769282
8004823: Add VM support for type annotation reflection
stefank
parents:
6983
diff
changeset
|
859 } |
0 | 860 return rh(); |
861 } | |
862 | |
7462
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
863 oop Reflection::new_parameter(Handle method, int index, Symbol* sym, |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
864 int flags, TRAPS) { |
7588
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7462
diff
changeset
|
865 Handle name; |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7462
diff
changeset
|
866 |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7462
diff
changeset
|
867 // A null symbol here translates to the empty string |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7462
diff
changeset
|
868 if(NULL != sym) { |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7462
diff
changeset
|
869 name = java_lang_String::create_from_symbol(sym, CHECK_NULL); |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7462
diff
changeset
|
870 } else { |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7462
diff
changeset
|
871 name = java_lang_String::create_from_str("", CHECK_NULL); |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7462
diff
changeset
|
872 } |
f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
coleenp
parents:
7462
diff
changeset
|
873 |
7462
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
874 Handle rh = java_lang_reflect_Parameter::create(CHECK_NULL); |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
875 java_lang_reflect_Parameter::set_name(rh(), name()); |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
876 java_lang_reflect_Parameter::set_modifiers(rh(), flags); |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
877 java_lang_reflect_Parameter::set_executable(rh(), method()); |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
878 java_lang_reflect_Parameter::set_index(rh(), index); |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
879 return rh(); |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
880 } |
ade95d680b42
8004728: Add hotspot support for parameter reflection
coleenp
parents:
7457
diff
changeset
|
881 |
0 | 882 |
883 methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, methodHandle method, | |
884 KlassHandle recv_klass, Handle receiver, TRAPS) { | |
885 assert(!method.is_null() , "method should not be null"); | |
886 | |
887 CallInfo info; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
888 Symbol* signature = method->signature(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
889 Symbol* name = method->name(); |
0 | 890 LinkResolver::resolve_interface_call(info, receiver, recv_klass, klass, |
891 name, signature, | |
892 KlassHandle(), false, true, | |
893 CHECK_(methodHandle())); | |
894 return info.selected_method(); | |
895 } | |
896 | |
897 | |
898 oop Reflection::invoke(instanceKlassHandle klass, methodHandle reflected_method, | |
899 Handle receiver, bool override, objArrayHandle ptypes, | |
900 BasicType rtype, objArrayHandle args, bool is_method_invoke, TRAPS) { | |
901 ResourceMark rm(THREAD); | |
902 | |
903 methodHandle method; // actual method to invoke | |
904 KlassHandle target_klass; // target klass, receiver's klass for non-static | |
905 | |
906 // Ensure klass is initialized | |
907 klass->initialize(CHECK_NULL); | |
908 | |
909 bool is_static = reflected_method->is_static(); | |
910 if (is_static) { | |
911 // ignore receiver argument | |
912 method = reflected_method; | |
913 target_klass = klass; | |
914 } else { | |
915 // check for null receiver | |
916 if (receiver.is_null()) { | |
917 THROW_0(vmSymbols::java_lang_NullPointerException()); | |
918 } | |
919 // Check class of receiver against class declaring method | |
920 if (!receiver->is_a(klass())) { | |
921 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "object is not an instance of declaring class"); | |
922 } | |
923 // target klass is receiver's klass | |
924 target_klass = KlassHandle(THREAD, receiver->klass()); | |
925 // no need to resolve if method is private or <init> | |
926 if (reflected_method->is_private() || reflected_method->name() == vmSymbols::object_initializer_name()) { | |
927 method = reflected_method; | |
928 } else { | |
929 // 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
|
930 if (reflected_method->method_holder()->is_interface()) { |
0 | 931 // resolve interface call |
932 if (ReflectionWrapResolutionErrors) { | |
933 // new default: 6531596 | |
934 // Match resolution errors with those thrown due to reflection inlining | |
935 // Linktime resolution & IllegalAccessCheck already done by Class.getMethod() | |
936 method = resolve_interface_call(klass, reflected_method, target_klass, receiver, THREAD); | |
937 if (HAS_PENDING_EXCEPTION) { | |
938 // Method resolution threw an exception; wrap it in an InvocationTargetException | |
939 oop resolution_exception = PENDING_EXCEPTION; | |
940 CLEAR_PENDING_EXCEPTION; | |
941 JavaCallArguments args(Handle(THREAD, resolution_exception)); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
942 THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
943 vmSymbols::throwable_void_signature(), |
0 | 944 &args); |
945 } | |
946 } else { | |
947 method = resolve_interface_call(klass, reflected_method, target_klass, receiver, CHECK_(NULL)); | |
948 } | |
949 } else { | |
950 // if the method can be overridden, we resolve using the vtable index. | |
951 int index = reflected_method->vtable_index(); | |
952 method = reflected_method; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
953 if (index != Method::nonvirtual_vtable_index) { |
0 | 954 // target_klass might be an arrayKlassOop but all vtables start at |
955 // 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
|
956 InstanceKlass* inst = (InstanceKlass*)target_klass(); |
0 | 957 method = methodHandle(THREAD, inst->method_at_vtable(index)); |
958 } | |
959 if (!method.is_null()) { | |
960 // Check for abstract methods as well | |
961 if (method->is_abstract()) { | |
962 // new default: 6531596 | |
963 if (ReflectionWrapResolutionErrors) { | |
964 ResourceMark rm(THREAD); | |
965 Handle h_origexception = Exceptions::new_exception(THREAD, | |
966 vmSymbols::java_lang_AbstractMethodError(), | |
6983 | 967 Method::name_and_sig_as_C_string(target_klass(), |
0 | 968 method->name(), |
969 method->signature())); | |
970 JavaCallArguments args(h_origexception); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
971 THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
972 vmSymbols::throwable_void_signature(), |
0 | 973 &args); |
974 } else { | |
975 ResourceMark rm(THREAD); | |
976 THROW_MSG_0(vmSymbols::java_lang_AbstractMethodError(), | |
6983 | 977 Method::name_and_sig_as_C_string(target_klass(), |
0 | 978 method->name(), |
979 method->signature())); | |
980 } | |
981 } | |
982 } | |
983 } | |
984 } | |
985 } | |
986 | |
987 // I believe this is a ShouldNotGetHere case which requires | |
988 // an internal vtable bug. If you ever get this please let Karen know. | |
989 if (method.is_null()) { | |
990 ResourceMark rm(THREAD); | |
991 THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), | |
6983 | 992 Method::name_and_sig_as_C_string(klass(), |
0 | 993 reflected_method->name(), |
994 reflected_method->signature())); | |
995 } | |
996 | |
997 // In the JDK 1.4 reflection implementation, the security check is | |
998 // done at the Java level | |
999 if (!(JDK_Version::is_gte_jdk14x_version() && UseNewReflection)) { | |
1000 | |
1001 // Access checking (unless overridden by Method) | |
1002 if (!override) { | |
1003 if (!(klass->is_public() && reflected_method->is_public())) { | |
1004 bool access = Reflection::reflect_check_access(klass(), reflected_method->access_flags(), target_klass(), is_method_invoke, CHECK_NULL); | |
1005 if (!access) { | |
1006 return NULL; // exception | |
1007 } | |
1008 } | |
1009 } | |
1010 | |
1011 } // !(Universe::is_gte_jdk14x_version() && UseNewReflection) | |
1012 | |
1013 assert(ptypes->is_objArray(), "just checking"); | |
1014 int args_len = args.is_null() ? 0 : args->length(); | |
1015 // Check number of arguments | |
1016 if (ptypes->length() != args_len) { | |
1017 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "wrong number of arguments"); | |
1018 } | |
1019 | |
1020 // Create object to contain parameters for the JavaCall | |
1021 JavaCallArguments java_args(method->size_of_parameters()); | |
1022 | |
1023 if (!is_static) { | |
1024 java_args.push_oop(receiver); | |
1025 } | |
1026 | |
1027 for (int i = 0; i < args_len; i++) { | |
1028 oop type_mirror = ptypes->obj_at(i); | |
1029 oop arg = args->obj_at(i); | |
1030 if (java_lang_Class::is_primitive(type_mirror)) { | |
1031 jvalue value; | |
1032 BasicType ptype = basic_type_mirror_to_basic_type(type_mirror, CHECK_NULL); | |
1033 BasicType atype = unbox_for_primitive(arg, &value, CHECK_NULL); | |
1034 if (ptype != atype) { | |
1035 widen(&value, atype, ptype, CHECK_NULL); | |
1036 } | |
1037 switch (ptype) { | |
1038 case T_BOOLEAN: java_args.push_int(value.z); break; | |
1039 case T_CHAR: java_args.push_int(value.c); break; | |
1040 case T_BYTE: java_args.push_int(value.b); break; | |
1041 case T_SHORT: java_args.push_int(value.s); break; | |
1042 case T_INT: java_args.push_int(value.i); break; | |
1043 case T_LONG: java_args.push_long(value.j); break; | |
1044 case T_FLOAT: java_args.push_float(value.f); break; | |
1045 case T_DOUBLE: java_args.push_double(value.d); break; | |
1046 default: | |
1047 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); | |
1048 } | |
1049 } else { | |
1050 if (arg != NULL) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1051 Klass* k = java_lang_Class::as_Klass(type_mirror); |
0 | 1052 if (!arg->is_a(k)) { |
1053 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); | |
1054 } | |
1055 } | |
1056 Handle arg_handle(THREAD, arg); // Create handle for argument | |
1057 java_args.push_oop(arg_handle); // Push handle | |
1058 } | |
1059 } | |
1060 | |
1061 assert(java_args.size_of_parameters() == method->size_of_parameters(), "just checking"); | |
1062 | |
1063 // All oops (including receiver) is passed in as Handles. An potential oop is returned as an | |
1064 // oop (i.e., NOT as an handle) | |
1065 JavaValue result(rtype); | |
1066 JavaCalls::call(&result, method, &java_args, THREAD); | |
1067 | |
1068 if (HAS_PENDING_EXCEPTION) { | |
1069 // Method threw an exception; wrap it in an InvocationTargetException | |
1070 oop target_exception = PENDING_EXCEPTION; | |
1071 CLEAR_PENDING_EXCEPTION; | |
1072 JavaCallArguments args(Handle(THREAD, target_exception)); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1073 THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1074 vmSymbols::throwable_void_signature(), |
0 | 1075 &args); |
1076 } else { | |
1077 if (rtype == T_BOOLEAN || rtype == T_BYTE || rtype == T_CHAR || rtype == T_SHORT) | |
1078 narrow((jvalue*) result.get_value_addr(), rtype, CHECK_NULL); | |
1079 return box((jvalue*) result.get_value_addr(), rtype, CHECK_NULL); | |
1080 } | |
1081 } | |
1082 | |
1083 | |
1084 void Reflection::narrow(jvalue* value, BasicType narrow_type, TRAPS) { | |
1085 switch (narrow_type) { | |
1086 case T_BOOLEAN: | |
1087 value->z = (jboolean) value->i; | |
1088 return; | |
1089 case T_BYTE: | |
1090 value->b = (jbyte) value->i; | |
1091 return; | |
1092 case T_CHAR: | |
1093 value->c = (jchar) value->i; | |
1094 return; | |
1095 case T_SHORT: | |
1096 value->s = (jshort) value->i; | |
1097 return; | |
1098 default: | |
1099 break; // fail | |
1100 } | |
1101 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "argument type mismatch"); | |
1102 } | |
1103 | |
1104 | |
1105 BasicType Reflection::basic_type_mirror_to_basic_type(oop basic_type_mirror, TRAPS) { | |
1106 assert(java_lang_Class::is_primitive(basic_type_mirror), "just checking"); | |
1107 return java_lang_Class::primitive_type(basic_type_mirror); | |
1108 } | |
1109 | |
1110 // This would be nicer if, say, java.lang.reflect.Method was a subclass | |
1111 // of java.lang.reflect.Constructor | |
1112 | |
1113 oop Reflection::invoke_method(oop method_mirror, Handle receiver, objArrayHandle args, TRAPS) { | |
1114 oop mirror = java_lang_reflect_Method::clazz(method_mirror); | |
1115 int slot = java_lang_reflect_Method::slot(method_mirror); | |
1116 bool override = java_lang_reflect_Method::override(method_mirror) != 0; | |
1117 objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Method::parameter_types(method_mirror))); | |
1118 | |
1119 oop return_type_mirror = java_lang_reflect_Method::return_type(method_mirror); | |
1120 BasicType rtype; | |
1121 if (java_lang_Class::is_primitive(return_type_mirror)) { | |
1122 rtype = basic_type_mirror_to_basic_type(return_type_mirror, CHECK_NULL); | |
1123 } else { | |
1124 rtype = T_OBJECT; | |
1125 } | |
1126 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1127 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
|
1128 Method* m = klass->method_with_idnum(slot); |
51
1ffa5cdd0b7e
6667089: 3/3 multiple redefinitions of a class break reflection
dcubed
parents:
0
diff
changeset
|
1129 if (m == NULL) { |
0 | 1130 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke"); |
1131 } | |
51
1ffa5cdd0b7e
6667089: 3/3 multiple redefinitions of a class break reflection
dcubed
parents:
0
diff
changeset
|
1132 methodHandle method(THREAD, m); |
0 | 1133 |
1134 return invoke(klass, method, receiver, override, ptypes, rtype, args, true, THREAD); | |
1135 } | |
1136 | |
1137 | |
1138 oop Reflection::invoke_constructor(oop constructor_mirror, objArrayHandle args, TRAPS) { | |
1139 oop mirror = java_lang_reflect_Constructor::clazz(constructor_mirror); | |
1140 int slot = java_lang_reflect_Constructor::slot(constructor_mirror); | |
1141 bool override = java_lang_reflect_Constructor::override(constructor_mirror) != 0; | |
1142 objArrayHandle ptypes(THREAD, objArrayOop(java_lang_reflect_Constructor::parameter_types(constructor_mirror))); | |
1143 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1144 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
|
1145 Method* m = klass->method_with_idnum(slot); |
51
1ffa5cdd0b7e
6667089: 3/3 multiple redefinitions of a class break reflection
dcubed
parents:
0
diff
changeset
|
1146 if (m == NULL) { |
0 | 1147 THROW_MSG_0(vmSymbols::java_lang_InternalError(), "invoke"); |
1148 } | |
51
1ffa5cdd0b7e
6667089: 3/3 multiple redefinitions of a class break reflection
dcubed
parents:
0
diff
changeset
|
1149 methodHandle method(THREAD, m); |
0 | 1150 assert(method->name() == vmSymbols::object_initializer_name(), "invalid constructor"); |
1151 | |
1152 // Make sure klass gets initialize | |
1153 klass->initialize(CHECK_NULL); | |
1154 | |
1155 // Create new instance (the receiver) | |
1156 klass->check_valid_for_instantiation(false, CHECK_NULL); | |
1157 Handle receiver = klass->allocate_instance_handle(CHECK_NULL); | |
1158 | |
1159 // Ignore result from call and return receiver | |
1160 invoke(klass, method, receiver, override, ptypes, T_VOID, args, false, CHECK_NULL); | |
1161 return receiver(); | |
1162 } |