< prev index next >

src/hotspot/share/classfile/javaClasses.cpp

Print this page
@@ -50,12 +50,14 @@
  #include "memory/oopFactory.hpp"
  #include "memory/resourceArea.hpp"
  #include "memory/universe.hpp"
  #include "oops/fieldInfo.hpp"
  #include "oops/fieldStreams.inline.hpp"
+ #include "oops/flatArrayKlass.hpp"
+ #include "oops/inlineKlass.inline.hpp"
  #include "oops/instanceKlass.inline.hpp"
- #include "oops/instanceMirrorKlass.hpp"
+ #include "oops/instanceMirrorKlass.inline.hpp"
  #include "oops/klass.hpp"
  #include "oops/klass.inline.hpp"
  #include "oops/method.inline.hpp"
  #include "oops/objArrayKlass.hpp"
  #include "oops/objArrayOop.inline.hpp"

@@ -1071,25 +1073,34 @@
  
    set_static_oop_field_count(mirror(), mk->compute_static_oop_field_count(mirror()));
  
    // It might also have a component mirror.  This mirror must already exist.
    if (k->is_array_klass()) {
-     if (k->is_typeArray_klass()) {
+     if (k->is_flatArray_klass()) {
+       Klass* element_klass = (Klass*) FlatArrayKlass::cast(k)->element_klass();
+       assert(element_klass->is_inline_klass(), "Must be inline type component");
+       if (is_scratch) {
+         comp_mirror = Handle(THREAD, HeapShared::scratch_java_mirror(element_klass));
+       } else {
+         comp_mirror = Handle(THREAD, element_klass->java_mirror());
+       }
+     } else if (k->is_typeArray_klass()) {
        BasicType type = TypeArrayKlass::cast(k)->element_type();
        if (is_scratch) {
          comp_mirror = Handle(THREAD, HeapShared::scratch_java_mirror(type));
        } else {
          comp_mirror = Handle(THREAD, Universe::java_mirror(type));
        }
      } else {
        assert(k->is_objArray_klass(), "Must be");
        Klass* element_klass = ObjArrayKlass::cast(k)->element_klass();
        assert(element_klass != nullptr, "Must have an element klass");
+       oop comp_oop = element_klass->java_mirror();
        if (is_scratch) {
          comp_mirror = Handle(THREAD, HeapShared::scratch_java_mirror(element_klass));
        } else {
-         comp_mirror = Handle(THREAD, element_klass->java_mirror());
+         comp_mirror = Handle(THREAD, comp_oop);
        }
      }
      assert(comp_mirror() != nullptr, "must have a mirror");
  
      // Two-way link between the array klass and its component mirror:

@@ -1141,10 +1152,11 @@
      if (comp_mirror() != nullptr) {
        // Set after k->java_mirror() is published, because compiled code running
        // concurrently doesn't expect a k to have a null java_mirror.
        release_set_array_klass(comp_mirror(), k);
      }
+ 
      if (CDSConfig::is_dumping_heap()) {
        create_scratch_mirror(k, CHECK);
      }
    } else {
      assert(fixup_mirror_list() != nullptr, "fixup_mirror_list not initialized");

@@ -1163,13 +1175,13 @@
  //
  // Note: we archive the "scratch mirror" instead of k->java_mirror(), because the
  // latter may contain dumptime-specific information that cannot be archived
  // (e.g., ClassLoaderData*, or static fields that are modified by Java code execution).
  void java_lang_Class::create_scratch_mirror(Klass* k, TRAPS) {
-   if (k->class_loader() != nullptr &&
-       k->class_loader() != SystemDictionary::java_platform_loader() &&
-       k->class_loader() != SystemDictionary::java_system_loader()) {
+   if ((k->class_loader() != nullptr &&
+        k->class_loader() != SystemDictionary::java_platform_loader() &&
+        k->class_loader() != SystemDictionary::java_system_loader())) {
      // We only archive the mirrors of classes loaded by the built-in loaders
      return;
    }
  
    Handle protection_domain, classData; // set to null. Will be reinitialized at runtime

@@ -1393,11 +1405,13 @@
    }
    if (name == nullptr) {
      st->print("<null>");
      return;
    }
-   if (is_instance)  st->print("L");
+   if (is_instance)  {
+     st->print("L");
+   }
    st->write((char*) name->base(), (int) name->utf8_length());
    if (is_instance)  st->print(";");
  }
  
  Symbol* java_lang_Class::as_signature(oop java_class, bool intern_if_not_found) {

@@ -1452,10 +1466,14 @@
  }
  
  
  void java_lang_Class::release_set_array_klass(oop java_class, Klass* klass) {
    assert(klass->is_klass() && klass->is_array_klass(), "should be array klass");
+   if (klass->is_flatArray_klass() || (klass->is_objArray_klass() && ObjArrayKlass::cast(klass)->is_null_free_array_klass())) {
+     // TODO 8336006 Ignore flat / null-free arrays
+     return;
+   }
    java_class->release_metadata_field_put(_array_klass_offset, klass);
  }
  
  
  BasicType java_lang_Class::primitive_type(oop java_class) {

@@ -2837,11 +2855,11 @@
      if (!skip_throwableInit_check) {
        assert(skip_fillInStackTrace_check, "logic error in backtrace filtering");
  
        // skip <init> methods of the exception class and superclasses
        // This is similar to classic VM.
-       if (method->name() == vmSymbols::object_initializer_name() &&
+       if (method->is_object_constructor() &&
            throwable->is_a(method->method_holder())) {
          continue;
        } else {
          // there are none or we've seen them all - either way stop checking
          skip_throwableInit_check = true;

@@ -3196,12 +3214,12 @@
  }
  #endif
  
  static int get_flags(const methodHandle& m) {
    int flags = m->access_flags().as_method_flags();
-   if (m->is_object_initializer()) {
-     flags |= java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR;
+   if (m->is_object_constructor()) {
+     flags |= java_lang_invoke_MemberName::MN_IS_OBJECT_CONSTRUCTOR;
    } else {
      // Note: Static initializers can be here. Record them as plain methods.
      flags |= java_lang_invoke_MemberName::MN_IS_METHOD;
    }
    if (m->caller_sensitive()) {

@@ -3588,21 +3606,21 @@
  int java_lang_reflect_Field::_clazz_offset;
  int java_lang_reflect_Field::_name_offset;
  int java_lang_reflect_Field::_type_offset;
  int java_lang_reflect_Field::_slot_offset;
  int java_lang_reflect_Field::_modifiers_offset;
- int java_lang_reflect_Field::_trusted_final_offset;
+ int java_lang_reflect_Field::_flags_offset;
  int java_lang_reflect_Field::_signature_offset;
  int java_lang_reflect_Field::_annotations_offset;
  
  #define FIELD_FIELDS_DO(macro) \
    macro(_clazz_offset,     k, vmSymbols::clazz_name(),     class_signature,  false); \
    macro(_name_offset,      k, vmSymbols::name_name(),      string_signature, false); \
    macro(_type_offset,      k, vmSymbols::type_name(),      class_signature,  false); \
    macro(_slot_offset,      k, vmSymbols::slot_name(),      int_signature,    false); \
    macro(_modifiers_offset, k, vmSymbols::modifiers_name(), int_signature,    false); \
-   macro(_trusted_final_offset,    k, vmSymbols::trusted_final_name(),    bool_signature,       false); \
+   macro(_flags_offset,     k, vmSymbols::flags_name(),     int_signature,    false); \
    macro(_signature_offset,        k, vmSymbols::signature_name(),        string_signature,     false); \
    macro(_annotations_offset,      k, vmSymbols::annotations_name(),      byte_array_signature, false);
  
  void java_lang_reflect_Field::compute_offsets() {
    InstanceKlass* k = vmClasses::reflect_Field_klass();

@@ -3663,12 +3681,12 @@
  
  void java_lang_reflect_Field::set_modifiers(oop field, int value) {
    field->int_field_put(_modifiers_offset, value);
  }
  
- void java_lang_reflect_Field::set_trusted_final(oop field) {
-   field->bool_field_put(_trusted_final_offset, true);
+ void java_lang_reflect_Field::set_flags(oop field, int value) {
+   field->int_field_put(_flags_offset, value);
  }
  
  void java_lang_reflect_Field::set_signature(oop field, oop value) {
    field->obj_field_put(_signature_offset, value);
  }

@@ -3967,19 +3985,22 @@
    bool is_reference = ik->reference_type() != REF_NONE;
    assert(!is_reference || ik->is_subclass_of(vmClasses::Reference_klass()), "sanity");
    return is_reference;
  }
  
- int java_lang_boxing_object::_value_offset;
- int java_lang_boxing_object::_long_value_offset;
+ int java_lang_boxing_object::_sub32bits_value_offset;
+ int java_lang_boxing_object::_32bits_value_offset;
+ int java_lang_boxing_object::_64bits_value_offset;
  
  #define BOXING_FIELDS_DO(macro) \
-   macro(_value_offset,      integerKlass, "value", int_signature, false); \
-   macro(_long_value_offset, longKlass, "value", long_signature, false);
+   macro(_sub32bits_value_offset, byteKlass, "value", byte_signature, false); \
+   macro(_32bits_value_offset,    intKlass,  "value", int_signature,  false); \
+   macro(_64bits_value_offset,    longKlass, "value", long_signature, false);
  
  void java_lang_boxing_object::compute_offsets() {
-   InstanceKlass* integerKlass = vmClasses::Integer_klass();
+   InstanceKlass* byteKlass = vmClasses::Byte_klass();
+   InstanceKlass* intKlass = vmClasses::Integer_klass();
    InstanceKlass* longKlass = vmClasses::Long_klass();
    BOXING_FIELDS_DO(FIELD_COMPUTE_OFFSET);
  }
  
  #if INCLUDE_CDS

@@ -4002,32 +4023,32 @@
  oop java_lang_boxing_object::create(BasicType type, jvalue* value, TRAPS) {
    oop box = initialize_and_allocate(type, CHECK_NULL);
    if (box == nullptr)  return nullptr;
    switch (type) {
      case T_BOOLEAN:
-       box->bool_field_put(_value_offset, value->z);
+       box->bool_field_put(_sub32bits_value_offset, value->z);
        break;
      case T_CHAR:
-       box->char_field_put(_value_offset, value->c);
+       box->char_field_put(_sub32bits_value_offset, value->c);
        break;
      case T_FLOAT:
-       box->float_field_put(_value_offset, value->f);
+       box->float_field_put(_32bits_value_offset, value->f);
        break;
      case T_DOUBLE:
-       box->double_field_put(_long_value_offset, value->d);
+       box->double_field_put(_64bits_value_offset, value->d);
        break;
      case T_BYTE:
-       box->byte_field_put(_value_offset, value->b);
+       box->byte_field_put(_sub32bits_value_offset, value->b);
        break;
      case T_SHORT:
-       box->short_field_put(_value_offset, value->s);
+       box->short_field_put(_sub32bits_value_offset, value->s);
        break;
      case T_INT:
-       box->int_field_put(_value_offset, value->i);
+       box->int_field_put(_32bits_value_offset, value->i);
        break;
      case T_LONG:
-       box->long_field_put(_long_value_offset, value->j);
+       box->long_field_put(_64bits_value_offset, value->j);
        break;
      default:
        return nullptr;
    }
    return box;

@@ -4045,32 +4066,32 @@
  
  BasicType java_lang_boxing_object::get_value(oop box, jvalue* value) {
    BasicType type = vmClasses::box_klass_type(box->klass());
    switch (type) {
    case T_BOOLEAN:
-     value->z = box->bool_field(_value_offset);
+     value->z = box->bool_field(_sub32bits_value_offset);
      break;
    case T_CHAR:
-     value->c = box->char_field(_value_offset);
+     value->c = box->char_field(_sub32bits_value_offset);
      break;
    case T_FLOAT:
-     value->f = box->float_field(_value_offset);
+       value->f = box->float_field(_32bits_value_offset);
      break;
    case T_DOUBLE:
-     value->d = box->double_field(_long_value_offset);
+     value->d = box->double_field(_64bits_value_offset);
      break;
    case T_BYTE:
-     value->b = box->byte_field(_value_offset);
+     value->b = box->byte_field(_sub32bits_value_offset);
      break;
    case T_SHORT:
-     value->s = box->short_field(_value_offset);
+     value->s = box->short_field(_sub32bits_value_offset);
      break;
    case T_INT:
-     value->i = box->int_field(_value_offset);
+       value->i = box->int_field(_32bits_value_offset);
      break;
    case T_LONG:
-     value->j = box->long_field(_long_value_offset);
+     value->j = box->long_field(_64bits_value_offset);
      break;
    default:
      return T_ILLEGAL;
    } // end switch
    return type;

@@ -4079,32 +4100,32 @@
  
  BasicType java_lang_boxing_object::set_value(oop box, jvalue* value) {
    BasicType type = vmClasses::box_klass_type(box->klass());
    switch (type) {
    case T_BOOLEAN:
-     box->bool_field_put(_value_offset, value->z);
+     box->bool_field_put(_sub32bits_value_offset, value->z);
      break;
    case T_CHAR:
-     box->char_field_put(_value_offset, value->c);
+     box->char_field_put(_sub32bits_value_offset, value->c);
      break;
    case T_FLOAT:
-     box->float_field_put(_value_offset, value->f);
+     box->float_field_put(_32bits_value_offset, value->f);
      break;
    case T_DOUBLE:
-     box->double_field_put(_long_value_offset, value->d);
+     box->double_field_put(_64bits_value_offset, value->d);
      break;
    case T_BYTE:
-     box->byte_field_put(_value_offset, value->b);
+     box->byte_field_put(_sub32bits_value_offset, value->b);
      break;
    case T_SHORT:
-     box->short_field_put(_value_offset, value->s);
+     box->short_field_put(_sub32bits_value_offset, value->s);
      break;
    case T_INT:
-     box->int_field_put(_value_offset, value->i);
+     box->int_field_put(_32bits_value_offset, value->i);
      break;
    case T_LONG:
-     box->long_field_put(_long_value_offset, value->j);
+     box->long_field_put(_64bits_value_offset, value->j);
      break;
    default:
      return T_ILLEGAL;
    } // end switch
    return type;

@@ -4496,21 +4517,20 @@
  void java_lang_invoke_MemberName::set_flags(oop mname, int flags) {
    assert(is_instance(mname), "wrong type");
    mname->int_field_put(_flags_offset, flags);
  }
  
- 
  // Return vmtarget from ResolvedMethodName method field through indirection
  Method* java_lang_invoke_MemberName::vmtarget(oop mname) {
    assert(is_instance(mname), "wrong type");
    oop method = mname->obj_field(_method_offset);
    return method == nullptr ? nullptr : java_lang_invoke_ResolvedMethodName::vmtarget(method);
  }
  
  bool java_lang_invoke_MemberName::is_method(oop mname) {
    assert(is_instance(mname), "must be MemberName");
-   return (flags(mname) & (MN_IS_METHOD | MN_IS_CONSTRUCTOR)) > 0;
+   return (flags(mname) & (MN_IS_METHOD | MN_IS_OBJECT_CONSTRUCTOR)) > 0;
  }
  
  void java_lang_invoke_MemberName::set_method(oop mname, oop resolved_method) {
    assert(is_instance(mname), "wrong type");
    mname->obj_field_put(_method_offset, resolved_method);

@@ -5501,26 +5521,30 @@
  }
  
  void JavaClasses::check_offsets() {
    bool valid = true;
  
- #define CHECK_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
-   valid &= check_offset(klass_name, cpp_klass_name :: _##field_name ## _offset, #field_name, field_sig)
+ #define CHECK_SUB32BITS_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
+   valid &= check_offset(klass_name, cpp_klass_name :: _ ##sub32bits_ ## field_name ## _offset, #field_name, field_sig)
+ 
+ #define CHECK_32BITS_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
+   valid &= check_offset(klass_name, cpp_klass_name :: _##32bits_ ## field_name ## _offset, #field_name, field_sig)
+ 
+ #define CHECK_64BITS_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
+   valid &= check_offset(klass_name, cpp_klass_name :: _##64bits_ ## field_name ## _offset, #field_name, field_sig)
  
- #define CHECK_LONG_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
-   valid &= check_offset(klass_name, cpp_klass_name :: _##long_ ## field_name ## _offset, #field_name, field_sig)
  
    // Boxed primitive objects (java_lang_boxing_object)
  
-   CHECK_OFFSET("java/lang/Boolean",   java_lang_boxing_object, value, "Z");
-   CHECK_OFFSET("java/lang/Character", java_lang_boxing_object, value, "C");
-   CHECK_OFFSET("java/lang/Float",     java_lang_boxing_object, value, "F");
-   CHECK_LONG_OFFSET("java/lang/Double", java_lang_boxing_object, value, "D");
-   CHECK_OFFSET("java/lang/Byte",      java_lang_boxing_object, value, "B");
-   CHECK_OFFSET("java/lang/Short",     java_lang_boxing_object, value, "S");
-   CHECK_OFFSET("java/lang/Integer",   java_lang_boxing_object, value, "I");
-   CHECK_LONG_OFFSET("java/lang/Long", java_lang_boxing_object, value, "J");
+   CHECK_SUB32BITS_OFFSET("java/lang/Boolean",   java_lang_boxing_object, value, "Z");
+   CHECK_SUB32BITS_OFFSET("java/lang/Character", java_lang_boxing_object, value, "C");
+   CHECK_32BITS_OFFSET("java/lang/Float",     java_lang_boxing_object, value, "F");
+   CHECK_64BITS_OFFSET("java/lang/Double", java_lang_boxing_object, value, "D");
+   CHECK_SUB32BITS_OFFSET("java/lang/Byte",      java_lang_boxing_object, value, "B");
+   CHECK_SUB32BITS_OFFSET("java/lang/Short",     java_lang_boxing_object, value, "S");
+   CHECK_32BITS_OFFSET("java/lang/Integer",   java_lang_boxing_object, value, "I");
+   CHECK_64BITS_OFFSET("java/lang/Long", java_lang_boxing_object, value, "J");
  
    if (!valid) vm_exit_during_initialization("Field offset verification failed");
  }
  
  #endif // PRODUCT
< prev index next >