< prev index next >

src/hotspot/share/classfile/javaClasses.cpp

Print this page
*** 50,19 ***
  #include "memory/oopFactory.hpp"
  #include "memory/resourceArea.hpp"
  #include "memory/universe.hpp"
  #include "oops/fieldInfo.hpp"
  #include "oops/fieldStreams.inline.hpp"
  #include "oops/instanceKlass.inline.hpp"
! #include "oops/instanceMirrorKlass.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/symbol.hpp"
  #include "oops/typeArrayOop.inline.hpp"
  #include "prims/jvmtiExport.hpp"
  #include "prims/methodHandles.hpp"
  #include "prims/resolvedMethodTable.hpp"
--- 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.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 ***
    set_klass(mirror(), k);
  
    // Set the modifiers flag.
    u2 computed_modifiers = k->compute_modifier_flags();
    set_modifiers(mirror(), computed_modifiers);
  
    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()) {
      // 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");
        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 {
--- 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_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 ***
  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()) {
      Handle mirror;
      Handle comp_mirror;
  
      allocate_mirror(k, /*is_scratch=*/false, protection_domain, classData, mirror, comp_mirror, CHECK);
  
--- 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");

*** 1234,20 ***
    // 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()) {
      // - 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());
      }
    }
  
    assert(class_loader() == k->class_loader(), "should be same");
    if (class_loader.not_null()) {
      set_class_loader(mirror(), class_loader());
--- 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));
    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 ***
      ResourceMark rm(THREAD);
      log_trace(aot, heap, mirror)(
          "Restored %s archived mirror " PTR_FORMAT, k->external_name(), p2i(mirror()));
    }
  
!   if (CDSConfig::is_dumping_heap()) {
      create_scratch_mirror(k, CHECK_(false));
    }
  
    return true;
  }
--- 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() && (!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) {

*** 1479,10 ***
--- 1503,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 ***
    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);
  
  void java_lang_Class::compute_offsets() {
    if (_offsets_computed) {
      return;
    }
--- 1563,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_identity_offset,         k, "identity",            bool_signature,         false);
  
  void java_lang_Class::compute_offsets() {
    if (_offsets_computed) {
      return;
    }

*** 1988,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);
  
    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),
--- 2014,11 ---
    InstanceKlass* k = vmClasses::StackTraceElement_klass();
    assert(k != nullptr, "must be loaded in 1.4+");
    if (k->should_be_initialized()) {
      k->initialize(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 ***
    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);
  }
  
  
! void java_lang_Throwable::set_backtrace(oop throwable, oop value) {
    throwable->release_obj_field_put(_backtrace_offset, value);
  }
  
  int java_lang_Throwable::depth(oop throwable) {
    return throwable->int_field(_depth_offset);
--- 2305,16 ---
    InstanceKlass* ik = vmClasses::Throwable_klass();
    oop base = ik->static_field_base_raw();
    return base->obj_field(_static_unassigned_stacktrace_offset);
  }
  
! refArrayOop java_lang_Throwable::backtrace(oop throwable) {
!   return (refArrayOop)throwable->obj_field_acquire(_backtrace_offset);
  }
  
  
! 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 ***
  // 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;
    typeArrayOop    _methods;
    typeArrayOop    _bcis;
!   objArrayOop     _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;
--- 2380,15 ---
  // The code of this class is not GC safe. Allocations can only happen
  // in expand().
  class BacktraceBuilder: public StackObj {
   friend class BacktraceIterator;
   private:
!   refArrayHandle  _backtrace;
!   refArrayOop     _head;
    typeArrayOop    _methods;
    typeArrayOop    _bcis;
!   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 ***
      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) {
      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) {
      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));
      assert(mirrors != nullptr, "mirror array should be initialized in backtrace");
      return mirrors;
    }
!   static typeArrayOop get_names(objArrayHandle 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) {
      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);
      _index = 0;
    }
  
!   BacktraceBuilder(Thread* thread, objArrayHandle 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);
--- 2404,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(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(refArrayHandle chunk) {
      typeArrayOop bcis = typeArrayOop(chunk->obj_at(trace_bcis_offset));
      assert(bcis != nullptr, "bci array should be initialized in backtrace");
      return bcis;
    }
!   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(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(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 = refArrayHandle(THREAD, _head);
      _index = 0;
    }
  
!   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 ***
             _mirrors->length() == _names->length(),
             "method and source information arrays should match");
  
      // head is the preallocated backtrace
      _head = backtrace();
!     _backtrace = Handle(thread, _head);
      _index = 0;
    }
  
    void expand(TRAPS) {
!     objArrayHandle old_head(THREAD, _head);
      PauseNoSafepointVerifier pnsv(&_nsv);
  
!     objArrayOop head = oopFactory::new_objectArray(trace_size, CHECK);
!     objArrayHandle 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);
  
      typeArrayOop names = oopFactory::new_symbolArray(trace_chunk_size, CHECK);
      typeArrayHandle new_names(THREAD, names);
  
      if (!old_head.is_null()) {
--- 2451,29 ---
             _mirrors->length() == _names->length(),
             "method and source information arrays should match");
  
      // head is the preallocated backtrace
      _head = backtrace();
!     _backtrace = refArrayHandle(thread, _head);
      _index = 0;
    }
  
    void expand(TRAPS) {
!     refArrayHandle old_head(THREAD, _head);
      PauseNoSafepointVerifier pnsv(&_nsv);
  
!     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);
  
!     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 ***
      _mirrors = new_mirrors();
      _names  = new_names();
      _index = 0;
    }
  
!   oop backtrace() {
      return _backtrace();
    }
  
    inline void push(Method* method, int bci, TRAPS) {
      // Smear the -1 bci to 0 since the array only holds unsigned
--- 2491,11 ---
      _mirrors = new_mirrors();
      _names  = new_names();
      _index = 0;
    }
  
!   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 ***
                     _method_id(mid), _bci(bci), _version(version), _name(name), _mirror(mirror) {}
  };
  
  class BacktraceIterator : public StackObj {
    int _index;
!   objArrayHandle  _result;
!   objArrayHandle  _mirrors;
    typeArrayHandle _methods;
    typeArrayHandle _bcis;
    typeArrayHandle _names;
  
!   void init(objArrayHandle 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));
        _names = typeArrayHandle(thread, BacktraceBuilder::get_names(_result));
        _index = 0;
      }
    }
   public:
!   BacktraceIterator(objArrayHandle 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) {
--- 2549,29 ---
                     _method_id(mid), _bci(bci), _version(version), _name(name), _mirror(mirror) {}
  };
  
  class BacktraceIterator : public StackObj {
    int _index;
!   refArrayHandle  _result;
!   refArrayHandle  _mirrors;
    typeArrayHandle _methods;
    typeArrayHandle _bcis;
    typeArrayHandle _names;
  
!   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 = refArrayHandle(thread, BacktraceBuilder::get_mirrors(_result));
        _names = typeArrayHandle(thread, BacktraceBuilder::get_names(_result));
        _index = 0;
      }
    }
   public:
!   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 ***
      _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)));
        init(result, thread);
      }
      return e;
    }
  
--- 2583,11 ---
      _index++;
  
      if (_index >= java_lang_Throwable::trace_chunk_size) {
        int next_offset = java_lang_Throwable::trace_next_offset;
        // Get next chunk
!       refArrayHandle result (thread, refArrayOop(_result->obj_at(next_offset)));
        init(result, thread);
      }
      return e;
    }
  

*** 2648,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())));
      if (result.is_null()) {
        st->print_raw_cr("\t<<no stack trace available>>");
        return;
      }
      BacktraceIterator iter(result, THREAD);
--- 2674,11 ---
    st->cr();
  
    // Now print the stack trace.
    JavaThread* THREAD = JavaThread::current(); // For exception macros.
    while (throwable.not_null()) {
!     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 ***
      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() &&
            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;
--- 2858,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->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 ***
  
    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()));
    assert(backtrace.not_null(), "backtrace should have been preallocated");
  
    ResourceMark rm(THREAD);
    vframeStream st(THREAD, false /* stop_at_java_call_stub */, false /* process_frames */);
  
--- 2927,11 ---
  
    assert(throwable->is_a(vmClasses::Throwable_klass()), "sanity check");
  
    JavaThread* THREAD = JavaThread::current(); // For exception macros.
  
!   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 ***
    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) {
  
    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");
  
    if (stack_trace_array_h->length() != depth) {
      THROW(vmSymbols::java_lang_IndexOutOfBoundsException());
    }
  
!   objArrayHandle result(THREAD, objArrayOop(backtrace()));
    BacktraceIterator iter(result, THREAD);
  
    int index = 0;
    while (iter.repeat()) {
      BacktraceElement bte = iter.next(THREAD);
--- 2956,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,
!                                                    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_refArray(), "Stack trace array should be an array of StackTraceElement");
  
    if (stack_trace_array_h->length() != depth) {
      THROW(vmSymbols::java_lang_IndexOutOfBoundsException());
    }
  
!   refArrayHandle result(THREAD, refArrayOop(backtrace()));
    BacktraceIterator iter(result, THREAD);
  
    int index = 0;
    while (iter.repeat()) {
      BacktraceElement bte = iter.next(THREAD);

*** 3026,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)));
    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);
    if (hidden != nullptr) {
      return false;
    }
  
    // Get first backtrace element.
--- 3052,18 ---
    return init_error;
  }
  
  bool java_lang_Throwable::get_top_method_and_bci(oop throwable, Method** method, int* bci) {
    JavaThread* current = JavaThread::current();
!   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 = backtrace(throwable)->obj_at(trace_hidden_offset);
    if (hidden != nullptr) {
      return false;
    }
  
    // Get first backtrace element.

*** 3191,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;
    } else {
      // Note: Static initializers can be here. Record them as plain methods.
      flags |= java_lang_invoke_MemberName::MN_IS_METHOD;
    }
    if (m->caller_sensitive()) {
--- 3217,12 ---
  }
  #endif
  
  static int get_flags(const methodHandle& m) {
    int flags = m->access_flags().as_method_flags();
!   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 ***
  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::_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(_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();
--- 3609,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::_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(_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 ***
  
  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_signature(oop field, oop value) {
    field->obj_field_put(_signature_offset, value);
  }
--- 3684,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_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 ***
    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;
  
! #define BOXING_FIELDS_DO(macro) \
!   macro(_value_offset,      integerKlass, "value", int_signature, false); \
!   macro(_long_value_offset, longKlass, "value", long_signature, false);
  
  void java_lang_boxing_object::compute_offsets() {
!   InstanceKlass* integerKlass = vmClasses::Integer_klass();
!   InstanceKlass* longKlass = vmClasses::Long_klass();
    BOXING_FIELDS_DO(FIELD_COMPUTE_OFFSET);
  }
  
  #if INCLUDE_CDS
  void java_lang_boxing_object::serialize_offsets(SerializeClosure* f) {
    BOXING_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
  }
  #endif
  
  oop java_lang_boxing_object::initialize_and_allocate(BasicType type, TRAPS) {
--- 3985,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::_offsets;
  
! #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() {
!   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 ***
  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);
        break;
      case T_CHAR:
!       box->char_field_put(_value_offset, value->c);
        break;
      case T_FLOAT:
!       box->float_field_put(_value_offset, value->f);
        break;
      case T_DOUBLE:
!       box->double_field_put(_long_value_offset, value->d);
        break;
      case T_BYTE:
!       box->byte_field_put(_value_offset, value->b);
        break;
      case T_SHORT:
!       box->short_field_put(_value_offset, value->s);
        break;
      case T_INT:
!       box->int_field_put(_value_offset, value->i);
        break;
      case T_LONG:
!       box->long_field_put(_long_value_offset, value->j);
        break;
      default:
        return nullptr;
    }
    return box;
--- 4029,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(type), value->z);
        break;
      case T_CHAR:
!       box->char_field_put(value_offset(type), value->c);
        break;
      case T_FLOAT:
!       box->float_field_put(value_offset(type), value->f);
        break;
      case T_DOUBLE:
!       box->double_field_put(value_offset(type), value->d);
        break;
      case T_BYTE:
!       box->byte_field_put(value_offset(type), value->b);
        break;
      case T_SHORT:
!       box->short_field_put(value_offset(type), value->s);
        break;
      case T_INT:
!       box->int_field_put(value_offset(type), value->i);
        break;
      case T_LONG:
!       box->long_field_put(value_offset(type), value->j);
        break;
      default:
        return nullptr;
    }
    return box;

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

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

*** 4320,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));
  }
  
! objArrayOop jdk_internal_foreign_abi_ABIDescriptor::outputStorage(oop entry) {
!   return oop_cast<objArrayOop>(entry->obj_field(_outputStorage_offset));
  }
  
! objArrayOop jdk_internal_foreign_abi_ABIDescriptor::volatileStorage(oop entry) {
!   return oop_cast<objArrayOop>(entry->obj_field(_volatileStorage_offset));
  }
  
  jint jdk_internal_foreign_abi_ABIDescriptor::stackAlignment(oop entry) {
    return entry->int_field(_stackAlignment_offset);
  }
--- 4355,20 ---
  void jdk_internal_foreign_abi_ABIDescriptor::serialize_offsets(SerializeClosure* f) {
    ABIDescriptor_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
  }
  #endif
  
! refArrayOop jdk_internal_foreign_abi_ABIDescriptor::inputStorage(oop entry) {
!   return oop_cast<refArrayOop>(entry->obj_field(_inputStorage_offset));
  }
  
! refArrayOop jdk_internal_foreign_abi_ABIDescriptor::outputStorage(oop entry) {
!   return oop_cast<refArrayOop>(entry->obj_field(_outputStorage_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 ***
  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));
  }
  
! objArrayOop jdk_internal_foreign_abi_CallConv::retRegs(oop entry) {
!   return oop_cast<objArrayOop>(entry->obj_field(_retRegs_offset));
  }
  
  oop java_lang_invoke_MethodHandle::type(oop mh) {
    return mh->obj_field(_type_offset);
  }
--- 4447,16 ---
  void jdk_internal_foreign_abi_CallConv::serialize_offsets(SerializeClosure* f) {
    CallConv_FIELDS_DO(FIELD_SERIALIZE_OFFSET);
  }
  #endif
  
! refArrayOop jdk_internal_foreign_abi_CallConv::argRegs(oop entry) {
!   return oop_cast<refArrayOop>(entry->obj_field(_argRegs_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 ***
  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;
  }
  
  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);
--- 4515,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_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 ***
  }
  #endif
  
  void java_lang_invoke_MethodType::print_signature(oop mt, outputStream* st) {
    st->print("(");
!   objArrayOop 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 {
--- 4628,11 ---
  }
  #endif
  
  void java_lang_invoke_MethodType::print_signature(oop mt, outputStream* st) {
    st->print("(");
!   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 ***
  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) {
    assert(is_instance(mt), "must be a MethodType");
!   return (objArrayOop) mt->obj_field(_ptypes_offset);
  }
  
  oop java_lang_invoke_MethodType::ptype(oop mt, int idx) {
    return ptypes(mt)->obj_at(idx);
  }
--- 4679,13 ---
  oop java_lang_invoke_MethodType::rtype(oop mt) {
    assert(is_instance(mt), "must be a MethodType");
    return mt->obj_field(_rtype_offset);
  }
  
! refArrayOop java_lang_invoke_MethodType::ptypes(oop mt) {
    assert(is_instance(mt), "must be a MethodType");
!   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 ***
  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);
    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];
--- 4693,11 ---
  int java_lang_invoke_MethodType::ptype_count(oop mt) {
    return ptypes(mt)->length();
  }
  
  int java_lang_invoke_MethodType::ptype_slot_count(oop 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 ***
  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) {
    oop base = ik->static_field_base_raw();
!   return objArrayOop(base->obj_field(_static_cache_offset));
  }
  
  Symbol* java_lang_Integer_IntegerCache::symbol() {
    return vmSymbols::java_lang_Integer_IntegerCache();
  }
--- 5118,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);
  }
  
! refArrayOop java_lang_Integer_IntegerCache::cache(InstanceKlass *ik) {
    oop base = ik->static_field_base_raw();
!   return refArrayOop(base->obj_field(_static_cache_offset));
  }
  
  Symbol* java_lang_Integer_IntegerCache::symbol() {
    return vmSymbols::java_lang_Integer_IntegerCache();
  }

*** 5114,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) {
    oop base = ik->static_field_base_raw();
!   return objArrayOop(base->obj_field(_static_cache_offset));
  }
  
  Symbol* java_lang_Long_LongCache::symbol() {
    return vmSymbols::java_lang_Long_LongCache();
  }
--- 5148,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);
  }
  
! refArrayOop java_lang_Long_LongCache::cache(InstanceKlass *ik) {
    oop base = ik->static_field_base_raw();
!   return refArrayOop(base->obj_field(_static_cache_offset));
  }
  
  Symbol* java_lang_Long_LongCache::symbol() {
    return vmSymbols::java_lang_Long_LongCache();
  }

*** 5144,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) {
    oop base = ik->static_field_base_raw();
!   return objArrayOop(base->obj_field(_static_cache_offset));
  }
  
  Symbol* java_lang_Character_CharacterCache::symbol() {
    return vmSymbols::java_lang_Character_CharacterCache();
  }
--- 5178,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);
  }
  
! refArrayOop java_lang_Character_CharacterCache::cache(InstanceKlass *ik) {
    oop base = ik->static_field_base_raw();
!   return refArrayOop(base->obj_field(_static_cache_offset));
  }
  
  Symbol* java_lang_Character_CharacterCache::symbol() {
    return vmSymbols::java_lang_Character_CharacterCache();
  }

*** 5174,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) {
    oop base = ik->static_field_base_raw();
!   return objArrayOop(base->obj_field(_static_cache_offset));
  }
  
  Symbol* java_lang_Short_ShortCache::symbol() {
    return vmSymbols::java_lang_Short_ShortCache();
  }
--- 5208,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);
  }
  
! refArrayOop java_lang_Short_ShortCache::cache(InstanceKlass *ik) {
    oop base = ik->static_field_base_raw();
!   return refArrayOop(base->obj_field(_static_cache_offset));
  }
  
  Symbol* java_lang_Short_ShortCache::symbol() {
    return vmSymbols::java_lang_Short_ShortCache();
  }

*** 5204,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) {
    oop base = ik->static_field_base_raw();
!   return objArrayOop(base->obj_field(_static_cache_offset));
  }
  
  Symbol* java_lang_Byte_ByteCache::symbol() {
    return vmSymbols::java_lang_Byte_ByteCache();
  }
--- 5238,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);
  }
  
! refArrayOop java_lang_Byte_ByteCache::cache(InstanceKlass *ik) {
    oop base = ik->static_field_base_raw();
!   return refArrayOop(base->obj_field(_static_cache_offset));
  }
  
  Symbol* java_lang_Byte_ByteCache::symbol() {
    return vmSymbols::java_lang_Byte_ByteCache();
  }

*** 5483,26 ***
  }
  
  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");
  
    if (!valid) vm_exit_during_initialization("Field offset verification failed");
  }
  
  #endif // PRODUCT
--- 5517,21 ---
  }
  
  void JavaClasses::check_offsets() {
    bool valid = true;
  
! #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 >