|
58 | 58 | #include "oops/fieldStreams.inline.hpp" |
59 | 59 | #include "oops/objArrayOop.inline.hpp" |
60 | 60 | #include "oops/oop.inline.hpp" |
| 61 | +#include "oops/oopHandle.inline.hpp" |
61 | 62 | #include "oops/typeArrayOop.inline.hpp" |
62 | 63 | #include "prims/jvmtiExport.hpp" |
63 | 64 | #include "runtime/arguments.hpp" |
@@ -159,12 +160,35 @@ bool HeapShared::is_subgraph_root_class(InstanceKlass* ik) { |
159 | 160 | is_subgraph_root_class_of(fmg_archive_subgraph_entry_fields, ik); |
160 | 161 | } |
161 | 162 |
|
| 163 | +oop HeapShared::CachedOopInfo::orig_referrer() const { |
| 164 | + return _orig_referrer.resolve(); |
| 165 | +} |
| 166 | + |
162 | 167 | unsigned HeapShared::oop_hash(oop const& p) { |
| 168 | + assert(SafepointSynchronize::is_at_safepoint() || |
| 169 | + JavaThread::current()->is_in_no_safepoint_scope(), "sanity"); |
163 | 170 | // Do not call p->identity_hash() as that will update the |
164 | 171 | // object header. |
165 | 172 | return primitive_hash(cast_from_oop<intptr_t>(p)); |
166 | 173 | } |
167 | 174 |
|
| 175 | +unsigned int HeapShared::oop_handle_hash_raw(const OopHandle& oh) { |
| 176 | + return oop_hash(oh.resolve()); |
| 177 | +} |
| 178 | + |
| 179 | +unsigned int HeapShared::oop_handle_hash(const OopHandle& oh) { |
| 180 | + oop o = oh.resolve(); |
| 181 | + if (o == nullptr) { |
| 182 | + return 0; |
| 183 | + } else { |
| 184 | + return o->identity_hash(); |
| 185 | + } |
| 186 | +} |
| 187 | + |
| 188 | +bool HeapShared::oop_handle_equals(const OopHandle& a, const OopHandle& b) { |
| 189 | + return a.resolve() == b.resolve(); |
| 190 | +} |
| 191 | + |
168 | 192 | static void reset_states(oop obj, TRAPS) { |
169 | 193 | Handle h_obj(THREAD, obj); |
170 | 194 | InstanceKlass* klass = InstanceKlass::cast(obj->klass()); |
@@ -216,7 +240,8 @@ HeapShared::ArchivedObjectCache* HeapShared::_archived_object_cache = nullptr; |
216 | 240 |
|
217 | 241 | bool HeapShared::has_been_archived(oop obj) { |
218 | 242 | assert(CDSConfig::is_dumping_heap(), "dump-time only"); |
219 | | - return archived_object_cache()->get(obj) != nullptr; |
| 243 | + OopHandle oh(&obj); |
| 244 | + return archived_object_cache()->get(oh) != nullptr; |
220 | 245 | } |
221 | 246 |
|
222 | 247 | int HeapShared::append_root(oop obj) { |
@@ -303,7 +328,9 @@ bool HeapShared::archive_object(oop obj, oop referrer, KlassSubGraphInfo* subgra |
303 | 328 | count_allocation(obj->size()); |
304 | 329 | ArchiveHeapWriter::add_source_obj(obj); |
305 | 330 | CachedOopInfo info = make_cached_oop_info(obj, referrer); |
306 | | - archived_object_cache()->put_when_absent(obj, info); |
| 331 | + |
| 332 | + OopHandle oh(Universe::vm_global(), obj); |
| 333 | + archived_object_cache()->put_when_absent(oh, info); |
307 | 334 | archived_object_cache()->maybe_grow(); |
308 | 335 | mark_native_pointers(obj); |
309 | 336 |
|
@@ -636,14 +663,16 @@ void HeapShared::mark_native_pointers(oop orig_obj) { |
636 | 663 | } |
637 | 664 |
|
638 | 665 | void HeapShared::get_pointer_info(oop src_obj, bool& has_oop_pointers, bool& has_native_pointers) { |
639 | | - CachedOopInfo* info = archived_object_cache()->get(src_obj); |
| 666 | + OopHandle oh(&src_obj); |
| 667 | + CachedOopInfo* info = archived_object_cache()->get(oh); |
640 | 668 | assert(info != nullptr, "must be"); |
641 | 669 | has_oop_pointers = info->has_oop_pointers(); |
642 | 670 | has_native_pointers = info->has_native_pointers(); |
643 | 671 | } |
644 | 672 |
|
645 | 673 | void HeapShared::set_has_native_pointers(oop src_obj) { |
646 | | - CachedOopInfo* info = archived_object_cache()->get(src_obj); |
| 674 | + OopHandle oh(&src_obj); |
| 675 | + CachedOopInfo* info = archived_object_cache()->get(oh); |
647 | 676 | assert(info != nullptr, "must be"); |
648 | 677 | info->set_has_native_pointers(); |
649 | 678 | } |
@@ -1453,7 +1482,7 @@ class PointsToOopsChecker : public BasicOopIterateClosure { |
1453 | 1482 | HeapShared::CachedOopInfo HeapShared::make_cached_oop_info(oop obj, oop referrer) { |
1454 | 1483 | PointsToOopsChecker points_to_oops_checker; |
1455 | 1484 | obj->oop_iterate(&points_to_oops_checker); |
1456 | | - return CachedOopInfo(referrer, points_to_oops_checker.result()); |
| 1485 | + return CachedOopInfo(OopHandle(Universe::vm_global(), referrer), points_to_oops_checker.result()); |
1457 | 1486 | } |
1458 | 1487 |
|
1459 | 1488 | void HeapShared::init_box_classes(TRAPS) { |
@@ -2096,6 +2125,18 @@ bool HeapShared::is_dumped_interned_string(oop o) { |
2096 | 2125 | return _dumped_interned_strings->get(o) != nullptr; |
2097 | 2126 | } |
2098 | 2127 |
|
| 2128 | +// These tables should be used only within the CDS safepoint, so |
| 2129 | +// delete them before we exit the safepoint. Otherwise the table will |
| 2130 | +// contain bad oops after a GC. |
| 2131 | +void HeapShared::delete_tables_with_raw_oops() { |
| 2132 | + assert(_seen_objects_table == nullptr, "should have been deleted"); |
| 2133 | + |
| 2134 | + delete _dumped_interned_strings; |
| 2135 | + _dumped_interned_strings = nullptr; |
| 2136 | + |
| 2137 | + ArchiveHeapWriter::delete_tables_with_raw_oops(); |
| 2138 | +} |
| 2139 | + |
2099 | 2140 | void HeapShared::debug_trace() { |
2100 | 2141 | ResourceMark rm; |
2101 | 2142 | oop referrer = _object_being_archived.referrer(); |
|
0 commit comments