1 /* 2 * Copyright (c) 2013, 2015, Red Hat, Inc. and/or its affiliates. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 * 22 */ 23 24 #include "memory/universe.hpp" 25 #include "gc/shared/collectedHeap.hpp" 26 #include "gc/shenandoah/brooksPointer.hpp" 27 #include "gc/shenandoah/shenandoahBarrierSet.hpp" 28 29 BrooksPointer::BrooksPointer(HeapWord** hw) : _heap_word(hw) {} 30 31 BrooksPointer BrooksPointer::get(oop obj) { 32 HeapWord* hw_obj = (HeapWord*) obj; 33 HeapWord* brooks_ptr = hw_obj - 1; 34 // We know that the value in that memory location is a pointer to another 35 // heapword/oop. 36 return BrooksPointer((HeapWord**) brooks_ptr); 37 } 38 39 void BrooksPointer::set_forwardee(oop forwardee) { 40 assert(ShenandoahHeap::heap()->is_in(forwardee), "forwardee must be valid oop in the heap"); 41 *_heap_word = (HeapWord*) forwardee; 42 #ifdef ASSERT 43 if (ShenandoahTraceBrooksPointers) { 44 tty->print_cr("setting_forwardee to "PTR_FORMAT" = "PTR_FORMAT, p2i((HeapWord*) forwardee), p2i(*_heap_word)); 45 } 46 #endif 47 } 48 49 HeapWord* BrooksPointer::cas_forwardee(HeapWord* old, HeapWord* forwardee) { 50 assert(ShenandoahHeap::heap()->is_in(forwardee), "forwardee must point to a heap address"); 51 52 53 54 HeapWord* o = old; 55 HeapWord* n = forwardee; 56 HeapWord* result; 57 58 #ifdef ASSERT 59 if (ShenandoahTraceBrooksPointers) { 60 tty->print_cr("Attempting to CAS "PTR_FORMAT" value "PTR_FORMAT" from "PTR_FORMAT" to "PTR_FORMAT, p2i(_heap_word), p2i(*_heap_word), p2i(o), p2i(n)); 61 } 62 #endif 63 64 #ifdef ASSERT 65 if (ShenandoahVerifyWritesToFromSpace || ShenandoahVerifyReadsToFromSpace) { 66 ShenandoahHeap* sh = (ShenandoahHeap*) Universe::heap(); 67 ShenandoahHeapRegion* hr = sh->heap_region_containing(old); 68 69 { 70 hr->memProtectionOff(); 71 result = (HeapWord*) (HeapWord*) Atomic::cmpxchg_ptr(n, _heap_word, o); 72 hr->memProtectionOn(); 73 } 74 } else { 75 result = (HeapWord*) (HeapWord*) Atomic::cmpxchg_ptr(n, _heap_word, o); 76 } 77 #else 78 result = (HeapWord*) (HeapWord*) Atomic::cmpxchg_ptr(n, _heap_word, o); 79 #endif 80 81 #ifdef ASSERT 82 if (ShenandoahTraceBrooksPointers) { 83 tty->print_cr("Result of CAS from "PTR_FORMAT" to "PTR_FORMAT" was "PTR_FORMAT" read value was "PTR_FORMAT, p2i(o), p2i(n), p2i(result), p2i(*_heap_word)); 84 } 85 #endif 86 87 return result; 88 } 89 90 bool BrooksPointer::check_forwardee_is_in_heap(oop forwardee) { 91 return Universe::heap()->is_in(forwardee); 92 }