comparison src/share/vm/classfile/classFileParser.cpp @ 1909:d2e35ffae982

6994630: java/lang/instrument/IsModifiableClassAgent.java fails with -XX:+EnableInvokeDynamic Summary: The logic of ClassFileParser::java_dyn_MethodHandle_fix_pre needs to take care of an already changed vmentry signature. Reviewed-by: never, jrose
author twisti
date Thu, 28 Oct 2010 00:48:18 -0700
parents a932f331ef90
children 3b2dea75431e
comparison
equal deleted inserted replaced
1908:f195c4737aca 1909:d2e35ffae982
1 /* 1 /*
2 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
2514 // 2514 //
2515 // Check the fields in java.lang.ref.Reference for the "discovered" 2515 // Check the fields in java.lang.ref.Reference for the "discovered"
2516 // field. If it is not present, artifically create a field for it. 2516 // field. If it is not present, artifically create a field for it.
2517 // This allows this VM to run on early JDK where the field is not 2517 // This allows this VM to run on early JDK where the field is not
2518 // present. 2518 // present.
2519
2520 //
2521 // Increment fac.nonstatic_oop_count so that the start of the
2522 // next type of non-static oops leaves room for the fake oop.
2523 // Do not increment next_nonstatic_oop_offset so that the
2524 // fake oop is place after the java.lang.ref.Reference oop
2525 // fields.
2526 //
2527 // Check the fields in java.lang.ref.Reference for the "discovered"
2528 // field. If it is not present, artifically create a field for it.
2529 // This allows this VM to run on early JDK where the field is not
2530 // present.
2531 int reference_sig_index = 0; 2519 int reference_sig_index = 0;
2532 int reference_name_index = 0; 2520 int reference_name_index = 0;
2533 int reference_index = 0; 2521 int reference_index = 0;
2534 int extra = java_lang_ref_Reference::number_of_fake_oop_fields; 2522 int extra = java_lang_ref_Reference::number_of_fake_oop_fields;
2535 const int n = (*fields_ptr)()->length(); 2523 const int n = (*fields_ptr)()->length();
2661 2649
2662 2650
2663 // Force MethodHandle.vmentry to be an unmanaged pointer. 2651 // Force MethodHandle.vmentry to be an unmanaged pointer.
2664 // There is no way for a classfile to express this, so we must help it. 2652 // There is no way for a classfile to express this, so we must help it.
2665 void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp, 2653 void ClassFileParser::java_dyn_MethodHandle_fix_pre(constantPoolHandle cp,
2666 typeArrayHandle* fields_ptr, 2654 typeArrayHandle fields,
2667 FieldAllocationCount *fac_ptr, 2655 FieldAllocationCount *fac_ptr,
2668 TRAPS) { 2656 TRAPS) {
2669 // Add fake fields for java.dyn.MethodHandle instances 2657 // Add fake fields for java.dyn.MethodHandle instances
2670 // 2658 //
2671 // This is not particularly nice, but since there is no way to express 2659 // This is not particularly nice, but since there is no way to express
2685 2673
2686 if (word_sig_index == 0) 2674 if (word_sig_index == 0)
2687 THROW_MSG(vmSymbols::java_lang_VirtualMachineError(), 2675 THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
2688 "missing I or J signature (for vmentry) in java.dyn.MethodHandle"); 2676 "missing I or J signature (for vmentry) in java.dyn.MethodHandle");
2689 2677
2678 // Find vmentry field and change the signature.
2690 bool found_vmentry = false; 2679 bool found_vmentry = false;
2691 2680 for (int i = 0; i < fields->length(); i += instanceKlass::next_offset) {
2692 const int n = (*fields_ptr)()->length(); 2681 int name_index = fields->ushort_at(i + instanceKlass::name_index_offset);
2693 for (int i = 0; i < n; i += instanceKlass::next_offset) { 2682 int sig_index = fields->ushort_at(i + instanceKlass::signature_index_offset);
2694 int name_index = (*fields_ptr)->ushort_at(i + instanceKlass::name_index_offset); 2683 int acc_flags = fields->ushort_at(i + instanceKlass::access_flags_offset);
2695 int sig_index = (*fields_ptr)->ushort_at(i + instanceKlass::signature_index_offset);
2696 int acc_flags = (*fields_ptr)->ushort_at(i + instanceKlass::access_flags_offset);
2697 symbolOop f_name = cp->symbol_at(name_index); 2684 symbolOop f_name = cp->symbol_at(name_index);
2698 symbolOop f_sig = cp->symbol_at(sig_index); 2685 symbolOop f_sig = cp->symbol_at(sig_index);
2699 if (f_sig == vmSymbols::byte_signature() && 2686
2700 f_name == vmSymbols::vmentry_name() && 2687 if (f_name == vmSymbols::vmentry_name() && (acc_flags & JVM_ACC_STATIC) == 0) {
2701 (acc_flags & JVM_ACC_STATIC) == 0) { 2688 if (f_sig == vmSymbols::machine_word_signature()) {
2702 // Adjust the field type from byte to an unmanaged pointer. 2689 // If the signature of vmentry is already changed, we're done.
2703 assert(fac_ptr->nonstatic_byte_count > 0, ""); 2690 found_vmentry = true;
2704 fac_ptr->nonstatic_byte_count -= 1; 2691 break;
2705 2692 }
2706 (*fields_ptr)->ushort_at_put(i + instanceKlass::signature_index_offset, word_sig_index); 2693 else if (f_sig == vmSymbols::byte_signature()) {
2707 assert(wordSize == longSize || wordSize == jintSize, "ILP32 or LP64"); 2694 // Adjust the field type from byte to an unmanaged pointer.
2708 if (wordSize == longSize) fac_ptr->nonstatic_double_count += 1; 2695 assert(fac_ptr->nonstatic_byte_count > 0, "");
2709 else fac_ptr->nonstatic_word_count += 1; 2696 fac_ptr->nonstatic_byte_count -= 1;
2710 2697
2711 FieldAllocationType atype = (FieldAllocationType) (*fields_ptr)->ushort_at(i + instanceKlass::low_offset); 2698 fields->ushort_at_put(i + instanceKlass::signature_index_offset, word_sig_index);
2712 assert(atype == NONSTATIC_BYTE, ""); 2699 assert(wordSize == longSize || wordSize == jintSize, "ILP32 or LP64");
2713 FieldAllocationType new_atype = (wordSize == longSize) ? NONSTATIC_DOUBLE : NONSTATIC_WORD; 2700 if (wordSize == longSize) fac_ptr->nonstatic_double_count += 1;
2714 (*fields_ptr)->ushort_at_put(i + instanceKlass::low_offset, new_atype); 2701 else fac_ptr->nonstatic_word_count += 1;
2715 2702
2716 found_vmentry = true; 2703 FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i + instanceKlass::low_offset);
2717 break; 2704 assert(atype == NONSTATIC_BYTE, "");
2705 FieldAllocationType new_atype = (wordSize == longSize) ? NONSTATIC_DOUBLE : NONSTATIC_WORD;
2706 fields->ushort_at_put(i + instanceKlass::low_offset, new_atype);
2707
2708 found_vmentry = true;
2709 break;
2710 }
2718 } 2711 }
2719 } 2712 }
2720 2713
2721 if (!found_vmentry) 2714 if (!found_vmentry)
2722 THROW_MSG(vmSymbols::java_lang_VirtualMachineError(), 2715 THROW_MSG(vmSymbols::java_lang_VirtualMachineError(),
2723 "missing vmentry byte field in java.dyn.MethodHandle"); 2716 "missing vmentry byte field in java.dyn.MethodHandle");
2724
2725 } 2717 }
2726 2718
2727 2719
2728 instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, 2720 instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
2729 Handle class_loader, 2721 Handle class_loader,
3080 java_lang_Class_fix_pre(&methods, &fac, CHECK_(nullHandle)); 3072 java_lang_Class_fix_pre(&methods, &fac, CHECK_(nullHandle));
3081 } 3073 }
3082 3074
3083 // adjust the vmentry field declaration in java.dyn.MethodHandle 3075 // adjust the vmentry field declaration in java.dyn.MethodHandle
3084 if (EnableMethodHandles && class_name() == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) { 3076 if (EnableMethodHandles && class_name() == vmSymbols::sun_dyn_MethodHandleImpl() && class_loader.is_null()) {
3085 java_dyn_MethodHandle_fix_pre(cp, &fields, &fac, CHECK_(nullHandle)); 3077 java_dyn_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle));
3086 } 3078 }
3087 3079
3088 // Add a fake "discovered" field if it is not present 3080 // Add a fake "discovered" field if it is not present
3089 // for compatibility with earlier jdk's. 3081 // for compatibility with earlier jdk's.
3090 if (class_name() == vmSymbols::java_lang_ref_Reference() 3082 if (class_name() == vmSymbols::java_lang_ref_Reference()