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