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