comparison src/share/vm/classfile/placeholders.cpp @ 2177:3582bf76420e

6990754: Use native memory and reference counting to implement SymbolTable Summary: move symbols from permgen into C heap and reference count them Reviewed-by: never, acorn, jmasa, stefank
author coleenp
date Thu, 27 Jan 2011 16:11:27 -0800
parents f95d63e2154a
children 1d1603768966
comparison
equal deleted inserted replaced
2176:27e4ea99855d 2177:3582bf76420e
29 #include "runtime/fieldType.hpp" 29 #include "runtime/fieldType.hpp"
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, symbolOop name, 34 PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name,
35 oop loader, bool havesupername, 35 oop loader, bool havesupername,
36 symbolOop supername) { 36 Symbol* supername) {
37 PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable::new_entry(hash, name); 37 PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable<Symbol*>::new_entry(hash, name);
38 // Hashtable with Symbol* literal must increment and decrement refcount.
39 name->increment_refcount();
38 entry->set_loader(loader); 40 entry->set_loader(loader);
39 entry->set_havesupername(havesupername); 41 entry->set_havesupername(havesupername);
40 entry->set_supername(supername); 42 entry->set_supername(supername);
41 entry->set_superThreadQ(NULL); 43 entry->set_superThreadQ(NULL);
42 entry->set_loadInstanceThreadQ(NULL); 44 entry->set_loadInstanceThreadQ(NULL);
44 entry->set_definer(NULL); 46 entry->set_definer(NULL);
45 entry->set_instanceKlass(NULL); 47 entry->set_instanceKlass(NULL);
46 return entry; 48 return entry;
47 } 49 }
48 50
51 void PlaceholderTable::free_entry(PlaceholderEntry* entry) {
52 // decrement Symbol refcount here because Hashtable doesn't.
53 entry->literal()->decrement_refcount();
54 if (entry->supername() != NULL) entry->supername()->decrement_refcount();
55 Hashtable<Symbol*>::free_entry(entry);
56 }
57
49 58
50 // Placeholder objects represent classes currently being loaded. 59 // Placeholder objects represent classes currently being loaded.
51 // All threads examining the placeholder table must hold the 60 // All threads examining the placeholder table must hold the
52 // SystemDictionary_lock, so we don't need special precautions 61 // SystemDictionary_lock, so we don't need special precautions
53 // on store ordering here. 62 // on store ordering here.
54 void PlaceholderTable::add_entry(int index, unsigned int hash, 63 void PlaceholderTable::add_entry(int index, unsigned int hash,
55 symbolHandle class_name, Handle class_loader, 64 Symbol* class_name, Handle class_loader,
56 bool havesupername, symbolHandle supername){ 65 bool havesupername, Symbol* supername){
57 assert_locked_or_safepoint(SystemDictionary_lock); 66 assert_locked_or_safepoint(SystemDictionary_lock);
58 assert(!class_name.is_null(), "adding NULL obj"); 67 assert(class_name != NULL, "adding NULL obj");
59 68
60 // Both readers and writers are locked so it's safe to just 69 // 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. 70 // create the placeholder and insert it in the list without a membar.
62 PlaceholderEntry* entry = new_entry(hash, class_name(), class_loader(), havesupername, supername()); 71 PlaceholderEntry* entry = new_entry(hash, class_name, class_loader(), havesupername, supername);
63 add_entry(index, entry); 72 add_entry(index, entry);
64 } 73 }
65 74
66 75
67 // Remove a placeholder object. 76 // Remove a placeholder object.
68 void PlaceholderTable::remove_entry(int index, unsigned int hash, 77 void PlaceholderTable::remove_entry(int index, unsigned int hash,
69 symbolHandle class_name, 78 Symbol* class_name,
70 Handle class_loader) { 79 Handle class_loader) {
71 assert_locked_or_safepoint(SystemDictionary_lock); 80 assert_locked_or_safepoint(SystemDictionary_lock);
72 PlaceholderEntry** p = bucket_addr(index); 81 PlaceholderEntry** p = bucket_addr(index);
73 while (*p) { 82 while (*p) {
74 PlaceholderEntry *probe = *p; 83 PlaceholderEntry *probe = *p;
75 if (probe->hash() == hash && probe->equals(class_name(), class_loader())) { 84 if (probe->hash() == hash && probe->equals(class_name, class_loader())) {
76 // Delete entry 85 // Delete entry
77 *p = probe->next(); 86 *p = probe->next();
78 free_entry(probe); 87 free_entry(probe);
79 return; 88 return;
80 } 89 }
81 p = probe->next_addr(); 90 p = probe->next_addr();
82 } 91 }
83 } 92 }
84 93
85 PlaceholderEntry* PlaceholderTable::get_entry(int index, unsigned int hash, 94 PlaceholderEntry* PlaceholderTable::get_entry(int index, unsigned int hash,
86 symbolHandle class_name, 95 Symbol* class_name,
87 Handle class_loader) { 96 Handle class_loader) {
88 assert_locked_or_safepoint(SystemDictionary_lock); 97 assert_locked_or_safepoint(SystemDictionary_lock);
89 98
90 symbolOop class_name_ = class_name();
91 oop class_loader_ = class_loader(); 99 oop class_loader_ = class_loader();
92 100
93 for (PlaceholderEntry *place_probe = bucket(index); 101 for (PlaceholderEntry *place_probe = bucket(index);
94 place_probe != NULL; 102 place_probe != NULL;
95 place_probe = place_probe->next()) { 103 place_probe = place_probe->next()) {
96 if (place_probe->hash() == hash && 104 if (place_probe->hash() == hash &&
97 place_probe->equals(class_name_, class_loader_)) { 105 place_probe->equals(class_name, class_loader_)) {
98 return place_probe; 106 return place_probe;
99 } 107 }
100 } 108 }
101 return NULL; 109 return NULL;
102 } 110 }
103 111
104 symbolOop PlaceholderTable::find_entry(int index, unsigned int hash, 112 Symbol* PlaceholderTable::find_entry(int index, unsigned int hash,
105 symbolHandle class_name, 113 Symbol* class_name,
106 Handle class_loader) { 114 Handle class_loader) {
107 PlaceholderEntry* probe = get_entry(index, hash, class_name, class_loader); 115 PlaceholderEntry* probe = get_entry(index, hash, class_name, class_loader);
108 return (probe? probe->klass(): symbolOop(NULL)); 116 return (probe? probe->klassname(): (Symbol*)NULL);
109 } 117 }
110 118
111 // find_and_add returns probe pointer - old or new 119 // find_and_add returns probe pointer - old or new
112 // If no entry exists, add a placeholder entry 120 // If no entry exists, add a placeholder entry
113 // If entry exists, reuse entry 121 // If entry exists, reuse entry
114 // For both, push SeenThread for classloadAction 122 // For both, push SeenThread for classloadAction
115 // if havesupername: this is used for circularity for instanceklass loading 123 // if havesupername: this is used for circularity for instanceklass loading
116 PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, symbolHandle name, Handle loader, classloadAction action, symbolHandle supername, Thread* thread) { 124 PlaceholderEntry* PlaceholderTable::find_and_add(int index, unsigned int hash, Symbol* name, Handle loader, classloadAction action, Symbol* supername, Thread* thread) {
117 PlaceholderEntry* probe = get_entry(index, hash, name, loader); 125 PlaceholderEntry* probe = get_entry(index, hash, name, loader);
118 if (probe == NULL) { 126 if (probe == NULL) {
119 // Nothing found, add place holder 127 // Nothing found, add place holder
120 add_entry(index, hash, name, loader, (action == LOAD_SUPER), supername); 128 add_entry(index, hash, name, loader, (action == LOAD_SUPER), supername);
121 probe = get_entry(index, hash, name, loader); 129 probe = get_entry(index, hash, name, loader);
122 } else { 130 } else {
123 if (action == LOAD_SUPER) { 131 if (action == LOAD_SUPER) {
124 probe->set_havesupername(true); 132 probe->set_havesupername(true);
125 probe->set_supername(supername()); 133 probe->set_supername(supername);
126 } 134 }
127 } 135 }
128 if (probe) probe->add_seen_thread(thread, action); 136 if (probe) probe->add_seen_thread(thread, action);
129 return probe; 137 return probe;
130 } 138 }
143 // Note: you can be in both placeholders and systemDictionary 151 // Note: you can be in both placeholders and systemDictionary
144 // see parse_stream for redefine classes 152 // see parse_stream for redefine classes
145 // Therefore - must always check SD first 153 // Therefore - must always check SD first
146 // Ignores the case where entry is not found 154 // Ignores the case where entry is not found
147 void PlaceholderTable::find_and_remove(int index, unsigned int hash, 155 void PlaceholderTable::find_and_remove(int index, unsigned int hash,
148 symbolHandle name, Handle loader, Thread* thread) { 156 Symbol* name, Handle loader, Thread* thread) {
149 assert_locked_or_safepoint(SystemDictionary_lock); 157 assert_locked_or_safepoint(SystemDictionary_lock);
150 PlaceholderEntry *probe = get_entry(index, hash, name, loader); 158 PlaceholderEntry *probe = get_entry(index, hash, name, loader);
151 if (probe != NULL) { 159 if (probe != NULL) {
152 // No other threads using this entry 160 // No other threads using this entry
153 if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL) 161 if ((probe->superThreadQ() == NULL) && (probe->loadInstanceThreadQ() == NULL)
156 } 164 }
157 } 165 }
158 } 166 }
159 167
160 PlaceholderTable::PlaceholderTable(int table_size) 168 PlaceholderTable::PlaceholderTable(int table_size)
161 : TwoOopHashtable(table_size, sizeof(PlaceholderEntry)) { 169 : TwoOopHashtable<Symbol*>(table_size, sizeof(PlaceholderEntry)) {
162 } 170 }
163 171
164 172
165 void PlaceholderTable::oops_do(OopClosure* f) { 173 void PlaceholderTable::oops_do(OopClosure* f) {
166 for (int index = 0; index < table_size(); index++) { 174 for (int index = 0; index < table_size(); index++) {
172 } 180 }
173 } 181 }
174 182
175 183
176 void PlaceholderEntry::oops_do(OopClosure* blk) { 184 void PlaceholderEntry::oops_do(OopClosure* blk) {
177 assert(klass() != NULL, "should have a non-null klass"); 185 assert(klassname() != NULL, "should have a non-null klass");
178 blk->do_oop((oop*)klass_addr());
179 if (_loader != NULL) { 186 if (_loader != NULL) {
180 blk->do_oop(loader_addr()); 187 blk->do_oop(loader_addr());
181 } 188 }
182 if (_supername != NULL) {
183 blk->do_oop((oop*)supername_addr());
184 }
185 if (_instanceKlass != NULL) { 189 if (_instanceKlass != NULL) {
186 blk->do_oop((oop*)instanceKlass_addr()); 190 blk->do_oop((oop*)instanceKlass_addr());
187 } 191 }
188 } 192 }
189 193
190 // do all entries in the placeholder table 194 // do all entries in the placeholder table
191 void PlaceholderTable::entries_do(void f(symbolOop, oop)) { 195 void PlaceholderTable::entries_do(void f(Symbol*, oop)) {
192 for (int index = 0; index < table_size(); index++) { 196 for (int index = 0; index < table_size(); index++) {
193 for (PlaceholderEntry* probe = bucket(index); 197 for (PlaceholderEntry* probe = bucket(index);
194 probe != NULL; 198 probe != NULL;
195 probe = probe->next()) { 199 probe = probe->next()) {
196 f(probe->klass(), probe->loader()); 200 f(probe->klassname(), probe->loader());
197 } 201 }
198 } 202 }
199 } 203 }
200 204
201 205
202 #ifndef PRODUCT 206 #ifndef PRODUCT
203 // Note, doesn't append a cr 207 // Note, doesn't append a cr
204 void PlaceholderEntry::print() const { 208 void PlaceholderEntry::print() const {
205 klass()->print_value(); 209 klassname()->print_value();
206 if (loader() != NULL) { 210 if (loader() != NULL) {
207 tty->print(", loader "); 211 tty->print(", loader ");
208 loader()->print_value(); 212 loader()->print_value();
209 } 213 }
210 if (supername() != NULL) { 214 if (supername() != NULL) {
236 guarantee(loader() == NULL || loader()->is_instance(), 240 guarantee(loader() == NULL || loader()->is_instance(),
237 "checking type of _loader"); 241 "checking type of _loader");
238 guarantee(instanceKlass() == NULL 242 guarantee(instanceKlass() == NULL
239 || Klass::cast(instanceKlass())->oop_is_instance(), 243 || Klass::cast(instanceKlass())->oop_is_instance(),
240 "checking type of instanceKlass result"); 244 "checking type of instanceKlass result");
241 klass()->verify();
242 } 245 }
243 246
244 void PlaceholderTable::verify() { 247 void PlaceholderTable::verify() {
245 int element_count = 0; 248 int element_count = 0;
246 for (int pindex = 0; pindex < table_size(); pindex++) { 249 for (int pindex = 0; pindex < table_size(); pindex++) {