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