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 }