1
1
/*
2
- * Copyright (c) 2023 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2024 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
@@ -62,6 +62,7 @@ address ArchiveHeapWriter::_requested_top;
62
62
63
63
GrowableArrayCHeap<ArchiveHeapWriter::NativePointerInfo, mtClassShared>* ArchiveHeapWriter::_native_pointers;
64
64
GrowableArrayCHeap<oop, mtClassShared>* ArchiveHeapWriter::_source_objs;
65
+ GrowableArrayCHeap<int , mtClassShared>* ArchiveHeapWriter::_source_objs_order;
65
66
66
67
ArchiveHeapWriter::BufferOffsetToSourceObjectTable*
67
68
ArchiveHeapWriter::_buffer_offset_to_source_obj_table = nullptr ;
@@ -72,6 +73,7 @@ typedef ResourceHashtable<address, size_t,
72
73
AnyObj::C_HEAP,
73
74
mtClassShared> FillersTable;
74
75
static FillersTable* _fillers;
76
+ static int _num_native_ptrs = 0 ;
75
77
76
78
void ArchiveHeapWriter::init () {
77
79
if (HeapShared::can_write ()) {
@@ -84,13 +86,15 @@ void ArchiveHeapWriter::init() {
84
86
85
87
_native_pointers = new GrowableArrayCHeap<NativePointerInfo, mtClassShared>(2048 );
86
88
_source_objs = new GrowableArrayCHeap<oop, mtClassShared>(10000 );
89
+ _source_objs_order = new GrowableArrayCHeap<int , mtClassShared>(10000 );
87
90
88
91
guarantee (UseG1GC, " implementation limitation" );
89
92
guarantee (MIN_GC_REGION_ALIGNMENT <= /* G1*/ HeapRegion::min_region_size_in_words () * HeapWordSize, " must be" );
90
93
}
91
94
}
92
95
93
96
void ArchiveHeapWriter::add_source_obj (oop src_obj) {
97
+ _source_objs_order->append (_source_objs->length ());
94
98
_source_objs->append (src_obj);
95
99
}
96
100
@@ -226,9 +230,54 @@ void ArchiveHeapWriter::copy_roots_to_buffer(GrowableArrayCHeap<oop, mtClassShar
226
230
_buffer_used = new_used;
227
231
}
228
232
233
+ static int oop_sorting_rank (oop o) {
234
+ bool has_o_ptr = HeapShared::has_oop_pointers (o);
235
+ bool has_n_ptr = HeapShared::has_native_pointers (o);
236
+
237
+ if (!has_o_ptr) {
238
+ if (!has_n_ptr) {
239
+ return 0 ;
240
+ } else {
241
+ return 1 ;
242
+ }
243
+ } else {
244
+ if (has_n_ptr) {
245
+ return 2 ;
246
+ } else {
247
+ return 3 ;
248
+ }
249
+ }
250
+ }
251
+
252
+ // The goal is to sort the objects in increasing order of:
253
+ // - objects that have no pointers
254
+ // - objects that have only native pointers
255
+ // - objects that have both native and oop pointers
256
+ // - objects that have only oop pointers
257
+ int ArchiveHeapWriter::compare_objs_by_oop_fields (int * a, int * b) {
258
+ oop oa = _source_objs->at (*a);
259
+ oop ob = _source_objs->at (*b);
260
+
261
+ int rank_a = oop_sorting_rank (oa);
262
+ int rank_b = oop_sorting_rank (ob);
263
+
264
+ if (rank_a != rank_b) {
265
+ return rank_a - rank_b;
266
+ } else {
267
+ // If they are the same rank, sort them by their position in the _source_objs array
268
+ return *a - *b;
269
+ }
270
+ }
271
+
272
+ void ArchiveHeapWriter::sort_source_objs () {
273
+ _source_objs_order->sort (compare_objs_by_oop_fields);
274
+ }
275
+
229
276
void ArchiveHeapWriter::copy_source_objs_to_buffer (GrowableArrayCHeap<oop, mtClassShared>* roots) {
230
- for (int i = 0 ; i < _source_objs->length (); i++) {
231
- oop src_obj = _source_objs->at (i);
277
+ sort_source_objs ();
278
+ for (int i = 0 ; i < _source_objs_order->length (); i++) {
279
+ int src_obj_index = _source_objs_order->at (i);
280
+ oop src_obj = _source_objs->at (src_obj_index);
232
281
HeapShared::CachedOopInfo* info = HeapShared::archived_object_cache ()->get (src_obj);
233
282
assert (info != nullptr , " must be" );
234
283
size_t buffer_offset = copy_one_source_obj_to_buffer (src_obj);
@@ -239,8 +288,8 @@ void ArchiveHeapWriter::copy_source_objs_to_buffer(GrowableArrayCHeap<oop, mtCla
239
288
240
289
copy_roots_to_buffer (roots);
241
290
242
- log_info (cds)(" Size of heap region = " SIZE_FORMAT " bytes, %d objects, %d roots" ,
243
- _buffer_used, _source_objs->length () + 1 , roots->length ());
291
+ log_info (cds)(" Size of heap region = " SIZE_FORMAT " bytes, %d objects, %d roots, %d native ptrs " ,
292
+ _buffer_used, _source_objs->length () + 1 , roots->length (), _num_native_ptrs );
244
293
}
245
294
246
295
size_t ArchiveHeapWriter::filler_array_byte_size (int length) {
@@ -512,21 +561,35 @@ class ArchiveHeapWriter::EmbeddedOopRelocator: public BasicOopIterateClosure {
512
561
}
513
562
};
514
563
564
+ static void log_bitmap_usage (const char * which, BitMap* bitmap, size_t total_bits) {
565
+ // The whole heap is covered by total_bits, but there are only non-zero bits within [start ... end).
566
+ size_t start = bitmap->find_first_set_bit (0 );
567
+ size_t end = bitmap->size ();
568
+ log_info (cds)(" %s = " SIZE_FORMAT_W (7 ) " ... " SIZE_FORMAT_W (7 ) " (%3zu%% ... %3zu%% = %3zu%%)" , which,
569
+ start, end,
570
+ start * 100 / total_bits,
571
+ end * 100 / total_bits,
572
+ (end - start) * 100 / total_bits);
573
+ }
574
+
515
575
// Update all oop fields embedded in the buffered objects
516
576
void ArchiveHeapWriter::relocate_embedded_oops (GrowableArrayCHeap<oop, mtClassShared>* roots,
517
577
ArchiveHeapInfo* heap_info) {
518
578
size_t oopmap_unit = (UseCompressedOops ? sizeof (narrowOop) : sizeof (oop));
519
579
size_t heap_region_byte_size = _buffer_used;
520
580
heap_info->oopmap ()->resize (heap_region_byte_size / oopmap_unit);
521
581
522
- auto iterator = [&] (oop src_obj, HeapShared::CachedOopInfo& info) {
523
- oop requested_obj = requested_obj_from_buffer_offset (info.buffer_offset ());
582
+ for (int i = 0 ; i < _source_objs_order->length (); i++) {
583
+ int src_obj_index = _source_objs_order->at (i);
584
+ oop src_obj = _source_objs->at (src_obj_index);
585
+ HeapShared::CachedOopInfo* info = HeapShared::archived_object_cache ()->get (src_obj);
586
+ assert (info != nullptr , " must be" );
587
+ oop requested_obj = requested_obj_from_buffer_offset (info->buffer_offset ());
524
588
update_header_for_requested_obj (requested_obj, src_obj, src_obj->klass ());
525
- address buffered_obj = offset_to_buffered_address<address>(info. buffer_offset ());
589
+ address buffered_obj = offset_to_buffered_address<address>(info-> buffer_offset ());
526
590
EmbeddedOopRelocator relocator (src_obj, buffered_obj, heap_info->oopmap ());
527
591
src_obj->oop_iterate (&relocator);
528
592
};
529
- HeapShared::archived_object_cache ()->iterate_all (iterator);
530
593
531
594
// Relocate HeapShared::roots(), which is created in copy_roots_to_buffer() and
532
595
// doesn't have a corresponding src_obj, so we can't use EmbeddedOopRelocator on it.
@@ -542,6 +605,10 @@ void ArchiveHeapWriter::relocate_embedded_oops(GrowableArrayCHeap<oop, mtClassSh
542
605
}
543
606
544
607
compute_ptrmap (heap_info);
608
+
609
+ size_t total_bytes = (size_t )_buffer->length ();
610
+ log_bitmap_usage (" oopmap" , heap_info->oopmap (), total_bytes / (UseCompressedOops ? sizeof (narrowOop) : sizeof (oop)));
611
+ log_bitmap_usage (" ptrmap" , heap_info->ptrmap (), total_bytes / sizeof (address));
545
612
}
546
613
547
614
void ArchiveHeapWriter::mark_native_pointer (oop src_obj, int field_offset) {
@@ -551,6 +618,8 @@ void ArchiveHeapWriter::mark_native_pointer(oop src_obj, int field_offset) {
551
618
info._src_obj = src_obj;
552
619
info._field_offset = field_offset;
553
620
_native_pointers->append (info);
621
+ HeapShared::set_has_native_pointers (src_obj);
622
+ _num_native_ptrs ++;
554
623
}
555
624
}
556
625
@@ -565,6 +634,13 @@ bool ArchiveHeapWriter::is_marked_as_native_pointer(ArchiveHeapInfo* heap_info,
565
634
assert ((Metadata**)_requested_bottom <= requested_field_addr && requested_field_addr < (Metadata**) _requested_top, " range check" );
566
635
567
636
BitMap::idx_t idx = requested_field_addr - (Metadata**) _requested_bottom;
637
+ // Leading zeros have been removed so some addresses may not be in the ptrmap
638
+ size_t start_pos = FileMapInfo::current_info ()->heap_ptrmap_start_pos ();
639
+ if (idx < start_pos) {
640
+ return false ;
641
+ } else {
642
+ idx -= start_pos;
643
+ }
568
644
return (idx < heap_info->ptrmap ()->size ()) && (heap_info->ptrmap ()->at (idx) == true );
569
645
}
570
646
0 commit comments