src/hotspot/share/classfile/placeholders.cpp
changeset 47216 71c04702a3d5
parent 46742 24ec8a039c90
child 49824 e242740a92b8
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 2003, 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/placeholders.hpp"
       
    27 #include "classfile/systemDictionary.hpp"
       
    28 #include "oops/oop.inline.hpp"
       
    29 #include "runtime/fieldType.hpp"
       
    30 #include "utilities/hashtable.inline.hpp"
       
    31 
       
    32 // Placeholder methods
       
    33 
       
    34 PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name,
       
    35                                               ClassLoaderData* loader_data,
       
    36                                               bool havesupername,
       
    37                                               Symbol* supername) {
       
    38   PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::new_entry(hash, name);
       
    39   // Hashtable with Symbol* literal must increment and decrement refcount.
       
    40   name->increment_refcount();
       
    41   entry->set_loader_data(loader_data);
       
    42   entry->set_havesupername(havesupername);
       
    43   entry->set_supername(supername);
       
    44   entry->set_superThreadQ(NULL);
       
    45   entry->set_loadInstanceThreadQ(NULL);
       
    46   entry->set_defineThreadQ(NULL);
       
    47   entry->set_definer(NULL);
       
    48   entry->set_instance_klass(NULL);
       
    49   return entry;
       
    50 }
       
    51 
       
    52 void PlaceholderTable::free_entry(PlaceholderEntry* entry) {
       
    53   // decrement Symbol refcount here because Hashtable doesn't.
       
    54   entry->literal()->decrement_refcount();
       
    55   if (entry->supername() != NULL) entry->supername()->decrement_refcount();
       
    56   Hashtable<Symbol*, mtClass>::free_entry(entry);
       
    57 }
       
    58 
       
    59 
       
    60 // Placeholder objects represent classes currently being loaded.
       
    61 // All threads examining the placeholder table must hold the
       
    62 // SystemDictionary_lock, so we don't need special precautions
       
    63 // on store ordering here.
       
    64 void PlaceholderTable::add_entry(int index, unsigned int hash,
       
    65                                  Symbol* class_name, ClassLoaderData* loader_data,
       
    66                                  bool havesupername, Symbol* supername){
       
    67   assert_locked_or_safepoint(SystemDictionary_lock);
       
    68   assert(class_name != NULL, "adding NULL obj");
       
    69 
       
    70   // Both readers and writers are locked so it's safe to just
       
    71   // create the placeholder and insert it in the list without a membar.
       
    72   PlaceholderEntry* entry = new_entry(hash, class_name, loader_data, havesupername, supername);
       
    73   add_entry(index, entry);
       
    74 }
       
    75 
       
    76 
       
    77 // Remove a placeholder object.
       
    78 void PlaceholderTable::remove_entry(int index, unsigned int hash,
       
    79                                     Symbol* class_name,
       
    80                                     ClassLoaderData* loader_data) {
       
    81   assert_locked_or_safepoint(SystemDictionary_lock);
       
    82   PlaceholderEntry** p = bucket_addr(index);
       
    83   while (*p) {
       
    84     PlaceholderEntry *probe = *p;
       
    85     if (probe->hash() == hash && probe->equals(class_name, loader_data)) {
       
    86       // Delete entry
       
    87       *p = probe->next();
       
    88       free_entry(probe);
       
    89       return;
       
    90     }
       
    91     p = probe->next_addr();
       
    92   }
       
    93 }
       
    94 
       
    95 PlaceholderEntry* PlaceholderTable::get_entry(int index, unsigned int hash,
       
    96                                        Symbol* class_name,
       
    97                                        ClassLoaderData* loader_data) {
       
    98   assert_locked_or_safepoint(SystemDictionary_lock);
       
    99 
       
   100   for (PlaceholderEntry *place_probe = bucket(index);
       
   101                          place_probe != NULL;
       
   102                          place_probe = place_probe->next()) {
       
   103     if (place_probe->hash() == hash &&
       
   104         place_probe->equals(class_name, loader_data)) {
       
   105       return place_probe;
       
   106     }
       
   107   }
       
   108   return NULL;
       
   109 }
       
   110 
       
   111 Symbol* PlaceholderTable::find_entry(int index, unsigned int hash,
       
   112                                        Symbol* class_name,
       
   113                                        ClassLoaderData* loader_data) {
       
   114   PlaceholderEntry* probe = get_entry(index, hash, class_name, loader_data);
       
   115   return (probe? probe->klassname(): (Symbol*)NULL);
       
   116 }
       
   117 
       
   118   // find_and_add returns probe pointer - old or new
       
   119   // If no entry exists, add a placeholder entry
       
   120   // If entry exists, reuse entry
       
   121   // For both, push SeenThread for classloadAction
       
   122   // if havesupername: this is used for circularity for instanceklass loading
       
   123 PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash,
       
   124                                                  Symbol* name,
       
   125                                                  ClassLoaderData* loader_data,
       
   126                                                  classloadAction action,
       
   127                                                  Symbol* supername,
       
   128                                                  Thread* thread) {
       
   129   PlaceholderEntry* probe = get_entry(index, hash, name, loader_data);
       
   130   if (probe == NULL) {
       
   131     // Nothing found, add place holder
       
   132     add_entry(index, hash, name, loader_data, (action == LOAD_SUPER), supername);
       
   133     probe = get_entry(index, hash, name, loader_data);
       
   134   } else {
       
   135     if (action == LOAD_SUPER) {
       
   136       probe->set_havesupername(true);
       
   137       probe->set_supername(supername);
       
   138     }
       
   139   }
       
   140   if (probe) probe->add_seen_thread(thread, action);
       
   141   return probe;
       
   142 }
       
   143 
       
   144 
       
   145 // placeholder is used to track class loading internal states
       
   146 // placeholder existence now for loading superclass/superinterface
       
   147 // superthreadQ tracks class circularity, while loading superclass/superinterface
       
   148 // loadInstanceThreadQ tracks load_instance_class calls
       
   149 // definer() tracks the single thread that owns define token
       
   150 // defineThreadQ tracks waiters on defining thread's results
       
   151 // 1st claimant creates placeholder
       
   152 // find_and_add adds SeenThread entry for appropriate queue
       
   153 // All claimants remove SeenThread after completing action
       
   154 // On removal: if definer and all queues empty, remove entry
       
   155 // Note: you can be in both placeholders and systemDictionary
       
   156 // Therefore - must always check SD first
       
   157 // Ignores the case where entry is not found
       
   158 void PlaceholderTable::find_and_remove(int index, unsigned int hash,
       
   159                                        Symbol* name, ClassLoaderData* loader_data,
       
   160                                        classloadAction action,
       
   161                                        Thread* thread) {
       
   162     assert_locked_or_safepoint(SystemDictionary_lock);
       
   163     PlaceholderEntry *probe = get_entry(index, hash, name, loader_data);
       
   164     if (probe != NULL) {
       
   165        probe->remove_seen_thread(thread, action);
       
   166        // If no other threads using this entry, and this thread is not using this entry for other states
       
   167        if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL)
       
   168           && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) {
       
   169          remove_entry(index, hash, name, loader_data);
       
   170        }
       
   171     }
       
   172   }
       
   173 
       
   174 PlaceholderTable::PlaceholderTable(int table_size)
       
   175     : Hashtable<Symbol*, mtClass>(table_size, sizeof(PlaceholderEntry)) {
       
   176 }
       
   177 
       
   178 void PlaceholderEntry::verify() const {
       
   179   guarantee(loader_data() != NULL, "Must have been setup.");
       
   180   guarantee(loader_data()->class_loader() == NULL || loader_data()->class_loader()->is_instance(),
       
   181             "checking type of _loader");
       
   182   guarantee(instance_klass() == NULL
       
   183             || instance_klass()->is_instance_klass(),
       
   184             "checking type of instance_klass result");
       
   185 }
       
   186 
       
   187 void PlaceholderTable::verify() {
       
   188   verify_table<PlaceholderEntry>("Placeholder Table");
       
   189 }
       
   190 
       
   191 
       
   192 // Note, doesn't append a cr
       
   193 // Can't call this print_on because HashtableEntry doesn't initialize its vptr
       
   194 // and print_on is a virtual function so the vptr call crashes.
       
   195 void PlaceholderEntry::print_entry(outputStream* st) const {
       
   196   klassname()->print_value_on(st);
       
   197   if (loader_data() != NULL) {
       
   198     st->print(", loader ");
       
   199     loader_data()->print_value_on(st);
       
   200   }
       
   201   if (supername() != NULL) {
       
   202     st->print(", supername ");
       
   203     supername()->print_value_on(st);
       
   204   }
       
   205   if (definer() != NULL) {
       
   206     st->print(", definer ");
       
   207     definer()->print_value_on(st);
       
   208   }
       
   209   if (instance_klass() != NULL) {
       
   210     st->print(", InstanceKlass ");
       
   211     instance_klass()->print_value_on(st);
       
   212   }
       
   213   st->cr();
       
   214   st->print("loadInstanceThreadQ threads:");
       
   215   loadInstanceThreadQ()->print_action_queue(st);
       
   216   st->cr();
       
   217   st->print("superThreadQ threads:");
       
   218   superThreadQ()->print_action_queue(st);
       
   219   st->cr();
       
   220   st->print("defineThreadQ threads:");
       
   221   defineThreadQ()->print_action_queue(st);
       
   222   st->cr();
       
   223 }
       
   224 
       
   225 void PlaceholderTable::print_on(outputStream* st) const {
       
   226   st->print_cr("Placeholder table (table_size=%d, placeholders=%d)",
       
   227                 table_size(), number_of_entries());
       
   228   for (int pindex = 0; pindex < table_size(); pindex++) {
       
   229     for (PlaceholderEntry* probe = bucket(pindex);
       
   230                            probe != NULL;
       
   231                            probe = probe->next()) {
       
   232       st->print("%4d: placeholder ", pindex);
       
   233       probe->print_entry(st);
       
   234     }
       
   235   }
       
   236 }