| 1 | /* |
| 2 | * Copyright (c) 2016, 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_GC_PARALLEL_PSPARALLELCOMPACT_INLINE_HPP |
| 26 | #define SHARE_GC_PARALLEL_PSPARALLELCOMPACT_INLINE_HPP |
| 27 | |
| 28 | #include "gc/parallel/parallelScavengeHeap.hpp" |
| 29 | #include "gc/parallel/parMarkBitMap.inline.hpp" |
| 30 | #include "gc/parallel/psParallelCompact.hpp" |
| 31 | #include "gc/shared/collectedHeap.hpp" |
| 32 | #include "oops/access.inline.hpp" |
| 33 | #include "oops/compressedOops.inline.hpp" |
| 34 | #include "oops/klass.hpp" |
| 35 | #include "oops/oop.inline.hpp" |
| 36 | |
| 37 | inline bool PSParallelCompact::is_marked(oop obj) { |
| 38 | return mark_bitmap()->is_marked(obj); |
| 39 | } |
| 40 | |
| 41 | inline double PSParallelCompact::normal_distribution(double density) { |
| 42 | assert(_dwl_initialized, "uninitialized" ); |
| 43 | const double squared_term = (density - _dwl_mean) / _dwl_std_dev; |
| 44 | return _dwl_first_term * exp(-0.5 * squared_term * squared_term); |
| 45 | } |
| 46 | |
| 47 | inline bool PSParallelCompact::dead_space_crosses_boundary(const RegionData* region, |
| 48 | idx_t bit) { |
| 49 | assert(bit > 0, "cannot call this for the first bit/region" ); |
| 50 | assert(_summary_data.region_to_addr(region) == _mark_bitmap.bit_to_addr(bit), |
| 51 | "sanity check" ); |
| 52 | |
| 53 | // Dead space crosses the boundary if (1) a partial object does not extend |
| 54 | // onto the region, (2) an object does not start at the beginning of the |
| 55 | // region, and (3) an object does not end at the end of the prior region. |
| 56 | return region->partial_obj_size() == 0 && |
| 57 | !_mark_bitmap.is_obj_beg(bit) && |
| 58 | !_mark_bitmap.is_obj_end(bit - 1); |
| 59 | } |
| 60 | |
| 61 | inline bool PSParallelCompact::is_in(HeapWord* p, HeapWord* beg_addr, HeapWord* end_addr) { |
| 62 | return p >= beg_addr && p < end_addr; |
| 63 | } |
| 64 | |
| 65 | inline bool PSParallelCompact::is_in(oop* p, HeapWord* beg_addr, HeapWord* end_addr) { |
| 66 | return is_in((HeapWord*)p, beg_addr, end_addr); |
| 67 | } |
| 68 | |
| 69 | inline MutableSpace* PSParallelCompact::space(SpaceId id) { |
| 70 | assert(id < last_space_id, "id out of range" ); |
| 71 | return _space_info[id].space(); |
| 72 | } |
| 73 | |
| 74 | inline HeapWord* PSParallelCompact::new_top(SpaceId id) { |
| 75 | assert(id < last_space_id, "id out of range" ); |
| 76 | return _space_info[id].new_top(); |
| 77 | } |
| 78 | |
| 79 | inline HeapWord* PSParallelCompact::dense_prefix(SpaceId id) { |
| 80 | assert(id < last_space_id, "id out of range" ); |
| 81 | return _space_info[id].dense_prefix(); |
| 82 | } |
| 83 | |
| 84 | inline ObjectStartArray* PSParallelCompact::start_array(SpaceId id) { |
| 85 | assert(id < last_space_id, "id out of range" ); |
| 86 | return _space_info[id].start_array(); |
| 87 | } |
| 88 | |
| 89 | #ifdef ASSERT |
| 90 | inline void PSParallelCompact::check_new_location(HeapWord* old_addr, HeapWord* new_addr) { |
| 91 | assert(old_addr >= new_addr || space_id(old_addr) != space_id(new_addr), |
| 92 | "must move left or to a different space" ); |
| 93 | assert(is_object_aligned(old_addr) && is_object_aligned(new_addr), |
| 94 | "checking alignment" ); |
| 95 | } |
| 96 | #endif // ASSERT |
| 97 | |
| 98 | inline bool PSParallelCompact::mark_obj(oop obj) { |
| 99 | const int obj_size = obj->size(); |
| 100 | if (mark_bitmap()->mark_obj(obj, obj_size)) { |
| 101 | _summary_data.add_obj(obj, obj_size); |
| 102 | return true; |
| 103 | } else { |
| 104 | return false; |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | template <class T> |
| 109 | inline void PSParallelCompact::adjust_pointer(T* p, ParCompactionManager* cm) { |
| 110 | T heap_oop = RawAccess<>::oop_load(p); |
| 111 | if (!CompressedOops::is_null(heap_oop)) { |
| 112 | oop obj = CompressedOops::decode_not_null(heap_oop); |
| 113 | assert(ParallelScavengeHeap::heap()->is_in(obj), "should be in heap" ); |
| 114 | |
| 115 | oop new_obj = (oop)summary_data().calc_new_pointer(obj, cm); |
| 116 | assert(new_obj != NULL, // is forwarding ptr? |
| 117 | "should be forwarded" ); |
| 118 | // Just always do the update unconditionally? |
| 119 | if (new_obj != NULL) { |
| 120 | assert(ParallelScavengeHeap::heap()->is_in_reserved(new_obj), |
| 121 | "should be in object space" ); |
| 122 | RawAccess<IS_NOT_NULL>::oop_store(p, new_obj); |
| 123 | } |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | class PCAdjustPointerClosure: public BasicOopIterateClosure { |
| 128 | public: |
| 129 | PCAdjustPointerClosure(ParCompactionManager* cm) { |
| 130 | assert(cm != NULL, "associate ParCompactionManage should not be NULL" ); |
| 131 | _cm = cm; |
| 132 | } |
| 133 | template <typename T> void do_oop_nv(T* p) { PSParallelCompact::adjust_pointer(p, _cm); } |
| 134 | virtual void do_oop(oop* p) { do_oop_nv(p); } |
| 135 | virtual void do_oop(narrowOop* p) { do_oop_nv(p); } |
| 136 | |
| 137 | // This closure provides its own oop verification code. |
| 138 | debug_only(virtual bool should_verify_oops() { return false; }) |
| 139 | virtual ReferenceIterationMode reference_iteration_mode() { return DO_FIELDS; } |
| 140 | private: |
| 141 | ParCompactionManager* _cm; |
| 142 | }; |
| 143 | |
| 144 | #endif // SHARE_GC_PARALLEL_PSPARALLELCOMPACT_INLINE_HPP |
| 145 | |