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