comparison src/share/vm/memory/referenceProcessor.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 aed758eda82a
comparison
equal deleted inserted replaced
6724:36d1d483d5d6 6725:da91efe96a93
1 /* 1 /*
2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2001, 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.
539 bool referent_is_dead = (iter.referent() != NULL) && !iter.is_referent_alive(); 539 bool referent_is_dead = (iter.referent() != NULL) && !iter.is_referent_alive();
540 if (referent_is_dead && 540 if (referent_is_dead &&
541 !policy->should_clear_reference(iter.obj(), _soft_ref_timestamp_clock)) { 541 !policy->should_clear_reference(iter.obj(), _soft_ref_timestamp_clock)) {
542 if (TraceReferenceGC) { 542 if (TraceReferenceGC) {
543 gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s" ") by policy", 543 gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s" ") by policy",
544 iter.obj(), iter.obj()->blueprint()->internal_name()); 544 iter.obj(), iter.obj()->klass()->internal_name());
545 } 545 }
546 // Remove Reference object from list 546 // Remove Reference object from list
547 iter.remove(); 547 iter.remove();
548 // Make the Reference object active again 548 // Make the Reference object active again
549 iter.make_active(); 549 iter.make_active();
578 DEBUG_ONLY(oop next = java_lang_ref_Reference::next(iter.obj());) 578 DEBUG_ONLY(oop next = java_lang_ref_Reference::next(iter.obj());)
579 assert(next == NULL, "Should not discover inactive Reference"); 579 assert(next == NULL, "Should not discover inactive Reference");
580 if (iter.is_referent_alive()) { 580 if (iter.is_referent_alive()) {
581 if (TraceReferenceGC) { 581 if (TraceReferenceGC) {
582 gclog_or_tty->print_cr("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)", 582 gclog_or_tty->print_cr("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)",
583 iter.obj(), iter.obj()->blueprint()->internal_name()); 583 iter.obj(), iter.obj()->klass()->internal_name());
584 } 584 }
585 // The referent is reachable after all. 585 // The referent is reachable after all.
586 // Remove Reference object from list. 586 // Remove Reference object from list.
587 iter.remove(); 587 iter.remove();
588 // Update the referent pointer as necessary: Note that this 588 // Update the referent pointer as necessary: Note that this
664 iter.make_referent_alive(); 664 iter.make_referent_alive();
665 } 665 }
666 if (TraceReferenceGC) { 666 if (TraceReferenceGC) {
667 gclog_or_tty->print_cr("Adding %sreference (" INTPTR_FORMAT ": %s) as pending", 667 gclog_or_tty->print_cr("Adding %sreference (" INTPTR_FORMAT ": %s) as pending",
668 clear_referent ? "cleared " : "", 668 clear_referent ? "cleared " : "",
669 iter.obj(), iter.obj()->blueprint()->internal_name()); 669 iter.obj(), iter.obj()->klass()->internal_name());
670 } 670 }
671 assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference"); 671 assert(iter.obj()->is_oop(UseConcMarkSweepGC), "Adding a bad reference");
672 iter.next(); 672 iter.next();
673 } 673 }
674 // Remember to update the next pointer of the last ref. 674 // Remember to update the next pointer of the last ref.
1079 _bs->write_ref_field((void*)discovered_addr, next_discovered); 1079 _bs->write_ref_field((void*)discovered_addr, next_discovered);
1080 } 1080 }
1081 1081
1082 if (TraceReferenceGC) { 1082 if (TraceReferenceGC) {
1083 gclog_or_tty->print_cr("Discovered reference (mt) (" INTPTR_FORMAT ": %s)", 1083 gclog_or_tty->print_cr("Discovered reference (mt) (" INTPTR_FORMAT ": %s)",
1084 obj, obj->blueprint()->internal_name()); 1084 obj, obj->klass()->internal_name());
1085 } 1085 }
1086 } else { 1086 } else {
1087 // If retest was non NULL, another thread beat us to it: 1087 // If retest was non NULL, another thread beat us to it:
1088 // The reference has already been discovered... 1088 // The reference has already been discovered...
1089 if (TraceReferenceGC) { 1089 if (TraceReferenceGC) {
1090 gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)", 1090 gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)",
1091 obj, obj->blueprint()->internal_name()); 1091 obj, obj->klass()->internal_name());
1092 } 1092 }
1093 } 1093 }
1094 } 1094 }
1095 1095
1096 #ifndef PRODUCT 1096 #ifndef PRODUCT
1181 assert(discovered->is_oop_or_null(), "bad discovered field"); 1181 assert(discovered->is_oop_or_null(), "bad discovered field");
1182 if (discovered != NULL) { 1182 if (discovered != NULL) {
1183 // The reference has already been discovered... 1183 // The reference has already been discovered...
1184 if (TraceReferenceGC) { 1184 if (TraceReferenceGC) {
1185 gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)", 1185 gclog_or_tty->print_cr("Already discovered reference (" INTPTR_FORMAT ": %s)",
1186 obj, obj->blueprint()->internal_name()); 1186 obj, obj->klass()->internal_name());
1187 } 1187 }
1188 if (RefDiscoveryPolicy == ReferentBasedDiscovery) { 1188 if (RefDiscoveryPolicy == ReferentBasedDiscovery) {
1189 // assumes that an object is not processed twice; 1189 // assumes that an object is not processed twice;
1190 // if it's been already discovered it must be on another 1190 // if it's been already discovered it must be on another
1191 // generation's discovered list; so we won't discover it. 1191 // generation's discovered list; so we won't discover it.
1249 list->set_head(obj); 1249 list->set_head(obj);
1250 list->inc_length(1); 1250 list->inc_length(1);
1251 1251
1252 if (TraceReferenceGC) { 1252 if (TraceReferenceGC) {
1253 gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)", 1253 gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)",
1254 obj, obj->blueprint()->internal_name()); 1254 obj, obj->klass()->internal_name());
1255 } 1255 }
1256 } 1256 }
1257 assert(obj->is_oop(), "Discovered a bad reference"); 1257 assert(obj->is_oop(), "Discovered a bad reference");
1258 verify_referent(obj); 1258 verify_referent(obj);
1259 return true; 1259 return true;
1265 // in any order and, indeed, concurrently. 1265 // in any order and, indeed, concurrently.
1266 void ReferenceProcessor::preclean_discovered_references( 1266 void ReferenceProcessor::preclean_discovered_references(
1267 BoolObjectClosure* is_alive, 1267 BoolObjectClosure* is_alive,
1268 OopClosure* keep_alive, 1268 OopClosure* keep_alive,
1269 VoidClosure* complete_gc, 1269 VoidClosure* complete_gc,
1270 YieldClosure* yield, 1270 YieldClosure* yield) {
1271 bool should_unload_classes) {
1272 1271
1273 NOT_PRODUCT(verify_ok_to_handle_reflists()); 1272 NOT_PRODUCT(verify_ok_to_handle_reflists());
1274 1273
1275 #ifdef ASSERT
1276 bool must_remember_klasses = ClassUnloading && !UseConcMarkSweepGC ||
1277 CMSClassUnloadingEnabled && UseConcMarkSweepGC ||
1278 ExplicitGCInvokesConcurrentAndUnloadsClasses &&
1279 UseConcMarkSweepGC && should_unload_classes;
1280 RememberKlassesChecker mx(must_remember_klasses);
1281 #endif
1282 // Soft references 1274 // Soft references
1283 { 1275 {
1284 TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC, 1276 TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
1285 false, gclog_or_tty); 1277 false, gclog_or_tty);
1286 for (uint i = 0; i < _max_num_q; i++) { 1278 for (uint i = 0; i < _max_num_q; i++) {
1355 next != NULL) { 1347 next != NULL) {
1356 // The referent has been cleared, or is alive, or the Reference is not 1348 // The referent has been cleared, or is alive, or the Reference is not
1357 // active; we need to trace and mark its cohort. 1349 // active; we need to trace and mark its cohort.
1358 if (TraceReferenceGC) { 1350 if (TraceReferenceGC) {
1359 gclog_or_tty->print_cr("Precleaning Reference (" INTPTR_FORMAT ": %s)", 1351 gclog_or_tty->print_cr("Precleaning Reference (" INTPTR_FORMAT ": %s)",
1360 iter.obj(), iter.obj()->blueprint()->internal_name()); 1352 iter.obj(), iter.obj()->klass()->internal_name());
1361 } 1353 }
1362 // Remove Reference object from list 1354 // Remove Reference object from list
1363 iter.remove(); 1355 iter.remove();
1364 // Keep alive its cohort. 1356 // Keep alive its cohort.
1365 iter.make_referent_alive(); 1357 iter.make_referent_alive();