< prev index next >

src/hotspot/share/classfile/javaClasses.cpp

Print this page


  33 #include "code/dependencyContext.hpp"
  34 #include "code/pcDesc.hpp"
  35 #include "interpreter/interpreter.hpp"
  36 #include "interpreter/linkResolver.hpp"
  37 #include "logging/log.hpp"
  38 #include "logging/logStream.hpp"
  39 #include "memory/heapShared.inline.hpp"
  40 #include "memory/metaspaceShared.hpp"
  41 #include "memory/oopFactory.hpp"
  42 #include "memory/resourceArea.hpp"
  43 #include "memory/universe.hpp"
  44 #include "oops/fieldStreams.hpp"
  45 #include "oops/instanceKlass.hpp"
  46 #include "oops/instanceMirrorKlass.hpp"
  47 #include "oops/klass.hpp"
  48 #include "oops/method.inline.hpp"
  49 #include "oops/objArrayOop.inline.hpp"
  50 #include "oops/oop.inline.hpp"
  51 #include "oops/symbol.hpp"
  52 #include "oops/typeArrayOop.inline.hpp"

  53 #include "prims/resolvedMethodTable.hpp"
  54 #include "runtime/fieldDescriptor.inline.hpp"
  55 #include "runtime/frame.inline.hpp"
  56 #include "runtime/handles.inline.hpp"
  57 #include "runtime/interfaceSupport.inline.hpp"
  58 #include "runtime/java.hpp"
  59 #include "runtime/javaCalls.hpp"
  60 #include "runtime/jniHandles.inline.hpp"
  61 #include "runtime/safepoint.hpp"
  62 #include "runtime/safepointVerifiers.hpp"
  63 #include "runtime/thread.inline.hpp"
  64 #include "runtime/vframe.inline.hpp"
  65 #include "utilities/align.hpp"
  66 #include "utilities/preserveException.hpp"
  67 #if INCLUDE_JVMCI
  68 #include "jvmci/jvmciJavaClasses.hpp"
  69 #endif
  70 
  71 #define INJECTED_FIELD_COMPUTE_OFFSET(klass, name, signature, may_be_java)    \
  72   klass::_##name##_offset = JavaClasses::compute_injected_offset(JavaClasses::klass##_##name##_enum);


 108 #undef LOOKUP_INJECTED_FIELD
 109 
 110   if (start != -1) {
 111     *field_count = count;
 112     return _injected_fields + start;
 113   }
 114   return NULL;
 115 }
 116 
 117 
 118 // Helpful routine for computing field offsets at run time rather than hardcoding them
 119 // Finds local fields only, including static fields.  Static field offsets are from the
 120 // beginning of the mirror.
 121 static void compute_offset(int &dest_offset,
 122                            InstanceKlass* ik, Symbol* name_symbol, Symbol* signature_symbol,
 123                            bool is_static = false) {
 124   fieldDescriptor fd;
 125   if (ik == NULL) {
 126     ResourceMark rm;
 127     log_error(class)("Mismatch JDK version for field: %s type: %s", name_symbol->as_C_string(), signature_symbol->as_C_string());
 128     vm_exit_during_initialization("Invalid layout of preloaded class");
 129   }
 130 
 131   if (!ik->find_local_field(name_symbol, signature_symbol, &fd) || fd.is_static() != is_static) {
 132     ResourceMark rm;
 133     log_error(class)("Invalid layout of %s field: %s type: %s", ik->external_name(),
 134                      name_symbol->as_C_string(), signature_symbol->as_C_string());
 135 #ifndef PRODUCT
 136     // Prints all fields and offsets
 137     Log(class) lt;
 138     LogStream ls(lt.error());
 139     ik->print_on(&ls);
 140 #endif //PRODUCT
 141     vm_exit_during_initialization("Invalid layout of preloaded class: use -Xlog:class+load=info to see the origin of the problem class");
 142   }
 143   dest_offset = fd.offset();
 144 }
 145 
 146 // Overloading to pass name as a string.
 147 static void compute_offset(int& dest_offset, InstanceKlass* ik,
 148                            const char* name_string, Symbol* signature_symbol,
 149                            bool is_static = false) {
 150   TempNewSymbol name = SymbolTable::probe(name_string, (int)strlen(name_string));
 151   if (name == NULL) {
 152     ResourceMark rm;
 153     log_error(class)("Name %s should be in the SymbolTable since its class is loaded", name_string);
 154     vm_exit_during_initialization("Invalid layout of preloaded class", ik->external_name());
 155   }
 156   compute_offset(dest_offset, ik, name, signature_symbol, is_static);
 157 }
 158 
 159 int java_lang_String::value_offset  = 0;
 160 int java_lang_String::hash_offset   = 0;
 161 int java_lang_String::coder_offset  = 0;
 162 
 163 bool java_lang_String::initialized  = false;
 164 
 165 bool java_lang_String::is_instance(oop obj) {
 166   return is_instance_inlined(obj);
 167 }
 168 
 169 #if INCLUDE_CDS
 170 #define FIELD_SERIALIZE_OFFSET(offset, klass, name, signature, is_static) \
 171   f->do_u4((u4*)&offset)
 172 #endif
 173 
 174 #define FIELD_COMPUTE_OFFSET(offset, klass, name, signature, is_static) \


1179   // The field at _array_klass_offset is pointing to the original one dimension
1180   // higher array klass if exists. Relocate the pointer.
1181   Klass *arr = array_klass_acquire(mirror);
1182   if (arr != NULL) {
1183     Klass *reloc_arr = MetaspaceShared::get_relocated_klass(arr);
1184     log_debug(cds, heap, mirror)(
1185       "Relocate mirror metadata field at _array_klass_offset from " PTR_FORMAT " ==> " PTR_FORMAT,
1186       p2i(arr), p2i(reloc_arr));
1187     archived_mirror->metadata_field_put(_array_klass_offset, reloc_arr);
1188   }
1189   return archived_mirror;
1190 }
1191 
1192 // Returns true if the mirror is updated, false if no archived mirror
1193 // data is present. After the archived mirror object is restored, the
1194 // shared klass' _has_raw_archived_mirror flag is cleared.
1195 bool java_lang_Class::restore_archived_mirror(Klass *k,
1196                                               Handle class_loader, Handle module,
1197                                               Handle protection_domain, TRAPS) {
1198   // Postpone restoring archived mirror until java.lang.Class is loaded. Please
1199   // see more details in SystemDictionary::resolve_preloaded_classes().
1200   if (!SystemDictionary::Class_klass_loaded()) {
1201     assert(fixup_mirror_list() != NULL, "fixup_mirror_list not initialized");
1202     fixup_mirror_list()->push(k);
1203     return true;
1204   }
1205 
1206   oop m = HeapShared::materialize_archived_object(k->archived_java_mirror_raw_narrow());
1207 
1208   if (m == NULL) {
1209     return false;
1210   }
1211 
1212   log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m));
1213 
1214   // mirror is archived, restore
1215   assert(HeapShared::is_archived_object(m), "must be archived mirror object");
1216   Handle mirror(THREAD, m);
1217 
1218   if (!k->is_array_klass()) {
1219     // - local static final fields with initial values were initialized at dump time


4233 // Invoked before SystemDictionary::initialize, so pre-loaded classes
4234 // are not available to determine the offset_of_static_fields.
4235 void JavaClasses::compute_hard_coded_offsets() {
4236 
4237   // java_lang_boxing_object
4238   java_lang_boxing_object::value_offset      = member_offset(java_lang_boxing_object::hc_value_offset);
4239   java_lang_boxing_object::long_value_offset = align_up(member_offset(java_lang_boxing_object::hc_value_offset), BytesPerLong);
4240 
4241   // java_lang_ref_Reference
4242   java_lang_ref_Reference::referent_offset    = member_offset(java_lang_ref_Reference::hc_referent_offset);
4243   java_lang_ref_Reference::queue_offset       = member_offset(java_lang_ref_Reference::hc_queue_offset);
4244   java_lang_ref_Reference::next_offset        = member_offset(java_lang_ref_Reference::hc_next_offset);
4245   java_lang_ref_Reference::discovered_offset  = member_offset(java_lang_ref_Reference::hc_discovered_offset);
4246 }
4247 
4248 #define DO_COMPUTE_OFFSETS(k) k::compute_offsets();
4249 
4250 // Compute non-hard-coded field offsets of all the classes in this file
4251 void JavaClasses::compute_offsets() {
4252   if (UseSharedSpaces) {


4253     return; // field offsets are loaded from archive
4254   }
4255 
4256   // We have already called the compute_offsets() of the
4257   // BASIC_JAVA_CLASSES_DO_PART1 classes (java_lang_String and java_lang_Class)
4258   // earlier inside SystemDictionary::resolve_preloaded_classes()
4259   BASIC_JAVA_CLASSES_DO_PART2(DO_COMPUTE_OFFSETS);
4260 
4261   // generated interpreter code wants to know about the offsets we just computed:
4262   AbstractAssembler::update_delayed_values();
4263 }
4264 
4265 #if INCLUDE_CDS
4266 #define DO_SERIALIZE_OFFSETS(k) k::serialize_offsets(soc);
4267 
4268 void JavaClasses::serialize_offsets(SerializeClosure* soc) {
4269   BASIC_JAVA_CLASSES_DO(DO_SERIALIZE_OFFSETS);
4270 }
4271 #endif
4272 
4273 
4274 #ifndef PRODUCT
4275 
4276 // These functions exist to assert the validity of hard-coded field offsets to guard
4277 // against changes in the class files
4278 


4339 int InjectedField::compute_offset() {
4340   InstanceKlass* ik = InstanceKlass::cast(klass());
4341   for (AllFieldStream fs(ik); !fs.done(); fs.next()) {
4342     if (!may_be_java && !fs.access_flags().is_internal()) {
4343       // Only look at injected fields
4344       continue;
4345     }
4346     if (fs.name() == name() && fs.signature() == signature()) {
4347       return fs.offset();
4348     }
4349   }
4350   ResourceMark rm;
4351   tty->print_cr("Invalid layout of %s at %s/%s%s", ik->external_name(), name()->as_C_string(), signature()->as_C_string(), may_be_java ? " (may_be_java)" : "");
4352 #ifndef PRODUCT
4353   ik->print();
4354   tty->print_cr("all fields:");
4355   for (AllFieldStream fs(ik); !fs.done(); fs.next()) {
4356     tty->print_cr("  name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int());
4357   }
4358 #endif //PRODUCT
4359   vm_exit_during_initialization("Invalid layout of preloaded class: use -Xlog:class+load=info to see the origin of the problem class");
4360   return -1;
4361 }
4362 
4363 void javaClasses_init() {
4364   JavaClasses::compute_offsets();
4365   JavaClasses::check_offsets();
4366   FilteredFieldsMap::initialize();  // must be done after computing offsets.
4367 }


  33 #include "code/dependencyContext.hpp"
  34 #include "code/pcDesc.hpp"
  35 #include "interpreter/interpreter.hpp"
  36 #include "interpreter/linkResolver.hpp"
  37 #include "logging/log.hpp"
  38 #include "logging/logStream.hpp"
  39 #include "memory/heapShared.inline.hpp"
  40 #include "memory/metaspaceShared.hpp"
  41 #include "memory/oopFactory.hpp"
  42 #include "memory/resourceArea.hpp"
  43 #include "memory/universe.hpp"
  44 #include "oops/fieldStreams.hpp"
  45 #include "oops/instanceKlass.hpp"
  46 #include "oops/instanceMirrorKlass.hpp"
  47 #include "oops/klass.hpp"
  48 #include "oops/method.inline.hpp"
  49 #include "oops/objArrayOop.inline.hpp"
  50 #include "oops/oop.inline.hpp"
  51 #include "oops/symbol.hpp"
  52 #include "oops/typeArrayOop.inline.hpp"
  53 #include "prims/jvmtiEnvBase.hpp"
  54 #include "prims/resolvedMethodTable.hpp"
  55 #include "runtime/fieldDescriptor.inline.hpp"
  56 #include "runtime/frame.inline.hpp"
  57 #include "runtime/handles.inline.hpp"
  58 #include "runtime/interfaceSupport.inline.hpp"
  59 #include "runtime/java.hpp"
  60 #include "runtime/javaCalls.hpp"
  61 #include "runtime/jniHandles.inline.hpp"
  62 #include "runtime/safepoint.hpp"
  63 #include "runtime/safepointVerifiers.hpp"
  64 #include "runtime/thread.inline.hpp"
  65 #include "runtime/vframe.inline.hpp"
  66 #include "utilities/align.hpp"
  67 #include "utilities/preserveException.hpp"
  68 #if INCLUDE_JVMCI
  69 #include "jvmci/jvmciJavaClasses.hpp"
  70 #endif
  71 
  72 #define INJECTED_FIELD_COMPUTE_OFFSET(klass, name, signature, may_be_java)    \
  73   klass::_##name##_offset = JavaClasses::compute_injected_offset(JavaClasses::klass##_##name##_enum);


 109 #undef LOOKUP_INJECTED_FIELD
 110 
 111   if (start != -1) {
 112     *field_count = count;
 113     return _injected_fields + start;
 114   }
 115   return NULL;
 116 }
 117 
 118 
 119 // Helpful routine for computing field offsets at run time rather than hardcoding them
 120 // Finds local fields only, including static fields.  Static field offsets are from the
 121 // beginning of the mirror.
 122 static void compute_offset(int &dest_offset,
 123                            InstanceKlass* ik, Symbol* name_symbol, Symbol* signature_symbol,
 124                            bool is_static = false) {
 125   fieldDescriptor fd;
 126   if (ik == NULL) {
 127     ResourceMark rm;
 128     log_error(class)("Mismatch JDK version for field: %s type: %s", name_symbol->as_C_string(), signature_symbol->as_C_string());
 129     vm_exit_during_initialization("Invalid layout of well-known class");
 130   }
 131 
 132   if (!ik->find_local_field(name_symbol, signature_symbol, &fd) || fd.is_static() != is_static) {
 133     ResourceMark rm;
 134     log_error(class)("Invalid layout of %s field: %s type: %s", ik->external_name(),
 135                      name_symbol->as_C_string(), signature_symbol->as_C_string());
 136 #ifndef PRODUCT
 137     // Prints all fields and offsets
 138     Log(class) lt;
 139     LogStream ls(lt.error());
 140     ik->print_on(&ls);
 141 #endif //PRODUCT
 142     vm_exit_during_initialization("Invalid layout of well-known class: use -Xlog:class+load=info to see the origin of the problem class");
 143   }
 144   dest_offset = fd.offset();
 145 }
 146 
 147 // Overloading to pass name as a string.
 148 static void compute_offset(int& dest_offset, InstanceKlass* ik,
 149                            const char* name_string, Symbol* signature_symbol,
 150                            bool is_static = false) {
 151   TempNewSymbol name = SymbolTable::probe(name_string, (int)strlen(name_string));
 152   if (name == NULL) {
 153     ResourceMark rm;
 154     log_error(class)("Name %s should be in the SymbolTable since its class is loaded", name_string);
 155     vm_exit_during_initialization("Invalid layout of well-known class", ik->external_name());
 156   }
 157   compute_offset(dest_offset, ik, name, signature_symbol, is_static);
 158 }
 159 
 160 int java_lang_String::value_offset  = 0;
 161 int java_lang_String::hash_offset   = 0;
 162 int java_lang_String::coder_offset  = 0;
 163 
 164 bool java_lang_String::initialized  = false;
 165 
 166 bool java_lang_String::is_instance(oop obj) {
 167   return is_instance_inlined(obj);
 168 }
 169 
 170 #if INCLUDE_CDS
 171 #define FIELD_SERIALIZE_OFFSET(offset, klass, name, signature, is_static) \
 172   f->do_u4((u4*)&offset)
 173 #endif
 174 
 175 #define FIELD_COMPUTE_OFFSET(offset, klass, name, signature, is_static) \


1180   // The field at _array_klass_offset is pointing to the original one dimension
1181   // higher array klass if exists. Relocate the pointer.
1182   Klass *arr = array_klass_acquire(mirror);
1183   if (arr != NULL) {
1184     Klass *reloc_arr = MetaspaceShared::get_relocated_klass(arr);
1185     log_debug(cds, heap, mirror)(
1186       "Relocate mirror metadata field at _array_klass_offset from " PTR_FORMAT " ==> " PTR_FORMAT,
1187       p2i(arr), p2i(reloc_arr));
1188     archived_mirror->metadata_field_put(_array_klass_offset, reloc_arr);
1189   }
1190   return archived_mirror;
1191 }
1192 
1193 // Returns true if the mirror is updated, false if no archived mirror
1194 // data is present. After the archived mirror object is restored, the
1195 // shared klass' _has_raw_archived_mirror flag is cleared.
1196 bool java_lang_Class::restore_archived_mirror(Klass *k,
1197                                               Handle class_loader, Handle module,
1198                                               Handle protection_domain, TRAPS) {
1199   // Postpone restoring archived mirror until java.lang.Class is loaded. Please
1200   // see more details in SystemDictionary::resolve_well_known_classes().
1201   if (!SystemDictionary::Class_klass_loaded()) {
1202     assert(fixup_mirror_list() != NULL, "fixup_mirror_list not initialized");
1203     fixup_mirror_list()->push(k);
1204     return true;
1205   }
1206 
1207   oop m = HeapShared::materialize_archived_object(k->archived_java_mirror_raw_narrow());
1208 
1209   if (m == NULL) {
1210     return false;
1211   }
1212 
1213   log_debug(cds, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m));
1214 
1215   // mirror is archived, restore
1216   assert(HeapShared::is_archived_object(m), "must be archived mirror object");
1217   Handle mirror(THREAD, m);
1218 
1219   if (!k->is_array_klass()) {
1220     // - local static final fields with initial values were initialized at dump time


4234 // Invoked before SystemDictionary::initialize, so pre-loaded classes
4235 // are not available to determine the offset_of_static_fields.
4236 void JavaClasses::compute_hard_coded_offsets() {
4237 
4238   // java_lang_boxing_object
4239   java_lang_boxing_object::value_offset      = member_offset(java_lang_boxing_object::hc_value_offset);
4240   java_lang_boxing_object::long_value_offset = align_up(member_offset(java_lang_boxing_object::hc_value_offset), BytesPerLong);
4241 
4242   // java_lang_ref_Reference
4243   java_lang_ref_Reference::referent_offset    = member_offset(java_lang_ref_Reference::hc_referent_offset);
4244   java_lang_ref_Reference::queue_offset       = member_offset(java_lang_ref_Reference::hc_queue_offset);
4245   java_lang_ref_Reference::next_offset        = member_offset(java_lang_ref_Reference::hc_next_offset);
4246   java_lang_ref_Reference::discovered_offset  = member_offset(java_lang_ref_Reference::hc_discovered_offset);
4247 }
4248 
4249 #define DO_COMPUTE_OFFSETS(k) k::compute_offsets();
4250 
4251 // Compute non-hard-coded field offsets of all the classes in this file
4252 void JavaClasses::compute_offsets() {
4253   if (UseSharedSpaces) {
4254     assert(JvmtiEnvBase::get_phase() <= JVMTI_PHASE_PRIMORDIAL,
4255            "Field offsets of well-known classes must be computed in JVMTI_PHASE_PRIMORDIAL or before");
4256     return; // field offsets are loaded from archive
4257   }
4258 
4259   // We have already called the compute_offsets() of the
4260   // BASIC_JAVA_CLASSES_DO_PART1 classes (java_lang_String and java_lang_Class)
4261   // earlier inside SystemDictionary::resolve_well_known_classes()
4262   BASIC_JAVA_CLASSES_DO_PART2(DO_COMPUTE_OFFSETS);
4263 
4264   // generated interpreter code wants to know about the offsets we just computed:
4265   AbstractAssembler::update_delayed_values();
4266 }
4267 
4268 #if INCLUDE_CDS
4269 #define DO_SERIALIZE_OFFSETS(k) k::serialize_offsets(soc);
4270 
4271 void JavaClasses::serialize_offsets(SerializeClosure* soc) {
4272   BASIC_JAVA_CLASSES_DO(DO_SERIALIZE_OFFSETS);
4273 }
4274 #endif
4275 
4276 
4277 #ifndef PRODUCT
4278 
4279 // These functions exist to assert the validity of hard-coded field offsets to guard
4280 // against changes in the class files
4281 


4342 int InjectedField::compute_offset() {
4343   InstanceKlass* ik = InstanceKlass::cast(klass());
4344   for (AllFieldStream fs(ik); !fs.done(); fs.next()) {
4345     if (!may_be_java && !fs.access_flags().is_internal()) {
4346       // Only look at injected fields
4347       continue;
4348     }
4349     if (fs.name() == name() && fs.signature() == signature()) {
4350       return fs.offset();
4351     }
4352   }
4353   ResourceMark rm;
4354   tty->print_cr("Invalid layout of %s at %s/%s%s", ik->external_name(), name()->as_C_string(), signature()->as_C_string(), may_be_java ? " (may_be_java)" : "");
4355 #ifndef PRODUCT
4356   ik->print();
4357   tty->print_cr("all fields:");
4358   for (AllFieldStream fs(ik); !fs.done(); fs.next()) {
4359     tty->print_cr("  name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int());
4360   }
4361 #endif //PRODUCT
4362   vm_exit_during_initialization("Invalid layout of well-known class: use -Xlog:class+load=info to see the origin of the problem class");
4363   return -1;
4364 }
4365 
4366 void javaClasses_init() {
4367   JavaClasses::compute_offsets();
4368   JavaClasses::check_offsets();
4369   FilteredFieldsMap::initialize();  // must be done after computing offsets.
4370 }
< prev index next >