|
1 /* |
|
2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. |
|
8 * |
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 * version 2 for more details (a copy is included in the LICENSE file that |
|
13 * accompanied this code). |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License version |
|
16 * 2 along with this work; if not, write to the Free Software Foundation, |
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 * |
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
20 * or visit www.oracle.com if you need additional information or have any |
|
21 * questions. |
|
22 * |
|
23 */ |
|
24 |
|
25 #ifndef SHARE_MEMORY_ARCHIVEUTILS_HPP |
|
26 #define SHARE_MEMORY_ARCHIVEUTILS_HPP |
|
27 |
|
28 #include "logging/log.hpp" |
|
29 #include "runtime/arguments.hpp" |
|
30 #include "utilities/bitMap.hpp" |
|
31 |
|
32 // ArchivePtrMarker is used to mark the location of pointers embedded in a CDS archive. E.g., when an |
|
33 // InstanceKlass k is dumped, we mark the location of the k->_name pointer by effectively calling |
|
34 // mark_pointer(/*ptr_loc=*/&k->_name). It's required that (_prt_base <= ptr_loc < _ptr_end). _ptr_base is |
|
35 // fixed, but _ptr_end can be expanded as more objects are dumped. |
|
36 class ArchivePtrMarker : AllStatic { |
|
37 static CHeapBitMap* _ptrmap; |
|
38 static address* _ptr_base; |
|
39 static address* _ptr_end; |
|
40 |
|
41 // Once _ptrmap is compacted, we don't allow bit marking anymore. This is to |
|
42 // avoid unintentional copy operations after the bitmap has been finalized and written. |
|
43 static bool _compacted; |
|
44 public: |
|
45 static void initialize(CHeapBitMap* ptrmap, address* ptr_base, address* ptr_end); |
|
46 static void mark_pointer(address* ptr_loc); |
|
47 static void compact(address relocatable_base, address relocatable_end); |
|
48 static void compact(size_t max_non_null_offset); |
|
49 |
|
50 template <typename T> |
|
51 static void mark_pointer(T* ptr_loc) { |
|
52 mark_pointer((address*)ptr_loc); |
|
53 } |
|
54 |
|
55 static void expand_ptr_end(address *new_ptr_end) { |
|
56 assert(_ptr_end <= new_ptr_end, "must be"); |
|
57 _ptr_end = new_ptr_end; |
|
58 } |
|
59 |
|
60 static CHeapBitMap* ptrmap() { |
|
61 return _ptrmap; |
|
62 } |
|
63 }; |
|
64 |
|
65 // SharedDataRelocator is used to shift pointers in the CDS archive. |
|
66 // |
|
67 // The CDS archive is basically a contiguous block of memory (divided into several regions) |
|
68 // that contains multiple objects. The objects may contain direct pointers that point to other objects |
|
69 // within the archive (e.g., InstanceKlass::_name points to a Symbol in the archive). During dumping, we |
|
70 // built a bitmap that marks the locations of all these pointers (using ArchivePtrMarker, see comments above). |
|
71 // |
|
72 // The contents of the archive assumes that it’s mapped at the default SharedBaseAddress (e.g. 0x800000000). |
|
73 // If the archive ends up being mapped at a different address (e.g. 0x810000000), SharedDataRelocator |
|
74 // is used to shift each marked pointer by a delta (0x10000000 in this example), so that it points to |
|
75 // the actually mapped location of the target object. |
|
76 template <bool COMPACTING> |
|
77 class SharedDataRelocator: public BitMapClosure { |
|
78 // for all (address** p), where (is_marked(p) && _patch_base <= p && p < _patch_end) { *p += delta; } |
|
79 |
|
80 // Patch all pointers within this region that are marked. |
|
81 address* _patch_base; |
|
82 address* _patch_end; |
|
83 |
|
84 // Before patching, all pointers must point to this region. |
|
85 address _valid_old_base; |
|
86 address _valid_old_end; |
|
87 |
|
88 // After patching, all pointers must point to this region. |
|
89 address _valid_new_base; |
|
90 address _valid_new_end; |
|
91 |
|
92 // How much to relocate for each pointer. |
|
93 intx _delta; |
|
94 |
|
95 // The following fields are used only when COMPACTING == true; |
|
96 // The highest offset (inclusive) in the bitmap that contains a non-null pointer. |
|
97 // This is used at dump time to reduce the size of the bitmap (which may have been over-allocated). |
|
98 size_t _max_non_null_offset; |
|
99 CHeapBitMap* _ptrmap; |
|
100 |
|
101 public: |
|
102 SharedDataRelocator(address* patch_base, address* patch_end, |
|
103 address valid_old_base, address valid_old_end, |
|
104 address valid_new_base, address valid_new_end, intx delta, |
|
105 CHeapBitMap* ptrmap = NULL) : |
|
106 _patch_base(patch_base), _patch_end(patch_end), |
|
107 _valid_old_base(valid_old_base), _valid_old_end(valid_old_end), |
|
108 _valid_new_base(valid_new_base), _valid_new_end(valid_new_end), |
|
109 _delta(delta) { |
|
110 log_debug(cds, reloc)("SharedDataRelocator::_patch_base = " PTR_FORMAT, p2i(_patch_base)); |
|
111 log_debug(cds, reloc)("SharedDataRelocator::_patch_end = " PTR_FORMAT, p2i(_patch_end)); |
|
112 log_debug(cds, reloc)("SharedDataRelocator::_valid_old_base = " PTR_FORMAT, p2i(_valid_old_base)); |
|
113 log_debug(cds, reloc)("SharedDataRelocator::_valid_old_end = " PTR_FORMAT, p2i(_valid_old_end)); |
|
114 log_debug(cds, reloc)("SharedDataRelocator::_valid_new_base = " PTR_FORMAT, p2i(_valid_new_base)); |
|
115 log_debug(cds, reloc)("SharedDataRelocator::_valid_new_end = " PTR_FORMAT, p2i(_valid_new_end)); |
|
116 if (COMPACTING) { |
|
117 assert(ptrmap != NULL, "must be"); |
|
118 _max_non_null_offset = 0; |
|
119 _ptrmap = ptrmap; |
|
120 } else { |
|
121 // Don't touch the _max_non_null_offset and _ptrmap fields. Hopefully a good C++ compiler can |
|
122 // elide them. |
|
123 assert(ptrmap == NULL, "must be"); |
|
124 } |
|
125 } |
|
126 |
|
127 size_t max_non_null_offset() { |
|
128 assert(COMPACTING, "must be"); |
|
129 return _max_non_null_offset; |
|
130 } |
|
131 |
|
132 inline bool do_bit(size_t offset); |
|
133 }; |
|
134 |
|
135 |
|
136 #endif // SHARE_MEMORY_ARCHIVEUTILS_HPP |