2 * Copyright Amazon.com Inc. 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 GC_SHARED_FULLGCFORWARDING_INLINE_HPP
26 #define GC_SHARED_FULLGCFORWARDING_INLINE_HPP
27
28 #include "gc/shared/fullGCForwarding.hpp"
29
30 #include "oops/oop.inline.hpp"
31 #include "utilities/globalDefinitions.hpp"
32
33 void FullGCForwarding::forward_to(oop from, oop to) {
34 #ifdef _LP64
35 uintptr_t encoded = pointer_delta(cast_from_oop<HeapWord*>(to), _heap_base) << Shift;
36 assert(encoded <= static_cast<uintptr_t>(right_n_bits(_num_low_bits)), "encoded forwardee must fit");
37 uintptr_t mark = from->mark().value();
38 mark &= ~right_n_bits(_num_low_bits);
39 mark |= (encoded | markWord::marked_value);
40 from->set_mark(markWord(mark));
41 #else
42 from->forward_to(to);
43 #endif
44 }
45
46 oop FullGCForwarding::forwardee(oop from) {
47 #ifdef _LP64
48 uintptr_t mark = from->mark().value();
49 HeapWord* decoded = _heap_base + ((mark & right_n_bits(_num_low_bits)) >> Shift);
50 return cast_to_oop(decoded);
51 #else
52 return from->forwardee();
53 #endif
54 }
55
56 bool FullGCForwarding::is_forwarded(oop obj) {
57 return obj->mark().is_forwarded();
58 }
59
60 #endif // GC_SHARED_FULLGCFORWARDING_INLINE_HPP
|
2 * Copyright Amazon.com Inc. 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 #ifndef SHARE_GC_SHARED_FULLGCFORWARDING_INLINE_HPP
25 #define SHARE_GC_SHARED_FULLGCFORWARDING_INLINE_HPP
26
27 #include "gc/shared/gc_globals.hpp"
28 #include "gc/shared/fullGCForwarding.hpp"
29 #include "oops/markWord.hpp"
30 #include "oops/oop.inline.hpp"
31 #include "utilities/macros.hpp"
32
33 inline bool FullGCForwarding::is_forwarded(oop obj) {
34 return obj->is_forwarded();
35 }
36
37 size_t FullGCForwarding::biased_region_index_containing(HeapWord* addr) {
38 return (uintptr_t)addr >> BLOCK_SIZE_BYTES_SHIFT;
39 }
40
41 bool FullGCForwarding::is_fallback(uintptr_t encoded) {
42 return (encoded & OFFSET_MASK) == FALLBACK_PATTERN_IN_PLACE;
43 }
44
45 uintptr_t FullGCForwarding::encode_forwarding(HeapWord* from, HeapWord* to) {
46 size_t from_block_idx = biased_region_index_containing(from);
47
48 HeapWord* to_region_base = _biased_bases[from_block_idx];
49 if (to_region_base == UNUSED_BASE) {
50 _biased_bases[from_block_idx] = to_region_base = to;
51 }
52
53 // Avoid pointer_delta() on purpose: using an unsigned subtraction,
54 // we get an underflow when to < to_region_base, which means
55 // we can use a single comparison instead of:
56 // if (to_region_base > to || (to - to_region_base) > MAX_OFFSET) { .. }
57 size_t offset = size_t(to - to_region_base);
58 if (offset > MAX_OFFSET) {
59 offset = FALLBACK_PATTERN;
60 }
61 uintptr_t encoded = (offset << OFFSET_BITS_SHIFT) | markWord::marked_value;
62
63 assert(is_fallback(encoded) || to == decode_forwarding(from, encoded), "must be reversible");
64 assert((encoded & ~AVAILABLE_BITS_MASK) == 0, "must encode to available bits");
65 return encoded;
66 }
67
68 HeapWord* FullGCForwarding::decode_forwarding(HeapWord* from, uintptr_t encoded) {
69 assert(!is_fallback(encoded), "must not be fallback-forwarded, encoded: " INTPTR_FORMAT ", OFFSET_MASK: " INTPTR_FORMAT ", FALLBACK_PATTERN_IN_PLACE: " INTPTR_FORMAT, encoded, OFFSET_MASK, FALLBACK_PATTERN_IN_PLACE);
70 assert((encoded & ~AVAILABLE_BITS_MASK) == 0, "must decode from available bits, encoded: " INTPTR_FORMAT, encoded);
71 uintptr_t offset = (encoded >> OFFSET_BITS_SHIFT);
72
73 size_t from_idx = biased_region_index_containing(from);
74 HeapWord* base = _biased_bases[from_idx];
75 assert(base != UNUSED_BASE, "must not be unused base: encoded: " INTPTR_FORMAT, encoded);
76 HeapWord* decoded = base + offset;
77 assert(decoded >= _heap_start,
78 "Address must be above heap start. encoded: " INTPTR_FORMAT ", base: " PTR_FORMAT,
79 encoded, p2i(base));
80
81 return decoded;
82 }
83
84 inline void FullGCForwarding::forward_to_impl(oop from, oop to) {
85 assert(_bases_table != nullptr, "call begin() before forwarding");
86
87 markWord from_header = from->mark();
88 HeapWord* from_hw = cast_from_oop<HeapWord*>(from);
89 HeapWord* to_hw = cast_from_oop<HeapWord*>(to);
90 uintptr_t encoded = encode_forwarding(from_hw, to_hw);
91 markWord new_header = markWord((from_header.value() & ~OFFSET_MASK) | encoded);
92 from->set_mark(new_header);
93
94 if (is_fallback(encoded)) {
95 fallback_forward_to(from_hw, to_hw);
96 }
97 NOT_PRODUCT(Atomic::inc(&_num_forwardings);)
98 }
99
100 inline void FullGCForwarding::forward_to(oop obj, oop fwd) {
101 assert(fwd != nullptr, "no null forwarding");
102 #ifdef _LP64
103 assert(_bases_table != nullptr, "expect sliding forwarding initialized");
104 forward_to_impl(obj, fwd);
105 assert(forwardee(obj) == fwd, "must be forwarded to correct forwardee, obj: " PTR_FORMAT ", forwardee(obj): " PTR_FORMAT ", fwd: " PTR_FORMAT ", mark: " INTPTR_FORMAT, p2i(obj), p2i(forwardee(obj)), p2i(fwd), obj->mark().value());
106 #else
107 obj->forward_to(fwd);
108 #endif
109 }
110
111 inline oop FullGCForwarding::forwardee_impl(oop from) {
112 assert(_bases_table != nullptr, "call begin() before asking for forwarding");
113
114 markWord header = from->mark();
115 HeapWord* from_hw = cast_from_oop<HeapWord*>(from);
116 if (is_fallback(header.value())) {
117 HeapWord* to = fallback_forwardee(from_hw);
118 return cast_to_oop(to);
119 }
120 uintptr_t encoded = header.value() & OFFSET_MASK;
121 HeapWord* to = decode_forwarding(from_hw, encoded);
122 return cast_to_oop(to);
123 }
124
125 inline oop FullGCForwarding::forwardee(oop obj) {
126 #ifdef _LP64
127 assert(_bases_table != nullptr, "expect sliding forwarding initialized");
128 return forwardee_impl(obj);
129 #else
130 return obj->forwardee();
131 #endif
132 }
133
134 #endif // SHARE_GC_SHARED_FULLGCFORWARDING_INLINE_HPP
|