< prev index next >

src/hotspot/share/oops/constantPool.cpp

Print this page
*** 1,7 ***
  /*
!  * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.
--- 1,7 ---
  /*
!  * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.

*** 49,15 ***
--- 49,18 ---
  #include "memory/universe.hpp"
  #include "oops/array.hpp"
  #include "oops/constantPool.inline.hpp"
  #include "oops/cpCache.inline.hpp"
  #include "oops/fieldStreams.inline.hpp"
+ #include "oops/flatArrayKlass.hpp"
  #include "oops/instanceKlass.hpp"
  #include "oops/klass.inline.hpp"
  #include "oops/objArrayKlass.hpp"
  #include "oops/objArrayOop.inline.hpp"
  #include "oops/oop.inline.hpp"
+ #include "oops/oopCast.inline.hpp"
+ #include "oops/refArrayOop.hpp"
  #include "oops/typeArrayOop.inline.hpp"
  #include "prims/jvmtiExport.hpp"
  #include "runtime/atomicAccess.hpp"
  #include "runtime/fieldDescriptor.inline.hpp"
  #include "runtime/handles.inline.hpp"

*** 164,17 ***
        it->push(symbol_at_addr(i));
      }
    }
  }
  
! objArrayOop ConstantPool::resolved_references() const {
    return _cache->resolved_references();
  }
  
  // Called from outside constant pool resolution where a resolved_reference array
  // may not be present.
! objArrayOop ConstantPool::resolved_references_or_null() const {
    if (_cache == nullptr) {
      return nullptr;
    } else {
      return _cache->resolved_references();
    }
--- 167,17 ---
        it->push(symbol_at_addr(i));
      }
    }
  }
  
! refArrayOop ConstantPool::resolved_references() const {
    return _cache->resolved_references();
  }
  
  // Called from outside constant pool resolution where a resolved_reference array
  // may not be present.
! refArrayOop ConstantPool::resolved_references_or_null() const {
    if (_cache == nullptr) {
      return nullptr;
    } else {
      return _cache->resolved_references();
    }

*** 187,11 ***
  }
  
  // Use a CAS for multithreaded access
  oop ConstantPool::set_resolved_reference_at(int index, oop new_result) {
    assert(oopDesc::is_oop_or_null(new_result), "Must be oop");
!   return resolved_references()->replace_if_null(index, new_result);
  }
  
  // Create resolved_references array and mapping array for original cp indexes
  // The ldc bytecode was rewritten to have the resolved reference array index so need a way
  // to map it back for resolving and some unlikely miscellaneous uses.
--- 190,11 ---
  }
  
  // Use a CAS for multithreaded access
  oop ConstantPool::set_resolved_reference_at(int index, oop new_result) {
    assert(oopDesc::is_oop_or_null(new_result), "Must be oop");
!   return oop_cast<refArrayOop>(resolved_references())->replace_if_null(index, new_result);
  }
  
  // Create resolved_references array and mapping array for original cp indexes
  // The ldc bytecode was rewritten to have the resolved reference array index so need a way
  // to map it back for resolving and some unlikely miscellaneous uses.

*** 218,18 ***
        set_reference_map(om);
      }
  
      // Create Java array for holding resolved strings, methodHandles,
      // methodTypes, invokedynamic and invokehandle appendix objects, etc.
!     objArrayOop stom = oopFactory::new_objArray(vmClasses::Object_klass(), map_length, CHECK);
      HandleMark hm(THREAD);
      Handle refs_handle (THREAD, stom);  // must handleize.
      set_resolved_references(loader_data->add_handle(refs_handle));
  
      // Create a "scratch" copy of the resolved references array to archive
      if (CDSConfig::is_dumping_heap()) {
!       objArrayOop scratch_references = oopFactory::new_objArray(vmClasses::Object_klass(), map_length, CHECK);
        HeapShared::add_scratch_resolved_references(this, scratch_references);
      }
    }
  }
  
--- 221,18 ---
        set_reference_map(om);
      }
  
      // Create Java array for holding resolved strings, methodHandles,
      // methodTypes, invokedynamic and invokehandle appendix objects, etc.
!     refArrayOop stom = oopFactory::new_refArray(vmClasses::Object_klass(), map_length, CHECK);
      HandleMark hm(THREAD);
      Handle refs_handle (THREAD, stom);  // must handleize.
      set_resolved_references(loader_data->add_handle(refs_handle));
  
      // Create a "scratch" copy of the resolved references array to archive
      if (CDSConfig::is_dumping_heap()) {
!       refArrayOop scratch_references = oopFactory::new_refArray(vmClasses::Object_klass(), map_length, CHECK);
        HeapShared::add_scratch_resolved_references(this, scratch_references);
      }
    }
  }
  

*** 258,11 ***
        break;
  #ifndef PRODUCT
      case JVM_CONSTANT_Class:
      case JVM_CONSTANT_UnresolvedClass:
      case JVM_CONSTANT_UnresolvedClassInError:
!       // All of these should have been reverted back to ClassIndex before calling
        // this function.
        ShouldNotReachHere();
  #endif
      }
    }
--- 261,11 ---
        break;
  #ifndef PRODUCT
      case JVM_CONSTANT_Class:
      case JVM_CONSTANT_UnresolvedClass:
      case JVM_CONSTANT_UnresolvedClassInError:
!       // All of these should have been reverted back to Unresolved before calling
        // this function.
        ShouldNotReachHere();
  #endif
      }
    }

*** 321,11 ***
    }
  }
  
  // Returns the _resolved_reference array after removing unarchivable items from it.
  // Returns null if this class is not supported, or _resolved_reference doesn't exist.
! objArrayOop ConstantPool::prepare_resolved_references_for_archiving() {
    if (_cache == nullptr) {
      return nullptr; // nothing to do
    }
  
    InstanceKlass *ik = pool_holder();
--- 324,11 ---
    }
  }
  
  // Returns the _resolved_reference array after removing unarchivable items from it.
  // Returns null if this class is not supported, or _resolved_reference doesn't exist.
! refArrayOop ConstantPool::prepare_resolved_references_for_archiving() {
    if (_cache == nullptr) {
      return nullptr; // nothing to do
    }
  
    InstanceKlass *ik = pool_holder();

*** 333,21 ***
      // Archiving resolved references for classes from non-builtin loaders
      // is not yet supported.
      return nullptr;
    }
  
!   objArrayOop rr = resolved_references();
    if (rr != nullptr) {
      ResourceMark rm;
      int rr_len = rr->length();
      GrowableArray<bool> keep_resolved_refs(rr_len, rr_len, false);
  
      iterate_archivable_resolved_references([&](int rr_index) {
        keep_resolved_refs.at_put(rr_index, true);
      });
  
!     objArrayOop scratch_rr = HeapShared::scratch_resolved_references(this);
      Array<u2>* ref_map = reference_map();
      int ref_map_len = ref_map == nullptr ? 0 : ref_map->length();
      for (int i = 0; i < rr_len; i++) {
        oop obj = rr->obj_at(i);
        scratch_rr->obj_at_put(i, nullptr);
--- 336,21 ---
      // Archiving resolved references for classes from non-builtin loaders
      // is not yet supported.
      return nullptr;
    }
  
!   refArrayOop rr = resolved_references();
    if (rr != nullptr) {
      ResourceMark rm;
      int rr_len = rr->length();
      GrowableArray<bool> keep_resolved_refs(rr_len, rr_len, false);
  
      iterate_archivable_resolved_references([&](int rr_index) {
        keep_resolved_refs.at_put(rr_index, true);
      });
  
!     refArrayOop scratch_rr = HeapShared::scratch_resolved_references(this);
      Array<u2>* ref_map = reference_map();
      int ref_map_len = ref_map == nullptr ? 0 : ref_map->length();
      for (int i = 0; i < rr_len; i++) {
        oop obj = rr->obj_at(i);
        scratch_rr->obj_at_put(i, nullptr);

*** 474,10 ***
--- 477,11 ---
    }
  
    if (src_k->is_objArray_klass()) {
      src_k = ObjArrayKlass::cast(src_k)->bottom_klass();
      assert(!src_k->is_objArray_klass(), "sanity");
+     assert(src_k->is_instance_klass() || src_k->is_typeArray_klass(), "Sanity check");
    }
  
    if (src_k->is_typeArray_klass()) {
      type = "prim";
    } else {

*** 673,10 ***
--- 677,18 ---
      mirror_handle = Handle(THREAD, k->java_mirror());
      // Do access check for klasses
      verify_constant_pool_resolve(this_cp, k, THREAD);
    }
  
+ #ifdef DEBUG
+   if (!HAS_PENDING_EXCEPTION && k->is_objArray_klass()) {
+     Klass* bottom_klass = ObjArrayKlass::cast(k)->bottom_klass();
+     assert(bottom_klass != nullptr, "Should be set");
+     assert(bottom_klass->is_instance_klass() || bottom_klass->is_typeArray_klass(), "Sanity check");
+   }
+ #endif
+ 
    // Failed to resolve class. We must record the errors so that subsequent attempts
    // to resolve this constant pool entry fail with the same error (JVMS 5.4.3).
    if (HAS_PENDING_EXCEPTION) {
      save_and_throw_exception(this_cp, cp_index, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_NULL);
      // If CHECK_NULL above doesn't return the exception, that means that

*** 1340,11 ***
    return str;
  }
  
  void ConstantPool::copy_bootstrap_arguments_at_impl(const constantPoolHandle& this_cp, int cp_index,
                                                      int start_arg, int end_arg,
!                                                     objArrayHandle info, int pos,
                                                      bool must_resolve, Handle if_not_available,
                                                      TRAPS) {
    int limit = pos + end_arg - start_arg;
    // checks: cp_index in range [0..this_cp->length),
    // tag at cp_index, start..end in range [0..this_cp->bootstrap_argument_count],
--- 1352,11 ---
    return str;
  }
  
  void ConstantPool::copy_bootstrap_arguments_at_impl(const constantPoolHandle& this_cp, int cp_index,
                                                      int start_arg, int end_arg,
!                                                     refArrayHandle info, int pos,
                                                      bool must_resolve, Handle if_not_available,
                                                      TRAPS) {
    int limit = pos + end_arg - start_arg;
    // checks: cp_index in range [0..this_cp->length),
    // tag at cp_index, start..end in range [0..this_cp->bootstrap_argument_count],
< prev index next >