comparison src/share/vm/prims/jvm.cpp @ 3938:e6b1331a51d2

7086585: make Java field injection more flexible Reviewed-by: jrose, twisti, kvn, coleenp
author never
date Sat, 10 Sep 2011 17:29:02 -0700
parents 19241ae0d839
children f08d439fab8c
comparison
equal deleted inserted replaced
3937:c565834fb592 3938:e6b1331a51d2
30 #include "classfile/systemDictionary.hpp" 30 #include "classfile/systemDictionary.hpp"
31 #include "classfile/vmSymbols.hpp" 31 #include "classfile/vmSymbols.hpp"
32 #include "gc_interface/collectedHeap.inline.hpp" 32 #include "gc_interface/collectedHeap.inline.hpp"
33 #include "memory/oopFactory.hpp" 33 #include "memory/oopFactory.hpp"
34 #include "memory/universe.inline.hpp" 34 #include "memory/universe.inline.hpp"
35 #include "oops/fieldStreams.hpp"
35 #include "oops/instanceKlass.hpp" 36 #include "oops/instanceKlass.hpp"
36 #include "oops/objArrayKlass.hpp" 37 #include "oops/objArrayKlass.hpp"
37 #include "prims/jvm.h" 38 #include "prims/jvm.h"
38 #include "prims/jvm_misc.hpp" 39 #include "prims/jvm_misc.hpp"
39 #include "prims/jvmtiExport.hpp" 40 #include "prims/jvmtiExport.hpp"
1491 int slot = java_lang_reflect_Field::slot(reflected); 1492 int slot = java_lang_reflect_Field::slot(reflected);
1492 int modifiers = java_lang_reflect_Field::modifiers(reflected); 1493 int modifiers = java_lang_reflect_Field::modifiers(reflected);
1493 1494
1494 fieldDescriptor fd; 1495 fieldDescriptor fd;
1495 KlassHandle kh(THREAD, k); 1496 KlassHandle kh(THREAD, k);
1496 intptr_t offset = instanceKlass::cast(kh())->offset_from_fields(slot); 1497 intptr_t offset = instanceKlass::cast(kh())->field_offset(slot);
1497 1498
1498 if (modifiers & JVM_ACC_STATIC) { 1499 if (modifiers & JVM_ACC_STATIC) {
1499 // for static fields we only look in the current class 1500 // for static fields we only look in the current class
1500 if (!instanceKlass::cast(kh())->find_local_field_from_offset(offset, 1501 if (!instanceKlass::cast(kh())->find_local_field_from_offset(offset,
1501 true, &fd)) { 1502 true, &fd)) {
1591 constantPoolHandle cp(THREAD, k->constants()); 1592 constantPoolHandle cp(THREAD, k->constants());
1592 1593
1593 // Ensure class is linked 1594 // Ensure class is linked
1594 k->link_class(CHECK_NULL); 1595 k->link_class(CHECK_NULL);
1595 1596
1596 typeArrayHandle fields(THREAD, k->fields());
1597 int fields_len = fields->length();
1598
1599 // 4496456 We need to filter out java.lang.Throwable.backtrace 1597 // 4496456 We need to filter out java.lang.Throwable.backtrace
1600 bool skip_backtrace = false; 1598 bool skip_backtrace = false;
1601 1599
1602 // Allocate result 1600 // Allocate result
1603 int num_fields; 1601 int num_fields;
1604 1602
1605 if (publicOnly) { 1603 if (publicOnly) {
1606 num_fields = 0; 1604 num_fields = 0;
1607 for (int i = 0, j = 0; i < fields_len; i += instanceKlass::next_offset, j++) { 1605 for (JavaFieldStream fs(k()); !fs.done(); fs.next()) {
1608 int mods = fields->ushort_at(i + instanceKlass::access_flags_offset) & JVM_RECOGNIZED_FIELD_MODIFIERS; 1606 if (fs.access_flags().is_public()) ++num_fields;
1609 if (mods & JVM_ACC_PUBLIC) ++num_fields;
1610 } 1607 }
1611 } else { 1608 } else {
1612 num_fields = fields_len / instanceKlass::next_offset; 1609 num_fields = k->java_fields_count();
1613 1610
1614 if (k() == SystemDictionary::Throwable_klass()) { 1611 if (k() == SystemDictionary::Throwable_klass()) {
1615 num_fields--; 1612 num_fields--;
1616 skip_backtrace = true; 1613 skip_backtrace = true;
1617 } 1614 }
1620 objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), num_fields, CHECK_NULL); 1617 objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Field_klass(), num_fields, CHECK_NULL);
1621 objArrayHandle result (THREAD, r); 1618 objArrayHandle result (THREAD, r);
1622 1619
1623 int out_idx = 0; 1620 int out_idx = 0;
1624 fieldDescriptor fd; 1621 fieldDescriptor fd;
1625 for (int i = 0; i < fields_len; i += instanceKlass::next_offset) { 1622 for (JavaFieldStream fs(k); !fs.done(); fs.next()) {
1626 if (skip_backtrace) { 1623 if (skip_backtrace) {
1627 // 4496456 skip java.lang.Throwable.backtrace 1624 // 4496456 skip java.lang.Throwable.backtrace
1628 int offset = k->offset_from_fields(i); 1625 int offset = fs.offset();
1629 if (offset == java_lang_Throwable::get_backtrace_offset()) continue; 1626 if (offset == java_lang_Throwable::get_backtrace_offset()) continue;
1630 } 1627 }
1631 1628
1632 int mods = fields->ushort_at(i + instanceKlass::access_flags_offset) & JVM_RECOGNIZED_FIELD_MODIFIERS; 1629 if (!publicOnly || fs.access_flags().is_public()) {
1633 if (!publicOnly || (mods & JVM_ACC_PUBLIC)) { 1630 fd.initialize(k(), fs.index());
1634 fd.initialize(k(), i);
1635 oop field = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL); 1631 oop field = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL);
1636 result->obj_at_put(out_idx, field); 1632 result->obj_at_put(out_idx, field);
1637 ++out_idx; 1633 ++out_idx;
1638 } 1634 }
1639 } 1635 }
2117 JVMWrapper("JVM_GetClassFieldsCount"); 2113 JVMWrapper("JVM_GetClassFieldsCount");
2118 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); 2114 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls));
2119 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); 2115 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
2120 if (!Klass::cast(k)->oop_is_instance()) 2116 if (!Klass::cast(k)->oop_is_instance())
2121 return 0; 2117 return 0;
2122 return instanceKlass::cast(k)->fields()->length() / instanceKlass::next_offset; 2118 return instanceKlass::cast(k)->java_fields_count();
2123 JVM_END 2119 JVM_END
2124 2120
2125 2121
2126 JVM_QUICK_ENTRY(jint, JVM_GetClassMethodsCount(JNIEnv *env, jclass cls)) 2122 JVM_QUICK_ENTRY(jint, JVM_GetClassMethodsCount(JNIEnv *env, jclass cls))
2127 JVMWrapper("JVM_GetClassMethodsCount"); 2123 JVMWrapper("JVM_GetClassMethodsCount");
2213 2209
2214 JVM_QUICK_ENTRY(jint, JVM_GetFieldIxModifiers(JNIEnv *env, jclass cls, int field_index)) 2210 JVM_QUICK_ENTRY(jint, JVM_GetFieldIxModifiers(JNIEnv *env, jclass cls, int field_index))
2215 JVMWrapper("JVM_GetFieldIxModifiers"); 2211 JVMWrapper("JVM_GetFieldIxModifiers");
2216 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); 2212 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls));
2217 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); 2213 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
2218 typeArrayOop fields = instanceKlass::cast(k)->fields(); 2214 return instanceKlass::cast(k)->field_access_flags(field_index) & JVM_RECOGNIZED_FIELD_MODIFIERS;
2219 return fields->ushort_at(field_index * instanceKlass::next_offset + instanceKlass::access_flags_offset) & JVM_RECOGNIZED_FIELD_MODIFIERS;
2220 JVM_END 2215 JVM_END
2221 2216
2222 2217
2223 JVM_QUICK_ENTRY(jint, JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cls, int method_index)) 2218 JVM_QUICK_ENTRY(jint, JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cls, int method_index))
2224 JVMWrapper("JVM_GetMethodIxLocalsCount"); 2219 JVMWrapper("JVM_GetMethodIxLocalsCount");
2397 ShouldNotReachHere(); 2392 ShouldNotReachHere();
2398 return NULL; 2393 return NULL;
2399 JVM_END 2394 JVM_END
2400 2395
2401 2396
2402 JVM_QUICK_ENTRY(jint, JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls)) 2397 JVM_ENTRY(jint, JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls))
2403 JVMWrapper("JVM_GetCPFieldModifiers"); 2398 JVMWrapper("JVM_GetCPFieldModifiers");
2404 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls)); 2399 klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls));
2405 klassOop k_called = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(called_cls)); 2400 klassOop k_called = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(called_cls));
2406 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread); 2401 k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
2407 k_called = JvmtiThreadState::class_to_verify_considering_redefinition(k_called, thread); 2402 k_called = JvmtiThreadState::class_to_verify_considering_redefinition(k_called, thread);
2409 constantPoolOop cp_called = instanceKlass::cast(k_called)->constants(); 2404 constantPoolOop cp_called = instanceKlass::cast(k_called)->constants();
2410 switch (cp->tag_at(cp_index).value()) { 2405 switch (cp->tag_at(cp_index).value()) {
2411 case JVM_CONSTANT_Fieldref: { 2406 case JVM_CONSTANT_Fieldref: {
2412 Symbol* name = cp->uncached_name_ref_at(cp_index); 2407 Symbol* name = cp->uncached_name_ref_at(cp_index);
2413 Symbol* signature = cp->uncached_signature_ref_at(cp_index); 2408 Symbol* signature = cp->uncached_signature_ref_at(cp_index);
2414 typeArrayOop fields = instanceKlass::cast(k_called)->fields(); 2409 for (JavaFieldStream fs(k_called); !fs.done(); fs.next()) {
2415 int fields_count = fields->length(); 2410 if (fs.name() == name && fs.signature() == signature) {
2416 for (int i = 0; i < fields_count; i += instanceKlass::next_offset) { 2411 return fs.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS;
2417 if (cp_called->symbol_at(fields->ushort_at(i + instanceKlass::name_index_offset)) == name &&
2418 cp_called->symbol_at(fields->ushort_at(i + instanceKlass::signature_index_offset)) == signature) {
2419 return fields->ushort_at(i + instanceKlass::access_flags_offset) & JVM_RECOGNIZED_FIELD_MODIFIERS;
2420 } 2412 }
2421 } 2413 }
2422 return -1; 2414 return -1;
2423 } 2415 }
2424 default: 2416 default: