< prev index next > src/hotspot/share/cds/archiveHeapWriter.hpp
Print this page
/*
! * 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.
/*
! * 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.
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.
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)
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);
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);
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);
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);
}
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 >