Mercurial > hg > graal-jvmci-8
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()); |