hotspot/src/share/vm/classfile/protectionDomainCache.cpp
changeset 46554 aa1cfd918c4f
parent 46475 75902cea18af
child 46701 f559541c0daa
equal deleted inserted replaced
45608:9927a9f16738 46554:aa1cfd918c4f
       
     1 /*
       
     2  * Copyright (c) 2017, 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 "classfile/protectionDomainCache.hpp"
       
    27 #include "classfile/systemDictionary.hpp"
       
    28 #include "memory/iterator.hpp"
       
    29 #include "memory/resourceArea.hpp"
       
    30 #include "oops/oop.inline.hpp"
       
    31 #include "utilities/hashtable.inline.hpp"
       
    32 
       
    33 unsigned int ProtectionDomainCacheTable::compute_hash(Handle protection_domain) {
       
    34   // Identity hash can safepoint, so keep protection domain in a Handle.
       
    35   return (unsigned int)(protection_domain->identity_hash());
       
    36 }
       
    37 
       
    38 int ProtectionDomainCacheTable::index_for(Handle protection_domain) {
       
    39   return hash_to_index(compute_hash(protection_domain));
       
    40 }
       
    41 
       
    42 ProtectionDomainCacheTable::ProtectionDomainCacheTable(int table_size)
       
    43   : Hashtable<oop, mtClass>(table_size, sizeof(ProtectionDomainCacheEntry))
       
    44 {
       
    45 }
       
    46 
       
    47 void ProtectionDomainCacheTable::unlink(BoolObjectClosure* is_alive) {
       
    48   assert(SafepointSynchronize::is_at_safepoint(), "must be");
       
    49   for (int i = 0; i < table_size(); ++i) {
       
    50     ProtectionDomainCacheEntry** p = bucket_addr(i);
       
    51     ProtectionDomainCacheEntry* entry = bucket(i);
       
    52     while (entry != NULL) {
       
    53       if (is_alive->do_object_b(entry->literal())) {
       
    54         p = entry->next_addr();
       
    55       } else {
       
    56         if (log_is_enabled(Debug, protectiondomain)) {
       
    57           outputStream* log = Log(protectiondomain)::debug_stream();
       
    58           log->print("protection domain unlinked: ");
       
    59           entry->literal()->print_value_on(log);
       
    60           log->cr();
       
    61         }
       
    62         *p = entry->next();
       
    63         free_entry(entry);
       
    64       }
       
    65       entry = *p;
       
    66     }
       
    67   }
       
    68 }
       
    69 
       
    70 void ProtectionDomainCacheTable::oops_do(OopClosure* f) {
       
    71   for (int index = 0; index < table_size(); index++) {
       
    72     for (ProtectionDomainCacheEntry* probe = bucket(index);
       
    73                                      probe != NULL;
       
    74                                      probe = probe->next()) {
       
    75       probe->oops_do(f);
       
    76     }
       
    77   }
       
    78 }
       
    79 
       
    80 #ifndef PRODUCT
       
    81 void ProtectionDomainCacheTable::print() {
       
    82   tty->print_cr("Protection domain cache table (table_size=%d, classes=%d)",
       
    83                 table_size(), number_of_entries());
       
    84   for (int index = 0; index < table_size(); index++) {
       
    85     for (ProtectionDomainCacheEntry* probe = bucket(index);
       
    86                                      probe != NULL;
       
    87                                      probe = probe->next()) {
       
    88       probe->print();
       
    89     }
       
    90   }
       
    91 }
       
    92 
       
    93 void ProtectionDomainCacheEntry::print() {
       
    94   tty->print_cr("entry " PTR_FORMAT " value " PTR_FORMAT " next " PTR_FORMAT,
       
    95                 p2i(this), p2i(literal()), p2i(next()));
       
    96 }
       
    97 #endif
       
    98 
       
    99 void ProtectionDomainCacheTable::verify() {
       
   100   verify_table<ProtectionDomainCacheEntry>("Protection Domain Table");
       
   101 }
       
   102 
       
   103 void ProtectionDomainCacheEntry::verify() {
       
   104   guarantee(literal()->is_oop(), "must be an oop");
       
   105 }
       
   106 
       
   107 ProtectionDomainCacheEntry* ProtectionDomainCacheTable::get(Handle protection_domain) {
       
   108   unsigned int hash = compute_hash(protection_domain);
       
   109   int index = hash_to_index(hash);
       
   110 
       
   111   ProtectionDomainCacheEntry* entry = find_entry(index, protection_domain);
       
   112   if (entry == NULL) {
       
   113     entry = add_entry(index, hash, protection_domain);
       
   114   }
       
   115   return entry;
       
   116 }
       
   117 
       
   118 ProtectionDomainCacheEntry* ProtectionDomainCacheTable::find_entry(int index, Handle protection_domain) {
       
   119   for (ProtectionDomainCacheEntry* e = bucket(index); e != NULL; e = e->next()) {
       
   120     if (e->protection_domain() == protection_domain()) {
       
   121       return e;
       
   122     }
       
   123   }
       
   124 
       
   125   return NULL;
       
   126 }
       
   127 
       
   128 ProtectionDomainCacheEntry* ProtectionDomainCacheTable::add_entry(int index, unsigned int hash, Handle protection_domain) {
       
   129   assert_locked_or_safepoint(SystemDictionary_lock);
       
   130   assert(index == index_for(protection_domain), "incorrect index?");
       
   131   assert(find_entry(index, protection_domain) == NULL, "no double entry");
       
   132 
       
   133   ProtectionDomainCacheEntry* p = new_entry(hash, protection_domain);
       
   134   Hashtable<oop, mtClass>::add_entry(index, p);
       
   135   return p;
       
   136 }