1833 assert(out_idx == num_fields, "just checking"); |
1833 assert(out_idx == num_fields, "just checking"); |
1834 return (jobjectArray) JNIHandles::make_local(env, result()); |
1834 return (jobjectArray) JNIHandles::make_local(env, result()); |
1835 } |
1835 } |
1836 JVM_END |
1836 JVM_END |
1837 |
1837 |
1838 JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly)) |
1838 static bool select_method(methodHandle method, bool want_constructor) { |
1839 { |
1839 if (want_constructor) { |
1840 JVMWrapper("JVM_GetClassDeclaredMethods"); |
1840 return (method->is_initializer() && !method->is_static()); |
|
1841 } else { |
|
1842 return (!method->is_initializer() && !method->is_overpass()); |
|
1843 } |
|
1844 } |
|
1845 |
|
1846 static jobjectArray get_class_declared_methods_helper( |
|
1847 JNIEnv *env, |
|
1848 jclass ofClass, jboolean publicOnly, |
|
1849 bool want_constructor, |
|
1850 Klass* klass, TRAPS) { |
|
1851 |
1841 JvmtiVMObjectAllocEventCollector oam; |
1852 JvmtiVMObjectAllocEventCollector oam; |
1842 |
1853 |
1843 // Exclude primitive types and array types |
1854 // Exclude primitive types and array types |
1844 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) |
1855 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) |
1845 || java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) { |
1856 || java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) { |
1846 // Return empty array |
1857 // Return empty array |
1847 oop res = oopFactory::new_objArray(SystemDictionary::reflect_Method_klass(), 0, CHECK_NULL); |
1858 oop res = oopFactory::new_objArray(klass, 0, CHECK_NULL); |
1848 return (jobjectArray) JNIHandles::make_local(env, res); |
1859 return (jobjectArray) JNIHandles::make_local(env, res); |
1849 } |
1860 } |
1850 |
1861 |
1851 instanceKlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))); |
1862 instanceKlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))); |
1852 |
1863 |
1853 // Ensure class is linked |
1864 // Ensure class is linked |
1854 k->link_class(CHECK_NULL); |
1865 k->link_class(CHECK_NULL); |
1855 |
1866 |
1856 Array<Method*>* methods = k->methods(); |
1867 Array<Method*>* methods = k->methods(); |
1857 int methods_length = methods->length(); |
1868 int methods_length = methods->length(); |
|
1869 |
|
1870 // Save original method_idnum in case of redefinition, which can change |
|
1871 // the idnum of obsolete methods. The new method will have the same idnum |
|
1872 // but if we refresh the methods array, the counts will be wrong. |
|
1873 ResourceMark rm(THREAD); |
|
1874 GrowableArray<int>* idnums = new GrowableArray<int>(methods_length); |
1858 int num_methods = 0; |
1875 int num_methods = 0; |
1859 |
1876 |
1860 int i; |
1877 for (int i = 0; i < methods_length; i++) { |
1861 for (i = 0; i < methods_length; i++) { |
|
1862 methodHandle method(THREAD, methods->at(i)); |
1878 methodHandle method(THREAD, methods->at(i)); |
1863 if (!method->is_initializer() && !method->is_overpass()) { |
1879 if (select_method(method, want_constructor)) { |
1864 if (!publicOnly || method->is_public()) { |
1880 if (!publicOnly || method->is_public()) { |
|
1881 idnums->push(method->method_idnum()); |
1865 ++num_methods; |
1882 ++num_methods; |
1866 } |
1883 } |
1867 } |
1884 } |
1868 } |
1885 } |
1869 |
1886 |
1870 // Allocate result |
1887 // Allocate result |
1871 objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Method_klass(), num_methods, CHECK_NULL); |
1888 objArrayOop r = oopFactory::new_objArray(klass, num_methods, CHECK_NULL); |
1872 objArrayHandle result (THREAD, r); |
1889 objArrayHandle result (THREAD, r); |
1873 |
1890 |
1874 int out_idx = 0; |
1891 // Now just put the methods that we selected above, but go by their idnum |
1875 for (i = 0; i < methods_length; i++) { |
1892 // in case of redefinition. The methods can be redefined at any safepoint, |
1876 methodHandle method(THREAD, methods->at(i)); |
1893 // so above when allocating the oop array and below when creating reflect |
1877 if (!method->is_initializer() && !method->is_overpass()) { |
1894 // objects. |
1878 if (!publicOnly || method->is_public()) { |
1895 for (int i = 0; i < num_methods; i++) { |
1879 oop m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL); |
1896 methodHandle method(THREAD, k->method_with_idnum(idnums->at(i))); |
1880 result->obj_at_put(out_idx, m); |
1897 if (method.is_null()) { |
1881 ++out_idx; |
1898 // Method may have been deleted and seems this API can handle null |
|
1899 // Otherwise should probably put a method that throws NSME |
|
1900 result->obj_at_put(i, NULL); |
|
1901 } else { |
|
1902 oop m; |
|
1903 if (want_constructor) { |
|
1904 m = Reflection::new_constructor(method, CHECK_NULL); |
|
1905 } else { |
|
1906 m = Reflection::new_method(method, UseNewReflection, false, CHECK_NULL); |
1882 } |
1907 } |
1883 } |
1908 result->obj_at_put(i, m); |
1884 } |
1909 } |
1885 assert(out_idx == num_methods, "just checking"); |
1910 } |
|
1911 |
1886 return (jobjectArray) JNIHandles::make_local(env, result()); |
1912 return (jobjectArray) JNIHandles::make_local(env, result()); |
|
1913 } |
|
1914 |
|
1915 JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly)) |
|
1916 { |
|
1917 JVMWrapper("JVM_GetClassDeclaredMethods"); |
|
1918 return get_class_declared_methods_helper(env, ofClass, publicOnly, |
|
1919 /*want_constructor*/ false, |
|
1920 SystemDictionary::reflect_Method_klass(), THREAD); |
1887 } |
1921 } |
1888 JVM_END |
1922 JVM_END |
1889 |
1923 |
1890 JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly)) |
1924 JVM_ENTRY(jobjectArray, JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly)) |
1891 { |
1925 { |
1892 JVMWrapper("JVM_GetClassDeclaredConstructors"); |
1926 JVMWrapper("JVM_GetClassDeclaredConstructors"); |
1893 JvmtiVMObjectAllocEventCollector oam; |
1927 return get_class_declared_methods_helper(env, ofClass, publicOnly, |
1894 |
1928 /*want_constructor*/ true, |
1895 // Exclude primitive types and array types |
1929 SystemDictionary::reflect_Constructor_klass(), THREAD); |
1896 if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(ofClass)) |
|
1897 || java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))->oop_is_array()) { |
|
1898 // Return empty array |
|
1899 oop res = oopFactory::new_objArray(SystemDictionary::reflect_Constructor_klass(), 0 , CHECK_NULL); |
|
1900 return (jobjectArray) JNIHandles::make_local(env, res); |
|
1901 } |
|
1902 |
|
1903 instanceKlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(ofClass))); |
|
1904 |
|
1905 // Ensure class is linked |
|
1906 k->link_class(CHECK_NULL); |
|
1907 |
|
1908 Array<Method*>* methods = k->methods(); |
|
1909 int methods_length = methods->length(); |
|
1910 int num_constructors = 0; |
|
1911 |
|
1912 int i; |
|
1913 for (i = 0; i < methods_length; i++) { |
|
1914 methodHandle method(THREAD, methods->at(i)); |
|
1915 if (method->is_initializer() && !method->is_static()) { |
|
1916 if (!publicOnly || method->is_public()) { |
|
1917 ++num_constructors; |
|
1918 } |
|
1919 } |
|
1920 } |
|
1921 |
|
1922 // Allocate result |
|
1923 objArrayOop r = oopFactory::new_objArray(SystemDictionary::reflect_Constructor_klass(), num_constructors, CHECK_NULL); |
|
1924 objArrayHandle result(THREAD, r); |
|
1925 |
|
1926 int out_idx = 0; |
|
1927 for (i = 0; i < methods_length; i++) { |
|
1928 methodHandle method(THREAD, methods->at(i)); |
|
1929 if (method->is_initializer() && !method->is_static()) { |
|
1930 if (!publicOnly || method->is_public()) { |
|
1931 oop m = Reflection::new_constructor(method, CHECK_NULL); |
|
1932 result->obj_at_put(out_idx, m); |
|
1933 ++out_idx; |
|
1934 } |
|
1935 } |
|
1936 } |
|
1937 assert(out_idx == num_constructors, "just checking"); |
|
1938 return (jobjectArray) JNIHandles::make_local(env, result()); |
|
1939 } |
1930 } |
1940 JVM_END |
1931 JVM_END |
1941 |
1932 |
1942 JVM_ENTRY(jint, JVM_GetClassAccessFlags(JNIEnv *env, jclass cls)) |
1933 JVM_ENTRY(jint, JVM_GetClassAccessFlags(JNIEnv *env, jclass cls)) |
1943 { |
1934 { |