< prev index next >

src/hotspot/share/cds/archiveHeapWriter.hpp

Print this page
*** 1,7 ***
  /*
!  * Copyright (c) 2024, 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) 2023, 2024, 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.

*** 61,10 ***
--- 61,11 ---
    size_t heap_roots_offset() const { return _heap_roots_offset; }
  };
  
  #if INCLUDE_CDS_JAVA_HEAP
  class ArchiveHeapWriter : AllStatic {
+   friend class HeapShared;
    // ArchiveHeapWriter manipulates three types of addresses:
    //
    //     "source" vs "buffered" vs "requested"
    //
    // (Note: the design and convention is the same as for the archiving of Metaspace objects.

*** 138,10 ***
--- 139,11 ---
    static address _requested_bottom;
    static address _requested_top;
  
    static GrowableArrayCHeap<NativePointerInfo, mtClassShared>* _native_pointers;
    static GrowableArrayCHeap<oop, mtClassShared>* _source_objs;
+   static GrowableArrayCHeap<oop, mtClassShared>* _perm_objs;
  
    // We sort _source_objs_order to minimize the number of bits in ptrmap and oopmap.
    // See comments near the body of ArchiveHeapWriter::compare_objs_by_oop_fields().
    // The objects will be written in the order of:
    //_source_objs->at(_source_objs_order->at(0)._index)

*** 191,21 ***
    static size_t buffered_address_to_offset(address buffered_addr) {
      assert(in_buffer(buffered_addr), "sanity");
      return buffered_addr - buffer_bottom();
    }
  
!   static void copy_roots_to_buffer(GrowableArrayCHeap<oop, mtClassShared>* roots);
!   static void copy_source_objs_to_buffer(GrowableArrayCHeap<oop, mtClassShared>* roots);
    static size_t copy_one_source_obj_to_buffer(oop src_obj);
  
    static void maybe_fill_gc_region_gap(size_t required_byte_size);
    static size_t filler_array_byte_size(int length);
    static int filler_array_length(size_t fill_bytes);
    static HeapWord* init_filler_array_at_buffer_top(int array_length, size_t fill_bytes);
  
    static void set_requested_address(ArchiveHeapInfo* info);
!   static void relocate_embedded_oops(GrowableArrayCHeap<oop, mtClassShared>* roots, ArchiveHeapInfo* info);
    static void compute_ptrmap(ArchiveHeapInfo *info);
    static bool is_in_requested_range(oop o);
    static oop requested_obj_from_buffer_offset(size_t offset);
  
    static oop load_oop_from_buffer(oop* buffered_addr);
--- 193,26 ---
    static size_t buffered_address_to_offset(address buffered_addr) {
      assert(in_buffer(buffered_addr), "sanity");
      return buffered_addr - buffer_bottom();
    }
  
!   static size_t create_objarray_in_buffer(GrowableArrayCHeap<oop, mtClassShared>* input, int from,
!                                           int num_elms, int extra_length, size_t& objarray_word_size);
+   static int copy_source_objs_to_buffer(GrowableArrayCHeap<oop, mtClassShared>* roots, GrowableArray<size_t>* permobj_seg_offsets);
+   template <typename T> static void add_permobj_segments_to_roots(GrowableArrayCHeap<oop, mtClassShared>* roots,
+                                                                   ArchiveHeapInfo* info, GrowableArray<size_t>* permobj_seg_offsets);
+   static void update_stats(oop src_obj);
    static size_t copy_one_source_obj_to_buffer(oop src_obj);
  
    static void maybe_fill_gc_region_gap(size_t required_byte_size);
    static size_t filler_array_byte_size(int length);
    static int filler_array_length(size_t fill_bytes);
    static HeapWord* init_filler_array_at_buffer_top(int array_length, size_t fill_bytes);
  
    static void set_requested_address(ArchiveHeapInfo* info);
!   static void relocate_embedded_oops(GrowableArrayCHeap<oop, mtClassShared>* roots, ArchiveHeapInfo* info,
+                                      GrowableArray<size_t>* permobj_seg_offsets, int num_permobj);
    static void compute_ptrmap(ArchiveHeapInfo *info);
    static bool is_in_requested_range(oop o);
    static oop requested_obj_from_buffer_offset(size_t offset);
  
    static oop load_oop_from_buffer(oop* buffered_addr);

*** 217,17 ***
    template <typename T> static void store_requested_oop_in_buffer(T* buffered_addr, oop request_oop);
  
    template <typename T> static T* requested_addr_to_buffered_addr(T* p);
    template <typename T> static void relocate_field_in_buffer(T* field_addr_in_buffer, CHeapBitMap* oopmap);
    template <typename T> static void mark_oop_pointer(T* buffered_addr, CHeapBitMap* oopmap);
!   template <typename T> static void relocate_root_at(oop requested_roots, int index, CHeapBitMap* oopmap);
  
    static void update_header_for_requested_obj(oop requested_obj, oop src_obj, Klass* src_klass);
  
    static int compare_objs_by_oop_fields(HeapObjOrder* a, HeapObjOrder* b);
    static void sort_source_objs();
- 
  public:
    static void init() NOT_CDS_JAVA_HEAP_RETURN;
    static void add_source_obj(oop src_obj);
    static bool is_too_large_to_archive(size_t size);
    static bool is_too_large_to_archive(oop obj);
--- 224,30 ---
    template <typename T> static void store_requested_oop_in_buffer(T* buffered_addr, oop request_oop);
  
    template <typename T> static T* requested_addr_to_buffered_addr(T* p);
    template <typename T> static void relocate_field_in_buffer(T* field_addr_in_buffer, CHeapBitMap* oopmap);
    template <typename T> static void mark_oop_pointer(T* buffered_addr, CHeapBitMap* oopmap);
!   template <typename T> static void relocate_root_at(oop requested_roots, address buffered_roots_addr, int index, CHeapBitMap* oopmap);
  
    static void update_header_for_requested_obj(oop requested_obj, oop src_obj, Klass* src_klass);
  
+   // "Permanent Objects"
+   //
+   // These objects are guaranteed to be in the heap at runtime. The AOT can use
+   // HeapShared::get_archived_object_permanent_index() and HeapShared::get_archived_object() to
+   // inline these objects into the AOT cache.
+   //
+   // Currently all archived objects are "permanent". We may want to narrow the scope ....
+   //
+   // The permobjs are divided into multiple segments, each containing 64K elements (or 4096 in debug builds).
+   // This is to avoid overflowing MIN_GC_REGION_ALIGNMENT.
+   static constexpr int PERMOBJ_SEGMENT_MAX_SHIFT  = DEBUG_ONLY(12) NOT_DEBUG(16);
+   static constexpr int PERMOBJ_SEGMENT_MAX_LENGTH = 1 << PERMOBJ_SEGMENT_MAX_SHIFT;
+   static constexpr int PERMOBJ_SEGMENT_MAX_MASK   = PERMOBJ_SEGMENT_MAX_LENGTH - 1;
+ 
    static int compare_objs_by_oop_fields(HeapObjOrder* a, HeapObjOrder* b);
    static void sort_source_objs();
  public:
    static void init() NOT_CDS_JAVA_HEAP_RETURN;
    static void add_source_obj(oop src_obj);
    static bool is_too_large_to_archive(size_t size);
    static bool is_too_large_to_archive(oop obj);

*** 240,10 ***
--- 260,13 ---
    }
    static size_t heap_roots_word_size() {
      return _heap_roots_word_size;
    }
    static size_t get_filler_size_at(address buffered_addr);
+   static int get_permobj_segment_at(address buffered_addr, size_t* byte_size, int* permobj_segment_length);
+   static oop get_permobj_source_addr(int permobj_segment, int index);
+   static oop get_perm_object_by_index(int permanent_index);
  
    static void mark_native_pointer(oop src_obj, int offset);
    static bool is_marked_as_native_pointer(ArchiveHeapInfo* heap_info, oop src_obj, int field_offset);
    static oop source_obj_to_requested_obj(oop src_obj);
    static oop buffered_addr_to_source_obj(address buffered_addr);
< prev index next >