comparison src/share/vm/classfile/placeholders.cpp @ 6725:da91efe96a93

6964458: Reimplement class meta-data storage to use native memory Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author coleenp
date Sat, 01 Sep 2012 13:25:18 -0400
parents d2a62e0f25eb
children 070d523b96a7
comparison
equal deleted inserted replaced
6724:36d1d483d5d6 6725:da91efe96a93
1 /* 1 /*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 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 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
30 #include "utilities/hashtable.inline.hpp" 30 #include "utilities/hashtable.inline.hpp"
31 31
32 // Placeholder methods 32 // Placeholder methods
33 33
34 PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name, 34 PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name,
35 oop loader, bool havesupername, 35 ClassLoaderData* loader_data,
36 bool havesupername,
36 Symbol* supername) { 37 Symbol* supername) {
37 PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::new_entry(hash, name); 38 PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::new_entry(hash, name);
38 // Hashtable with Symbol* literal must increment and decrement refcount. 39 // Hashtable with Symbol* literal must increment and decrement refcount.
39 name->increment_refcount(); 40 name->increment_refcount();
40 entry->set_loader(loader); 41 entry->set_loader_data(loader_data);
41 entry->set_havesupername(havesupername); 42 entry->set_havesupername(havesupername);
42 entry->set_supername(supername); 43 entry->set_supername(supername);
43 entry->set_superThreadQ(NULL); 44 entry->set_superThreadQ(NULL);
44 entry->set_loadInstanceThreadQ(NULL); 45 entry->set_loadInstanceThreadQ(NULL);
45 entry->set_defineThreadQ(NULL); 46 entry->set_defineThreadQ(NULL);
59 // Placeholder objects represent classes currently being loaded. 60 // Placeholder objects represent classes currently being loaded.
60 // All threads examining the placeholder table must hold the 61 // All threads examining the placeholder table must hold the
61 // SystemDictionary_lock, so we don't need special precautions 62 // SystemDictionary_lock, so we don't need special precautions
62 // on store ordering here. 63 // on store ordering here.
63 void PlaceholderTable::add_entry(int index, unsigned int hash, 64 void PlaceholderTable::add_entry(int index, unsigned int hash,
64 Symbol* class_name, Handle class_loader, 65 Symbol* class_name, ClassLoaderData* loader_data,
65 bool havesupername, Symbol* supername){ 66 bool havesupername, Symbol* supername){
66 assert_locked_or_safepoint(SystemDictionary_lock); 67 assert_locked_or_safepoint(SystemDictionary_lock);
67 assert(class_name != NULL, "adding NULL obj"); 68 assert(class_name != NULL, "adding NULL obj");
68 69
69 // Both readers and writers are locked so it's safe to just 70 // Both readers and writers are locked so it's safe to just
70 // create the placeholder and insert it in the list without a membar. 71 // create the placeholder and insert it in the list without a membar.
71 PlaceholderEntry* entry = new_entry(hash, class_name, class_loader(), havesupername, supername); 72 PlaceholderEntry* entry = new_entry(hash, class_name, loader_data, havesupername, supername);
72 add_entry(index, entry); 73 add_entry(index, entry);
73 } 74 }
74 75
75 76
76 // Remove a placeholder object. 77 // Remove a placeholder object.
77 void PlaceholderTable::remove_entry(int index, unsigned int hash, 78 void PlaceholderTable::remove_entry(int index, unsigned int hash,
78 Symbol* class_name, 79 Symbol* class_name,
79 Handle class_loader) { 80 ClassLoaderData* loader_data) {
80 assert_locked_or_safepoint(SystemDictionary_lock); 81 assert_locked_or_safepoint(SystemDictionary_lock);
81 PlaceholderEntry** p = bucket_addr(index); 82 PlaceholderEntry** p = bucket_addr(index);
82 while (*p) { 83 while (*p) {
83 PlaceholderEntry *probe = *p; 84 PlaceholderEntry *probe = *p;
84 if (probe->hash() == hash && probe->equals(class_name, class_loader())) { 85 if (probe->hash() == hash && probe->equals(class_name, loader_data)) {
85 // Delete entry 86 // Delete entry
86 *p = probe->next(); 87 *p = probe->next();
87 free_entry(probe); 88 free_entry(probe);
88 return; 89 return;
89 } 90 }
91 } 92 }
92 } 93 }
93 94
94 PlaceholderEntry* PlaceholderTable::get_entry(int index, unsigned int hash, 95 PlaceholderEntry* PlaceholderTable::get_entry(int index, unsigned int hash,
95 Symbol* class_name, 96 Symbol* class_name,
96 Handle class_loader) { 97 ClassLoaderData* loader_data) {
97 assert_locked_or_safepoint(SystemDictionary_lock); 98 assert_locked_or_safepoint(SystemDictionary_lock);
98
99 oop class_loader_ = class_loader();
100 99
101 for (PlaceholderEntry *place_probe = bucket(index); 100 for (PlaceholderEntry *place_probe = bucket(index);
102 place_probe != NULL; 101 place_probe != NULL;
103 place_probe = place_probe->next()) { 102 place_probe = place_probe->next()) {
104 if (place_probe->hash() == hash && 103 if (place_probe->hash() == hash &&
105 place_probe->equals(class_name, class_loader_)) { 104 place_probe->equals(class_name, loader_data)) {
106 return place_probe; 105 return place_probe;
107 } 106 }
108 } 107 }
109 return NULL; 108 return NULL;
110 } 109 }
111 110
112 Symbol* PlaceholderTable::find_entry(int index, unsigned int hash, 111 Symbol* PlaceholderTable::find_entry(int index, unsigned int hash,
113 Symbol* class_name, 112 Symbol* class_name,
114 Handle class_loader) { 113 ClassLoaderData* loader_data) {
115 PlaceholderEntry* probe = get_entry(index, hash, class_name, class_loader); 114 PlaceholderEntry* probe = get_entry(index, hash, class_name, loader_data);
116 return (probe? probe->klassname(): (Symbol*)NULL); 115 return (probe? probe->klassname(): (Symbol*)NULL);
117 } 116 }
118 117
119 // find_and_add returns probe pointer - old or new 118 // find_and_add returns probe pointer - old or new
120 // If no entry exists, add a placeholder entry 119 // If no entry exists, add a placeholder entry
121 // If entry exists, reuse entry 120 // If entry exists, reuse entry
122 // For both, push SeenThread for classloadAction 121 // For both, push SeenThread for classloadAction
123 // if havesupername: this is used for circularity for instanceklass loading 122 // if havesupername: this is used for circularity for instanceklass loading
124 PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, Symbol* name, Handle loader, classloadAction action, Symbol* supername, Thread* thread) { 123 PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash,
125 PlaceholderEntry* probe = get_entry(index, hash, name, loader); 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);
126 if (probe == NULL) { 130 if (probe == NULL) {
127 // Nothing found, add place holder 131 // Nothing found, add place holder
128 add_entry(index, hash, name, loader, (action == LOAD_SUPER), supername); 132 add_entry(index, hash, name, loader_data, (action == LOAD_SUPER), supername);
129 probe = get_entry(index, hash, name, loader); 133 probe = get_entry(index, hash, name, loader_data);
130 } else { 134 } else {
131 if (action == LOAD_SUPER) { 135 if (action == LOAD_SUPER) {
132 probe->set_havesupername(true); 136 probe->set_havesupername(true);
133 probe->set_supername(supername); 137 probe->set_supername(supername);
134 } 138 }
151 // Note: you can be in both placeholders and systemDictionary 155 // Note: you can be in both placeholders and systemDictionary
152 // see parse_stream for redefine classes 156 // see parse_stream for redefine classes
153 // Therefore - must always check SD first 157 // Therefore - must always check SD first
154 // Ignores the case where entry is not found 158 // Ignores the case where entry is not found
155 void PlaceholderTable::find_and_remove(int index, unsigned int hash, 159 void PlaceholderTable::find_and_remove(int index, unsigned int hash,
156 Symbol* name, Handle loader, Thread* thread) { 160 Symbol* name, ClassLoaderData* loader_data, Thread* thread) {
157 assert_locked_or_safepoint(SystemDictionary_lock); 161 assert_locked_or_safepoint(SystemDictionary_lock);
158 PlaceholderEntry *probe = get_entry(index, hash, name, loader); 162 PlaceholderEntry *probe = get_entry(index, hash, name, loader_data);
159 if (probe != NULL) { 163 if (probe != NULL) {
160 // No other threads using this entry 164 // No other threads using this entry
161 if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL) 165 if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL)
162 && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) { 166 && (probe->defineThreadQ() == NULL) && (probe->definer() == NULL)) {
163 remove_entry(index, hash, name, loader); 167 remove_entry(index, hash, name, loader_data);
164 } 168 }
165 } 169 }
166 } 170 }
167 171
168 PlaceholderTable::PlaceholderTable(int table_size) 172 PlaceholderTable::PlaceholderTable(int table_size)
169 : TwoOopHashtable<Symbol*, mtClass>(table_size, sizeof(PlaceholderEntry)) { 173 : TwoOopHashtable<Symbol*, mtClass>(table_size, sizeof(PlaceholderEntry)) {
170 } 174 }
171 175
172 176
173 void PlaceholderTable::oops_do(OopClosure* f) { 177 void PlaceholderTable::classes_do(KlassClosure* f) {
174 for (int index = 0; index < table_size(); index++) { 178 for (int index = 0; index < table_size(); index++) {
175 for (PlaceholderEntry* probe = bucket(index); 179 for (PlaceholderEntry* probe = bucket(index);
176 probe != NULL; 180 probe != NULL;
177 probe = probe->next()) { 181 probe = probe->next()) {
178 probe->oops_do(f); 182 probe->classes_do(f);
179 } 183 }
180 } 184 }
181 } 185 }
182 186
183 187
184 void PlaceholderEntry::oops_do(OopClosure* blk) { 188 void PlaceholderEntry::classes_do(KlassClosure* closure) {
185 assert(klassname() != NULL, "should have a non-null klass"); 189 assert(klassname() != NULL, "should have a non-null klass");
186 if (_loader != NULL) {
187 blk->do_oop(loader_addr());
188 }
189 if (_instanceKlass != NULL) { 190 if (_instanceKlass != NULL) {
190 blk->do_oop((oop*)instanceKlass_addr()); 191 closure->do_klass(InstanceKlass());
191 } 192 }
192 } 193 }
193 194
194 // do all entries in the placeholder table 195 // do all entries in the placeholder table
195 void PlaceholderTable::entries_do(void f(Symbol*, oop)) { 196 void PlaceholderTable::entries_do(void f(Symbol*)) {
196 for (int index = 0; index < table_size(); index++) { 197 for (int index = 0; index < table_size(); index++) {
197 for (PlaceholderEntry* probe = bucket(index); 198 for (PlaceholderEntry* probe = bucket(index);
198 probe != NULL; 199 probe != NULL;
199 probe = probe->next()) { 200 probe = probe->next()) {
200 f(probe->klassname(), probe->loader()); 201 f(probe->klassname());
201 } 202 }
202 } 203 }
203 } 204 }
204 205
205 206
206 #ifndef PRODUCT 207 #ifndef PRODUCT
207 // Note, doesn't append a cr 208 // Note, doesn't append a cr
208 void PlaceholderEntry::print() const { 209 void PlaceholderEntry::print() const {
209 klassname()->print_value(); 210 klassname()->print_value();
210 if (loader() != NULL) { 211 if (loader_data() != NULL) {
211 tty->print(", loader "); 212 tty->print(", loader ");
212 loader()->print_value(); 213 loader_data()->print_value();
213 } 214 }
214 if (supername() != NULL) { 215 if (supername() != NULL) {
215 tty->print(", supername "); 216 tty->print(", supername ");
216 supername()->print_value(); 217 supername()->print_value();
217 } 218 }
218 if (definer() != NULL) { 219 if (definer() != NULL) {
219 tty->print(", definer "); 220 tty->print(", definer ");
220 definer()->print_value(); 221 definer()->print_value();
221 } 222 }
222 if (instanceKlass() != NULL) { 223 if (InstanceKlass() != NULL) {
223 tty->print(", instanceKlass "); 224 tty->print(", InstanceKlass ");
224 instanceKlass()->print_value(); 225 InstanceKlass()->print_value();
225 } 226 }
226 tty->print("\n"); 227 tty->print("\n");
227 tty->print("loadInstanceThreadQ threads:"); 228 tty->print("loadInstanceThreadQ threads:");
228 loadInstanceThreadQ()->printActionQ(); 229 loadInstanceThreadQ()->printActionQ();
229 tty->print("\n"); 230 tty->print("\n");
235 tty->print("\n"); 236 tty->print("\n");
236 } 237 }
237 #endif 238 #endif
238 239
239 void PlaceholderEntry::verify() const { 240 void PlaceholderEntry::verify() const {
240 guarantee(loader() == NULL || loader()->is_instance(), 241 guarantee(loader_data() != NULL, "Must have been setup.");
242 guarantee(loader_data()->class_loader() == NULL || loader_data()->class_loader()->is_instance(),
241 "checking type of _loader"); 243 "checking type of _loader");
242 guarantee(instanceKlass() == NULL 244 guarantee(InstanceKlass() == NULL
243 || Klass::cast(instanceKlass())->oop_is_instance(), 245 || Klass::cast(InstanceKlass())->oop_is_instance(),
244 "checking type of instanceKlass result"); 246 "checking type of InstanceKlass result");
245 } 247 }
246 248
247 void PlaceholderTable::verify() { 249 void PlaceholderTable::verify() {
248 int element_count = 0; 250 int element_count = 0;
249 for (int pindex = 0; pindex < table_size(); pindex++) { 251 for (int pindex = 0; pindex < table_size(); pindex++) {