Mercurial > hg > truffle
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: |