Mercurial > hg > truffle
comparison src/share/vm/classfile/javaClasses.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 |
---|---|
23 */ | 23 */ |
24 | 24 |
25 # include "incls/_precompiled.incl" | 25 # include "incls/_precompiled.incl" |
26 # include "incls/_javaClasses.cpp.incl" | 26 # include "incls/_javaClasses.cpp.incl" |
27 | 27 |
28 static bool find_field(instanceKlass* ik, | |
29 symbolOop name_symbol, symbolOop signature_symbol, | |
30 fieldDescriptor* fd, | |
31 bool allow_super = false) { | |
32 if (allow_super) | |
33 return ik->find_field(name_symbol, signature_symbol, fd) != NULL; | |
34 else | |
35 return ik->find_local_field(name_symbol, signature_symbol, fd); | |
36 } | |
37 | |
28 // Helpful routine for computing field offsets at run time rather than hardcoding them | 38 // Helpful routine for computing field offsets at run time rather than hardcoding them |
29 static void | 39 static void |
30 compute_offset(int &dest_offset, | 40 compute_offset(int &dest_offset, |
31 klassOop klass_oop, symbolOop name_symbol, symbolOop signature_symbol) { | 41 klassOop klass_oop, symbolOop name_symbol, symbolOop signature_symbol, |
42 bool allow_super = false) { | |
32 fieldDescriptor fd; | 43 fieldDescriptor fd; |
33 instanceKlass* ik = instanceKlass::cast(klass_oop); | 44 instanceKlass* ik = instanceKlass::cast(klass_oop); |
34 if (!ik->find_local_field(name_symbol, signature_symbol, &fd)) { | 45 if (!find_field(ik, name_symbol, signature_symbol, &fd, allow_super)) { |
35 ResourceMark rm; | 46 ResourceMark rm; |
36 tty->print_cr("Invalid layout of %s at %s", ik->external_name(), name_symbol->as_C_string()); | 47 tty->print_cr("Invalid layout of %s at %s", ik->external_name(), name_symbol->as_C_string()); |
37 fatal("Invalid layout of preloaded class"); | 48 fatal("Invalid layout of preloaded class"); |
38 } | 49 } |
39 dest_offset = fd.offset(); | 50 dest_offset = fd.offset(); |
40 } | 51 } |
41 | 52 |
42 // Same as above but for "optional" offsets that might not be present in certain JDK versions | 53 // Same as above but for "optional" offsets that might not be present in certain JDK versions |
43 static void | 54 static void |
44 compute_optional_offset(int& dest_offset, | 55 compute_optional_offset(int& dest_offset, |
45 klassOop klass_oop, symbolOop name_symbol, symbolOop signature_symbol) { | 56 klassOop klass_oop, symbolOop name_symbol, symbolOop signature_symbol, |
57 bool allow_super = false) { | |
46 fieldDescriptor fd; | 58 fieldDescriptor fd; |
47 instanceKlass* ik = instanceKlass::cast(klass_oop); | 59 instanceKlass* ik = instanceKlass::cast(klass_oop); |
48 if (ik->find_local_field(name_symbol, signature_symbol, &fd)) { | 60 if (find_field(ik, name_symbol, signature_symbol, &fd, allow_super)) { |
49 dest_offset = fd.offset(); | 61 dest_offset = fd.offset(); |
50 } | 62 } |
51 } | 63 } |
64 | |
52 | 65 |
53 Handle java_lang_String::basic_create(int length, bool tenured, TRAPS) { | 66 Handle java_lang_String::basic_create(int length, bool tenured, TRAPS) { |
54 // Create the String object first, so there's a chance that the String | 67 // Create the String object first, so there's a chance that the String |
55 // and the char array it points to end up in the same cache line. | 68 // and the char array it points to end up in the same cache line. |
56 oop obj; | 69 oop obj; |
2105 | 2118 |
2106 SystemDictionary::soft_reference_klass()->long_field_put(offset, value); | 2119 SystemDictionary::soft_reference_klass()->long_field_put(offset, value); |
2107 } | 2120 } |
2108 | 2121 |
2109 | 2122 |
2123 // Support for java_dyn_MethodHandle | |
2124 | |
2125 int java_dyn_MethodHandle::_type_offset; | |
2126 int java_dyn_MethodHandle::_vmtarget_offset; | |
2127 int java_dyn_MethodHandle::_vmentry_offset; | |
2128 int java_dyn_MethodHandle::_vmslots_offset; | |
2129 | |
2130 int sun_dyn_MemberName::_clazz_offset; | |
2131 int sun_dyn_MemberName::_name_offset; | |
2132 int sun_dyn_MemberName::_type_offset; | |
2133 int sun_dyn_MemberName::_flags_offset; | |
2134 int sun_dyn_MemberName::_vmtarget_offset; | |
2135 int sun_dyn_MemberName::_vmindex_offset; | |
2136 | |
2137 int sun_dyn_DirectMethodHandle::_vmindex_offset; | |
2138 | |
2139 int sun_dyn_BoundMethodHandle::_argument_offset; | |
2140 int sun_dyn_BoundMethodHandle::_vmargslot_offset; | |
2141 | |
2142 int sun_dyn_AdapterMethodHandle::_conversion_offset; | |
2143 | |
2144 void java_dyn_MethodHandle::compute_offsets() { | |
2145 klassOop k = SystemDictionary::MethodHandle_klass(); | |
2146 if (k != NULL && EnableMethodHandles) { | |
2147 compute_offset(_type_offset, k, vmSymbols::type_name(), vmSymbols::java_dyn_MethodType_signature(), true); | |
2148 compute_offset(_vmtarget_offset, k, vmSymbols::vmtarget_name(), vmSymbols::object_signature(), true); | |
2149 compute_offset(_vmentry_offset, k, vmSymbols::vmentry_name(), vmSymbols::machine_word_signature(), true); | |
2150 | |
2151 // Note: MH.vmslots (if it is present) is a hoisted copy of MH.type.form.vmslots. | |
2152 // It is optional pending experiments to keep or toss. | |
2153 compute_optional_offset(_vmslots_offset, k, vmSymbols::vmslots_name(), vmSymbols::int_signature(), true); | |
2154 } | |
2155 } | |
2156 | |
2157 void sun_dyn_MemberName::compute_offsets() { | |
2158 klassOop k = SystemDictionary::MemberName_klass(); | |
2159 if (k != NULL && EnableMethodHandles) { | |
2160 compute_offset(_clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); | |
2161 compute_offset(_name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature()); | |
2162 compute_offset(_type_offset, k, vmSymbols::type_name(), vmSymbols::object_signature()); | |
2163 compute_offset(_flags_offset, k, vmSymbols::flags_name(), vmSymbols::int_signature()); | |
2164 compute_offset(_vmtarget_offset, k, vmSymbols::vmtarget_name(), vmSymbols::object_signature()); | |
2165 compute_offset(_vmindex_offset, k, vmSymbols::vmindex_name(), vmSymbols::int_signature()); | |
2166 } | |
2167 } | |
2168 | |
2169 void sun_dyn_DirectMethodHandle::compute_offsets() { | |
2170 klassOop k = SystemDictionary::DirectMethodHandle_klass(); | |
2171 if (k != NULL && EnableMethodHandles) { | |
2172 compute_offset(_vmindex_offset, k, vmSymbols::vmindex_name(), vmSymbols::int_signature(), true); | |
2173 } | |
2174 } | |
2175 | |
2176 void sun_dyn_BoundMethodHandle::compute_offsets() { | |
2177 klassOop k = SystemDictionary::BoundMethodHandle_klass(); | |
2178 if (k != NULL && EnableMethodHandles) { | |
2179 compute_offset(_vmargslot_offset, k, vmSymbols::vmargslot_name(), vmSymbols::int_signature(), true); | |
2180 compute_offset(_argument_offset, k, vmSymbols::argument_name(), vmSymbols::object_signature(), true); | |
2181 } | |
2182 } | |
2183 | |
2184 void sun_dyn_AdapterMethodHandle::compute_offsets() { | |
2185 klassOop k = SystemDictionary::AdapterMethodHandle_klass(); | |
2186 if (k != NULL && EnableMethodHandles) { | |
2187 compute_offset(_conversion_offset, k, vmSymbols::conversion_name(), vmSymbols::int_signature(), true); | |
2188 } | |
2189 } | |
2190 | |
2191 oop java_dyn_MethodHandle::type(oop mh) { | |
2192 return mh->obj_field(_type_offset); | |
2193 } | |
2194 | |
2195 void java_dyn_MethodHandle::set_type(oop mh, oop mtype) { | |
2196 mh->obj_field_put(_type_offset, mtype); | |
2197 } | |
2198 | |
2199 int java_dyn_MethodHandle::vmslots(oop mh) { | |
2200 int vmslots_offset = _vmslots_offset; | |
2201 if (vmslots_offset != 0) { | |
2202 #ifdef ASSERT | |
2203 int x = mh->int_field(vmslots_offset); | |
2204 int y = compute_vmslots(mh); | |
2205 assert(x == y, "correct hoisted value"); | |
2206 #endif | |
2207 return mh->int_field(vmslots_offset); | |
2208 } else { | |
2209 return compute_vmslots(mh); | |
2210 } | |
2211 } | |
2212 | |
2213 // if MH.vmslots exists, hoist into it the value of type.form.vmslots | |
2214 void java_dyn_MethodHandle::init_vmslots(oop mh) { | |
2215 int vmslots_offset = _vmslots_offset; | |
2216 if (vmslots_offset != 0) { | |
2217 mh->int_field_put(vmslots_offset, compute_vmslots(mh)); | |
2218 } | |
2219 } | |
2220 | |
2221 // fetch type.form.vmslots, which is the number of JVM stack slots | |
2222 // required to carry the arguments of this MH | |
2223 int java_dyn_MethodHandle::compute_vmslots(oop mh) { | |
2224 oop mtype = type(mh); | |
2225 if (mtype == NULL) return 0; // Java code would get NPE | |
2226 oop form = java_dyn_MethodType::form(mtype); | |
2227 if (form == NULL) return 0; // Java code would get NPE | |
2228 return java_dyn_MethodTypeForm::vmslots(form); | |
2229 } | |
2230 | |
2231 // fetch the low-level entry point for this mh | |
2232 MethodHandleEntry* java_dyn_MethodHandle::vmentry(oop mh) { | |
2233 return (MethodHandleEntry*) mh->address_field(_vmentry_offset); | |
2234 } | |
2235 | |
2236 void java_dyn_MethodHandle::set_vmentry(oop mh, MethodHandleEntry* me) { | |
2237 assert(_vmentry_offset != 0, "must be present"); | |
2238 | |
2239 // This is always the final step that initializes a valid method handle: | |
2240 mh->release_address_field_put(_vmentry_offset, (address) me); | |
2241 | |
2242 // There should be enough memory barriers on exit from native methods | |
2243 // to ensure that the MH is fully initialized to all threads before | |
2244 // Java code can publish it in global data structures. | |
2245 // But just in case, we use release_address_field_put. | |
2246 } | |
2247 | |
2248 /// MemberName accessors | |
2249 | |
2250 oop sun_dyn_MemberName::clazz(oop mname) { | |
2251 assert(is_instance(mname), "wrong type"); | |
2252 return mname->obj_field(_clazz_offset); | |
2253 } | |
2254 | |
2255 void sun_dyn_MemberName::set_clazz(oop mname, oop clazz) { | |
2256 assert(is_instance(mname), "wrong type"); | |
2257 mname->obj_field_put(_clazz_offset, clazz); | |
2258 } | |
2259 | |
2260 oop sun_dyn_MemberName::name(oop mname) { | |
2261 assert(is_instance(mname), "wrong type"); | |
2262 return mname->obj_field(_name_offset); | |
2263 } | |
2264 | |
2265 void sun_dyn_MemberName::set_name(oop mname, oop name) { | |
2266 assert(is_instance(mname), "wrong type"); | |
2267 mname->obj_field_put(_name_offset, name); | |
2268 } | |
2269 | |
2270 oop sun_dyn_MemberName::type(oop mname) { | |
2271 assert(is_instance(mname), "wrong type"); | |
2272 return mname->obj_field(_type_offset); | |
2273 } | |
2274 | |
2275 void sun_dyn_MemberName::set_type(oop mname, oop type) { | |
2276 assert(is_instance(mname), "wrong type"); | |
2277 mname->obj_field_put(_type_offset, type); | |
2278 } | |
2279 | |
2280 int sun_dyn_MemberName::flags(oop mname) { | |
2281 assert(is_instance(mname), "wrong type"); | |
2282 return mname->int_field(_flags_offset); | |
2283 } | |
2284 | |
2285 void sun_dyn_MemberName::set_flags(oop mname, int flags) { | |
2286 assert(is_instance(mname), "wrong type"); | |
2287 mname->int_field_put(_flags_offset, flags); | |
2288 } | |
2289 | |
2290 oop sun_dyn_MemberName::vmtarget(oop mname) { | |
2291 assert(is_instance(mname), "wrong type"); | |
2292 return mname->obj_field(_vmtarget_offset); | |
2293 } | |
2294 | |
2295 void sun_dyn_MemberName::set_vmtarget(oop mname, oop ref) { | |
2296 assert(is_instance(mname), "wrong type"); | |
2297 mname->obj_field_put(_vmtarget_offset, ref); | |
2298 } | |
2299 | |
2300 int sun_dyn_MemberName::vmindex(oop mname) { | |
2301 assert(is_instance(mname), "wrong type"); | |
2302 return mname->int_field(_vmindex_offset); | |
2303 } | |
2304 | |
2305 void sun_dyn_MemberName::set_vmindex(oop mname, int index) { | |
2306 assert(is_instance(mname), "wrong type"); | |
2307 mname->int_field_put(_vmindex_offset, index); | |
2308 } | |
2309 | |
2310 oop java_dyn_MethodHandle::vmtarget(oop mh) { | |
2311 assert(is_instance(mh), "MH only"); | |
2312 return mh->obj_field(_vmtarget_offset); | |
2313 } | |
2314 | |
2315 void java_dyn_MethodHandle::set_vmtarget(oop mh, oop ref) { | |
2316 assert(is_instance(mh), "MH only"); | |
2317 mh->obj_field_put(_vmtarget_offset, ref); | |
2318 } | |
2319 | |
2320 int sun_dyn_DirectMethodHandle::vmindex(oop mh) { | |
2321 assert(is_instance(mh), "DMH only"); | |
2322 return mh->int_field(_vmindex_offset); | |
2323 } | |
2324 | |
2325 void sun_dyn_DirectMethodHandle::set_vmindex(oop mh, int index) { | |
2326 assert(is_instance(mh), "DMH only"); | |
2327 mh->int_field_put(_vmindex_offset, index); | |
2328 } | |
2329 | |
2330 int sun_dyn_BoundMethodHandle::vmargslot(oop mh) { | |
2331 assert(is_instance(mh), "BMH only"); | |
2332 return mh->int_field(_vmargslot_offset); | |
2333 } | |
2334 | |
2335 oop sun_dyn_BoundMethodHandle::argument(oop mh) { | |
2336 assert(is_instance(mh), "BMH only"); | |
2337 return mh->obj_field(_argument_offset); | |
2338 } | |
2339 | |
2340 int sun_dyn_AdapterMethodHandle::conversion(oop mh) { | |
2341 assert(is_instance(mh), "AMH only"); | |
2342 return mh->int_field(_conversion_offset); | |
2343 } | |
2344 | |
2345 void sun_dyn_AdapterMethodHandle::set_conversion(oop mh, int conv) { | |
2346 assert(is_instance(mh), "AMH only"); | |
2347 mh->int_field_put(_conversion_offset, conv); | |
2348 } | |
2349 | |
2350 | |
2351 // Support for java_dyn_MethodType | |
2352 | |
2353 int java_dyn_MethodType::_rtype_offset; | |
2354 int java_dyn_MethodType::_ptypes_offset; | |
2355 int java_dyn_MethodType::_form_offset; | |
2356 | |
2357 void java_dyn_MethodType::compute_offsets() { | |
2358 klassOop k = SystemDictionary::MethodType_klass(); | |
2359 if (k != NULL) { | |
2360 compute_offset(_rtype_offset, k, vmSymbols::rtype_name(), vmSymbols::class_signature()); | |
2361 compute_offset(_ptypes_offset, k, vmSymbols::ptypes_name(), vmSymbols::class_array_signature()); | |
2362 compute_offset(_form_offset, k, vmSymbols::form_name(), vmSymbols::java_dyn_MethodTypeForm_signature()); | |
2363 } | |
2364 } | |
2365 | |
2366 void java_dyn_MethodType::print_signature(oop mt, outputStream* st) { | |
2367 st->print("("); | |
2368 objArrayOop pts = ptypes(mt); | |
2369 for (int i = 0, limit = pts->length(); i < limit; i++) { | |
2370 java_lang_Class::print_signature(pts->obj_at(i), st); | |
2371 } | |
2372 st->print(")"); | |
2373 java_lang_Class::print_signature(rtype(mt), st); | |
2374 } | |
2375 | |
2376 symbolOop java_dyn_MethodType::as_signature(oop mt, bool intern_if_not_found, TRAPS) { | |
2377 ResourceMark rm; | |
2378 stringStream buffer(128); | |
2379 print_signature(mt, &buffer); | |
2380 const char* sigstr = buffer.base(); | |
2381 int siglen = (int) buffer.size(); | |
2382 if (!intern_if_not_found) | |
2383 return SymbolTable::probe(sigstr, siglen); | |
2384 else | |
2385 return oopFactory::new_symbol(sigstr, siglen, THREAD); | |
2386 } | |
2387 | |
2388 oop java_dyn_MethodType::rtype(oop mt) { | |
2389 assert(is_instance(mt), "must be a MethodType"); | |
2390 return mt->obj_field(_rtype_offset); | |
2391 } | |
2392 | |
2393 objArrayOop java_dyn_MethodType::ptypes(oop mt) { | |
2394 assert(is_instance(mt), "must be a MethodType"); | |
2395 return (objArrayOop) mt->obj_field(_ptypes_offset); | |
2396 } | |
2397 | |
2398 oop java_dyn_MethodType::form(oop mt) { | |
2399 assert(is_instance(mt), "must be a MethodType"); | |
2400 return mt->obj_field(_form_offset); | |
2401 } | |
2402 | |
2403 oop java_dyn_MethodType::ptype(oop mt, int idx) { | |
2404 return ptypes(mt)->obj_at(idx); | |
2405 } | |
2406 | |
2407 | |
2408 | |
2409 // Support for java_dyn_MethodTypeForm | |
2410 | |
2411 int java_dyn_MethodTypeForm::_vmslots_offset; | |
2412 int java_dyn_MethodTypeForm::_erasedType_offset; | |
2413 | |
2414 void java_dyn_MethodTypeForm::compute_offsets() { | |
2415 klassOop k = SystemDictionary::MethodTypeForm_klass(); | |
2416 if (k != NULL) { | |
2417 compute_optional_offset(_vmslots_offset, k, vmSymbols::vmslots_name(), vmSymbols::int_signature(), true); | |
2418 compute_optional_offset(_erasedType_offset, k, vmSymbols::erasedType_name(), vmSymbols::java_dyn_MethodType_signature(), true); | |
2419 } | |
2420 } | |
2421 | |
2422 int java_dyn_MethodTypeForm::vmslots(oop mtform) { | |
2423 assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only"); | |
2424 return mtform->int_field(_vmslots_offset); | |
2425 } | |
2426 | |
2427 oop java_dyn_MethodTypeForm::erasedType(oop mtform) { | |
2428 assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only"); | |
2429 return mtform->obj_field(_erasedType_offset); | |
2430 } | |
2431 | |
2432 | |
2433 | |
2434 | |
2110 // Support for java_security_AccessControlContext | 2435 // Support for java_security_AccessControlContext |
2111 | 2436 |
2112 int java_security_AccessControlContext::_context_offset = 0; | 2437 int java_security_AccessControlContext::_context_offset = 0; |
2113 int java_security_AccessControlContext::_privilegedContext_offset = 0; | 2438 int java_security_AccessControlContext::_privilegedContext_offset = 0; |
2114 int java_security_AccessControlContext::_isPrivileged_offset = 0; | 2439 int java_security_AccessControlContext::_isPrivileged_offset = 0; |
2115 | |
2116 | 2440 |
2117 void java_security_AccessControlContext::compute_offsets() { | 2441 void java_security_AccessControlContext::compute_offsets() { |
2118 assert(_isPrivileged_offset == 0, "offsets should be initialized only once"); | 2442 assert(_isPrivileged_offset == 0, "offsets should be initialized only once"); |
2119 fieldDescriptor fd; | 2443 fieldDescriptor fd; |
2120 instanceKlass* ik = instanceKlass::cast(SystemDictionary::AccessControlContext_klass()); | 2444 instanceKlass* ik = instanceKlass::cast(SystemDictionary::AccessControlContext_klass()); |
2440 | 2764 |
2441 java_lang_Class::compute_offsets(); | 2765 java_lang_Class::compute_offsets(); |
2442 java_lang_System::compute_offsets(); | 2766 java_lang_System::compute_offsets(); |
2443 java_lang_Thread::compute_offsets(); | 2767 java_lang_Thread::compute_offsets(); |
2444 java_lang_ThreadGroup::compute_offsets(); | 2768 java_lang_ThreadGroup::compute_offsets(); |
2769 if (EnableMethodHandles) { | |
2770 java_dyn_MethodHandle::compute_offsets(); | |
2771 sun_dyn_MemberName::compute_offsets(); | |
2772 sun_dyn_DirectMethodHandle::compute_offsets(); | |
2773 sun_dyn_BoundMethodHandle::compute_offsets(); | |
2774 sun_dyn_AdapterMethodHandle::compute_offsets(); | |
2775 java_dyn_MethodType::compute_offsets(); | |
2776 java_dyn_MethodTypeForm::compute_offsets(); | |
2777 } | |
2445 java_security_AccessControlContext::compute_offsets(); | 2778 java_security_AccessControlContext::compute_offsets(); |
2446 // Initialize reflection classes. The layouts of these classes | 2779 // Initialize reflection classes. The layouts of these classes |
2447 // changed with the new reflection implementation in JDK 1.4, and | 2780 // changed with the new reflection implementation in JDK 1.4, and |
2448 // since the Universe doesn't know what JDK version it is until this | 2781 // since the Universe doesn't know what JDK version it is until this |
2449 // point we defer computation of these offsets until now. | 2782 // point we defer computation of these offsets until now. |
2457 if (JDK_Version::is_gte_jdk15x_version()) { | 2790 if (JDK_Version::is_gte_jdk15x_version()) { |
2458 sun_reflect_ConstantPool::compute_offsets(); | 2791 sun_reflect_ConstantPool::compute_offsets(); |
2459 sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets(); | 2792 sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets(); |
2460 } | 2793 } |
2461 sun_misc_AtomicLongCSImpl::compute_offsets(); | 2794 sun_misc_AtomicLongCSImpl::compute_offsets(); |
2795 | |
2796 // generated interpreter code wants to know about the offsets we just computed: | |
2797 AbstractAssembler::update_delayed_values(); | |
2462 } | 2798 } |
2463 | 2799 |
2464 #ifndef PRODUCT | 2800 #ifndef PRODUCT |
2465 | 2801 |
2466 // These functions exist to assert the validity of hard-coded field offsets to guard | 2802 // These functions exist to assert the validity of hard-coded field offsets to guard |