Mercurial > hg > truffle
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++) { |