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 #include "precompiled.hpp" 25 #include "jvmci/metadataHandles.hpp" 26 27 jmetadata MetadataHandles::allocate_metadata_handle(Metadata* obj) { 28 assert(obj->is_valid() && obj->is_metadata(), "must be"); 29 30 if (_head == NULL) { 31 // This is the first allocation. 32 _head = new MetadataHandleBlock(); 33 _last = _head; 34 _num_blocks++; 35 } 36 37 HandleRecord* handle = get_handle(); 38 39 if (handle != NULL) { 40 handle->set_value(obj); 41 #ifdef METADATA_TRACK_NAMES 42 handle->set_name(obj->print_value_string()); 43 #endif 44 return (jmetadata) handle; 45 } 46 47 // Check if an unused block follows last 48 if (_last->_next != NULL) { 49 // update last and retry 50 _last = _last->_next; 51 return allocate_metadata_handle(obj); 52 } 53 54 // No space available, we have to rebuild free list or expand 55 if (_allocate_before_rebuild == 0) { 56 rebuild_free_list(); // updates _allocate_before_rebuild counter 57 } else { 58 // Append new block 59 _last->_next = new MetadataHandleBlock(); 60 _last = _last->_next; 61 _allocate_before_rebuild--; 62 _num_blocks++; 63 } 64 return allocate_metadata_handle(obj); // retry 65 } 66 67 68 void MetadataHandles::rebuild_free_list() { 69 assert(_allocate_before_rebuild == 0 && _free_list == 0, "just checking"); 70 int free = 0; 71 int blocks = 0; 72 for (MetadataHandleBlock* current = _head; current != NULL; current = current->_next) { 73 for (int index = 0; index < current->_top; index++) { 74 HandleRecord* handle = &(current->_handles)[index]; 75 if (handle->value() == NULL) { 76 // this handle was cleared out by a delete call, reuse it 77 chain_free_list(handle); 78 free++; 79 } 80 } 81 // we should not rebuild free list if there are unused handles at the end 82 assert(current->_top == MetadataHandleBlock::block_size_in_handles, "just checking"); 83 blocks++; 84 } 85 assert(_num_blocks == blocks, "%d != %d", _num_blocks, blocks); 86 assert(_num_free_handles == free, "%d != %d", _num_free_handles, free); 87 // Heuristic: if more than half of the handles are NOT free we rebuild next time 88 // as well, otherwise we append a corresponding number of new blocks before 89 // attempting a free list rebuild again. 90 int total = blocks * MetadataHandleBlock::block_size_in_handles; 91 int extra = total - 2*free; 92 if (extra > 0) { 93 // Not as many free handles as we would like - compute number of new blocks to append 94 _allocate_before_rebuild = (extra + MetadataHandleBlock::block_size_in_handles - 1) / MetadataHandleBlock::block_size_in_handles; 95 } 96 } 97 98 void MetadataHandles::clear() { 99 _free_list = 0; 100 _last = _head; 101 if (_head != NULL) { 102 for (MetadataHandleBlock* block = _head; block != NULL; block = block->_next) { 103 block->_top = 0; 104 } 105 } 106 _num_handles = 0; 107 _num_free_handles = 0; 108 } 109 110 void MetadataHandles::metadata_do(void f(Metadata*)) { 111 for (MetadataHandleBlock* current = _head; current != NULL; current = current->_next) { 112 for (int index = 0; index < current->_top; index++) { 113 HandleRecord* root = &(current->_handles)[index]; 114 Metadata* value = root->value(); 115 // traverse heap pointers only, not deleted handles or free list 116 // pointers 117 if (value != NULL && ((intptr_t) value & ptr_tag) == 0) { 118 assert(value->is_valid(), "invalid metadata %s", current->get_name(index)); 119 f(value); 120 } 121 } 122 // the next handle block is valid only if current block is full 123 if (current->_top < MetadataHandleBlock::block_size_in_handles) { 124 break; 125 } 126 } 127 } 128 129 // Visit any live metadata handles and clean them up. Since clearing of these handles is driven by 130 // weak references they will be cleared at some point in the future when the reference cleaning logic is run. 131 void MetadataHandles::do_unloading() { 132 for (MetadataHandleBlock* current = _head; current != NULL; current = current->_next) { 133 for (int index = 0; index < current->_top; index++) { 134 HandleRecord* handle = &(current->_handles)[index]; 135 Metadata* value = handle->value(); 136 // traverse heap pointers only, not deleted handles or free list 137 // pointers 138 if (value != NULL && ((intptr_t) value & ptr_tag) == 0) { 139 Klass* klass = NULL; 140 if (value->is_klass()) { 141 klass = (Klass*)value; 142 } else if (value->is_method()) { 143 Method* m = (Method*)value; 144 klass = m->method_holder(); 145 } else if (value->is_constantPool()) { 146 ConstantPool* cp = (ConstantPool*)value; 147 klass = cp->pool_holder(); 148 } else { 149 ShouldNotReachHere(); 150 } 151 if (klass->class_loader_data()->is_unloading()) { 152 // This needs to be marked so that it's no longer scanned 153 // but can't be put on the free list yet. The 154 // HandleCleaner will set this to NULL and 155 // put it on the free list. 156 jlong old_value = Atomic::cmpxchg((jlong) (ptr_tag), (jlong*)handle, (jlong) value); 157 if (old_value == (jlong) value) { 158 // Success 159 } else { 160 guarantee(old_value == 0, "only other possible value"); 161 } 162 } 163 } 164 } 165 // the next handle block is valid only if current block is full 166 if (current->_top < MetadataHandleBlock::block_size_in_handles) { 167 break; 168 } 169 } 170 } --- EOF ---