comparison src/share/vm/classfile/loaderConstraints.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.
21 * questions. 21 * questions.
22 * 22 *
23 */ 23 */
24 24
25 #include "precompiled.hpp" 25 #include "precompiled.hpp"
26 #include "classfile/classLoaderData.inline.hpp"
26 #include "classfile/loaderConstraints.hpp" 27 #include "classfile/loaderConstraints.hpp"
27 #include "memory/resourceArea.hpp" 28 #include "memory/resourceArea.hpp"
28 #include "oops/oop.inline.hpp" 29 #include "oops/oop.inline.hpp"
29 #include "runtime/handles.inline.hpp" 30 #include "runtime/handles.inline.hpp"
30 #include "runtime/safepoint.hpp" 31 #include "runtime/safepoint.hpp"
31 #include "utilities/hashtable.inline.hpp" 32 #include "utilities/hashtable.inline.hpp"
32 33
34 void LoaderConstraintEntry::set_loader(int i, oop p) {
35 set_loader_data(i, ClassLoaderData::class_loader_data(p));
36 }
37
33 LoaderConstraintTable::LoaderConstraintTable(int nof_buckets) 38 LoaderConstraintTable::LoaderConstraintTable(int nof_buckets)
34 : Hashtable<klassOop, mtClass>(nof_buckets, sizeof(LoaderConstraintEntry)) {}; 39 : Hashtable<Klass*, mtClass>(nof_buckets, sizeof(LoaderConstraintEntry)) {};
35 40
36 41
37 LoaderConstraintEntry* LoaderConstraintTable::new_entry( 42 LoaderConstraintEntry* LoaderConstraintTable::new_entry(
38 unsigned int hash, Symbol* name, 43 unsigned int hash, Symbol* name,
39 klassOop klass, int num_loaders, 44 Klass* klass, int num_loaders,
40 int max_loaders) { 45 int max_loaders) {
41 LoaderConstraintEntry* entry; 46 LoaderConstraintEntry* entry;
42 entry = (LoaderConstraintEntry*)Hashtable<klassOop, mtClass>::new_entry(hash, klass); 47 entry = (LoaderConstraintEntry*)Hashtable<Klass*, mtClass>::new_entry(hash, klass);
43 entry->set_name(name); 48 entry->set_name(name);
44 entry->set_num_loaders(num_loaders); 49 entry->set_num_loaders(num_loaders);
45 entry->set_max_loaders(max_loaders); 50 entry->set_max_loaders(max_loaders);
46 return entry; 51 return entry;
47 } 52 }
48 53
49 void LoaderConstraintTable::free_entry(LoaderConstraintEntry *entry) { 54 void LoaderConstraintTable::free_entry(LoaderConstraintEntry *entry) {
50 // decrement name refcount before freeing 55 // decrement name refcount before freeing
51 entry->name()->decrement_refcount(); 56 entry->name()->decrement_refcount();
52 Hashtable<klassOop, mtClass>::free_entry(entry); 57 Hashtable<Klass*, mtClass>::free_entry(entry);
53 } 58 }
54 59
55 60 // Enhanced Class Redefinition support
56 void LoaderConstraintTable::oops_do(OopClosure* f) { 61 void LoaderConstraintTable::classes_do(KlassClosure* f) {
57 for (int index = 0; index < table_size(); index++) { 62 for (int index = 0; index < table_size(); index++) {
58 for (LoaderConstraintEntry* probe = bucket(index); 63 for (LoaderConstraintEntry* probe = bucket(index);
59 probe != NULL; 64 probe != NULL;
60 probe = probe->next()) { 65 probe = probe->next()) {
61 if (probe->klass() != NULL) { 66 if (probe->klass() != NULL) {
62 f->do_oop((oop*)probe->klass_addr()); 67 f->do_klass(probe->klass());
63 } 68 }
64 for (int n = 0; n < probe->num_loaders(); n++) { 69 }
65 if (probe->loader(n) != NULL) { 70 }
66 f->do_oop(probe->loader_addr(n)); 71 }
67 }
68 }
69 }
70 }
71 }
72
73 72
74 // The loaderConstraintTable must always be accessed with the 73 // The loaderConstraintTable must always be accessed with the
75 // SystemDictionary lock held. This is true even for readers as 74 // SystemDictionary lock held. This is true even for readers as
76 // entries in the table could be being dynamically resized. 75 // entries in the table could be being dynamically resized.
77 76
79 Symbol* name, Handle loader) { 78 Symbol* name, Handle loader) {
80 79
81 unsigned int hash = compute_hash(name); 80 unsigned int hash = compute_hash(name);
82 int index = hash_to_index(hash); 81 int index = hash_to_index(hash);
83 LoaderConstraintEntry** pp = bucket_addr(index); 82 LoaderConstraintEntry** pp = bucket_addr(index);
83 ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(loader());
84
84 while (*pp) { 85 while (*pp) {
85 LoaderConstraintEntry* p = *pp; 86 LoaderConstraintEntry* p = *pp;
86 if (p->hash() == hash) { 87 if (p->hash() == hash) {
87 if (p->name() == name) { 88 if (p->name() == name) {
88 for (int i = p->num_loaders() - 1; i >= 0; i--) { 89 for (int i = p->num_loaders() - 1; i >= 0; i--) {
89 if (p->loader(i) == loader()) { 90 if (p->loader_data(i) == loader_data) {
90 return pp; 91 return pp;
91 } 92 }
92 } 93 }
93 } 94 }
94 } 95 }
96 } 97 }
97 return pp; 98 return pp;
98 } 99 }
99 100
100 101
101 void LoaderConstraintTable::purge_loader_constraints(BoolObjectClosure* is_alive) { 102 void LoaderConstraintTable::purge_loader_constraints() {
102 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 103 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
103 // Remove unloaded entries from constraint table 104 // Remove unloaded entries from constraint table
104 for (int index = 0; index < table_size(); index++) { 105 for (int index = 0; index < table_size(); index++) {
105 LoaderConstraintEntry** p = bucket_addr(index); 106 LoaderConstraintEntry** p = bucket_addr(index);
106 while(*p) { 107 while(*p) {
107 LoaderConstraintEntry* probe = *p; 108 LoaderConstraintEntry* probe = *p;
108 klassOop klass = probe->klass(); 109 Klass* klass = probe->klass();
109 // Remove klass that is no longer alive 110 // Remove klass that is no longer alive
110 if (klass != NULL && !is_alive->do_object_b(klass)) { 111 if (klass != NULL &&
112 klass->class_loader_data()->is_unloading()) {
111 probe->set_klass(NULL); 113 probe->set_klass(NULL);
112 if (TraceLoaderConstraints) { 114 if (TraceLoaderConstraints) {
113 ResourceMark rm; 115 ResourceMark rm;
114 tty->print_cr("[Purging class object from constraint for name %s," 116 tty->print_cr("[Purging class object from constraint for name %s,"
115 " loader list:", 117 " loader list:",
116 probe->name()->as_C_string()); 118 probe->name()->as_C_string());
117 for (int i = 0; i < probe->num_loaders(); i++) { 119 for (int i = 0; i < probe->num_loaders(); i++) {
118 tty->print_cr("[ [%d]: %s", i, 120 tty->print_cr("[ [%d]: %s", i,
119 SystemDictionary::loader_name(probe->loader(i))); 121 SystemDictionary::loader_name(probe->loader_data(i)));
120 } 122 }
121 } 123 }
122 } 124 }
123 // Remove entries no longer alive from loader array 125 // Remove entries no longer alive from loader array
124 int n = 0; 126 int n = 0;
125 while (n < probe->num_loaders()) { 127 while (n < probe->num_loaders()) {
126 if (probe->loader(n) != NULL) { 128 if (probe->loader_data(n)->is_unloading()) {
127 if (!is_alive->do_object_b(probe->loader(n))) {
128 if (TraceLoaderConstraints) { 129 if (TraceLoaderConstraints) {
129 ResourceMark rm; 130 ResourceMark rm;
130 tty->print_cr("[Purging loader %s from constraint for name %s", 131 tty->print_cr("[Purging loader %s from constraint for name %s",
131 SystemDictionary::loader_name(probe->loader(n)), 132 SystemDictionary::loader_name(probe->loader_data(n)),
132 probe->name()->as_C_string() 133 probe->name()->as_C_string()
133 ); 134 );
134 } 135 }
135 136
136 // Compact array 137 // Compact array
137 int num = probe->num_loaders() - 1; 138 int num = probe->num_loaders() - 1;
138 probe->set_num_loaders(num); 139 probe->set_num_loaders(num);
139 probe->set_loader(n, probe->loader(num)); 140 probe->set_loader_data(n, probe->loader_data(num));
140 probe->set_loader(num, NULL); 141 probe->set_loader_data(num, NULL);
141 142
142 if (TraceLoaderConstraints) { 143 if (TraceLoaderConstraints) {
143 ResourceMark rm; 144 ResourceMark rm;
144 tty->print_cr("[New loader list:"); 145 tty->print_cr("[New loader list:");
145 for (int i = 0; i < probe->num_loaders(); i++) { 146 for (int i = 0; i < probe->num_loaders(); i++) {
146 tty->print_cr("[ [%d]: %s", i, 147 tty->print_cr("[ [%d]: %s", i,
147 SystemDictionary::loader_name(probe->loader(i))); 148 SystemDictionary::loader_name(probe->loader_data(i)));
148 } 149 }
149 } 150 }
150 151
151 continue; // current element replaced, so restart without 152 continue; // current element replaced, so restart without
152 // incrementing n 153 // incrementing n
153 } 154 }
154 }
155 n++; 155 n++;
156 } 156 }
157 // Check whether entry should be purged 157 // Check whether entry should be purged
158 if (probe->num_loaders() < 2) { 158 if (probe->num_loaders() < 2) {
159 if (TraceLoaderConstraints) { 159 if (TraceLoaderConstraints) {
167 FREE_C_HEAP_ARRAY(oop, probe->loaders(), mtClass); 167 FREE_C_HEAP_ARRAY(oop, probe->loaders(), mtClass);
168 free_entry(probe); 168 free_entry(probe);
169 } else { 169 } else {
170 #ifdef ASSERT 170 #ifdef ASSERT
171 if (probe->klass() != NULL) { 171 if (probe->klass() != NULL) {
172 assert(is_alive->do_object_b(probe->klass()), "klass should be live"); 172 ClassLoaderData* loader_data =
173 } 173 probe->klass()->class_loader_data();
174 for (n = 0; n < probe->num_loaders(); n++) { 174 assert(!loader_data->is_unloading(), "klass should be live");
175 if (probe->loader(n) != NULL) {
176 assert(is_alive->do_object_b(probe->loader(n)), "loader should be live");
177 }
178 } 175 }
179 #endif 176 #endif
180 // Go to next entry 177 // Go to next entry
181 p = probe->next_addr(); 178 p = probe->next_addr();
182 } 179 }
183 } 180 }
184 } 181 }
185 } 182 }
186 183
187 bool LoaderConstraintTable::add_entry(Symbol* class_name, 184 bool LoaderConstraintTable::add_entry(Symbol* class_name,
188 klassOop klass1, Handle class_loader1, 185 Klass* klass1, Handle class_loader1,
189 klassOop klass2, Handle class_loader2) { 186 Klass* klass2, Handle class_loader2) {
190 int failure_code = 0; // encode different reasons for failing 187 int failure_code = 0; // encode different reasons for failing
191 188
192 if (klass1 != NULL && klass2 != NULL && klass1 != klass2) { 189 if (klass1 != NULL && klass2 != NULL && klass1 != klass2) {
193 failure_code = 1; 190 failure_code = 1;
194 } else { 191 } else {
195 klassOop klass = klass1 != NULL ? klass1 : klass2; 192 Klass* klass = klass1 != NULL ? klass1 : klass2;
196 193
197 LoaderConstraintEntry** pp1 = find_loader_constraint(class_name, 194 LoaderConstraintEntry** pp1 = find_loader_constraint(class_name,
198 class_loader1); 195 class_loader1);
199 if (*pp1 != NULL && (*pp1)->klass() != NULL) { 196 if (*pp1 != NULL && (*pp1)->klass() != NULL) {
200 if (klass != NULL) { 197 if (klass != NULL) {
222 if (*pp1 == NULL && *pp2 == NULL) { 219 if (*pp1 == NULL && *pp2 == NULL) {
223 unsigned int hash = compute_hash(class_name); 220 unsigned int hash = compute_hash(class_name);
224 int index = hash_to_index(hash); 221 int index = hash_to_index(hash);
225 LoaderConstraintEntry* p; 222 LoaderConstraintEntry* p;
226 p = new_entry(hash, class_name, klass, 2, 2); 223 p = new_entry(hash, class_name, klass, 2, 2);
227 p->set_loaders(NEW_C_HEAP_ARRAY(oop, 2, mtClass)); 224 p->set_loaders(NEW_C_HEAP_ARRAY(ClassLoaderData*, 2, mtClass));
228 p->set_loader(0, class_loader1()); 225 p->set_loader(0, class_loader1());
229 p->set_loader(1, class_loader2()); 226 p->set_loader(1, class_loader2());
230 p->set_klass(klass); 227 p->set_klass(klass);
231 p->set_next(bucket(index)); 228 p->set_next(bucket(index));
232 set_entry(index, p); 229 set_entry(index, p);
317 } 314 }
318 return true; 315 return true;
319 } 316 }
320 } 317 }
321 318
322 klassOop LoaderConstraintTable::find_constrained_klass(Symbol* name, 319 Klass* LoaderConstraintTable::find_constrained_klass(Symbol* name,
323 Handle loader) { 320 Handle loader) {
324 LoaderConstraintEntry *p = *(find_loader_constraint(name, loader)); 321 LoaderConstraintEntry *p = *(find_loader_constraint(name, loader));
325 if (p != NULL && p->klass() != NULL) { 322 if (p != NULL && p->klass() != NULL) {
326 if (Klass::cast(p->klass())->oop_is_instance() && !instanceKlass::cast(p->klass())->is_loaded()) { 323 if (Klass::cast(p->klass())->oop_is_instance() && !InstanceKlass::cast(p->klass())->is_loaded()) {
327 // Only return fully loaded classes. Classes found through the 324 // Only return fully loaded classes. Classes found through the
328 // constraints might still be in the process of loading. 325 // constraints might still be in the process of loading.
329 return NULL; 326 return NULL;
330 } 327 }
331 return p->klass(); 328 return p->klass();
338 void LoaderConstraintTable::ensure_loader_constraint_capacity( 335 void LoaderConstraintTable::ensure_loader_constraint_capacity(
339 LoaderConstraintEntry *p, 336 LoaderConstraintEntry *p,
340 int nfree) { 337 int nfree) {
341 if (p->max_loaders() - p->num_loaders() < nfree) { 338 if (p->max_loaders() - p->num_loaders() < nfree) {
342 int n = nfree + p->num_loaders(); 339 int n = nfree + p->num_loaders();
343 oop* new_loaders = NEW_C_HEAP_ARRAY(oop, n, mtClass); 340 ClassLoaderData** new_loaders = NEW_C_HEAP_ARRAY(ClassLoaderData*, n, mtClass);
344 memcpy(new_loaders, p->loaders(), sizeof(oop) * p->num_loaders()); 341 memcpy(new_loaders, p->loaders(), sizeof(ClassLoaderData*) * p->num_loaders());
345 p->set_max_loaders(n); 342 p->set_max_loaders(n);
346 FREE_C_HEAP_ARRAY(oop, p->loaders(), mtClass); 343 FREE_C_HEAP_ARRAY(ClassLoaderData*, p->loaders(), mtClass);
347 p->set_loaders(new_loaders); 344 p->set_loaders(new_loaders);
348 } 345 }
349 } 346 }
350 347
351 348
352 void LoaderConstraintTable::extend_loader_constraint(LoaderConstraintEntry* p, 349 void LoaderConstraintTable::extend_loader_constraint(LoaderConstraintEntry* p,
353 Handle loader, 350 Handle loader,
354 klassOop klass) { 351 Klass* klass) {
355 ensure_loader_constraint_capacity(p, 1); 352 ensure_loader_constraint_capacity(p, 1);
356 int num = p->num_loaders(); 353 int num = p->num_loaders();
357 p->set_loader(num, loader()); 354 p->set_loader(num, loader());
358 p->set_num_loaders(num + 1); 355 p->set_num_loaders(num + 1);
359 if (TraceLoaderConstraints) { 356 if (TraceLoaderConstraints) {
374 371
375 372
376 void LoaderConstraintTable::merge_loader_constraints( 373 void LoaderConstraintTable::merge_loader_constraints(
377 LoaderConstraintEntry** pp1, 374 LoaderConstraintEntry** pp1,
378 LoaderConstraintEntry** pp2, 375 LoaderConstraintEntry** pp2,
379 klassOop klass) { 376 Klass* klass) {
380 // make sure *pp1 has higher capacity 377 // make sure *pp1 has higher capacity
381 if ((*pp1)->max_loaders() < (*pp2)->max_loaders()) { 378 if ((*pp1)->max_loaders() < (*pp2)->max_loaders()) {
382 LoaderConstraintEntry** tmp = pp2; 379 LoaderConstraintEntry** tmp = pp2;
383 pp2 = pp1; 380 pp2 = pp1;
384 pp1 = tmp; 381 pp1 = tmp;
389 386
390 ensure_loader_constraint_capacity(p1, p2->num_loaders()); 387 ensure_loader_constraint_capacity(p1, p2->num_loaders());
391 388
392 for (int i = 0; i < p2->num_loaders(); i++) { 389 for (int i = 0; i < p2->num_loaders(); i++) {
393 int num = p1->num_loaders(); 390 int num = p1->num_loaders();
394 p1->set_loader(num, p2->loader(i)); 391 p1->set_loader_data(num, p2->loader_data(i));
395 p1->set_num_loaders(num + 1); 392 p1->set_num_loaders(num + 1);
396 } 393 }
397 394
398 if (TraceLoaderConstraints) { 395 if (TraceLoaderConstraints) {
399 ResourceMark rm; 396 ResourceMark rm;
401 p1->name()->as_C_string() 398 p1->name()->as_C_string()
402 ); 399 );
403 400
404 for (int i = 0; i < p1->num_loaders(); i++) { 401 for (int i = 0; i < p1->num_loaders(); i++) {
405 tty->print_cr("[ [%d]: %s", i, 402 tty->print_cr("[ [%d]: %s", i,
406 SystemDictionary::loader_name(p1->loader(i))); 403 SystemDictionary::loader_name(p1->loader_data(i)));
407 } 404 }
408 if (p1->klass() == NULL) { 405 if (p1->klass() == NULL) {
409 tty->print_cr("[... and setting class object]"); 406 tty->print_cr("[... and setting class object]");
410 } 407 }
411 } 408 }
437 for (int cindex = 0; cindex < _loader_constraint_size; cindex++) { 434 for (int cindex = 0; cindex < _loader_constraint_size; cindex++) {
438 for (LoaderConstraintEntry* probe = bucket(cindex); 435 for (LoaderConstraintEntry* probe = bucket(cindex);
439 probe != NULL; 436 probe != NULL;
440 probe = probe->next()) { 437 probe = probe->next()) {
441 if (probe->klass() != NULL) { 438 if (probe->klass() != NULL) {
442 instanceKlass* ik = instanceKlass::cast(probe->klass()); 439 InstanceKlass* ik = InstanceKlass::cast(probe->klass());
443 guarantee(ik->name() == probe->name(), "name should match"); 440 guarantee(ik->name() == probe->name(), "name should match");
444 Symbol* name = ik->name(); 441 Symbol* name = ik->name();
445 Handle loader(thread, ik->class_loader()); 442 ClassLoaderData* loader_data = ik->class_loader_data();
446 unsigned int d_hash = dictionary->compute_hash(name, loader); 443 unsigned int d_hash = dictionary->compute_hash(name, loader_data);
447 int d_index = dictionary->hash_to_index(d_hash); 444 int d_index = dictionary->hash_to_index(d_hash);
448 klassOop k = dictionary->find_class(d_index, d_hash, name, loader); 445 Klass* k = dictionary->find_class(d_index, d_hash, name, loader_data);
449 if (k != NULL) { 446 if (k != NULL) {
450 // We found the class in the system dictionary, so we should 447 // We found the class in the system dictionary, so we should
451 // make sure that the klassOop matches what we already have. 448 // make sure that the Klass* matches what we already have.
452 guarantee(k == probe->klass(), "klass should be in dictionary"); 449 guarantee(k == probe->klass(), "klass should be in dictionary");
453 } else { 450 } else {
454 // If we don't find the class in the system dictionary, it 451 // If we don't find the class in the system dictionary, it
455 // has to be in the placeholders table. 452 // has to be in the placeholders table.
456 unsigned int p_hash = placeholders->compute_hash(name, loader); 453 unsigned int p_hash = placeholders->compute_hash(name, loader_data);
457 int p_index = placeholders->hash_to_index(p_hash); 454 int p_index = placeholders->hash_to_index(p_hash);
458 PlaceholderEntry* entry = placeholders->get_entry(p_index, p_hash, 455 PlaceholderEntry* entry = placeholders->get_entry(p_index, p_hash,
459 name, loader); 456 name, loader_data);
460 457
461 // The instanceKlass might not be on the entry, so the only 458 // The InstanceKlass might not be on the entry, so the only
462 // thing we can check here is whether we were successful in 459 // thing we can check here is whether we were successful in
463 // finding the class in the placeholders table. 460 // finding the class in the placeholders table.
464 guarantee(entry != NULL, "klass should be in the placeholders"); 461 guarantee(entry != NULL, "klass should be in the placeholders");
465 } 462 }
466 } 463 }
467 for (int n = 0; n< probe->num_loaders(); n++) { 464 for (int n = 0; n< probe->num_loaders(); n++) {
468 guarantee(probe->loader(n)->is_oop_or_null(), "should be oop"); 465 assert(ClassLoaderDataGraph::contains_loader_data(probe->loader_data(n)), "The loader is missing");
469 } 466 }
470 } 467 }
471 } 468 }
472 } 469 }
473 470
485 probe = probe->next()) { 482 probe = probe->next()) {
486 tty->print("%4d: ", cindex); 483 tty->print("%4d: ", cindex);
487 probe->name()->print(); 484 probe->name()->print();
488 tty->print(" , loaders:"); 485 tty->print(" , loaders:");
489 for (int n = 0; n < probe->num_loaders(); n++) { 486 for (int n = 0; n < probe->num_loaders(); n++) {
490 probe->loader(n)->print_value(); 487 probe->loader_data(n)->print_value();
491 tty->print(", "); 488 tty->print(", ");
492 } 489 }
493 tty->cr(); 490 tty->cr();
494 } 491 }
495 } 492 }