1 /* 2 * Copyright (c) 2019, Oracle and/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 #include "precompiled.hpp" 26 #include "memory/archiveUtils.hpp" 27 #include "utilities/bitMap.inline.hpp" 28 29 #if INCLUDE_CDS 30 31 CHeapBitMap* ArchivePtrMarker::_ptrmap = NULL; 32 address* ArchivePtrMarker::_ptr_base; 33 address* ArchivePtrMarker::_ptr_end; 34 bool ArchivePtrMarker::_compacted; 35 36 void ArchivePtrMarker::initialize(CHeapBitMap* ptrmap, address* ptr_base, address* ptr_end) { 37 assert(_ptrmap == NULL, "initialize only once"); 38 _ptr_base = ptr_base; 39 _ptr_end = ptr_end; 40 _compacted = false; 41 _ptrmap = ptrmap; 42 _ptrmap->initialize(12 * M / sizeof(intptr_t)); // default archive is about 12MB. 43 } 44 45 void ArchivePtrMarker::mark_pointer(address* ptr_loc) { 46 assert(_ptrmap != NULL, "not initialized"); 47 assert(!_compacted, "cannot mark anymore"); 48 49 if (_ptr_base <= ptr_loc && ptr_loc < _ptr_end) { 50 address value = *ptr_loc; 51 if (value != NULL) { 52 assert(uintx(ptr_loc) % sizeof(intptr_t) == 0, "pointers must be stored in aligned addresses"); 53 size_t idx = ptr_loc - _ptr_base; 54 if (_ptrmap->size() <= idx) { 55 _ptrmap->resize((idx + 1) * 3 / 2); 56 } 57 assert(idx < _ptrmap->size(), "must be"); 58 _ptrmap->set_bit(idx); 59 //tty->print_cr("Marking pointer [%p] -> %p @ " SIZE_FORMAT_W(9), ptr_loc, *ptr_loc, idx); 60 } 61 } 62 } 63 64 class ArchivePtrBitmapCleaner: public BitMapClosure { 65 CHeapBitMap* _ptrmap; 66 address* _ptr_base; 67 address _relocatable_base; 68 address _relocatable_end; 69 size_t _max_index; 70 71 public: 72 ArchivePtrBitmapCleaner(CHeapBitMap* ptrmap, address* ptr_base, address relocatable_base, address relocatable_end) : 73 _ptrmap(ptrmap), _ptr_base(ptr_base), 74 _relocatable_base(relocatable_base), _relocatable_end(relocatable_end), _max_index(0) {} 75 76 bool do_bit(size_t offset) { 77 address* ptr_loc = _ptr_base + offset; 78 address ptr_value = *ptr_loc; 79 if (ptr_value != NULL) { 80 assert(_relocatable_base <= ptr_value && ptr_value < _relocatable_end, "do not point to arbitrary locations!"); 81 if (_max_index < offset) { 82 _max_index = offset; 83 } 84 } else { 85 _ptrmap->clear_bit(offset); 86 tty->print_cr("Clearing pointer [%p] -> %p @ " SIZE_FORMAT_W(9), ptr_loc, *ptr_loc, offset); 87 } 88 89 return true; 90 } 91 92 size_t max_index() const { return _max_index; } 93 }; 94 95 void ArchivePtrMarker::compact(address relocatable_base, address relocatable_end) { 96 assert(!_compacted, "cannot compact again"); 97 ArchivePtrBitmapCleaner cleaner(_ptrmap, _ptr_base, relocatable_base, relocatable_end); 98 _ptrmap->iterate(&cleaner); 99 _ptrmap->resize(cleaner.max_index() + 1); 100 _compacted = true; 101 } 102 103 #endif // INCLUDE_CDS