1 /* 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 #include "precompiled.hpp" 25 #include "gc/shared/gc_globals.hpp" 26 #include "gc/shared/slidingForwarding.inline.hpp" 27 #include "oops/markWord.hpp" 28 #include "oops/oop.inline.hpp" 29 #include "utilities/align.hpp" 30 #include "unittest.hpp" 31 32 #ifdef _LP64 33 #ifndef PRODUCT 34 35 static uintptr_t make_mark(uintptr_t target_region, uintptr_t offset) { 36 return (target_region) << 3 | (offset << 4) | 3 /* forwarded */; 37 } 38 39 static uintptr_t make_fallback() { 40 return ((uintptr_t(1) << 2) /* fallback */ | 3 /* forwarded */); 41 } 42 43 // Test simple forwarding within the same region. 44 TEST_VM(SlidingForwarding, simple) { 45 FlagSetting fs(UseAltGCForwarding, true); 46 HeapWord fakeheap[32] = { nullptr }; 47 HeapWord* heap = align_up(fakeheap, 8 * sizeof(HeapWord)); 48 oop obj1 = cast_to_oop(&heap[2]); 49 oop obj2 = cast_to_oop(&heap[0]); 50 SlidingForwarding::initialize(MemRegion(&heap[0], &heap[16]), 8); 51 obj1->set_mark(markWord::prototype()); 52 SlidingForwarding::begin(); 53 54 SlidingForwarding::forward_to<true>(obj1, obj2); 55 ASSERT_EQ(obj1->mark().value(), make_mark(0 /* target_region */, 0 /* offset */)); 56 ASSERT_EQ(SlidingForwarding::forwardee<true>(obj1), obj2); 57 58 SlidingForwarding::end(); 59 } 60 61 // Test forwardings crossing 2 regions. 62 TEST_VM(SlidingForwarding, tworegions) { 63 FlagSetting fs(UseAltGCForwarding, true); 64 HeapWord fakeheap[32] = { nullptr }; 65 HeapWord* heap = align_up(fakeheap, 8 * sizeof(HeapWord)); 66 oop obj1 = cast_to_oop(&heap[14]); 67 oop obj2 = cast_to_oop(&heap[2]); 68 oop obj3 = cast_to_oop(&heap[10]); 69 SlidingForwarding::initialize(MemRegion(&heap[0], &heap[16]), 8); 70 obj1->set_mark(markWord::prototype()); 71 SlidingForwarding::begin(); 72 73 SlidingForwarding::forward_to<true>(obj1, obj2); 74 ASSERT_EQ(obj1->mark().value(), make_mark(0 /* target_region */, 2 /* offset */)); 75 ASSERT_EQ(SlidingForwarding::forwardee<true>(obj1), obj2); 76 77 SlidingForwarding::forward_to<true>(obj1, obj3); 78 ASSERT_EQ(obj1->mark().value(), make_mark(1 /* target_region */, 2 /* offset */)); 79 ASSERT_EQ(SlidingForwarding::forwardee<true>(obj1), obj3); 80 81 SlidingForwarding::end(); 82 } 83 84 // Test fallback forwardings crossing 4 regions. 85 TEST_VM(SlidingForwarding, fallback) { 86 FlagSetting fs(UseAltGCForwarding, true); 87 HeapWord fakeheap[32] = { nullptr }; 88 HeapWord* heap = align_up(fakeheap, 8 * sizeof(HeapWord)); 89 oop s_obj1 = cast_to_oop(&heap[12]); 90 oop s_obj2 = cast_to_oop(&heap[13]); 91 oop s_obj3 = cast_to_oop(&heap[14]); 92 oop s_obj4 = cast_to_oop(&heap[15]); 93 oop t_obj1 = cast_to_oop(&heap[2]); 94 oop t_obj2 = cast_to_oop(&heap[4]); 95 oop t_obj3 = cast_to_oop(&heap[10]); 96 oop t_obj4 = cast_to_oop(&heap[12]); 97 SlidingForwarding::initialize(MemRegion(&heap[0], &heap[16]), 4); 98 s_obj1->set_mark(markWord::prototype()); 99 s_obj2->set_mark(markWord::prototype()); 100 s_obj3->set_mark(markWord::prototype()); 101 s_obj4->set_mark(markWord::prototype()); 102 SlidingForwarding::begin(); 103 104 SlidingForwarding::forward_to<true>(s_obj1, t_obj1); 105 ASSERT_EQ(s_obj1->mark().value(), make_mark(0 /* target_region */, 2 /* offset */)); 106 ASSERT_EQ(SlidingForwarding::forwardee<true>(s_obj1), t_obj1); 107 108 SlidingForwarding::forward_to<true>(s_obj2, t_obj2); 109 ASSERT_EQ(s_obj2->mark().value(), make_mark(1 /* target_region */, 0 /* offset */)); 110 ASSERT_EQ(SlidingForwarding::forwardee<true>(s_obj2), t_obj2); 111 112 SlidingForwarding::forward_to<true>(s_obj3, t_obj3); 113 ASSERT_EQ(s_obj3->mark().value(), make_fallback()); 114 ASSERT_EQ(SlidingForwarding::forwardee<true>(s_obj3), t_obj3); 115 116 SlidingForwarding::forward_to<true>(s_obj4, t_obj4); 117 ASSERT_EQ(s_obj4->mark().value(), make_fallback()); 118 ASSERT_EQ(SlidingForwarding::forwardee<true>(s_obj4), t_obj4); 119 120 SlidingForwarding::end(); 121 } 122 123 #endif // PRODUCT 124 #endif // _LP64