Mercurial > hg > graal-jvmci-8
comparison src/share/vm/classfile/classFileParser.cpp @ 3938:e6b1331a51d2
7086585: make Java field injection more flexible
Reviewed-by: jrose, twisti, kvn, coleenp
author | never |
---|---|
date | Sat, 10 Sep 2011 17:29:02 -0700 |
parents | 498c6cf70f7e |
children | 4ceaf61479fc cd5d8cafcc84 |
comparison
equal
deleted
inserted
replaced
3937:c565834fb592 | 3938:e6b1331a51d2 |
---|---|
34 #include "memory/allocation.hpp" | 34 #include "memory/allocation.hpp" |
35 #include "memory/gcLocker.hpp" | 35 #include "memory/gcLocker.hpp" |
36 #include "memory/oopFactory.hpp" | 36 #include "memory/oopFactory.hpp" |
37 #include "memory/universe.inline.hpp" | 37 #include "memory/universe.inline.hpp" |
38 #include "oops/constantPoolOop.hpp" | 38 #include "oops/constantPoolOop.hpp" |
39 #include "oops/fieldStreams.hpp" | |
39 #include "oops/instanceKlass.hpp" | 40 #include "oops/instanceKlass.hpp" |
40 #include "oops/instanceMirrorKlass.hpp" | 41 #include "oops/instanceMirrorKlass.hpp" |
41 #include "oops/klass.inline.hpp" | 42 #include "oops/klass.inline.hpp" |
42 #include "oops/klassOop.hpp" | 43 #include "oops/klassOop.hpp" |
43 #include "oops/klassVtable.hpp" | 44 #include "oops/klassVtable.hpp" |
989 enum FieldAllocationType { | 990 enum FieldAllocationType { |
990 STATIC_OOP, // Oops | 991 STATIC_OOP, // Oops |
991 STATIC_BYTE, // Boolean, Byte, char | 992 STATIC_BYTE, // Boolean, Byte, char |
992 STATIC_SHORT, // shorts | 993 STATIC_SHORT, // shorts |
993 STATIC_WORD, // ints | 994 STATIC_WORD, // ints |
994 STATIC_DOUBLE, // long or double | 995 STATIC_DOUBLE, // aligned long or double |
995 STATIC_ALIGNED_DOUBLE,// aligned long or double | |
996 NONSTATIC_OOP, | 996 NONSTATIC_OOP, |
997 NONSTATIC_BYTE, | 997 NONSTATIC_BYTE, |
998 NONSTATIC_SHORT, | 998 NONSTATIC_SHORT, |
999 NONSTATIC_WORD, | 999 NONSTATIC_WORD, |
1000 NONSTATIC_DOUBLE, | 1000 NONSTATIC_DOUBLE, |
1001 NONSTATIC_ALIGNED_DOUBLE | 1001 MAX_FIELD_ALLOCATION_TYPE, |
1002 BAD_ALLOCATION_TYPE = -1 | |
1002 }; | 1003 }; |
1003 | 1004 |
1004 | 1005 static FieldAllocationType _basic_type_to_atype[2 * (T_CONFLICT + 1)] = { |
1005 struct FieldAllocationCount { | 1006 BAD_ALLOCATION_TYPE, // 0 |
1006 unsigned int static_oop_count; | 1007 BAD_ALLOCATION_TYPE, // 1 |
1007 unsigned int static_byte_count; | 1008 BAD_ALLOCATION_TYPE, // 2 |
1008 unsigned int static_short_count; | 1009 BAD_ALLOCATION_TYPE, // 3 |
1009 unsigned int static_word_count; | 1010 NONSTATIC_BYTE , // T_BOOLEAN = 4, |
1010 unsigned int static_double_count; | 1011 NONSTATIC_SHORT, // T_CHAR = 5, |
1011 unsigned int nonstatic_oop_count; | 1012 NONSTATIC_WORD, // T_FLOAT = 6, |
1012 unsigned int nonstatic_byte_count; | 1013 NONSTATIC_DOUBLE, // T_DOUBLE = 7, |
1013 unsigned int nonstatic_short_count; | 1014 NONSTATIC_BYTE, // T_BYTE = 8, |
1014 unsigned int nonstatic_word_count; | 1015 NONSTATIC_SHORT, // T_SHORT = 9, |
1015 unsigned int nonstatic_double_count; | 1016 NONSTATIC_WORD, // T_INT = 10, |
1017 NONSTATIC_DOUBLE, // T_LONG = 11, | |
1018 NONSTATIC_OOP, // T_OBJECT = 12, | |
1019 NONSTATIC_OOP, // T_ARRAY = 13, | |
1020 BAD_ALLOCATION_TYPE, // T_VOID = 14, | |
1021 BAD_ALLOCATION_TYPE, // T_ADDRESS = 15, | |
1022 BAD_ALLOCATION_TYPE, // T_NARROWOOP= 16, | |
1023 BAD_ALLOCATION_TYPE, // T_CONFLICT = 17, | |
1024 BAD_ALLOCATION_TYPE, // 0 | |
1025 BAD_ALLOCATION_TYPE, // 1 | |
1026 BAD_ALLOCATION_TYPE, // 2 | |
1027 BAD_ALLOCATION_TYPE, // 3 | |
1028 STATIC_BYTE , // T_BOOLEAN = 4, | |
1029 STATIC_SHORT, // T_CHAR = 5, | |
1030 STATIC_WORD, // T_FLOAT = 6, | |
1031 STATIC_DOUBLE, // T_DOUBLE = 7, | |
1032 STATIC_BYTE, // T_BYTE = 8, | |
1033 STATIC_SHORT, // T_SHORT = 9, | |
1034 STATIC_WORD, // T_INT = 10, | |
1035 STATIC_DOUBLE, // T_LONG = 11, | |
1036 STATIC_OOP, // T_OBJECT = 12, | |
1037 STATIC_OOP, // T_ARRAY = 13, | |
1038 BAD_ALLOCATION_TYPE, // T_VOID = 14, | |
1039 BAD_ALLOCATION_TYPE, // T_ADDRESS = 15, | |
1040 BAD_ALLOCATION_TYPE, // T_NARROWOOP= 16, | |
1041 BAD_ALLOCATION_TYPE, // T_CONFLICT = 17, | |
1016 }; | 1042 }; |
1017 | 1043 |
1018 typeArrayHandle ClassFileParser::parse_fields(constantPoolHandle cp, bool is_interface, | 1044 static FieldAllocationType basic_type_to_atype(bool is_static, BasicType type) { |
1019 struct FieldAllocationCount *fac, | 1045 assert(type >= T_BOOLEAN && type < T_VOID, "only allowable values"); |
1020 objArrayHandle* fields_annotations, TRAPS) { | 1046 FieldAllocationType result = _basic_type_to_atype[type + (is_static ? (T_CONFLICT + 1) : 0)]; |
1047 assert(result != BAD_ALLOCATION_TYPE, "bad type"); | |
1048 return result; | |
1049 } | |
1050 | |
1051 class FieldAllocationCount: public ResourceObj { | |
1052 public: | |
1053 unsigned int count[MAX_FIELD_ALLOCATION_TYPE]; | |
1054 | |
1055 FieldAllocationCount() { | |
1056 for (int i = 0; i < MAX_FIELD_ALLOCATION_TYPE; i++) { | |
1057 count[i] = 0; | |
1058 } | |
1059 } | |
1060 | |
1061 FieldAllocationType update(bool is_static, BasicType type) { | |
1062 FieldAllocationType atype = basic_type_to_atype(is_static, type); | |
1063 count[atype]++; | |
1064 return atype; | |
1065 } | |
1066 }; | |
1067 | |
1068 | |
1069 typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name, | |
1070 constantPoolHandle cp, bool is_interface, | |
1071 FieldAllocationCount *fac, | |
1072 objArrayHandle* fields_annotations, | |
1073 int* java_fields_count_ptr, TRAPS) { | |
1021 ClassFileStream* cfs = stream(); | 1074 ClassFileStream* cfs = stream(); |
1022 typeArrayHandle nullHandle; | 1075 typeArrayHandle nullHandle; |
1023 cfs->guarantee_more(2, CHECK_(nullHandle)); // length | 1076 cfs->guarantee_more(2, CHECK_(nullHandle)); // length |
1024 u2 length = cfs->get_u2_fast(); | 1077 u2 length = cfs->get_u2_fast(); |
1078 *java_fields_count_ptr = length; | |
1079 | |
1080 int num_injected = 0; | |
1081 InjectedField* injected = JavaClasses::get_injected(class_name, &num_injected); | |
1082 | |
1025 // Tuples of shorts [access, name index, sig index, initial value index, byte offset, generic signature index] | 1083 // Tuples of shorts [access, name index, sig index, initial value index, byte offset, generic signature index] |
1026 typeArrayOop new_fields = oopFactory::new_permanent_shortArray(length*instanceKlass::next_offset, CHECK_(nullHandle)); | 1084 typeArrayOop new_fields = oopFactory::new_permanent_shortArray((length + num_injected) * FieldInfo::field_slots, CHECK_(nullHandle)); |
1027 typeArrayHandle fields(THREAD, new_fields); | 1085 typeArrayHandle fields(THREAD, new_fields); |
1028 | 1086 |
1029 int index = 0; | |
1030 typeArrayHandle field_annotations; | 1087 typeArrayHandle field_annotations; |
1031 for (int n = 0; n < length; n++) { | 1088 for (int n = 0; n < length; n++) { |
1032 cfs->guarantee_more(8, CHECK_(nullHandle)); // access_flags, name_index, descriptor_index, attributes_count | 1089 cfs->guarantee_more(8, CHECK_(nullHandle)); // access_flags, name_index, descriptor_index, attributes_count |
1033 | 1090 |
1034 AccessFlags access_flags; | 1091 AccessFlags access_flags; |
1075 if (is_synthetic) { | 1132 if (is_synthetic) { |
1076 access_flags.set_is_synthetic(); | 1133 access_flags.set_is_synthetic(); |
1077 } | 1134 } |
1078 } | 1135 } |
1079 | 1136 |
1080 fields->short_at_put(index++, access_flags.as_short()); | 1137 FieldInfo* field = FieldInfo::from_field_array(fields(), n); |
1081 fields->short_at_put(index++, name_index); | 1138 field->initialize(access_flags.as_short(), |
1082 fields->short_at_put(index++, signature_index); | 1139 name_index, |
1083 fields->short_at_put(index++, constantvalue_index); | 1140 signature_index, |
1141 constantvalue_index, | |
1142 generic_signature_index, | |
1143 0); | |
1144 | |
1145 BasicType type = cp->basic_type_for_signature_at(signature_index); | |
1084 | 1146 |
1085 // Remember how many oops we encountered and compute allocation type | 1147 // Remember how many oops we encountered and compute allocation type |
1086 BasicType type = cp->basic_type_for_signature_at(signature_index); | 1148 FieldAllocationType atype = fac->update(is_static, type); |
1087 FieldAllocationType atype; | |
1088 if ( is_static ) { | |
1089 switch ( type ) { | |
1090 case T_BOOLEAN: | |
1091 case T_BYTE: | |
1092 fac->static_byte_count++; | |
1093 atype = STATIC_BYTE; | |
1094 break; | |
1095 case T_LONG: | |
1096 case T_DOUBLE: | |
1097 if (Universe::field_type_should_be_aligned(type)) { | |
1098 atype = STATIC_ALIGNED_DOUBLE; | |
1099 } else { | |
1100 atype = STATIC_DOUBLE; | |
1101 } | |
1102 fac->static_double_count++; | |
1103 break; | |
1104 case T_CHAR: | |
1105 case T_SHORT: | |
1106 fac->static_short_count++; | |
1107 atype = STATIC_SHORT; | |
1108 break; | |
1109 case T_FLOAT: | |
1110 case T_INT: | |
1111 fac->static_word_count++; | |
1112 atype = STATIC_WORD; | |
1113 break; | |
1114 case T_ARRAY: | |
1115 case T_OBJECT: | |
1116 fac->static_oop_count++; | |
1117 atype = STATIC_OOP; | |
1118 break; | |
1119 case T_ADDRESS: | |
1120 case T_VOID: | |
1121 default: | |
1122 assert(0, "bad field type"); | |
1123 } | |
1124 } else { | |
1125 switch ( type ) { | |
1126 case T_BOOLEAN: | |
1127 case T_BYTE: | |
1128 fac->nonstatic_byte_count++; | |
1129 atype = NONSTATIC_BYTE; | |
1130 break; | |
1131 case T_LONG: | |
1132 case T_DOUBLE: | |
1133 if (Universe::field_type_should_be_aligned(type)) { | |
1134 atype = NONSTATIC_ALIGNED_DOUBLE; | |
1135 } else { | |
1136 atype = NONSTATIC_DOUBLE; | |
1137 } | |
1138 fac->nonstatic_double_count++; | |
1139 break; | |
1140 case T_CHAR: | |
1141 case T_SHORT: | |
1142 fac->nonstatic_short_count++; | |
1143 atype = NONSTATIC_SHORT; | |
1144 break; | |
1145 case T_FLOAT: | |
1146 case T_INT: | |
1147 fac->nonstatic_word_count++; | |
1148 atype = NONSTATIC_WORD; | |
1149 break; | |
1150 case T_ARRAY: | |
1151 case T_OBJECT: | |
1152 fac->nonstatic_oop_count++; | |
1153 atype = NONSTATIC_OOP; | |
1154 break; | |
1155 case T_ADDRESS: | |
1156 case T_VOID: | |
1157 default: | |
1158 assert(0, "bad field type"); | |
1159 } | |
1160 } | |
1161 | 1149 |
1162 // The correct offset is computed later (all oop fields will be located together) | 1150 // The correct offset is computed later (all oop fields will be located together) |
1163 // We temporarily store the allocation type in the offset field | 1151 // We temporarily store the allocation type in the offset field |
1164 fields->short_at_put(index++, atype); | 1152 field->set_offset(atype); |
1165 fields->short_at_put(index++, 0); // Clear out high word of byte offset | 1153 } |
1166 fields->short_at_put(index++, generic_signature_index); | 1154 |
1155 if (num_injected != 0) { | |
1156 int index = length; | |
1157 for (int n = 0; n < num_injected; n++) { | |
1158 // Check for duplicates | |
1159 if (injected[n].may_be_java) { | |
1160 Symbol* name = injected[n].name(); | |
1161 Symbol* signature = injected[n].signature(); | |
1162 bool duplicate = false; | |
1163 for (int i = 0; i < length; i++) { | |
1164 FieldInfo* f = FieldInfo::from_field_array(fields(), i); | |
1165 if (name == cp->symbol_at(f->name_index()) && | |
1166 signature == cp->symbol_at(f->signature_index())) { | |
1167 // Symbol is desclared in Java so skip this one | |
1168 duplicate = true; | |
1169 break; | |
1170 } | |
1171 } | |
1172 if (duplicate) { | |
1173 // These will be removed from the field array at the end | |
1174 continue; | |
1175 } | |
1176 } | |
1177 | |
1178 // Injected field | |
1179 FieldInfo* field = FieldInfo::from_field_array(fields(), index); | |
1180 field->initialize(JVM_ACC_FIELD_INTERNAL, | |
1181 injected[n].name_index, | |
1182 injected[n].signature_index, | |
1183 0, | |
1184 0, | |
1185 0); | |
1186 | |
1187 BasicType type = FieldType::basic_type(injected[n].signature()); | |
1188 | |
1189 // Remember how many oops we encountered and compute allocation type | |
1190 FieldAllocationType atype = fac->update(false, type); | |
1191 | |
1192 // The correct offset is computed later (all oop fields will be located together) | |
1193 // We temporarily store the allocation type in the offset field | |
1194 field->set_offset(atype); | |
1195 index++; | |
1196 } | |
1197 | |
1198 if (index < length + num_injected) { | |
1199 // sometimes injected fields already exist in the Java source so | |
1200 // the fields array could be too long. In that case trim the | |
1201 // fields array. | |
1202 new_fields = oopFactory::new_permanent_shortArray(index * FieldInfo::field_slots, CHECK_(nullHandle)); | |
1203 for (int i = 0; i < index * FieldInfo::field_slots; i++) { | |
1204 new_fields->short_at_put(i, fields->short_at(i)); | |
1205 } | |
1206 fields = new_fields; | |
1207 } | |
1167 } | 1208 } |
1168 | 1209 |
1169 if (_need_verify && length > 1) { | 1210 if (_need_verify && length > 1) { |
1170 // Check duplicated fields | 1211 // Check duplicated fields |
1171 ResourceMark rm(THREAD); | 1212 ResourceMark rm(THREAD); |
1173 THREAD, NameSigHash*, HASH_ROW_SIZE); | 1214 THREAD, NameSigHash*, HASH_ROW_SIZE); |
1174 initialize_hashtable(names_and_sigs); | 1215 initialize_hashtable(names_and_sigs); |
1175 bool dup = false; | 1216 bool dup = false; |
1176 { | 1217 { |
1177 debug_only(No_Safepoint_Verifier nsv;) | 1218 debug_only(No_Safepoint_Verifier nsv;) |
1178 for (int i = 0; i < length*instanceKlass::next_offset; i += instanceKlass::next_offset) { | 1219 for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { |
1179 int name_index = fields->ushort_at(i + instanceKlass::name_index_offset); | 1220 Symbol* name = fs.name(); |
1180 Symbol* name = cp->symbol_at(name_index); | 1221 Symbol* sig = fs.signature(); |
1181 int sig_index = fields->ushort_at(i + instanceKlass::signature_index_offset); | |
1182 Symbol* sig = cp->symbol_at(sig_index); | |
1183 // If no duplicates, add name/signature in hashtable names_and_sigs. | 1222 // If no duplicates, add name/signature in hashtable names_and_sigs. |
1184 if (!put_after_lookup(name, sig, names_and_sigs)) { | 1223 if (!put_after_lookup(name, sig, names_and_sigs)) { |
1185 dup = true; | 1224 dup = true; |
1186 break; | 1225 break; |
1187 } | 1226 } |
2590 } | 2629 } |
2591 return annotations; | 2630 return annotations; |
2592 } | 2631 } |
2593 | 2632 |
2594 | 2633 |
2595 void ClassFileParser::java_lang_ref_Reference_fix_pre(typeArrayHandle* fields_ptr, | |
2596 constantPoolHandle cp, FieldAllocationCount *fac_ptr, TRAPS) { | |
2597 // This code is for compatibility with earlier jdk's that do not | |
2598 // have the "discovered" field in java.lang.ref.Reference. For 1.5 | |
2599 // the check for the "discovered" field should issue a warning if | |
2600 // the field is not found. For 1.6 this code should be issue a | |
2601 // fatal error if the "discovered" field is not found. | |
2602 // | |
2603 // Increment fac.nonstatic_oop_count so that the start of the | |
2604 // next type of non-static oops leaves room for the fake oop. | |
2605 // Do not increment next_nonstatic_oop_offset so that the | |
2606 // fake oop is place after the java.lang.ref.Reference oop | |
2607 // fields. | |
2608 // | |
2609 // Check the fields in java.lang.ref.Reference for the "discovered" | |
2610 // field. If it is not present, artifically create a field for it. | |
2611 // This allows this VM to run on early JDK where the field is not | |
2612 // present. | |
2613 int reference_sig_index = 0; | |
2614 int reference_name_index = 0; | |
2615 int reference_index = 0; | |
2616 int extra = java_lang_ref_Reference::number_of_fake_oop_fields; | |
2617 const int n = (*fields_ptr)()->length(); | |
2618 for (int i = 0; i < n; i += instanceKlass::next_offset ) { | |
2619 int name_index = | |
2620 (*fields_ptr)()->ushort_at(i + instanceKlass::name_index_offset); | |
2621 int sig_index = | |
2622 (*fields_ptr)()->ushort_at(i + instanceKlass::signature_index_offset); | |
2623 Symbol* f_name = cp->symbol_at(name_index); | |
2624 Symbol* f_sig = cp->symbol_at(sig_index); | |
2625 if (f_sig == vmSymbols::reference_signature() && reference_index == 0) { | |
2626 // Save the index for reference signature for later use. | |
2627 // The fake discovered field does not entries in the | |
2628 // constant pool so the index for its signature cannot | |
2629 // be extracted from the constant pool. It will need | |
2630 // later, however. It's signature is vmSymbols::reference_signature() | |
2631 // so same an index for that signature. | |
2632 reference_sig_index = sig_index; | |
2633 reference_name_index = name_index; | |
2634 reference_index = i; | |
2635 } | |
2636 if (f_name == vmSymbols::reference_discovered_name() && | |
2637 f_sig == vmSymbols::reference_signature()) { | |
2638 // The values below are fake but will force extra | |
2639 // non-static oop fields and a corresponding non-static | |
2640 // oop map block to be allocated. | |
2641 extra = 0; | |
2642 break; | |
2643 } | |
2644 } | |
2645 if (extra != 0) { | |
2646 fac_ptr->nonstatic_oop_count += extra; | |
2647 // Add the additional entry to "fields" so that the klass | |
2648 // contains the "discoverd" field and the field will be initialized | |
2649 // in instances of the object. | |
2650 int fields_with_fix_length = (*fields_ptr)()->length() + | |
2651 instanceKlass::next_offset; | |
2652 typeArrayOop ff = oopFactory::new_permanent_shortArray( | |
2653 fields_with_fix_length, CHECK); | |
2654 typeArrayHandle fields_with_fix(THREAD, ff); | |
2655 | |
2656 // Take everything from the original but the length. | |
2657 for (int idx = 0; idx < (*fields_ptr)->length(); idx++) { | |
2658 fields_with_fix->ushort_at_put(idx, (*fields_ptr)->ushort_at(idx)); | |
2659 } | |
2660 | |
2661 // Add the fake field at the end. | |
2662 int i = (*fields_ptr)->length(); | |
2663 // There is no name index for the fake "discovered" field nor | |
2664 // signature but a signature is needed so that the field will | |
2665 // be properly initialized. Use one found for | |
2666 // one of the other reference fields. Be sure the index for the | |
2667 // name is 0. In fieldDescriptor::initialize() the index of the | |
2668 // name is checked. That check is by passed for the last nonstatic | |
2669 // oop field in a java.lang.ref.Reference which is assumed to be | |
2670 // this artificial "discovered" field. An assertion checks that | |
2671 // the name index is 0. | |
2672 assert(reference_index != 0, "Missing signature for reference"); | |
2673 | |
2674 int j; | |
2675 for (j = 0; j < instanceKlass::next_offset; j++) { | |
2676 fields_with_fix->ushort_at_put(i + j, | |
2677 (*fields_ptr)->ushort_at(reference_index +j)); | |
2678 } | |
2679 // Clear the public access flag and set the private access flag. | |
2680 short flags; | |
2681 flags = | |
2682 fields_with_fix->ushort_at(i + instanceKlass::access_flags_offset); | |
2683 assert(!(flags & JVM_RECOGNIZED_FIELD_MODIFIERS), "Unexpected access flags set"); | |
2684 flags = flags & (~JVM_ACC_PUBLIC); | |
2685 flags = flags | JVM_ACC_PRIVATE; | |
2686 AccessFlags access_flags; | |
2687 access_flags.set_flags(flags); | |
2688 assert(!access_flags.is_public(), "Failed to clear public flag"); | |
2689 assert(access_flags.is_private(), "Failed to set private flag"); | |
2690 fields_with_fix->ushort_at_put(i + instanceKlass::access_flags_offset, | |
2691 flags); | |
2692 | |
2693 assert(fields_with_fix->ushort_at(i + instanceKlass::name_index_offset) | |
2694 == reference_name_index, "The fake reference name is incorrect"); | |
2695 assert(fields_with_fix->ushort_at(i + instanceKlass::signature_index_offset) | |
2696 == reference_sig_index, "The fake reference signature is incorrect"); | |
2697 // The type of the field is stored in the low_offset entry during | |
2698 // parsing. | |
2699 assert(fields_with_fix->ushort_at(i + instanceKlass::low_offset) == | |
2700 NONSTATIC_OOP, "The fake reference type is incorrect"); | |
2701 | |
2702 // "fields" is allocated in the permanent generation. Disgard | |
2703 // it and let it be collected. | |
2704 (*fields_ptr) = fields_with_fix; | |
2705 } | |
2706 return; | |
2707 } | |
2708 | |
2709 | |
2710 void ClassFileParser::java_lang_Class_fix_pre(int* nonstatic_field_size, | |
2711 FieldAllocationCount *fac_ptr) { | |
2712 // Add fake fields for java.lang.Class instances | |
2713 // | |
2714 // This is not particularly nice. We should consider adding a | |
2715 // private transient object field at the Java level to | |
2716 // java.lang.Class. Alternatively we could add a subclass of | |
2717 // instanceKlass which provides an accessor and size computer for | |
2718 // this field, but that appears to be more code than this hack. | |
2719 // | |
2720 // NOTE that we wedge these in at the beginning rather than the | |
2721 // end of the object because the Class layout changed between JDK | |
2722 // 1.3 and JDK 1.4 with the new reflection implementation; some | |
2723 // nonstatic oop fields were added at the Java level. The offsets | |
2724 // of these fake fields can't change between these two JDK | |
2725 // versions because when the offsets are computed at bootstrap | |
2726 // time we don't know yet which version of the JDK we're running in. | |
2727 | |
2728 // The values below are fake but will force three non-static oop fields and | |
2729 // a corresponding non-static oop map block to be allocated. | |
2730 const int extra = java_lang_Class::number_of_fake_oop_fields; | |
2731 fac_ptr->nonstatic_oop_count += extra; | |
2732 | |
2733 // Reserve some leading space for fake ints | |
2734 *nonstatic_field_size += align_size_up(java_lang_Class::hc_number_of_fake_int_fields * BytesPerInt, heapOopSize) / heapOopSize; | |
2735 } | |
2736 | |
2737 | |
2738 void ClassFileParser::java_lang_Class_fix_post(int* next_nonstatic_oop_offset_ptr) { | |
2739 // Cause the extra fake fields in java.lang.Class to show up before | |
2740 // the Java fields for layout compatibility between 1.3 and 1.4 | |
2741 // Incrementing next_nonstatic_oop_offset here advances the | |
2742 // location where the real java fields are placed. | |
2743 const int extra = java_lang_Class::number_of_fake_oop_fields; | |
2744 (*next_nonstatic_oop_offset_ptr) += (extra * heapOopSize); | |
2745 } | |
2746 | |
2747 | |
2748 // Force MethodHandle.vmentry to be an unmanaged pointer. | |
2749 // There is no way for a classfile to express this, so we must help it. | |
2750 void ClassFileParser::java_lang_invoke_MethodHandle_fix_pre(constantPoolHandle cp, | |
2751 typeArrayHandle fields, | |
2752 FieldAllocationCount *fac_ptr, | |
2753 TRAPS) { | |
2754 // Add fake fields for java.lang.invoke.MethodHandle instances | |
2755 // | |
2756 // This is not particularly nice, but since there is no way to express | |
2757 // a native wordSize field in Java, we must do it at this level. | |
2758 | |
2759 if (!EnableInvokeDynamic) return; | |
2760 | |
2761 int word_sig_index = 0; | |
2762 const int cp_size = cp->length(); | |
2763 for (int index = 1; index < cp_size; index++) { | |
2764 if (cp->tag_at(index).is_utf8() && | |
2765 cp->symbol_at(index) == vmSymbols::machine_word_signature()) { | |
2766 word_sig_index = index; | |
2767 break; | |
2768 } | |
2769 } | |
2770 | |
2771 if (word_sig_index == 0) | |
2772 THROW_MSG(vmSymbols::java_lang_VirtualMachineError(), | |
2773 "missing I or J signature (for vmentry) in java.lang.invoke.MethodHandle"); | |
2774 | |
2775 // Find vmentry field and change the signature. | |
2776 bool found_vmentry = false; | |
2777 for (int i = 0; i < fields->length(); i += instanceKlass::next_offset) { | |
2778 int name_index = fields->ushort_at(i + instanceKlass::name_index_offset); | |
2779 int sig_index = fields->ushort_at(i + instanceKlass::signature_index_offset); | |
2780 int acc_flags = fields->ushort_at(i + instanceKlass::access_flags_offset); | |
2781 Symbol* f_name = cp->symbol_at(name_index); | |
2782 Symbol* f_sig = cp->symbol_at(sig_index); | |
2783 if (f_name == vmSymbols::vmentry_name() && (acc_flags & JVM_ACC_STATIC) == 0) { | |
2784 if (f_sig == vmSymbols::machine_word_signature()) { | |
2785 // If the signature of vmentry is already changed, we're done. | |
2786 found_vmentry = true; | |
2787 break; | |
2788 } | |
2789 else if (f_sig == vmSymbols::byte_signature()) { | |
2790 // Adjust the field type from byte to an unmanaged pointer. | |
2791 assert(fac_ptr->nonstatic_byte_count > 0, ""); | |
2792 fac_ptr->nonstatic_byte_count -= 1; | |
2793 | |
2794 fields->ushort_at_put(i + instanceKlass::signature_index_offset, word_sig_index); | |
2795 assert(wordSize == longSize || wordSize == jintSize, "ILP32 or LP64"); | |
2796 if (wordSize == longSize) fac_ptr->nonstatic_double_count += 1; | |
2797 else fac_ptr->nonstatic_word_count += 1; | |
2798 | |
2799 FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i + instanceKlass::low_offset); | |
2800 assert(atype == NONSTATIC_BYTE, ""); | |
2801 FieldAllocationType new_atype = (wordSize == longSize) ? NONSTATIC_DOUBLE : NONSTATIC_WORD; | |
2802 fields->ushort_at_put(i + instanceKlass::low_offset, new_atype); | |
2803 | |
2804 found_vmentry = true; | |
2805 break; | |
2806 } | |
2807 } | |
2808 } | |
2809 | |
2810 if (!found_vmentry) | |
2811 THROW_MSG(vmSymbols::java_lang_VirtualMachineError(), | |
2812 "missing vmentry byte field in java.lang.invoke.MethodHandle"); | |
2813 } | |
2814 | |
2815 | |
2816 instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, | 2634 instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, |
2817 Handle class_loader, | 2635 Handle class_loader, |
2818 Handle protection_domain, | 2636 Handle protection_domain, |
2819 KlassHandle host_klass, | 2637 KlassHandle host_klass, |
2820 GrowableArray<Handle>* cp_patches, | 2638 GrowableArray<Handle>* cp_patches, |
3023 local_interfaces = objArrayHandle(THREAD, Universe::the_empty_system_obj_array()); | 2841 local_interfaces = objArrayHandle(THREAD, Universe::the_empty_system_obj_array()); |
3024 } else { | 2842 } else { |
3025 local_interfaces = parse_interfaces(cp, itfs_len, class_loader, protection_domain, _class_name, CHECK_(nullHandle)); | 2843 local_interfaces = parse_interfaces(cp, itfs_len, class_loader, protection_domain, _class_name, CHECK_(nullHandle)); |
3026 } | 2844 } |
3027 | 2845 |
2846 int java_fields_count = 0; | |
3028 // Fields (offsets are filled in later) | 2847 // Fields (offsets are filled in later) |
3029 struct FieldAllocationCount fac = {0,0,0,0,0,0,0,0,0,0}; | 2848 FieldAllocationCount fac; |
3030 objArrayHandle fields_annotations; | 2849 objArrayHandle fields_annotations; |
3031 typeArrayHandle fields = parse_fields(cp, access_flags.is_interface(), &fac, &fields_annotations, CHECK_(nullHandle)); | 2850 typeArrayHandle fields = parse_fields(class_name, cp, access_flags.is_interface(), &fac, &fields_annotations, |
2851 &java_fields_count, | |
2852 CHECK_(nullHandle)); | |
3032 // Methods | 2853 // Methods |
3033 bool has_final_method = false; | 2854 bool has_final_method = false; |
3034 AccessFlags promoted_flags; | 2855 AccessFlags promoted_flags; |
3035 promoted_flags.set_flags(0); | 2856 promoted_flags.set_flags(0); |
3036 // These need to be oop pointers because they are allocated lazily | 2857 // These need to be oop pointers because they are allocated lazily |
3144 int next_nonstatic_field_offset; | 2965 int next_nonstatic_field_offset; |
3145 | 2966 |
3146 // Calculate the starting byte offsets | 2967 // Calculate the starting byte offsets |
3147 next_static_oop_offset = instanceMirrorKlass::offset_of_static_fields(); | 2968 next_static_oop_offset = instanceMirrorKlass::offset_of_static_fields(); |
3148 next_static_double_offset = next_static_oop_offset + | 2969 next_static_double_offset = next_static_oop_offset + |
3149 (fac.static_oop_count * heapOopSize); | 2970 (fac.count[STATIC_OOP] * heapOopSize); |
3150 if ( fac.static_double_count && | 2971 if ( fac.count[STATIC_DOUBLE] && |
3151 (Universe::field_type_should_be_aligned(T_DOUBLE) || | 2972 (Universe::field_type_should_be_aligned(T_DOUBLE) || |
3152 Universe::field_type_should_be_aligned(T_LONG)) ) { | 2973 Universe::field_type_should_be_aligned(T_LONG)) ) { |
3153 next_static_double_offset = align_size_up(next_static_double_offset, BytesPerLong); | 2974 next_static_double_offset = align_size_up(next_static_double_offset, BytesPerLong); |
3154 } | 2975 } |
3155 | 2976 |
3156 next_static_word_offset = next_static_double_offset + | 2977 next_static_word_offset = next_static_double_offset + |
3157 (fac.static_double_count * BytesPerLong); | 2978 (fac.count[STATIC_DOUBLE] * BytesPerLong); |
3158 next_static_short_offset = next_static_word_offset + | 2979 next_static_short_offset = next_static_word_offset + |
3159 (fac.static_word_count * BytesPerInt); | 2980 (fac.count[STATIC_WORD] * BytesPerInt); |
3160 next_static_byte_offset = next_static_short_offset + | 2981 next_static_byte_offset = next_static_short_offset + |
3161 (fac.static_short_count * BytesPerShort); | 2982 (fac.count[STATIC_SHORT] * BytesPerShort); |
3162 next_static_type_offset = align_size_up((next_static_byte_offset + | 2983 next_static_type_offset = align_size_up((next_static_byte_offset + |
3163 fac.static_byte_count ), wordSize ); | 2984 fac.count[STATIC_BYTE] ), wordSize ); |
3164 static_field_size = (next_static_type_offset - | 2985 static_field_size = (next_static_type_offset - |
3165 next_static_oop_offset) / wordSize; | 2986 next_static_oop_offset) / wordSize; |
3166 | |
3167 // Add fake fields for java.lang.Class instances (also see below) | |
3168 if (class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) { | |
3169 java_lang_Class_fix_pre(&nonstatic_field_size, &fac); | |
3170 } | |
3171 | 2987 |
3172 first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() + | 2988 first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() + |
3173 nonstatic_field_size * heapOopSize; | 2989 nonstatic_field_size * heapOopSize; |
3174 next_nonstatic_field_offset = first_nonstatic_field_offset; | 2990 next_nonstatic_field_offset = first_nonstatic_field_offset; |
3175 | 2991 |
3176 // adjust the vmentry field declaration in java.lang.invoke.MethodHandle | 2992 unsigned int nonstatic_double_count = fac.count[NONSTATIC_DOUBLE]; |
3177 if (EnableInvokeDynamic && class_name == vmSymbols::java_lang_invoke_MethodHandle() && class_loader.is_null()) { | 2993 unsigned int nonstatic_word_count = fac.count[NONSTATIC_WORD]; |
3178 java_lang_invoke_MethodHandle_fix_pre(cp, fields, &fac, CHECK_(nullHandle)); | 2994 unsigned int nonstatic_short_count = fac.count[NONSTATIC_SHORT]; |
3179 } | 2995 unsigned int nonstatic_byte_count = fac.count[NONSTATIC_BYTE]; |
3180 | 2996 unsigned int nonstatic_oop_count = fac.count[NONSTATIC_OOP]; |
3181 // Add a fake "discovered" field if it is not present | |
3182 // for compatibility with earlier jdk's. | |
3183 if (class_name == vmSymbols::java_lang_ref_Reference() | |
3184 && class_loader.is_null()) { | |
3185 java_lang_ref_Reference_fix_pre(&fields, cp, &fac, CHECK_(nullHandle)); | |
3186 } | |
3187 // end of "discovered" field compactibility fix | |
3188 | |
3189 unsigned int nonstatic_double_count = fac.nonstatic_double_count; | |
3190 unsigned int nonstatic_word_count = fac.nonstatic_word_count; | |
3191 unsigned int nonstatic_short_count = fac.nonstatic_short_count; | |
3192 unsigned int nonstatic_byte_count = fac.nonstatic_byte_count; | |
3193 unsigned int nonstatic_oop_count = fac.nonstatic_oop_count; | |
3194 | 2997 |
3195 bool super_has_nonstatic_fields = | 2998 bool super_has_nonstatic_fields = |
3196 (super_klass() != NULL && super_klass->has_nonstatic_fields()); | 2999 (super_klass() != NULL && super_klass->has_nonstatic_fields()); |
3197 bool has_nonstatic_fields = super_has_nonstatic_fields || | 3000 bool has_nonstatic_fields = super_has_nonstatic_fields || |
3198 ((nonstatic_double_count + nonstatic_word_count + | 3001 ((nonstatic_double_count + nonstatic_word_count + |
3208 nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD( | 3011 nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD( |
3209 THREAD, int, nonstatic_oop_count + 1); | 3012 THREAD, int, nonstatic_oop_count + 1); |
3210 nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD( | 3013 nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD( |
3211 THREAD, unsigned int, nonstatic_oop_count + 1); | 3014 THREAD, unsigned int, nonstatic_oop_count + 1); |
3212 | 3015 |
3213 // Add fake fields for java.lang.Class instances (also see above). | 3016 first_nonstatic_oop_offset = 0; // will be set for first oop field |
3214 // FieldsAllocationStyle and CompactFields values will be reset to default. | |
3215 if(class_name == vmSymbols::java_lang_Class() && class_loader.is_null()) { | |
3216 java_lang_Class_fix_post(&next_nonstatic_field_offset); | |
3217 nonstatic_oop_offsets[0] = first_nonstatic_field_offset; | |
3218 const uint fake_oop_count = (next_nonstatic_field_offset - | |
3219 first_nonstatic_field_offset) / heapOopSize; | |
3220 nonstatic_oop_counts[0] = fake_oop_count; | |
3221 nonstatic_oop_map_count = 1; | |
3222 nonstatic_oop_count -= fake_oop_count; | |
3223 first_nonstatic_oop_offset = first_nonstatic_field_offset; | |
3224 } else { | |
3225 first_nonstatic_oop_offset = 0; // will be set for first oop field | |
3226 } | |
3227 | 3017 |
3228 #ifndef PRODUCT | 3018 #ifndef PRODUCT |
3229 if( PrintCompactFieldsSavings ) { | 3019 if( PrintCompactFieldsSavings ) { |
3230 next_nonstatic_double_offset = next_nonstatic_field_offset + | 3020 next_nonstatic_double_offset = next_nonstatic_field_offset + |
3231 (nonstatic_oop_count * heapOopSize); | 3021 (nonstatic_oop_count * heapOopSize); |
3376 - first_nonstatic_field_offset)/heapOopSize); | 3166 - first_nonstatic_field_offset)/heapOopSize); |
3377 | 3167 |
3378 // Iterate over fields again and compute correct offsets. | 3168 // Iterate over fields again and compute correct offsets. |
3379 // The field allocation type was temporarily stored in the offset slot. | 3169 // The field allocation type was temporarily stored in the offset slot. |
3380 // oop fields are located before non-oop fields (static and non-static). | 3170 // oop fields are located before non-oop fields (static and non-static). |
3381 int len = fields->length(); | 3171 for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) { |
3382 for (int i = 0; i < len; i += instanceKlass::next_offset) { | |
3383 int real_offset; | 3172 int real_offset; |
3384 FieldAllocationType atype = (FieldAllocationType) fields->ushort_at(i + instanceKlass::low_offset); | 3173 FieldAllocationType atype = (FieldAllocationType) fs.offset(); |
3385 switch (atype) { | 3174 switch (atype) { |
3386 case STATIC_OOP: | 3175 case STATIC_OOP: |
3387 real_offset = next_static_oop_offset; | 3176 real_offset = next_static_oop_offset; |
3388 next_static_oop_offset += heapOopSize; | 3177 next_static_oop_offset += heapOopSize; |
3389 break; | 3178 break; |
3397 break; | 3186 break; |
3398 case STATIC_WORD: | 3187 case STATIC_WORD: |
3399 real_offset = next_static_word_offset; | 3188 real_offset = next_static_word_offset; |
3400 next_static_word_offset += BytesPerInt; | 3189 next_static_word_offset += BytesPerInt; |
3401 break; | 3190 break; |
3402 case STATIC_ALIGNED_DOUBLE: | |
3403 case STATIC_DOUBLE: | 3191 case STATIC_DOUBLE: |
3404 real_offset = next_static_double_offset; | 3192 real_offset = next_static_double_offset; |
3405 next_static_double_offset += BytesPerLong; | 3193 next_static_double_offset += BytesPerLong; |
3406 break; | 3194 break; |
3407 case NONSTATIC_OOP: | 3195 case NONSTATIC_OOP: |
3459 } else { | 3247 } else { |
3460 real_offset = next_nonstatic_word_offset; | 3248 real_offset = next_nonstatic_word_offset; |
3461 next_nonstatic_word_offset += BytesPerInt; | 3249 next_nonstatic_word_offset += BytesPerInt; |
3462 } | 3250 } |
3463 break; | 3251 break; |
3464 case NONSTATIC_ALIGNED_DOUBLE: | |
3465 case NONSTATIC_DOUBLE: | 3252 case NONSTATIC_DOUBLE: |
3466 real_offset = next_nonstatic_double_offset; | 3253 real_offset = next_nonstatic_double_offset; |
3467 next_nonstatic_double_offset += BytesPerLong; | 3254 next_nonstatic_double_offset += BytesPerLong; |
3468 break; | 3255 break; |
3469 default: | 3256 default: |
3470 ShouldNotReachHere(); | 3257 ShouldNotReachHere(); |
3471 } | 3258 } |
3472 fields->short_at_put(i + instanceKlass::low_offset, extract_low_short_from_int(real_offset)); | 3259 fs.set_offset(real_offset); |
3473 fields->short_at_put(i + instanceKlass::high_offset, extract_high_short_from_int(real_offset)); | |
3474 } | 3260 } |
3475 | 3261 |
3476 // Size of instances | 3262 // Size of instances |
3477 int instance_size; | 3263 int instance_size; |
3478 | 3264 |
3515 // Not yet: supers are done below to support the new subtype-checking fields | 3301 // Not yet: supers are done below to support the new subtype-checking fields |
3516 //this_klass->set_super(super_klass()); | 3302 //this_klass->set_super(super_klass()); |
3517 this_klass->set_class_loader(class_loader()); | 3303 this_klass->set_class_loader(class_loader()); |
3518 this_klass->set_nonstatic_field_size(nonstatic_field_size); | 3304 this_klass->set_nonstatic_field_size(nonstatic_field_size); |
3519 this_klass->set_has_nonstatic_fields(has_nonstatic_fields); | 3305 this_klass->set_has_nonstatic_fields(has_nonstatic_fields); |
3520 this_klass->set_static_oop_field_count(fac.static_oop_count); | 3306 this_klass->set_static_oop_field_count(fac.count[STATIC_OOP]); |
3521 cp->set_pool_holder(this_klass()); | 3307 cp->set_pool_holder(this_klass()); |
3522 error_handler.set_in_error(false); // turn off error handler for cp | 3308 error_handler.set_in_error(false); // turn off error handler for cp |
3523 this_klass->set_constants(cp()); | 3309 this_klass->set_constants(cp()); |
3524 this_klass->set_local_interfaces(local_interfaces()); | 3310 this_klass->set_local_interfaces(local_interfaces()); |
3525 this_klass->set_fields(fields()); | 3311 this_klass->set_fields(fields(), java_fields_count); |
3526 this_klass->set_methods(methods()); | 3312 this_klass->set_methods(methods()); |
3527 if (has_final_method) { | 3313 if (has_final_method) { |
3528 this_klass->set_has_final_method(); | 3314 this_klass->set_has_final_method(); |
3529 } | 3315 } |
3530 this_klass->set_method_ordering(method_ordering()); | 3316 this_klass->set_method_ordering(method_ordering()); |