38
38
class MemRegion ;
39
39
40
40
class ArchiveHeapInfo {
41
- MemRegion _memregion;
41
+ MemRegion _buffer_region; // Contains the archived objects to be written into the CDS archive.
42
42
CHeapBitMap _oopmap;
43
43
CHeapBitMap _ptrmap;
44
+ size_t _heap_roots_offset; // Offset of the HeapShared::roots() object, from the bottom
45
+ // of the archived heap objects, in bytes.
44
46
45
47
public:
46
- ArchiveHeapInfo () : _memregion (), _oopmap(128 , mtClassShared), _ptrmap(128 , mtClassShared) {}
47
- bool is_used () { return !_memregion .is_empty (); }
48
+ ArchiveHeapInfo () : _buffer_region (), _oopmap(128 , mtClassShared), _ptrmap(128 , mtClassShared) {}
49
+ bool is_used () { return !_buffer_region .is_empty (); }
48
50
49
- MemRegion memregion () { return _memregion ; }
50
- void set_memregion (MemRegion r) { _memregion = r; }
51
+ MemRegion buffer_region () { return _buffer_region ; }
52
+ void set_buffer_region (MemRegion r) { _buffer_region = r; }
51
53
52
- char * start () { return (char *)_memregion .start (); }
53
- size_t byte_size () { return _memregion .byte_size (); }
54
+ char * buffer_start () { return (char *)_buffer_region .start (); }
55
+ size_t buffer_byte_size () { return _buffer_region .byte_size (); }
54
56
55
57
CHeapBitMap* oopmap () { return &_oopmap; }
56
58
CHeapBitMap* ptrmap () { return &_ptrmap; }
59
+
60
+ void set_heap_roots_offset (size_t n) { _heap_roots_offset = n; }
61
+ size_t heap_roots_offset () const { return _heap_roots_offset; }
57
62
};
58
63
59
64
#if INCLUDE_CDS_JAVA_HEAP
60
65
class ArchiveHeapWriter : AllStatic {
66
+ // ArchiveHeapWriter manipulates three types of addresses:
67
+ //
68
+ // "source" vs "buffered" vs "requested"
69
+ //
70
+ // (Note: the design and convention is the same as for the archiving of Metaspace objects.
71
+ // See archiveBuilder.hpp.)
72
+ //
73
+ // - "source objects" are regular Java objects allocated during the execution
74
+ // of "java -Xshare:dump". They can be used as regular oops.
75
+ //
76
+ // HeapShared::archive_objects() recursively searches for the oops that need to be
77
+ // stored into the CDS archive. These are entered into HeapShared::archived_object_cache().
78
+ //
79
+ // - "buffered objects" are copies of the "source objects", and are stored in into
80
+ // ArchiveHeapWriter::_buffer, which is a GrowableArray that sits outside of
81
+ // the valid heap range. Therefore we avoid using the addresses of these copies
82
+ // as oops. They are usually called "buffered_addr" in the code (of the type "address").
83
+ //
84
+ // The buffered objects are stored contiguously, possibly with interleaving fillers
85
+ // to make sure no objects span across boundaries of MIN_GC_REGION_ALIGNMENT.
86
+ //
87
+ // - Each archived object has a "requested address" -- at run time, if the object
88
+ // can be mapped at this address, we can avoid relocation.
89
+ //
90
+ // The requested address is implemented differently depending on UseCompressedOops:
91
+ //
92
+ // UseCompressedOops == true:
93
+ // The archived objects are stored assuming that the runtime COOPS compression
94
+ // scheme is exactly the same as in dump time (or else a more expensive runtime relocation
95
+ // would be needed.)
96
+ //
97
+ // At dump time, we assume that the runtime heap range is exactly the same as
98
+ // in dump time. The requested addresses of the archived objects are chosen such that
99
+ // they would occupy the top end of a G1 heap (TBD when dumping is supported by other
100
+ // collectors. See JDK-8298614).
101
+ //
102
+ // UseCompressedOops == false:
103
+ // At runtime, the heap range is usually picked (randomly) by the OS, so we will almost always
104
+ // need to perform relocation. Hence, the goal of the "requested address" is to ensure that
105
+ // the contents of the archived objects are deterministic. I.e., the oop fields of archived
106
+ // objects will always point to deterministic addresses.
107
+ //
108
+ // For G1, the archived heap is written such that the lowest archived object is placed
109
+ // at NOCOOPS_REQUESTED_BASE. (TBD after JDK-8298614).
110
+ // ----------------------------------------------------------------------
111
+
112
+ public:
113
+ static const intptr_t NOCOOPS_REQUESTED_BASE = 0x10000000 ;
114
+
115
+ private:
61
116
class EmbeddedOopRelocator ;
62
117
struct NativePointerInfo {
63
118
oop _src_obj;
@@ -70,30 +125,13 @@ class ArchiveHeapWriter : AllStatic {
70
125
// (TODO: Perhaps change to 256K to be compatible with Shenandoah)
71
126
static constexpr int MIN_GC_REGION_ALIGNMENT = 1 * M;
72
127
73
- // "source" vs "buffered" vs "requested"
74
- //
75
- // [1] HeapShared::archive_objects() identifies all of the oops that need to be stored
76
- // into the CDS archive. These are entered into HeapShared::archived_object_cache().
77
- // These are called "source objects"
78
- //
79
- // [2] ArchiveHeapWriter::write() copies all source objects into ArchiveHeapWriter::_buffer,
80
- // which is a GrowableArray that sites outside of the valid heap range. Therefore
81
- // we avoid using the addresses of these copies as oops. They are usually
82
- // called "buffered_addr" in the code (of the type "address").
83
- //
84
- // [3] Each archived object has a "requested address" -- at run time, if the object
85
- // can be mapped at this address, we can avoid relocation.
86
- //
87
- // Note: the design and convention is the same as for the archiving of Metaspace objects.
88
- // See archiveBuilder.hpp.
89
-
90
128
static GrowableArrayCHeap<u1, mtClassShared>* _buffer;
91
129
92
130
// The number of bytes that have written into _buffer (may be smaller than _buffer->length()).
93
131
static size_t _buffer_used;
94
132
95
133
// The bottom of the copy of Heap::roots() inside this->_buffer.
96
- static size_t _heap_roots_bottom_offset ;
134
+ static size_t _heap_roots_offset ;
97
135
static size_t _heap_roots_word_size;
98
136
99
137
// The address range of the requested location of the archived heap objects.
@@ -160,8 +198,8 @@ class ArchiveHeapWriter : AllStatic {
160
198
161
199
static oop load_oop_from_buffer (oop* buffered_addr);
162
200
static oop load_oop_from_buffer (narrowOop* buffered_addr);
163
- static void store_oop_in_buffer (oop* buffered_addr, oop requested_obj);
164
- static void store_oop_in_buffer (narrowOop* buffered_addr, oop requested_obj);
201
+ inline static void store_oop_in_buffer (oop* buffered_addr, oop requested_obj);
202
+ inline static void store_oop_in_buffer (narrowOop* buffered_addr, oop requested_obj);
165
203
166
204
template <typename T> static oop load_source_oop_from_buffer (T* buffered_addr);
167
205
template <typename T> static void store_requested_oop_in_buffer (T* buffered_addr, oop request_oop);
@@ -182,7 +220,7 @@ class ArchiveHeapWriter : AllStatic {
182
220
static address requested_address (); // requested address of the lowest achived heap object
183
221
static oop heap_roots_requested_address (); // requested address of HeapShared::roots()
184
222
static address buffered_heap_roots_addr () {
185
- return offset_to_buffered_address<address>(_heap_roots_bottom_offset );
223
+ return offset_to_buffered_address<address>(_heap_roots_offset );
186
224
}
187
225
static size_t heap_roots_word_size () {
188
226
return _heap_roots_word_size;
0 commit comments