placeholders.cpp revision 1879:f95d63e2154a
1/*
2 * Copyright (c) 2003, 2010, 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
34PlaceholderEntry* PlaceholderTable::new_entry(int hash, symbolOop name,
35                                              oop loader, bool havesupername,
36                                              symbolOop supername) {
37  PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable::new_entry(hash, name);
38  entry->set_loader(loader);
39  entry->set_havesupername(havesupername);
40  entry->set_supername(supername);
41  entry->set_superThreadQ(NULL);
42  entry->set_loadInstanceThreadQ(NULL);
43  entry->set_defineThreadQ(NULL);
44  entry->set_definer(NULL);
45  entry->set_instanceKlass(NULL);
46  return entry;
47}
48
49
50// Placeholder objects represent classes currently being loaded.
51// All threads examining the placeholder table must hold the
52// SystemDictionary_lock, so we don't need special precautions
53// on store ordering here.
54void PlaceholderTable::add_entry(int index, unsigned int hash,
55                                 symbolHandle class_name, Handle class_loader,
56                                 bool havesupername, symbolHandle supername){
57  assert_locked_or_safepoint(SystemDictionary_lock);
58  assert(!class_name.is_null(), "adding NULL obj");
59
60  // Both readers and writers are locked so it's safe to just
61  // create the placeholder and insert it in the list without a membar.
62  PlaceholderEntry* entry = new_entry(hash, class_name(), class_loader(), havesupername, supername());
63  add_entry(index, entry);
64}
65
66
67// Remove a placeholder object.
68void PlaceholderTable::remove_entry(int index, unsigned int hash,
69                                    symbolHandle class_name,
70                                    Handle class_loader) {
71  assert_locked_or_safepoint(SystemDictionary_lock);
72  PlaceholderEntry** p = bucket_addr(index);
73  while (*p) {
74    PlaceholderEntry *probe = *p;
75    if (probe->hash() == hash && probe->equals(class_name(), class_loader())) {
76      // Delete entry
77      *p = probe->next();
78      free_entry(probe);
79      return;
80    }
81    p = probe->next_addr();
82  }
83}
84
85PlaceholderEntry* PlaceholderTable::get_entry(int index, unsigned int hash,
86                                       symbolHandle class_name,
87                                       Handle class_loader) {
88  assert_locked_or_safepoint(SystemDictionary_lock);
89
90  symbolOop class_name_ = class_name();
91  oop class_loader_ = class_loader();
92
93  for (PlaceholderEntry *place_probe = bucket(index);
94                         place_probe != NULL;
95                         place_probe = place_probe->next()) {
96    if (place_probe->hash() == hash &&
97        place_probe->equals(class_name_, class_loader_)) {
98      return place_probe;
99    }
100  }
101  return NULL;
102}
103
104symbolOop PlaceholderTable::find_entry(int index, unsigned int hash,
105                                       symbolHandle class_name,
106                                       Handle class_loader) {
107  PlaceholderEntry* probe = get_entry(index, hash, class_name, class_loader);
108  return (probe? probe->klass(): symbolOop(NULL));
109}
110
111  // find_and_add returns probe pointer - old or new
112  // If no entry exists, add a placeholder entry
113  // If entry exists, reuse entry
114  // For both, push SeenThread for classloadAction
115  // if havesupername: this is used for circularity for instanceklass loading
116PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, symbolHandle name, Handle loader, classloadAction action, symbolHandle supername, Thread* thread) {
117  PlaceholderEntry* probe = get_entry(index, hash, name, loader);
118  if (probe == NULL) {
119    // Nothing found, add place holder
120    add_entry(index, hash, name, loader, (action == LOAD_SUPER), supername);
121    probe = get_entry(index, hash, name, loader);
122  } else {
123    if (action == LOAD_SUPER) {
124      probe->set_havesupername(true);
125      probe->set_supername(supername());
126    }
127  }
128  if (probe) probe->add_seen_thread(thread, action);
129  return probe;
130}
131
132
133// placeholder used to track class loading internal states
134// placeholder existence now for loading superclass/superinterface
135// superthreadQ tracks class circularity, while loading superclass/superinterface
136// loadInstanceThreadQ tracks load_instance_class calls
137// definer() tracks the single thread that owns define token
138// defineThreadQ tracks waiters on defining thread's results
139// 1st claimant creates placeholder
140// find_and_add adds SeenThread entry for appropriate queue
141// All claimants remove SeenThread after completing action
142// On removal: if definer and all queues empty, remove entry
143// Note: you can be in both placeholders and systemDictionary
144// see parse_stream for redefine classes
145// Therefore - must always check SD first
146// Ignores the case where entry is not found
147void PlaceholderTable::find_and_remove(int index, unsigned int hash,
148                       symbolHandle name, Handle loader, Thread* thread) {
149    assert_locked_or_safepoint(SystemDictionary_lock);
150    PlaceholderEntry *probe = get_entry(index, hash, name, loader);
151    if (probe != NULL) {
152       // No other threads using this entry
153       if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL)
154          && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) {
155         remove_entry(index, hash, name, loader);
156       }
157    }
158  }
159
160PlaceholderTable::PlaceholderTable(int table_size)
161    : TwoOopHashtable(table_size, sizeof(PlaceholderEntry)) {
162}
163
164
165void PlaceholderTable::oops_do(OopClosure* f) {
166  for (int index = 0; index < table_size(); index++) {
167    for (PlaceholderEntry* probe = bucket(index);
168                           probe != NULL;
169                           probe = probe->next()) {
170      probe->oops_do(f);
171    }
172  }
173}
174
175
176void PlaceholderEntry::oops_do(OopClosure* blk) {
177  assert(klass() != NULL, "should have a non-null klass");
178  blk->do_oop((oop*)klass_addr());
179  if (_loader != NULL) {
180    blk->do_oop(loader_addr());
181  }
182  if (_supername != NULL) {
183    blk->do_oop((oop*)supername_addr());
184  }
185  if (_instanceKlass != NULL) {
186    blk->do_oop((oop*)instanceKlass_addr());
187  }
188}
189
190// do all entries in the placeholder table
191void PlaceholderTable::entries_do(void f(symbolOop, oop)) {
192  for (int index = 0; index < table_size(); index++) {
193    for (PlaceholderEntry* probe = bucket(index);
194                           probe != NULL;
195                           probe = probe->next()) {
196      f(probe->klass(), probe->loader());
197    }
198  }
199}
200
201
202#ifndef PRODUCT
203// Note, doesn't append a cr
204void PlaceholderEntry::print() const {
205  klass()->print_value();
206  if (loader() != NULL) {
207    tty->print(", loader ");
208    loader()->print_value();
209  }
210  if (supername() != NULL) {
211    tty->print(", supername ");
212    supername()->print_value();
213  }
214  if (definer() != NULL) {
215    tty->print(", definer ");
216    definer()->print_value();
217  }
218  if (instanceKlass() != NULL) {
219    tty->print(", instanceKlass ");
220    instanceKlass()->print_value();
221  }
222  tty->print("\n");
223  tty->print("loadInstanceThreadQ threads:");
224  loadInstanceThreadQ()->printActionQ();
225  tty->print("\n");
226  tty->print("superThreadQ threads:");
227  superThreadQ()->printActionQ();
228  tty->print("\n");
229  tty->print("defineThreadQ threads:");
230  defineThreadQ()->printActionQ();
231  tty->print("\n");
232}
233#endif
234
235void PlaceholderEntry::verify() const {
236  guarantee(loader() == NULL || loader()->is_instance(),
237            "checking type of _loader");
238  guarantee(instanceKlass() == NULL
239            || Klass::cast(instanceKlass())->oop_is_instance(),
240            "checking type of instanceKlass result");
241  klass()->verify();
242}
243
244void PlaceholderTable::verify() {
245  int element_count = 0;
246  for (int pindex = 0; pindex < table_size(); pindex++) {
247    for (PlaceholderEntry* probe = bucket(pindex);
248                           probe != NULL;
249                           probe = probe->next()) {
250      probe->verify();
251      element_count++;  // both klasses and place holders count
252    }
253  }
254  guarantee(number_of_entries() == element_count,
255            "Verify of system dictionary failed");
256}
257
258
259#ifndef PRODUCT
260void PlaceholderTable::print() {
261  for (int pindex = 0; pindex < table_size(); pindex++) {
262    for (PlaceholderEntry* probe = bucket(pindex);
263                           probe != NULL;
264                           probe = probe->next()) {
265      if (Verbose) tty->print("%4d: ", pindex);
266      tty->print(" place holder ");
267
268      probe->print();
269      tty->cr();
270    }
271  }
272}
273#endif
274