Mercurial > hg > truffle
comparison src/share/vm/classfile/systemDictionary.cpp @ 710:e5b0439ef4ae
6655638: dynamic languages need method handles
Summary: initial implementation, with known omissions (x86/64, sparc, compiler optim., c-oops, C++ interp.)
Reviewed-by: kvn, twisti, never
author | jrose |
---|---|
date | Wed, 08 Apr 2009 10:56:49 -0700 |
parents | c89f86385056 |
children | be93aad57795 |
comparison
equal
deleted
inserted
replaced
709:1d037ecd7960 | 710:e5b0439ef4ae |
---|---|
29 Dictionary* SystemDictionary::_dictionary = NULL; | 29 Dictionary* SystemDictionary::_dictionary = NULL; |
30 PlaceholderTable* SystemDictionary::_placeholders = NULL; | 30 PlaceholderTable* SystemDictionary::_placeholders = NULL; |
31 Dictionary* SystemDictionary::_shared_dictionary = NULL; | 31 Dictionary* SystemDictionary::_shared_dictionary = NULL; |
32 LoaderConstraintTable* SystemDictionary::_loader_constraints = NULL; | 32 LoaderConstraintTable* SystemDictionary::_loader_constraints = NULL; |
33 ResolutionErrorTable* SystemDictionary::_resolution_errors = NULL; | 33 ResolutionErrorTable* SystemDictionary::_resolution_errors = NULL; |
34 SymbolPropertyTable* SystemDictionary::_invoke_method_table = NULL; | |
34 | 35 |
35 | 36 |
36 int SystemDictionary::_number_of_modifications = 0; | 37 int SystemDictionary::_number_of_modifications = 0; |
37 | 38 |
38 oop SystemDictionary::_system_loader_lock_obj = NULL; | 39 oop SystemDictionary::_system_loader_lock_obj = NULL; |
964 // java.lang.Object through resolve_or_fail, not this path. | 965 // java.lang.Object through resolve_or_fail, not this path. |
965 | 966 |
966 instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name, | 967 instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name, |
967 class_loader, | 968 class_loader, |
968 protection_domain, | 969 protection_domain, |
970 host_klass, | |
971 cp_patches, | |
969 parsed_name, | 972 parsed_name, |
970 THREAD); | 973 THREAD); |
971 | 974 |
972 | 975 |
973 // We don't redefine the class, so we just need to clean up whether there | 976 // We don't redefine the class, so we just need to clean up whether there |
1689 | 1692 |
1690 // Placeholders. These are *always* strong roots, as they | 1693 // Placeholders. These are *always* strong roots, as they |
1691 // represent classes we're actively loading. | 1694 // represent classes we're actively loading. |
1692 placeholders_do(blk); | 1695 placeholders_do(blk); |
1693 | 1696 |
1697 // Visit extra methods | |
1698 if (invoke_method_table() != NULL) | |
1699 invoke_method_table()->oops_do(blk); | |
1700 | |
1694 // Loader constraints. We must keep the symbolOop used in the name alive. | 1701 // Loader constraints. We must keep the symbolOop used in the name alive. |
1695 constraints()->always_strong_classes_do(blk); | 1702 constraints()->always_strong_classes_do(blk); |
1696 | 1703 |
1697 // Resolution errors keep the symbolOop for the error alive | 1704 // Resolution errors keep the symbolOop for the error alive |
1698 resolution_errors()->always_strong_classes_do(blk); | 1705 resolution_errors()->always_strong_classes_do(blk); |
1724 lazily_loaded_oops_do(f); | 1731 lazily_loaded_oops_do(f); |
1725 | 1732 |
1726 // Adjust dictionary | 1733 // Adjust dictionary |
1727 dictionary()->oops_do(f); | 1734 dictionary()->oops_do(f); |
1728 | 1735 |
1736 // Visit extra methods | |
1737 if (invoke_method_table() != NULL) | |
1738 invoke_method_table()->oops_do(f); | |
1739 | |
1729 // Partially loaded classes | 1740 // Partially loaded classes |
1730 placeholders()->oops_do(f); | 1741 placeholders()->oops_do(f); |
1731 | 1742 |
1732 // Adjust constraint table | 1743 // Adjust constraint table |
1733 constraints()->oops_do(f); | 1744 constraints()->oops_do(f); |
1796 placeholders()->entries_do(f); | 1807 placeholders()->entries_do(f); |
1797 } | 1808 } |
1798 | 1809 |
1799 void SystemDictionary::methods_do(void f(methodOop)) { | 1810 void SystemDictionary::methods_do(void f(methodOop)) { |
1800 dictionary()->methods_do(f); | 1811 dictionary()->methods_do(f); |
1812 if (invoke_method_table() != NULL) | |
1813 invoke_method_table()->methods_do(f); | |
1801 } | 1814 } |
1802 | 1815 |
1803 // ---------------------------------------------------------------------------- | 1816 // ---------------------------------------------------------------------------- |
1804 // Lazily load klasses | 1817 // Lazily load klasses |
1805 | 1818 |
1828 _dictionary = new Dictionary(_nof_buckets); | 1841 _dictionary = new Dictionary(_nof_buckets); |
1829 _placeholders = new PlaceholderTable(_nof_buckets); | 1842 _placeholders = new PlaceholderTable(_nof_buckets); |
1830 _number_of_modifications = 0; | 1843 _number_of_modifications = 0; |
1831 _loader_constraints = new LoaderConstraintTable(_loader_constraint_size); | 1844 _loader_constraints = new LoaderConstraintTable(_loader_constraint_size); |
1832 _resolution_errors = new ResolutionErrorTable(_resolution_error_size); | 1845 _resolution_errors = new ResolutionErrorTable(_resolution_error_size); |
1846 // _invoke_method_table is allocated lazily in find_method_handle_invoke() | |
1833 | 1847 |
1834 // Allocate private object used as system class loader lock | 1848 // Allocate private object used as system class loader lock |
1835 _system_loader_lock_obj = oopFactory::new_system_objArray(0, CHECK); | 1849 _system_loader_lock_obj = oopFactory::new_system_objArray(0, CHECK); |
1836 // Initialize basic classes | 1850 // Initialize basic classes |
1837 initialize_preloaded_classes(CHECK); | 1851 initialize_preloaded_classes(CHECK); |
1889 wk_klass_name_limits[1] = s; | 1903 wk_klass_name_limits[1] = s; |
1890 } else if (wk_klass_name_limits[0] > s) { | 1904 } else if (wk_klass_name_limits[0] > s) { |
1891 wk_klass_name_limits[0] = s; | 1905 wk_klass_name_limits[0] = s; |
1892 } | 1906 } |
1893 } | 1907 } |
1908 | |
1909 // move the starting value forward to the limit: | |
1910 start_id = limit_id; | |
1894 } | 1911 } |
1895 | 1912 |
1896 | 1913 |
1897 void SystemDictionary::initialize_preloaded_classes(TRAPS) { | 1914 void SystemDictionary::initialize_preloaded_classes(TRAPS) { |
1898 assert(WK_KLASS(object_klass) == NULL, "preloaded classes should only be initialized once"); | 1915 assert(WK_KLASS(object_klass) == NULL, "preloaded classes should only be initialized once"); |
1921 initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(phantom_reference_klass), scan, CHECK); | 1938 initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(phantom_reference_klass), scan, CHECK); |
1922 instanceKlass::cast(WK_KLASS(soft_reference_klass))->set_reference_type(REF_SOFT); | 1939 instanceKlass::cast(WK_KLASS(soft_reference_klass))->set_reference_type(REF_SOFT); |
1923 instanceKlass::cast(WK_KLASS(weak_reference_klass))->set_reference_type(REF_WEAK); | 1940 instanceKlass::cast(WK_KLASS(weak_reference_klass))->set_reference_type(REF_WEAK); |
1924 instanceKlass::cast(WK_KLASS(final_reference_klass))->set_reference_type(REF_FINAL); | 1941 instanceKlass::cast(WK_KLASS(final_reference_klass))->set_reference_type(REF_FINAL); |
1925 instanceKlass::cast(WK_KLASS(phantom_reference_klass))->set_reference_type(REF_PHANTOM); | 1942 instanceKlass::cast(WK_KLASS(phantom_reference_klass))->set_reference_type(REF_PHANTOM); |
1943 | |
1944 WKID meth_group_start = WK_KLASS_ENUM_NAME(MethodHandle_klass); | |
1945 WKID meth_group_end = WK_KLASS_ENUM_NAME(WrongMethodTypeException_klass); | |
1946 initialize_wk_klasses_until(meth_group_start, scan, CHECK); | |
1947 if (EnableMethodHandles) { | |
1948 initialize_wk_klasses_through(meth_group_start, scan, CHECK); | |
1949 } | |
1950 if (_well_known_klasses[meth_group_start] == NULL) { | |
1951 // Skip the rest of the method handle classes, if MethodHandle is not loaded. | |
1952 scan = WKID(meth_group_end+1); | |
1953 } | |
1926 | 1954 |
1927 initialize_wk_klasses_until(WKID_LIMIT, scan, CHECK); | 1955 initialize_wk_klasses_until(WKID_LIMIT, scan, CHECK); |
1928 | 1956 |
1929 _box_klasses[T_BOOLEAN] = WK_KLASS(boolean_klass); | 1957 _box_klasses[T_BOOLEAN] = WK_KLASS(boolean_klass); |
1930 _box_klasses[T_CHAR] = WK_KLASS(char_klass); | 1958 _box_klasses[T_CHAR] = WK_KLASS(char_klass); |
2252 } | 2280 } |
2253 return NULL; | 2281 return NULL; |
2254 } | 2282 } |
2255 | 2283 |
2256 | 2284 |
2285 methodOop SystemDictionary::find_method_handle_invoke(symbolHandle signature, | |
2286 Handle class_loader, | |
2287 Handle protection_domain, | |
2288 TRAPS) { | |
2289 if (!EnableMethodHandles) return NULL; | |
2290 assert(class_loader.is_null() && protection_domain.is_null(), | |
2291 "cannot load specialized versions of MethodHandle.invoke"); | |
2292 if (invoke_method_table() == NULL) { | |
2293 // create this side table lazily | |
2294 _invoke_method_table = new SymbolPropertyTable(_invoke_method_size); | |
2295 } | |
2296 unsigned int hash = invoke_method_table()->compute_hash(signature); | |
2297 int index = invoke_method_table()->hash_to_index(hash); | |
2298 SymbolPropertyEntry* spe = invoke_method_table()->find_entry(index, hash, signature); | |
2299 if (spe == NULL || spe->property_oop() == NULL) { | |
2300 // Must create lots of stuff here, but outside of the SystemDictionary lock. | |
2301 Handle mt = compute_method_handle_type(signature(), | |
2302 class_loader, protection_domain, | |
2303 CHECK_NULL); | |
2304 KlassHandle mh_klass = SystemDictionaryHandles::MethodHandle_klass(); | |
2305 methodHandle m = methodOopDesc::make_invoke_method(mh_klass, signature, | |
2306 mt, CHECK_NULL); | |
2307 // Now grab the lock. We might have to throw away the new method, | |
2308 // if a racing thread has managed to install one at the same time. | |
2309 { | |
2310 MutexLocker ml(SystemDictionary_lock, Thread::current()); | |
2311 spe = invoke_method_table()->find_entry(index, hash, signature); | |
2312 if (spe == NULL) | |
2313 spe = invoke_method_table()->add_entry(index, hash, signature); | |
2314 if (spe->property_oop() == NULL) | |
2315 spe->set_property_oop(m()); | |
2316 } | |
2317 } | |
2318 methodOop m = (methodOop) spe->property_oop(); | |
2319 assert(m->is_method(), ""); | |
2320 return m; | |
2321 } | |
2322 | |
2323 // Ask Java code to find or construct a java.dyn.MethodType for the given | |
2324 // signature, as interpreted relative to the given class loader. | |
2325 // Because of class loader constraints, all method handle usage must be | |
2326 // consistent with this loader. | |
2327 Handle SystemDictionary::compute_method_handle_type(symbolHandle signature, | |
2328 Handle class_loader, | |
2329 Handle protection_domain, | |
2330 TRAPS) { | |
2331 Handle empty; | |
2332 int npts = ArgumentCount(signature()).size(); | |
2333 objArrayHandle pts = oopFactory::new_objArray(SystemDictionary::class_klass(), npts, CHECK_(empty)); | |
2334 int arg = 0; | |
2335 Handle rt; // the return type from the signature | |
2336 for (SignatureStream ss(signature()); !ss.is_done(); ss.next()) { | |
2337 oop mirror; | |
2338 if (!ss.is_object()) { | |
2339 mirror = Universe::java_mirror(ss.type()); | |
2340 } else { | |
2341 symbolOop name_oop = ss.as_symbol(CHECK_(empty)); | |
2342 symbolHandle name(THREAD, name_oop); | |
2343 klassOop klass = resolve_or_fail(name, | |
2344 class_loader, protection_domain, | |
2345 true, CHECK_(empty)); | |
2346 mirror = Klass::cast(klass)->java_mirror(); | |
2347 } | |
2348 if (ss.at_return_type()) | |
2349 rt = Handle(THREAD, mirror); | |
2350 else | |
2351 pts->obj_at_put(arg++, mirror); | |
2352 } | |
2353 assert(arg == npts, ""); | |
2354 | |
2355 // call MethodType java.dyn.MethodType::makeImpl(Class rt, Class[] pts, false, true) | |
2356 bool varargs = false, trusted = true; | |
2357 JavaCallArguments args(Handle(THREAD, rt())); | |
2358 args.push_oop(pts()); | |
2359 args.push_int(false); | |
2360 args.push_int(trusted); | |
2361 JavaValue result(T_OBJECT); | |
2362 JavaCalls::call_static(&result, | |
2363 SystemDictionary::MethodType_klass(), | |
2364 vmSymbols::makeImpl_name(), vmSymbols::makeImpl_signature(), | |
2365 &args, CHECK_(empty)); | |
2366 return Handle(THREAD, (oop) result.get_jobject()); | |
2367 } | |
2368 | |
2369 | |
2257 // Since the identity hash code for symbols changes when the symbols are | 2370 // Since the identity hash code for symbols changes when the symbols are |
2258 // moved from the regular perm gen (hash in the mark word) to the shared | 2371 // moved from the regular perm gen (hash in the mark word) to the shared |
2259 // spaces (hash is the address), the classes loaded into the dictionary | 2372 // spaces (hash is the address), the classes loaded into the dictionary |
2260 // may be in the wrong buckets. | 2373 // may be in the wrong buckets. |
2261 | 2374 |