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 #ifndef SHARE_JVMCI_METADATAHANDLES_HPP 25 #define SHARE_JVMCI_METADATAHANDLES_HPP 26 27 #include "oops/constantPool.hpp" 28 #include "oops/metadata.hpp" 29 #include "oops/method.hpp" 30 #include "runtime/handles.hpp" 31 #include "runtime/os.hpp" 32 33 #ifdef ASSERT 34 #define METADATA_TRACK_NAMES 35 #endif 36 37 struct _jmetadata { 38 private: 39 Metadata* _value; 40 #ifdef METADATA_TRACK_NAMES 41 // Debug data for tracking stale metadata 42 const char* _name; 43 #endif 44 45 public: 46 Metadata* value() { return _value; } 47 48 #ifdef METADATA_TRACK_NAMES 49 void initialize() { 50 _value = NULL; 51 _name = NULL; 52 } 53 #endif 54 55 void set_value(Metadata* value) { 56 _value = value; 57 } 58 59 #ifdef METADATA_TRACK_NAMES 60 const char* name() { return _name; } 61 void set_name(const char* name) { 62 if (_name != NULL) { 63 os::free((void*) _name); 64 _name = NULL; 65 } 66 if (name != NULL) { 67 _name = os::strdup(name); 68 } 69 } 70 #endif 71 }; 72 73 typedef struct _jmetadata HandleRecord; 74 typedef struct _jmetadata *jmetadata; 75 class MetadataHandles; 76 77 class MetadataHandleBlock : public CHeapObj<mtJVMCI> { 78 friend class MetadataHandles; 79 private: 80 enum SomeConstants { 81 block_size_in_handles = 32 // Number of handles per handle block 82 }; 83 84 // Free handles always have their low bit set so those pointers can 85 // be distinguished from handles which are in use. The last handle 86 // on the free list has a NULL pointer with the tag bit set, so it's 87 // clear that the handle has been reclaimed. The _free_list is 88 // always a real pointer to a handle. 89 90 HandleRecord _handles[block_size_in_handles]; // The handles 91 int _top; // Index of next unused handle 92 MetadataHandleBlock* _next; // Link to next block 93 94 MetadataHandleBlock() { 95 _top = 0; 96 _next = NULL; 97 #ifdef METADATA_TRACK_NAMES 98 for (int i = 0; i < block_size_in_handles; i++) { 99 _handles[i].initialize(); 100 } 101 #endif 102 } 103 104 const char* get_name(int index) { 105 #ifdef METADATA_TRACK_NAMES 106 return _handles[index].name(); 107 #else 108 return "<missing>"; 109 #endif 110 } 111 }; 112 113 // JVMCI maintains direct references to metadata. To make these references safe in the face of 114 // class redefinition, they are held in handles so they can be scanned during GC. They are 115 // managed in a cooperative way between the Java code and HotSpot. A handle is filled in and 116 // passed back to the Java code which is responsible for setting the handle to NULL when it 117 // is no longer in use. This is done by jdk.vm.ci.hotspot.HandleCleaner. The 118 // rebuild_free_list function notices when the handle is clear and reclaims it for re-use. 119 class MetadataHandles : public CHeapObj<mtJVMCI> { 120 private: 121 enum SomeConstants { 122 ptr_tag = 1, 123 ptr_mask = ~((intptr_t)ptr_tag) 124 }; 125 126 MetadataHandleBlock* _head; // First block 127 MetadataHandleBlock* _last; // Last block in use 128 intptr_t _free_list; // Handle free list 129 int _allocate_before_rebuild; // Number of blocks to allocate before rebuilding free list 130 int _num_blocks; // Number of blocks 131 int _num_handles; 132 int _num_free_handles; 133 134 HandleRecord* get_free_handle() { 135 HandleRecord* handle = (HandleRecord*) (_free_list & ptr_mask); 136 _free_list = (ptr_mask & (intptr_t) (handle->value())); 137 assert(_free_list != ptr_tag, "should be null"); 138 _num_free_handles--; 139 return handle; 140 } 141 142 HandleRecord* get_handle() { 143 assert(_last != NULL, "sanity"); 144 // Try last block 145 if (_last->_top < MetadataHandleBlock::block_size_in_handles) { 146 _num_handles++; 147 return &(_last->_handles)[_last->_top++]; 148 } else if (_free_list != 0) { 149 // Try free list 150 return get_free_handle(); 151 } 152 return NULL; 153 } 154 155 void rebuild_free_list(); 156 157 jmetadata allocate_metadata_handle(Metadata* metadata); 158 159 public: 160 MetadataHandles() { 161 _head = NULL; 162 _last = NULL; 163 _free_list = 0; 164 _allocate_before_rebuild = 0; 165 _num_blocks = 0; 166 _num_handles = 0; 167 _num_free_handles = 0; 168 } 169 170 int num_handles() const { return _num_handles; } 171 int num_free_handles() const { return _num_free_handles; } 172 int num_blocks() const { return _num_blocks; } 173 174 jmetadata allocate_handle(const methodHandle& handle) { return allocate_metadata_handle(handle()); } 175 jmetadata allocate_handle(const constantPoolHandle& handle) { return allocate_metadata_handle(handle()); } 176 177 // Adds `handle` to the free list 178 void chain_free_list(HandleRecord* handle) { 179 handle->set_value((Metadata*) (ptr_tag | _free_list)); 180 #ifdef METADATA_TRACK_NAMES 181 handle->set_name(NULL); 182 #endif 183 _free_list = (intptr_t) handle; 184 _num_free_handles++; 185 } 186 187 // Clears all handles without releasing any handle memory. 188 void clear(); 189 190 void metadata_do(void f(Metadata*)); 191 192 void do_unloading(); 193 }; 194 195 #endif // SHARE_JVMCI_METADATAHANDLES_HPP