< prev index next >

src/hotspot/share/classfile/javaClasses.cpp

Print this page


 122 
 123 #define LOOKUP_INJECTED_FIELD(klass, name, signature, may_be_java) \
 124   if (sid == vmSymbols::VM_SYMBOL_ENUM_NAME(klass)) {              \
 125     count++;                                                       \
 126     if (start == -1) start = klass##_##name##_enum;                \
 127   }
 128   ALL_INJECTED_FIELDS(LOOKUP_INJECTED_FIELD);
 129 #undef LOOKUP_INJECTED_FIELD
 130 
 131   if (start != -1) {
 132     *field_count = count;
 133     return _injected_fields + start;
 134   }
 135   return NULL;
 136 }
 137 
 138 
 139 // Helpful routine for computing field offsets at run time rather than hardcoding them
 140 // Finds local fields only, including static fields.  Static field offsets are from the
 141 // beginning of the mirror.
 142 static void compute_offset(int &dest_offset,
 143                            InstanceKlass* ik, Symbol* name_symbol, Symbol* signature_symbol,
 144                            bool is_static = false) {
 145   fieldDescriptor fd;
 146   if (ik == NULL) {
 147     ResourceMark rm;
 148     log_error(class)("Mismatch JDK version for field: %s type: %s", name_symbol->as_C_string(), signature_symbol->as_C_string());
 149     vm_exit_during_initialization("Invalid layout of well-known class");
 150   }
 151 
 152   if (!ik->find_local_field(name_symbol, signature_symbol, &fd) || fd.is_static() != is_static) {
 153     ResourceMark rm;
 154     log_error(class)("Invalid layout of %s field: %s type: %s", ik->external_name(),
 155                      name_symbol->as_C_string(), signature_symbol->as_C_string());
 156 #ifndef PRODUCT
 157     // Prints all fields and offsets
 158     Log(class) lt;
 159     LogStream ls(lt.error());
 160     ik->print_on(&ls);
 161 #endif //PRODUCT
 162     vm_exit_during_initialization("Invalid layout of well-known class: use -Xlog:class+load=info to see the origin of the problem class");
 163   }
 164   dest_offset = fd.offset();
 165 }
 166 
 167 // Overloading to pass name as a string.
 168 static void compute_offset(int& dest_offset, InstanceKlass* ik,
 169                            const char* name_string, Symbol* signature_symbol,
 170                            bool is_static = false) {
 171   TempNewSymbol name = SymbolTable::probe(name_string, (int)strlen(name_string));
 172   if (name == NULL) {
 173     ResourceMark rm;
 174     log_error(class)("Name %s should be in the SymbolTable since its class is loaded", name_string);
 175     vm_exit_during_initialization("Invalid layout of well-known class", ik->external_name());
 176   }
 177   compute_offset(dest_offset, ik, name, signature_symbol, is_static);
 178 }
 179 
 180 
 181 #if INCLUDE_CDS
 182 #define FIELD_SERIALIZE_OFFSET(offset, klass, name, signature, is_static) \
 183   f->do_u4((u4*)&offset)
 184 #endif
 185 
 186 #define FIELD_COMPUTE_OFFSET(offset, klass, name, signature, is_static) \
 187   compute_offset(offset, klass, name, vmSymbols::signature(), is_static)
 188 
 189 
 190 // java_lang_String
 191 
 192 int java_lang_String::_value_offset;
 193 int java_lang_String::_hash_offset;
 194 int java_lang_String::_hashIsZero_offset;
 195 int java_lang_String::_coder_offset;
 196 
 197 bool java_lang_String::_initialized;
 198 
 199 bool java_lang_String::is_instance(oop obj) {
 200   return is_instance_inlined(obj);
 201 }
 202 
 203 #define STRING_FIELDS_DO(macro) \
 204   macro(_value_offset, k, vmSymbols::value_name(), byte_array_signature, false); \
 205   macro(_hash_offset,  k, "hash",                  int_signature,        false); \
 206   macro(_hashIsZero_offset, k, "hashIsZero",       bool_signature,       false); \
 207   macro(_coder_offset, k, "coder",                 byte_signature,       false);


3396   MODULE_INJECTED_FIELDS(INJECTED_FIELD_SERIALIZE_OFFSET);
3397 }
3398 #endif
3399 
3400 oop java_lang_Module::loader(oop module) {
3401   return module->obj_field(_loader_offset);
3402 }
3403 
3404 void java_lang_Module::set_loader(oop module, oop value) {
3405   module->obj_field_put(_loader_offset, value);
3406 }
3407 
3408 oop java_lang_Module::name(oop module) {
3409   return module->obj_field(_name_offset);
3410 }
3411 
3412 void java_lang_Module::set_name(oop module, oop value) {
3413   module->obj_field_put(_name_offset, value);
3414 }
3415 
3416 ModuleEntry* java_lang_Module::module_entry(oop module) {
3417   assert(_module_entry_offset != 0, "Uninitialized module_entry_offset");
3418   assert(module != NULL, "module can't be null");
3419   assert(oopDesc::is_oop(module), "module must be oop");
3420 
3421   ModuleEntry* module_entry = (ModuleEntry*)module->address_field(_module_entry_offset);





3422   if (module_entry == NULL) {
3423     // If the inject field containing the ModuleEntry* is null then return the
3424     // class loader's unnamed module.
3425     oop loader = java_lang_Module::loader(module);
3426     Handle h_loader = Handle(Thread::current(), loader);
3427     ClassLoaderData* loader_cld = SystemDictionary::register_loader(h_loader);
3428     return loader_cld->unnamed_module();
3429   }
3430   return module_entry;
3431 }
3432 
3433 void java_lang_Module::set_module_entry(oop module, ModuleEntry* module_entry) {
3434   assert(_module_entry_offset != 0, "Uninitialized module_entry_offset");
3435   assert(module != NULL, "module can't be null");
3436   assert(oopDesc::is_oop(module), "module must be oop");
3437   module->address_field_put(_module_entry_offset, (address)module_entry);
3438 }
3439 
3440 Handle reflect_ConstantPool::create(TRAPS) {
3441   assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");


4825 
4826   // We have already called the compute_offsets() of the
4827   // BASIC_JAVA_CLASSES_DO_PART1 classes (java_lang_String, java_lang_Class and
4828   // java_lang_ref_Reference) earlier inside SystemDictionary::resolve_well_known_classes()
4829   BASIC_JAVA_CLASSES_DO_PART2(DO_COMPUTE_OFFSETS);
4830 }
4831 
4832 #if INCLUDE_CDS
4833 #define DO_SERIALIZE_OFFSETS(k) k::serialize_offsets(soc);
4834 
4835 void JavaClasses::serialize_offsets(SerializeClosure* soc) {
4836   BASIC_JAVA_CLASSES_DO(DO_SERIALIZE_OFFSETS);
4837 }
4838 #endif
4839 
4840 #if INCLUDE_CDS_JAVA_HEAP
4841 bool JavaClasses::is_supported_for_archiving(oop obj) {
4842   Klass* klass = obj->klass();
4843 
4844   if (klass == SystemDictionary::ClassLoader_klass() ||  // ClassLoader::loader_data is malloc'ed.
4845       klass == SystemDictionary::Module_klass() ||       // Module::module_entry is malloc'ed
4846       // The next 3 classes are used to implement java.lang.invoke, and are not used directly in
4847       // regular Java code. The implementation of java.lang.invoke uses generated anonymoys classes
4848       // (e.g., as referenced by ResolvedMethodName::vmholder) that are not yet supported by CDS.
4849       // So for now we cannot not support these classes for archiving.
4850       //
4851       // These objects typically are not referenced by static fields, but rather by resolved
4852       // constant pool entries, so excluding them shouldn't affect the archiving of static fields.
4853       klass == SystemDictionary::ResolvedMethodName_klass() ||
4854       klass == SystemDictionary::MemberName_klass() ||
4855       klass == SystemDictionary::Context_klass()) {
4856     return false;
4857   }
4858 
4859   return true;
4860 }
4861 #endif
4862 
4863 #ifndef PRODUCT
4864 
4865 // These functions exist to assert the validity of de-serialized offsets in boxing object as a sanity check.




 122 
 123 #define LOOKUP_INJECTED_FIELD(klass, name, signature, may_be_java) \
 124   if (sid == vmSymbols::VM_SYMBOL_ENUM_NAME(klass)) {              \
 125     count++;                                                       \
 126     if (start == -1) start = klass##_##name##_enum;                \
 127   }
 128   ALL_INJECTED_FIELDS(LOOKUP_INJECTED_FIELD);
 129 #undef LOOKUP_INJECTED_FIELD
 130 
 131   if (start != -1) {
 132     *field_count = count;
 133     return _injected_fields + start;
 134   }
 135   return NULL;
 136 }
 137 
 138 
 139 // Helpful routine for computing field offsets at run time rather than hardcoding them
 140 // Finds local fields only, including static fields.  Static field offsets are from the
 141 // beginning of the mirror.
 142 void JavaClasses::compute_offset(int &dest_offset,
 143                                  InstanceKlass* ik, Symbol* name_symbol, Symbol* signature_symbol,
 144                                  bool is_static) {
 145   fieldDescriptor fd;
 146   if (ik == NULL) {
 147     ResourceMark rm;
 148     log_error(class)("Mismatch JDK version for field: %s type: %s", name_symbol->as_C_string(), signature_symbol->as_C_string());
 149     vm_exit_during_initialization("Invalid layout of well-known class");
 150   }
 151 
 152   if (!ik->find_local_field(name_symbol, signature_symbol, &fd) || fd.is_static() != is_static) {
 153     ResourceMark rm;
 154     log_error(class)("Invalid layout of %s field: %s type: %s", ik->external_name(),
 155                      name_symbol->as_C_string(), signature_symbol->as_C_string());
 156 #ifndef PRODUCT
 157     // Prints all fields and offsets
 158     Log(class) lt;
 159     LogStream ls(lt.error());
 160     ik->print_on(&ls);
 161 #endif //PRODUCT
 162     vm_exit_during_initialization("Invalid layout of well-known class: use -Xlog:class+load=info to see the origin of the problem class");
 163   }
 164   dest_offset = fd.offset();
 165 }
 166 
 167 // Overloading to pass name as a string.
 168 void JavaClasses::compute_offset(int& dest_offset, InstanceKlass* ik,
 169                                  const char* name_string, Symbol* signature_symbol,
 170                                  bool is_static) {
 171   TempNewSymbol name = SymbolTable::probe(name_string, (int)strlen(name_string));
 172   if (name == NULL) {
 173     ResourceMark rm;
 174     log_error(class)("Name %s should be in the SymbolTable since its class is loaded", name_string);
 175     vm_exit_during_initialization("Invalid layout of well-known class", ik->external_name());
 176   }
 177   compute_offset(dest_offset, ik, name, signature_symbol, is_static);
 178 }
 179 
 180 
 181 #if INCLUDE_CDS
 182 #define FIELD_SERIALIZE_OFFSET(offset, klass, name, signature, is_static) \
 183   f->do_u4((u4*)&offset)
 184 #endif
 185 
 186 #define FIELD_COMPUTE_OFFSET(offset, klass, name, signature, is_static) \
 187   JavaClasses::compute_offset(offset, klass, name, vmSymbols::signature(), is_static)
 188 
 189 
 190 // java_lang_String
 191 
 192 int java_lang_String::_value_offset;
 193 int java_lang_String::_hash_offset;
 194 int java_lang_String::_hashIsZero_offset;
 195 int java_lang_String::_coder_offset;
 196 
 197 bool java_lang_String::_initialized;
 198 
 199 bool java_lang_String::is_instance(oop obj) {
 200   return is_instance_inlined(obj);
 201 }
 202 
 203 #define STRING_FIELDS_DO(macro) \
 204   macro(_value_offset, k, vmSymbols::value_name(), byte_array_signature, false); \
 205   macro(_hash_offset,  k, "hash",                  int_signature,        false); \
 206   macro(_hashIsZero_offset, k, "hashIsZero",       bool_signature,       false); \
 207   macro(_coder_offset, k, "coder",                 byte_signature,       false);


3396   MODULE_INJECTED_FIELDS(INJECTED_FIELD_SERIALIZE_OFFSET);
3397 }
3398 #endif
3399 
3400 oop java_lang_Module::loader(oop module) {
3401   return module->obj_field(_loader_offset);
3402 }
3403 
3404 void java_lang_Module::set_loader(oop module, oop value) {
3405   module->obj_field_put(_loader_offset, value);
3406 }
3407 
3408 oop java_lang_Module::name(oop module) {
3409   return module->obj_field(_name_offset);
3410 }
3411 
3412 void java_lang_Module::set_name(oop module, oop value) {
3413   module->obj_field_put(_name_offset, value);
3414 }
3415 
3416 ModuleEntry* java_lang_Module::module_entry_raw(oop module) {
3417   assert(_module_entry_offset != 0, "Uninitialized module_entry_offset");
3418   assert(module != NULL, "module can't be null");
3419   assert(oopDesc::is_oop(module), "module must be oop");
3420 
3421   ModuleEntry* module_entry = (ModuleEntry*)module->address_field(_module_entry_offset);
3422   return module_entry;
3423 }
3424 
3425 ModuleEntry* java_lang_Module::module_entry(oop module) {
3426   ModuleEntry* module_entry = module_entry_raw(module);
3427   if (module_entry == NULL) {
3428     // If the inject field containing the ModuleEntry* is null then return the
3429     // class loader's unnamed module.
3430     oop loader = java_lang_Module::loader(module);
3431     Handle h_loader = Handle(Thread::current(), loader);
3432     ClassLoaderData* loader_cld = SystemDictionary::register_loader(h_loader);
3433     return loader_cld->unnamed_module();
3434   }
3435   return module_entry;
3436 }
3437 
3438 void java_lang_Module::set_module_entry(oop module, ModuleEntry* module_entry) {
3439   assert(_module_entry_offset != 0, "Uninitialized module_entry_offset");
3440   assert(module != NULL, "module can't be null");
3441   assert(oopDesc::is_oop(module), "module must be oop");
3442   module->address_field_put(_module_entry_offset, (address)module_entry);
3443 }
3444 
3445 Handle reflect_ConstantPool::create(TRAPS) {
3446   assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem");


4830 
4831   // We have already called the compute_offsets() of the
4832   // BASIC_JAVA_CLASSES_DO_PART1 classes (java_lang_String, java_lang_Class and
4833   // java_lang_ref_Reference) earlier inside SystemDictionary::resolve_well_known_classes()
4834   BASIC_JAVA_CLASSES_DO_PART2(DO_COMPUTE_OFFSETS);
4835 }
4836 
4837 #if INCLUDE_CDS
4838 #define DO_SERIALIZE_OFFSETS(k) k::serialize_offsets(soc);
4839 
4840 void JavaClasses::serialize_offsets(SerializeClosure* soc) {
4841   BASIC_JAVA_CLASSES_DO(DO_SERIALIZE_OFFSETS);
4842 }
4843 #endif
4844 
4845 #if INCLUDE_CDS_JAVA_HEAP
4846 bool JavaClasses::is_supported_for_archiving(oop obj) {
4847   Klass* klass = obj->klass();
4848 
4849   if (klass == SystemDictionary::ClassLoader_klass() ||  // ClassLoader::loader_data is malloc'ed.

4850       // The next 3 classes are used to implement java.lang.invoke, and are not used directly in
4851       // regular Java code. The implementation of java.lang.invoke uses generated anonymoys classes
4852       // (e.g., as referenced by ResolvedMethodName::vmholder) that are not yet supported by CDS.
4853       // So for now we cannot not support these classes for archiving.
4854       //
4855       // These objects typically are not referenced by static fields, but rather by resolved
4856       // constant pool entries, so excluding them shouldn't affect the archiving of static fields.
4857       klass == SystemDictionary::ResolvedMethodName_klass() ||
4858       klass == SystemDictionary::MemberName_klass() ||
4859       klass == SystemDictionary::Context_klass()) {
4860     return false;
4861   }
4862 
4863   return true;
4864 }
4865 #endif
4866 
4867 #ifndef PRODUCT
4868 
4869 // These functions exist to assert the validity of de-serialized offsets in boxing object as a sanity check.


< prev index next >