comparison src/share/vm/classfile/classFileParser.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 715dceaa89b7
children 75596850f863 6a93908f268f
comparison
equal deleted inserted replaced
709:1d037ecd7960 710:e5b0439ef4ae
1840 signature() == vmSymbols::void_method_signature() && 1840 signature() == vmSymbols::void_method_signature() &&
1841 m->is_vanilla_constructor()) { 1841 m->is_vanilla_constructor()) {
1842 _has_vanilla_constructor = true; 1842 _has_vanilla_constructor = true;
1843 } 1843 }
1844 1844
1845 if (EnableMethodHandles && m->is_method_handle_invoke()) {
1846 THROW_MSG_(vmSymbols::java_lang_VirtualMachineError(),
1847 "Method handle invokers must be defined internally to the VM", nullHandle);
1848 }
1849
1845 return m; 1850 return m;
1846 } 1851 }
1847 1852
1848 1853
1849 // The promoted_flags parameter is used to pass relevant access_flags 1854 // The promoted_flags parameter is used to pass relevant access_flags
2463 const int extra = java_lang_Class::number_of_fake_oop_fields; 2468 const int extra = java_lang_Class::number_of_fake_oop_fields;
2464 (*next_nonstatic_oop_offset_ptr) += (extra * heapOopSize); 2469 (*next_nonstatic_oop_offset_ptr) += (extra * heapOopSize);
2465 } 2470 }
2466 2471
2467 2472
2473 // Force MethodHandle.vmentry to be an unmanaged pointer.
2474 // There is no way for a classfile to express this, so we must help it.
2475 void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
2476 typeArrayHandle* fields_ptr,
2477 FieldAllocationCount *fac_ptr,
2478 TRAPS) {
2479 // Add fake fields for java.dyn.MethodHandle instances
2480 //
2481 // This is not particularly nice, but since there is no way to express
2482 // a native wordSize field in Java, we must do it at this level.
2483
2484 if (!EnableMethodHandles) return;
2485
2486 int word_sig_index = 0;
2487 const int cp_size = cp->length();
2488 for (int index = 1; index < cp_size; index++) {
2489 if (cp->tag_at(index).is_utf8() &&
2490 cp->symbol_at(index) == vmSymbols::machine_word_signature()) {
2491 word_sig_index = index;
2492 break;
2493 }
2494 }
2495
2496 if (word_sig_index == 0)
2497 THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
2498 "missing I or J signature (for vmentry) in java.dyn.MethodHandle");
2499
2500 bool found_vmentry = false;
2501
2502 const int n = (*fields_ptr)()->length();
2503 for (int i = 0; i < n; i += instanceKlass::next_offset) {
2504 int name_index = (*fields_ptr)->ushort_at(i + instanceKlass::name_index_offset);
2505 int sig_index = (*fields_ptr)->ushort_at(i + instanceKlass::signature_index_offset);
2506 int acc_flags = (*fields_ptr)->ushort_at(i + instanceKlass::access_flags_offset);
2507 symbolOop f_name = cp->symbol_at(name_index);
2508 symbolOop f_sig = cp->symbol_at(sig_index);
2509 if (f_sig == vmSymbols::byte_signature() &&
2510 f_name == vmSymbols::vmentry_name() &&
2511 (acc_flags & JVM_ACC_STATIC) == 0) {
2512 // Adjust the field type from byte to an unmanaged pointer.
2513 assert(fac_ptr->nonstatic_byte_count > 0, "");
2514 fac_ptr->nonstatic_byte_count -= 1;
2515 (*fields_ptr)->ushort_at_put(i + instanceKlass::signature_index_offset,
2516 word_sig_index);
2517 if (wordSize == jintSize) {
2518 fac_ptr->nonstatic_word_count += 1;
2519 } else {
2520 fac_ptr->nonstatic_double_count += 1;
2521 }
2522
2523 FieldAllocationType atype = (FieldAllocationType) (*fields_ptr)->ushort_at(i+4);
2524 assert(atype == NONSTATIC_BYTE, "");
2525 FieldAllocationType new_atype = NONSTATIC_WORD;
2526 if (wordSize > jintSize) {
2527 if (Universe::field_type_should_be_aligned(T_LONG)) {
2528 atype = NONSTATIC_ALIGNED_DOUBLE;
2529 } else {
2530 atype = NONSTATIC_DOUBLE;
2531 }
2532 }
2533 (*fields_ptr)->ushort_at_put(i+4, new_atype);
2534
2535 found_vmentry = true;
2536 break;
2537 }
2538 }
2539
2540 if (!found_vmentry)
2541 THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
2542 "missing vmentry byte field in java.dyn.MethodHandle");
2543
2544 }
2545
2546
2468 instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, 2547 instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
2469 Handle class_loader, 2548 Handle class_loader,
2470 Handle protection_domain, 2549 Handle protection_domain,
2550 KlassHandle host_klass,
2471 GrowableArray<Handle>* cp_patches, 2551 GrowableArray<Handle>* cp_patches,
2472 symbolHandle& parsed_name, 2552 symbolHandle& parsed_name,
2473 TRAPS) { 2553 TRAPS) {
2474 // So that JVMTI can cache class file in the state before retransformable agents 2554 // So that JVMTI can cache class file in the state before retransformable agents
2475 // have modified it 2555 // have modified it
2498 cfs = new ClassFileStream(ptr, end_ptr - ptr, cfs->source()); 2578 cfs = new ClassFileStream(ptr, end_ptr - ptr, cfs->source());
2499 set_stream(cfs); 2579 set_stream(cfs);
2500 } 2580 }
2501 } 2581 }
2502 2582
2583 _host_klass = host_klass;
2503 _cp_patches = cp_patches; 2584 _cp_patches = cp_patches;
2504 2585
2505 instanceKlassHandle nullHandle; 2586 instanceKlassHandle nullHandle;
2506 2587
2507 // Figure out whether we can skip format checking (matching classic VM behavior) 2588 // Figure out whether we can skip format checking (matching classic VM behavior)
2804 next_nonstatic_field_offset = first_nonstatic_field_offset; 2885 next_nonstatic_field_offset = first_nonstatic_field_offset;
2805 2886
2806 // Add fake fields for java.lang.Class instances (also see below) 2887 // Add fake fields for java.lang.Class instances (also see below)
2807 if (class_name() == vmSymbols::java_lang_Class() && class_loader.is_null()) { 2888 if (class_name() == vmSymbols::java_lang_Class() && class_loader.is_null()) {
2808 java_lang_Class_fix_pre(&methods, &fac, CHECK_(nullHandle)); 2889 java_lang_Class_fix_pre(&methods, &fac, CHECK_(nullHandle));
2890 }
2891
2892 // adjust the vmentry field declaration in java.dyn.MethodHandle
2893 if (EnableMethodHandles && class_name() == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) {
2894 java_dyn_MethodHandle_fix_pre(cp, &fields, &fac, CHECK_(nullHandle));
2809 } 2895 }
2810 2896
2811 // Add a fake "discovered" field if it is not present 2897 // Add a fake "discovered" field if it is not present
2812 // for compatibility with earlier jdk's. 2898 // for compatibility with earlier jdk's.
2813 if (class_name() == vmSymbols::java_lang_ref_Reference() 2899 if (class_name() == vmSymbols::java_lang_ref_Reference()
3132 this_klass->set_has_final_method(); 3218 this_klass->set_has_final_method();
3133 } 3219 }
3134 this_klass->set_method_ordering(method_ordering()); 3220 this_klass->set_method_ordering(method_ordering());
3135 this_klass->set_initial_method_idnum(methods->length()); 3221 this_klass->set_initial_method_idnum(methods->length());
3136 this_klass->set_name(cp->klass_name_at(this_class_index)); 3222 this_klass->set_name(cp->klass_name_at(this_class_index));
3137 if (LinkWellKnownClasses) // I am well known to myself 3223 if (LinkWellKnownClasses || is_anonymous()) // I am well known to myself
3138 cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve 3224 cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve
3139 this_klass->set_protection_domain(protection_domain()); 3225 this_klass->set_protection_domain(protection_domain());
3140 this_klass->set_fields_annotations(fields_annotations()); 3226 this_klass->set_fields_annotations(fields_annotations());
3141 this_klass->set_methods_annotations(methods_annotations()); 3227 this_klass->set_methods_annotations(methods_annotations());
3142 this_klass->set_methods_parameter_annotations(methods_parameter_annotations()); 3228 this_klass->set_methods_parameter_annotations(methods_parameter_annotations());