< prev index next >

src/hotspot/share/classfile/javaClasses.cpp

Print this page
@@ -50,19 +50,22 @@
  #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.inline.hpp"
  #include "oops/method.inline.hpp"
  #include "oops/objArrayKlass.hpp"
  #include "oops/objArrayOop.inline.hpp"
  #include "oops/oop.inline.hpp"
  #include "oops/oopCast.inline.hpp"
  #include "oops/recordComponent.hpp"
+ #include "oops/refArrayOop.inline.hpp"
  #include "oops/symbol.hpp"
  #include "oops/typeArrayOop.inline.hpp"
  #include "prims/jvmtiExport.hpp"
  #include "prims/methodHandles.hpp"
  #include "prims/resolvedMethodTable.hpp"

@@ -866,10 +869,11 @@
  int java_lang_Class::_classData_offset;
  int java_lang_Class::_classRedefinedCount_offset;
  int java_lang_Class::_reflectionData_offset;
  int java_lang_Class::_modifiers_offset;
  int java_lang_Class::_is_primitive_offset;
+ int java_lang_Class::_is_identity_offset;
  int java_lang_Class::_raw_access_flags_offset;
  
  bool java_lang_Class::_offsets_computed = false;
  GrowableArray<Klass*>* java_lang_Class::_fixup_mirror_list = nullptr;
  GrowableArray<Klass*>* java_lang_Class::_fixup_module_field_list = nullptr;

@@ -1089,29 +1093,32 @@
    set_klass(mirror(), k);
  
    // Set the modifiers flag.
    u2 computed_modifiers = k->compute_modifier_flags();
    set_modifiers(mirror(), computed_modifiers);
+   set_is_identity(mirror(), k->is_array_klass() || k->is_identity_class());
  
    InstanceMirrorKlass* mk = InstanceMirrorKlass::cast(mirror->klass());
    assert(oop_size(mirror()) == mk->instance_size(k), "should have been set");
  
    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()) {
+     assert(!k->is_refined_objArray_klass(), "Should not be called with the refined array klasses");
+ 
      // The Java code for array classes gets the access flags from the element type.
      set_raw_access_flags(mirror(), 0);
      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");
+       assert(k->is_unrefined_objArray_klass(), "Must be");
        Klass* element_klass = ObjArrayKlass::cast(k)->element_klass();
        assert(element_klass != nullptr, "Must have an element klass");
        if (is_scratch) {
          comp_mirror = Handle(THREAD, HeapShared::scratch_java_mirror(element_klass));
        } else {

@@ -1144,14 +1151,22 @@
  void java_lang_Class::create_mirror(Klass* k, Handle class_loader,
                                      Handle module, Handle protection_domain,
                                      Handle classData, TRAPS) {
    assert(k != nullptr, "Use create_basic_type_mirror for primitive types");
    assert(k->java_mirror() == nullptr, "should only assign mirror once");
- 
    // Class_klass has to be loaded because it is used to allocate
    // the mirror.
    if (vmClasses::Class_klass_is_loaded()) {
+ 
+     if (k->is_refined_objArray_klass()) {
+       Klass* super_klass = k->super();
+       assert(super_klass != nullptr, "Must be");
+       Handle mirror(THREAD, super_klass->java_mirror());
+       k->set_java_mirror(mirror);
+       return;
+     }
+ 
      Handle mirror;
      Handle comp_mirror;
  
      allocate_mirror(k, /*is_scratch=*/false, protection_domain, classData, mirror, comp_mirror, CHECK);
  

@@ -1170,10 +1185,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(!CDSConfig::is_using_aot_linked_classes(), "should not come here");

@@ -1193,13 +1209,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

@@ -1234,20 +1250,24 @@
    // Sanity: clear it now to prevent re-initialization if any of the following fails
    k->clear_archived_mirror_index();
  
    // mirror is archived, restore
    log_debug(aot, mirror)("Archived mirror is: " PTR_FORMAT, p2i(m));
-   assert(as_Klass(m) == k, "must be");
    Handle mirror(THREAD, m);
  
    if (!k->is_array_klass()) {
+     assert(as_Klass(m) == k, "must be");
      // - local static final fields with initial values were initialized at dump time
      assert(init_lock(mirror()) != nullptr, "allocated during AOT assembly");
  
      if (protection_domain.not_null()) {
        set_protection_domain(mirror(), protection_domain());
      }
+   } else if (k->is_objArray_klass()) {
+     ObjArrayKlass* objarray_k = (ObjArrayKlass*)as_Klass(m);
+     // Mirror should be restored for an ObjArrayKlass or one of its refined array klasses
+     assert(objarray_k == k || objarray_k->find_refined_array_klass((ObjArrayKlass*)k), "must be");
    }
  
    assert(class_loader() == k->class_loader(), "should be same");
    if (class_loader.not_null()) {
      set_class_loader(mirror(), class_loader());

@@ -1261,11 +1281,11 @@
      ResourceMark rm(THREAD);
      log_trace(aot, heap, mirror)(
          "Restored %s archived mirror " PTR_FORMAT, k->external_name(), p2i(mirror()));
    }
  
-   if (CDSConfig::is_dumping_heap()) {
+   if (CDSConfig::is_dumping_heap() && (!k->is_refined_objArray_klass())) {
      create_scratch_mirror(k, CHECK_(false));
    }
  
    return true;
  }

@@ -1380,10 +1400,14 @@
  void java_lang_Class::set_is_primitive(oop java_class) {
    assert(_is_primitive_offset != 0, "must be set");
    java_class->bool_field_put(_is_primitive_offset, true);
  }
  
+ void java_lang_Class::set_is_identity(oop java_class, bool value) {
+   assert(_is_identity_offset != 0, "must be set");
+   java_class->bool_field_put(_is_identity_offset, value);
+ }
  
  oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
    // Mirrors for basic types have a null klass field, which makes them special.
    oop java_class = InstanceMirrorKlass::cast(vmClasses::Class_klass())->allocate_instance(nullptr, CHECK_NULL);
    if (type != T_VOID) {

@@ -1421,11 +1445,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) {

@@ -1479,10 +1505,11 @@
    return k;
  }
  
  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");
+   assert(!klass->is_refined_objArray_klass(), "should not be ref or flat array klass");
    java_class->release_metadata_field_put(_array_klass_offset, klass);
  }
  
  
  BasicType java_lang_Class::primitive_type(oop java_class) {

@@ -1538,11 +1565,12 @@
    macro(_reflectionData_offset,      k, "reflectionData",      java_lang_ref_SoftReference_signature, false); \
    macro(_signers_offset,             k, "signers",             object_array_signature, false); \
    macro(_modifiers_offset,           k, vmSymbols::modifiers_name(), char_signature,    false); \
    macro(_raw_access_flags_offset,    k, "classFileAccessFlags",      char_signature,    false); \
    macro(_protection_domain_offset,   k, "protectionDomain",    java_security_ProtectionDomain_signature,  false); \
-   macro(_is_primitive_offset,        k, "primitive",           bool_signature,         false);
+   macro(_is_primitive_offset,        k, "primitive",           bool_signature,         false); \
+   macro(_is_identity_offset,         k, "identity",            bool_signature,         false);
  
  void java_lang_Class::compute_offsets() {
    if (_offsets_computed) {
      return;
    }

@@ -1988,11 +2016,11 @@
    InstanceKlass* k = vmClasses::StackTraceElement_klass();
    assert(k != nullptr, "must be loaded in 1.4+");
    if (k->should_be_initialized()) {
      k->initialize(CHECK_NULL);
    }
-   objArrayHandle trace = oopFactory::new_objArray_handle(k, gsthc._depth, CHECK_NULL);
+   refArrayHandle trace = oopFactory::new_refArray_handle(k, gsthc._depth, CHECK_NULL);
  
    for (int i = 0; i < gsthc._depth; i++) {
      methodHandle method(THREAD, gsthc._methods.at(i));
      oop element = java_lang_StackTraceElement::create(method,
                                                        gsthc._bcis.at(i),

@@ -2279,16 +2307,16 @@
    InstanceKlass* ik = vmClasses::Throwable_klass();
    oop base = ik->static_field_base_raw();
    return base->obj_field(_static_unassigned_stacktrace_offset);
  }
  
- oop java_lang_Throwable::backtrace(oop throwable) {
-   return throwable->obj_field_acquire(_backtrace_offset);
+ refArrayOop java_lang_Throwable::backtrace(oop throwable) {
+   return (refArrayOop)throwable->obj_field_acquire(_backtrace_offset);
  }
  
  
- void java_lang_Throwable::set_backtrace(oop throwable, oop value) {
+ void java_lang_Throwable::set_backtrace(oop throwable, refArrayOop value) {
    throwable->release_obj_field_put(_backtrace_offset, value);
  }
  
  int java_lang_Throwable::depth(oop throwable) {
    return throwable->int_field(_depth_offset);

@@ -2354,15 +2382,15 @@
  // The code of this class is not GC safe. Allocations can only happen
  // in expand().
  class BacktraceBuilder: public StackObj {
   friend class BacktraceIterator;
   private:
-   Handle          _backtrace;
-   objArrayOop     _head;
+   refArrayHandle  _backtrace;
+   refArrayOop     _head;
    typeArrayOop    _methods;
    typeArrayOop    _bcis;
-   objArrayOop     _mirrors;
+   refArrayOop     _mirrors;
    typeArrayOop    _names; // Needed to insulate method name against redefinition.
    // True if the top frame of the backtrace is omitted because it shall be hidden.
    bool            _has_hidden_top_frame;
    int             _index;
    NoSafepointVerifier _nsv;

@@ -2378,45 +2406,45 @@
      trace_size           = java_lang_Throwable::trace_size,
      trace_chunk_size     = java_lang_Throwable::trace_chunk_size
    };
  
    // get info out of chunks
-   static typeArrayOop get_methods(objArrayHandle chunk) {
+   static typeArrayOop get_methods(refArrayHandle chunk) {
      typeArrayOop methods = typeArrayOop(chunk->obj_at(trace_methods_offset));
      assert(methods != nullptr, "method array should be initialized in backtrace");
      return methods;
    }
-   static typeArrayOop get_bcis(objArrayHandle chunk) {
+   static typeArrayOop get_bcis(refArrayHandle chunk) {
      typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset));
      assert(bcis != nullptr, "bci array should be initialized in backtrace");
      return bcis;
    }
-   static objArrayOop get_mirrors(objArrayHandle chunk) {
-     objArrayOop mirrors = objArrayOop(chunk->obj_at(trace_mirrors_offset));
+   static refArrayOop get_mirrors(refArrayHandle chunk) {
+     refArrayOop mirrors = refArrayOop(chunk->obj_at(trace_mirrors_offset));
      assert(mirrors != nullptr, "mirror array should be initialized in backtrace");
      return mirrors;
    }
-   static typeArrayOop get_names(objArrayHandle chunk) {
+   static typeArrayOop get_names(refArrayHandle chunk) {
      typeArrayOop names = typeArrayOop(chunk->obj_at(trace_names_offset));
      assert(names != nullptr, "names array should be initialized in backtrace");
      return names;
    }
-   static bool has_hidden_top_frame(objArrayHandle chunk) {
+   static bool has_hidden_top_frame(refArrayHandle chunk) {
      oop hidden = chunk->obj_at(trace_hidden_offset);
      return hidden != nullptr;
    }
  
   public:
  
    // constructor for new backtrace
    BacktraceBuilder(TRAPS): _head(nullptr), _methods(nullptr), _bcis(nullptr), _mirrors(nullptr), _names(nullptr), _has_hidden_top_frame(false) {
      expand(CHECK);
-     _backtrace = Handle(THREAD, _head);
+     _backtrace = refArrayHandle(THREAD, _head);
      _index = 0;
    }
  
-   BacktraceBuilder(Thread* thread, objArrayHandle backtrace) {
+   BacktraceBuilder(Thread* thread, refArrayHandle backtrace) {
      _methods = get_methods(backtrace);
      _bcis = get_bcis(backtrace);
      _mirrors = get_mirrors(backtrace);
      _names = get_names(backtrace);
      _has_hidden_top_frame = has_hidden_top_frame(backtrace);

@@ -2425,29 +2453,29 @@
             _mirrors->length() == _names->length(),
             "method and source information arrays should match");
  
      // head is the preallocated backtrace
      _head = backtrace();
-     _backtrace = Handle(thread, _head);
+     _backtrace = refArrayHandle(thread, _head);
      _index = 0;
    }
  
    void expand(TRAPS) {
-     objArrayHandle old_head(THREAD, _head);
+     refArrayHandle old_head(THREAD, _head);
      PauseNoSafepointVerifier pnsv(&_nsv);
  
-     objArrayOop head = oopFactory::new_objectArray(trace_size, CHECK);
-     objArrayHandle new_head(THREAD, head);
+     refArrayOop head = oopFactory::new_objectArray(trace_size, CHECK);
+     refArrayHandle new_head(THREAD, head);
  
      typeArrayOop methods = oopFactory::new_shortArray(trace_chunk_size, CHECK);
      typeArrayHandle new_methods(THREAD, methods);
  
      typeArrayOop bcis = oopFactory::new_intArray(trace_chunk_size, CHECK);
      typeArrayHandle new_bcis(THREAD, bcis);
  
-     objArrayOop mirrors = oopFactory::new_objectArray(trace_chunk_size, CHECK);
-     objArrayHandle new_mirrors(THREAD, mirrors);
+     refArrayOop mirrors = oopFactory::new_objectArray(trace_chunk_size, CHECK);
+     refArrayHandle new_mirrors(THREAD, mirrors);
  
      typeArrayOop names = oopFactory::new_symbolArray(trace_chunk_size, CHECK);
      typeArrayHandle new_names(THREAD, names);
  
      if (!old_head.is_null()) {

@@ -2465,11 +2493,11 @@
      _mirrors = new_mirrors();
      _names  = new_names();
      _index = 0;
    }
  
-   oop backtrace() {
+   refArrayOop backtrace() {
      return _backtrace();
    }
  
    inline void push(Method* method, int bci, TRAPS) {
      // Smear the -1 bci to 0 since the array only holds unsigned

@@ -2523,29 +2551,29 @@
                     _method_id(mid), _bci(bci), _version(version), _name(name), _mirror(mirror) {}
  };
  
  class BacktraceIterator : public StackObj {
    int _index;
-   objArrayHandle  _result;
-   objArrayHandle  _mirrors;
+   refArrayHandle  _result;
+   refArrayHandle  _mirrors;
    typeArrayHandle _methods;
    typeArrayHandle _bcis;
    typeArrayHandle _names;
  
-   void init(objArrayHandle result, Thread* thread) {
+   void init(refArrayHandle result, Thread* thread) {
      // Get method id, bci, version and mirror from chunk
      _result = result;
      if (_result.not_null()) {
        _methods = typeArrayHandle(thread, BacktraceBuilder::get_methods(_result));
        _bcis = typeArrayHandle(thread, BacktraceBuilder::get_bcis(_result));
-       _mirrors = objArrayHandle(thread, BacktraceBuilder::get_mirrors(_result));
+       _mirrors = refArrayHandle(thread, BacktraceBuilder::get_mirrors(_result));
        _names = typeArrayHandle(thread, BacktraceBuilder::get_names(_result));
        _index = 0;
      }
    }
   public:
-   BacktraceIterator(objArrayHandle result, Thread* thread) {
+   BacktraceIterator(refArrayHandle result, Thread* thread) {
      init(result, thread);
      assert(_methods.is_null() || _methods->length() == java_lang_Throwable::trace_chunk_size, "lengths don't match");
    }
  
    BacktraceElement next(Thread* thread) {

@@ -2557,11 +2585,11 @@
      _index++;
  
      if (_index >= java_lang_Throwable::trace_chunk_size) {
        int next_offset = java_lang_Throwable::trace_next_offset;
        // Get next chunk
-       objArrayHandle result (thread, objArrayOop(_result->obj_at(next_offset)));
+       refArrayHandle result (thread, refArrayOop(_result->obj_at(next_offset)));
        init(result, thread);
      }
      return e;
    }
  

@@ -2648,11 +2676,11 @@
    st->cr();
  
    // Now print the stack trace.
    JavaThread* THREAD = JavaThread::current(); // For exception macros.
    while (throwable.not_null()) {
-     objArrayHandle result (THREAD, objArrayOop(backtrace(throwable())));
+     refArrayHandle result (THREAD, backtrace(throwable()));
      if (result.is_null()) {
        st->print_raw_cr("\t<<no stack trace available>>");
        return;
      }
      BacktraceIterator iter(result, THREAD);

@@ -2832,11 +2860,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;

@@ -2901,11 +2929,11 @@
  
    assert(throwable->is_a(vmClasses::Throwable_klass()), "sanity check");
  
    JavaThread* THREAD = JavaThread::current(); // For exception macros.
  
-   objArrayHandle backtrace (THREAD, (objArrayOop)java_lang_Throwable::backtrace(throwable()));
+   refArrayHandle backtrace(THREAD, java_lang_Throwable::backtrace(throwable()));
    assert(backtrace.not_null(), "backtrace should have been preallocated");
  
    ResourceMark rm(THREAD);
    vframeStream st(THREAD, false /* stop_at_java_call_stub */, false /* process_frames */);
  

@@ -2930,23 +2958,23 @@
    java_lang_Throwable::set_stacktrace(throwable(), java_lang_Throwable::unassigned_stacktrace());
    assert(java_lang_Throwable::unassigned_stacktrace() != nullptr, "not initialized");
  }
  
  void java_lang_Throwable::get_stack_trace_elements(int depth, Handle backtrace,
-                                                    objArrayHandle stack_trace_array_h, TRAPS) {
+                                                    refArrayHandle stack_trace_array_h, TRAPS) {
  
    if (backtrace.is_null() || stack_trace_array_h.is_null()) {
      THROW(vmSymbols::java_lang_NullPointerException());
    }
  
-   assert(stack_trace_array_h->is_objArray(), "Stack trace array should be an array of StackTraceElenent");
+   assert(stack_trace_array_h->is_refArray(), "Stack trace array should be an array of StackTraceElement");
  
    if (stack_trace_array_h->length() != depth) {
      THROW(vmSymbols::java_lang_IndexOutOfBoundsException());
    }
  
-   objArrayHandle result(THREAD, objArrayOop(backtrace()));
+   refArrayHandle result(THREAD, refArrayOop(backtrace()));
    BacktraceIterator iter(result, THREAD);
  
    int index = 0;
    while (iter.repeat()) {
      BacktraceElement bte = iter.next(THREAD);

@@ -3026,18 +3054,18 @@
    return init_error;
  }
  
  bool java_lang_Throwable::get_top_method_and_bci(oop throwable, Method** method, int* bci) {
    JavaThread* current = JavaThread::current();
-   objArrayHandle result(current, objArrayOop(backtrace(throwable)));
+   refArrayHandle result(current, backtrace(throwable));
    BacktraceIterator iter(result, current);
    // No backtrace available.
    if (!iter.repeat()) return false;
  
    // If the exception happened in a frame that has been hidden, i.e.,
    // omitted from the back trace, we can not compute the message.
-   oop hidden = ((objArrayOop)backtrace(throwable))->obj_at(trace_hidden_offset);
+   oop hidden = backtrace(throwable)->obj_at(trace_hidden_offset);
    if (hidden != nullptr) {
      return false;
    }
  
    // Get first backtrace element.

@@ -3191,12 +3219,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()) {

@@ -3583,21 +3611,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();

@@ -3658,12 +3686,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);
  }

@@ -3959,25 +3987,34 @@
    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::_offsets;
  
- #define BOXING_FIELDS_DO(macro) \
-   macro(_value_offset,      integerKlass, "value", int_signature, false); \
-   macro(_long_value_offset, longKlass, "value", long_signature, false);
+ #define BOXING_FIELDS_DO(macro)                                                                                                    \
+   macro(java_lang_boxing_object::_offsets[T_BOOLEAN - T_BOOLEAN], vmClasses::Boolean_klass(),   "value", bool_signature,   false); \
+   macro(java_lang_boxing_object::_offsets[T_CHAR - T_BOOLEAN],    vmClasses::Character_klass(), "value", char_signature,   false); \
+   macro(java_lang_boxing_object::_offsets[T_FLOAT - T_BOOLEAN],   vmClasses::Float_klass(),     "value", float_signature,  false); \
+   macro(java_lang_boxing_object::_offsets[T_DOUBLE - T_BOOLEAN],  vmClasses::Double_klass(),    "value", double_signature, false); \
+   macro(java_lang_boxing_object::_offsets[T_BYTE - T_BOOLEAN],    vmClasses::Byte_klass(),      "value", byte_signature,   false); \
+   macro(java_lang_boxing_object::_offsets[T_SHORT - T_BOOLEAN],   vmClasses::Short_klass(),     "value", short_signature,  false); \
+   macro(java_lang_boxing_object::_offsets[T_INT - T_BOOLEAN],     vmClasses::Integer_klass(),   "value", int_signature,    false); \
+   macro(java_lang_boxing_object::_offsets[T_LONG - T_BOOLEAN],    vmClasses::Long_klass(),      "value", long_signature,   false);
  
  void java_lang_boxing_object::compute_offsets() {
-   InstanceKlass* integerKlass = vmClasses::Integer_klass();
-   InstanceKlass* longKlass = vmClasses::Long_klass();
+   assert(T_LONG - T_BOOLEAN == 7, "Sanity check");
+   java_lang_boxing_object::_offsets = NEW_C_HEAP_ARRAY(int, 8, mtInternal);
    BOXING_FIELDS_DO(FIELD_COMPUTE_OFFSET);
  }
  
  #if INCLUDE_CDS
  void java_lang_boxing_object::serialize_offsets(SerializeClosure* f) {
+   if (f->reading()) {
+     assert(T_LONG - T_BOOLEAN == 7, "Sanity check");
+     java_lang_boxing_object::_offsets = NEW_C_HEAP_ARRAY(int, 8, mtInternal);
+   }
    BOXING_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
  }
  #endif
  
  oop java_lang_boxing_object::initialize_and_allocate(BasicType type, TRAPS) {

@@ -3994,32 +4031,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(value_offset(type), value->z);
        break;
      case T_CHAR:
-       box->char_field_put(_value_offset, value->c);
+       box->char_field_put(value_offset(type), value->c);
        break;
      case T_FLOAT:
-       box->float_field_put(_value_offset, value->f);
+       box->float_field_put(value_offset(type), value->f);
        break;
      case T_DOUBLE:
-       box->double_field_put(_long_value_offset, value->d);
+       box->double_field_put(value_offset(type), value->d);
        break;
      case T_BYTE:
-       box->byte_field_put(_value_offset, value->b);
+       box->byte_field_put(value_offset(type), value->b);
        break;
      case T_SHORT:
-       box->short_field_put(_value_offset, value->s);
+       box->short_field_put(value_offset(type), value->s);
        break;
      case T_INT:
-       box->int_field_put(_value_offset, value->i);
+       box->int_field_put(value_offset(type), value->i);
        break;
      case T_LONG:
-       box->long_field_put(_long_value_offset, value->j);
+       box->long_field_put(value_offset(type), value->j);
        break;
      default:
        return nullptr;
    }
    return box;

@@ -4037,32 +4074,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(value_offset(type));
      break;
    case T_CHAR:
-     value->c = box->char_field(_value_offset);
+     value->c = box->char_field(value_offset(type));
      break;
    case T_FLOAT:
-     value->f = box->float_field(_value_offset);
+     value->f = box->float_field(value_offset(type));
      break;
    case T_DOUBLE:
-     value->d = box->double_field(_long_value_offset);
+     value->d = box->double_field(value_offset(type));
      break;
    case T_BYTE:
-     value->b = box->byte_field(_value_offset);
+     value->b = box->byte_field(value_offset(type));
      break;
    case T_SHORT:
-     value->s = box->short_field(_value_offset);
+     value->s = box->short_field(value_offset(type));
      break;
    case T_INT:
-     value->i = box->int_field(_value_offset);
+     value->i = box->int_field(value_offset(type));
      break;
    case T_LONG:
-     value->j = box->long_field(_long_value_offset);
+     value->j = box->long_field(value_offset(type));
      break;
    default:
      return T_ILLEGAL;
    } // end switch
    return type;

@@ -4071,32 +4108,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(value_offset(type), value->z);
      break;
    case T_CHAR:
-     box->char_field_put(_value_offset, value->c);
+     box->char_field_put(value_offset(type), value->c);
      break;
    case T_FLOAT:
-     box->float_field_put(_value_offset, value->f);
+     box->float_field_put(value_offset(type), value->f);
      break;
    case T_DOUBLE:
-     box->double_field_put(_long_value_offset, value->d);
+     box->double_field_put(value_offset(type), value->d);
      break;
    case T_BYTE:
-     box->byte_field_put(_value_offset, value->b);
+     box->byte_field_put(value_offset(type), value->b);
      break;
    case T_SHORT:
-     box->short_field_put(_value_offset, value->s);
+     box->short_field_put(value_offset(type), value->s);
      break;
    case T_INT:
-     box->int_field_put(_value_offset, value->i);
+     box->int_field_put(value_offset(type), value->i);
      break;
    case T_LONG:
-     box->long_field_put(_long_value_offset, value->j);
+     box->long_field_put(value_offset(type), value->j);
      break;
    default:
      return T_ILLEGAL;
    } // end switch
    return type;

@@ -4320,20 +4357,20 @@
  void jdk_internal_foreign_abi_ABIDescriptor::serialize_offsets(SerializeClosure* f) {
    ABIDescriptor_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
  }
  #endif
  
- objArrayOop jdk_internal_foreign_abi_ABIDescriptor::inputStorage(oop entry) {
-   return oop_cast<objArrayOop>(entry->obj_field(_inputStorage_offset));
+ refArrayOop jdk_internal_foreign_abi_ABIDescriptor::inputStorage(oop entry) {
+   return oop_cast<refArrayOop>(entry->obj_field(_inputStorage_offset));
  }
  
- objArrayOop jdk_internal_foreign_abi_ABIDescriptor::outputStorage(oop entry) {
-   return oop_cast<objArrayOop>(entry->obj_field(_outputStorage_offset));
+ refArrayOop jdk_internal_foreign_abi_ABIDescriptor::outputStorage(oop entry) {
+   return oop_cast<refArrayOop>(entry->obj_field(_outputStorage_offset));
  }
  
- objArrayOop jdk_internal_foreign_abi_ABIDescriptor::volatileStorage(oop entry) {
-   return oop_cast<objArrayOop>(entry->obj_field(_volatileStorage_offset));
+ refArrayOop jdk_internal_foreign_abi_ABIDescriptor::volatileStorage(oop entry) {
+   return oop_cast<refArrayOop>(entry->obj_field(_volatileStorage_offset));
  }
  
  jint jdk_internal_foreign_abi_ABIDescriptor::stackAlignment(oop entry) {
    return entry->int_field(_stackAlignment_offset);
  }

@@ -4412,16 +4449,16 @@
  void jdk_internal_foreign_abi_CallConv::serialize_offsets(SerializeClosure* f) {
    CallConv_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
  }
  #endif
  
- objArrayOop jdk_internal_foreign_abi_CallConv::argRegs(oop entry) {
-   return oop_cast<objArrayOop>(entry->obj_field(_argRegs_offset));
+ refArrayOop jdk_internal_foreign_abi_CallConv::argRegs(oop entry) {
+   return oop_cast<refArrayOop>(entry->obj_field(_argRegs_offset));
  }
  
- objArrayOop jdk_internal_foreign_abi_CallConv::retRegs(oop entry) {
-   return oop_cast<objArrayOop>(entry->obj_field(_retRegs_offset));
+ refArrayOop jdk_internal_foreign_abi_CallConv::retRegs(oop entry) {
+   return oop_cast<refArrayOop>(entry->obj_field(_retRegs_offset));
  }
  
  oop java_lang_invoke_MethodHandle::type(oop mh) {
    return mh->obj_field(_type_offset);
  }

@@ -4480,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);

@@ -4594,11 +4630,11 @@
  }
  #endif
  
  void java_lang_invoke_MethodType::print_signature(oop mt, outputStream* st) {
    st->print("(");
-   objArrayOop pts = ptypes(mt);
+   refArrayOop pts = ptypes(mt);
    if (pts != nullptr) {
      for (int i = 0, limit = pts->length(); i < limit; i++) {
        java_lang_Class::print_signature(pts->obj_at(i), st);
      }
    } else {

@@ -4645,13 +4681,13 @@
  oop java_lang_invoke_MethodType::rtype(oop mt) {
    assert(is_instance(mt), "must be a MethodType");
    return mt->obj_field(_rtype_offset);
  }
  
- objArrayOop java_lang_invoke_MethodType::ptypes(oop mt) {
+ refArrayOop java_lang_invoke_MethodType::ptypes(oop mt) {
    assert(is_instance(mt), "must be a MethodType");
-   return (objArrayOop) mt->obj_field(_ptypes_offset);
+   return (refArrayOop) mt->obj_field(_ptypes_offset);
  }
  
  oop java_lang_invoke_MethodType::ptype(oop mt, int idx) {
    return ptypes(mt)->obj_at(idx);
  }

@@ -4659,11 +4695,11 @@
  int java_lang_invoke_MethodType::ptype_count(oop mt) {
    return ptypes(mt)->length();
  }
  
  int java_lang_invoke_MethodType::ptype_slot_count(oop mt) {
-   objArrayOop pts = ptypes(mt);
+   refArrayOop pts = ptypes(mt);
    int count = pts->length();
    int slots = 0;
    for (int i = 0; i < count; i++) {
      BasicType bt = java_lang_Class::as_BasicType(pts->obj_at(i));
      slots += type2size[bt];

@@ -5084,13 +5120,13 @@
  void java_lang_Integer_IntegerCache::compute_offsets(InstanceKlass *k) {
    guarantee(k != nullptr && k->is_initialized(), "must be loaded and initialized");
    INTEGER_CACHE_FIELDS_DO(FIELD_COMPUTE_OFFSET);
  }
  
- objArrayOop java_lang_Integer_IntegerCache::cache(InstanceKlass *ik) {
+ refArrayOop java_lang_Integer_IntegerCache::cache(InstanceKlass *ik) {
    oop base = ik->static_field_base_raw();
-   return objArrayOop(base->obj_field(_static_cache_offset));
+   return refArrayOop(base->obj_field(_static_cache_offset));
  }
  
  Symbol* java_lang_Integer_IntegerCache::symbol() {
    return vmSymbols::java_lang_Integer_IntegerCache();
  }

@@ -5114,13 +5150,13 @@
  void java_lang_Long_LongCache::compute_offsets(InstanceKlass *k) {
    guarantee(k != nullptr && k->is_initialized(), "must be loaded and initialized");
    LONG_CACHE_FIELDS_DO(FIELD_COMPUTE_OFFSET);
  }
  
- objArrayOop java_lang_Long_LongCache::cache(InstanceKlass *ik) {
+ refArrayOop java_lang_Long_LongCache::cache(InstanceKlass *ik) {
    oop base = ik->static_field_base_raw();
-   return objArrayOop(base->obj_field(_static_cache_offset));
+   return refArrayOop(base->obj_field(_static_cache_offset));
  }
  
  Symbol* java_lang_Long_LongCache::symbol() {
    return vmSymbols::java_lang_Long_LongCache();
  }

@@ -5144,13 +5180,13 @@
  void java_lang_Character_CharacterCache::compute_offsets(InstanceKlass *k) {
    guarantee(k != nullptr && k->is_initialized(), "must be loaded and initialized");
    CHARACTER_CACHE_FIELDS_DO(FIELD_COMPUTE_OFFSET);
  }
  
- objArrayOop java_lang_Character_CharacterCache::cache(InstanceKlass *ik) {
+ refArrayOop java_lang_Character_CharacterCache::cache(InstanceKlass *ik) {
    oop base = ik->static_field_base_raw();
-   return objArrayOop(base->obj_field(_static_cache_offset));
+   return refArrayOop(base->obj_field(_static_cache_offset));
  }
  
  Symbol* java_lang_Character_CharacterCache::symbol() {
    return vmSymbols::java_lang_Character_CharacterCache();
  }

@@ -5174,13 +5210,13 @@
  void java_lang_Short_ShortCache::compute_offsets(InstanceKlass *k) {
    guarantee(k != nullptr && k->is_initialized(), "must be loaded and initialized");
    SHORT_CACHE_FIELDS_DO(FIELD_COMPUTE_OFFSET);
  }
  
- objArrayOop java_lang_Short_ShortCache::cache(InstanceKlass *ik) {
+ refArrayOop java_lang_Short_ShortCache::cache(InstanceKlass *ik) {
    oop base = ik->static_field_base_raw();
-   return objArrayOop(base->obj_field(_static_cache_offset));
+   return refArrayOop(base->obj_field(_static_cache_offset));
  }
  
  Symbol* java_lang_Short_ShortCache::symbol() {
    return vmSymbols::java_lang_Short_ShortCache();
  }

@@ -5204,13 +5240,13 @@
  void java_lang_Byte_ByteCache::compute_offsets(InstanceKlass *k) {
    guarantee(k != nullptr && k->is_initialized(), "must be loaded and initialized");
    BYTE_CACHE_FIELDS_DO(FIELD_COMPUTE_OFFSET);
  }
  
- objArrayOop java_lang_Byte_ByteCache::cache(InstanceKlass *ik) {
+ refArrayOop java_lang_Byte_ByteCache::cache(InstanceKlass *ik) {
    oop base = ik->static_field_base_raw();
-   return objArrayOop(base->obj_field(_static_cache_offset));
+   return refArrayOop(base->obj_field(_static_cache_offset));
  }
  
  Symbol* java_lang_Byte_ByteCache::symbol() {
    return vmSymbols::java_lang_Byte_ByteCache();
  }

@@ -5483,26 +5519,21 @@
  }
  
  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_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");
+ #define CHECK_OFFSET(klass_name, type, field_sig) \
+   valid &= check_offset(klass_name, java_lang_boxing_object::value_offset(type), "value", field_sig)
+ 
+   CHECK_OFFSET("java/lang/Boolean",   T_BOOLEAN, "Z");
+   CHECK_OFFSET("java/lang/Character", T_CHAR,    "C");
+   CHECK_OFFSET("java/lang/Float",     T_FLOAT,   "F");
+   CHECK_OFFSET("java/lang/Double",    T_DOUBLE,  "D");
+   CHECK_OFFSET("java/lang/Byte",      T_BYTE,    "B");
+   CHECK_OFFSET("java/lang/Short",     T_SHORT,   "S");
+   CHECK_OFFSET("java/lang/Integer",   T_INT,     "I");
+   CHECK_OFFSET("java/lang/Long",      T_LONG,    "J");
  
    if (!valid) vm_exit_during_initialization("Field offset verification failed");
  }
  
  #endif // PRODUCT
< prev index next >