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