comparison src/share/vm/prims/jvm.cpp @ 12287:0f37d1badced

Merge
author dcubed
date Fri, 20 Sep 2013 12:58:35 -0700
parents b2e698d2276c 4f9a42c33738
children a07c25e4f67e 675ffabf3798
comparison
equal deleted inserted replaced
12271:bf13c3da3d11 12287:0f37d1badced
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 {