Mercurial > hg > graal-jvmci-8
comparison src/share/vm/gc_implementation/parNew/parNewGeneration.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 | aaf61e68b255 |
children | 2e6857353b2c |
comparison
equal
deleted
inserted
replaced
6724:36d1d483d5d6 | 6725:da91efe96a93 |
---|---|
476 } | 476 } |
477 } | 477 } |
478 | 478 |
479 ParScanClosure::ParScanClosure(ParNewGeneration* g, | 479 ParScanClosure::ParScanClosure(ParNewGeneration* g, |
480 ParScanThreadState* par_scan_state) : | 480 ParScanThreadState* par_scan_state) : |
481 OopsInGenClosure(g), _par_scan_state(par_scan_state), _g(g) | 481 OopsInKlassOrGenClosure(g), _par_scan_state(par_scan_state), _g(g) |
482 { | 482 { |
483 assert(_g->level() == 0, "Optimized for youngest generation"); | 483 assert(_g->level() == 0, "Optimized for youngest generation"); |
484 _boundary = _g->reserved().end(); | 484 _boundary = _g->reserved().end(); |
485 } | 485 } |
486 | 486 |
605 ParScanThreadState& par_scan_state = _state_set->thread_state(worker_id); | 605 ParScanThreadState& par_scan_state = _state_set->thread_state(worker_id); |
606 assert(_state_set->is_valid(worker_id), "Should not have been called"); | 606 assert(_state_set->is_valid(worker_id), "Should not have been called"); |
607 | 607 |
608 par_scan_state.set_young_old_boundary(_young_old_boundary); | 608 par_scan_state.set_young_old_boundary(_young_old_boundary); |
609 | 609 |
610 KlassScanClosure klass_scan_closure(&par_scan_state.to_space_root_closure(), | |
611 gch->rem_set()->klass_rem_set()); | |
612 | |
613 int so = SharedHeap::SO_AllClasses | SharedHeap::SO_Strings | SharedHeap::SO_CodeCache; | |
614 | |
610 par_scan_state.start_strong_roots(); | 615 par_scan_state.start_strong_roots(); |
611 gch->gen_process_strong_roots(_gen->level(), | 616 gch->gen_process_strong_roots(_gen->level(), |
612 true, // Process younger gens, if any, | 617 true, // Process younger gens, if any, |
613 // as strong roots. | 618 // as strong roots. |
614 false, // no scope; this is parallel code | 619 false, // no scope; this is parallel code |
615 false, // not collecting perm generation. | 620 true, // is scavenging |
616 SharedHeap::SO_AllClasses, | 621 SharedHeap::ScanningOption(so), |
617 &par_scan_state.to_space_root_closure(), | 622 &par_scan_state.to_space_root_closure(), |
618 true, // walk *all* scavengable nmethods | 623 true, // walk *all* scavengable nmethods |
619 &par_scan_state.older_gen_closure()); | 624 &par_scan_state.older_gen_closure(), |
625 &klass_scan_closure); | |
620 par_scan_state.end_strong_roots(); | 626 par_scan_state.end_strong_roots(); |
621 | 627 |
622 // "evacuate followers". | 628 // "evacuate followers". |
623 par_scan_state.evacuate_followers_closure().do_void(); | 629 par_scan_state.evacuate_followers_closure().do_void(); |
624 } | 630 } |
1189 new_obj->incr_age(); | 1195 new_obj->incr_age(); |
1190 par_scan_state->age_table()->add(new_obj, sz); | 1196 par_scan_state->age_table()->add(new_obj, sz); |
1191 } | 1197 } |
1192 assert(new_obj != NULL, "just checking"); | 1198 assert(new_obj != NULL, "just checking"); |
1193 | 1199 |
1200 #ifndef PRODUCT | |
1201 // This code must come after the CAS test, or it will print incorrect | |
1202 // information. | |
1203 if (TraceScavenge) { | |
1204 gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", | |
1205 is_in_reserved(new_obj) ? "copying" : "tenuring", | |
1206 new_obj->klass()->internal_name(), old, new_obj, new_obj->size()); | |
1207 } | |
1208 #endif | |
1209 | |
1194 if (forward_ptr == NULL) { | 1210 if (forward_ptr == NULL) { |
1195 oop obj_to_push = new_obj; | 1211 oop obj_to_push = new_obj; |
1196 if (par_scan_state->should_be_partially_scanned(obj_to_push, old)) { | 1212 if (par_scan_state->should_be_partially_scanned(obj_to_push, old)) { |
1197 // Length field used as index of next element to be scanned. | 1213 // Length field used as index of next element to be scanned. |
1198 // Real length can be obtained from real_forwardee() | 1214 // Real length can be obtained from real_forwardee() |
1300 // Increment age if new_obj still in new generation | 1316 // Increment age if new_obj still in new generation |
1301 new_obj->incr_age(); | 1317 new_obj->incr_age(); |
1302 par_scan_state->age_table()->add(new_obj, sz); | 1318 par_scan_state->age_table()->add(new_obj, sz); |
1303 } | 1319 } |
1304 assert(new_obj != NULL, "just checking"); | 1320 assert(new_obj != NULL, "just checking"); |
1321 | |
1322 #ifndef PRODUCT | |
1323 // This code must come after the CAS test, or it will print incorrect | |
1324 // information. | |
1325 if (TraceScavenge) { | |
1326 gclog_or_tty->print_cr("{%s %s " PTR_FORMAT " -> " PTR_FORMAT " (%d)}", | |
1327 is_in_reserved(new_obj) ? "copying" : "tenuring", | |
1328 new_obj->klass()->internal_name(), old, new_obj, new_obj->size()); | |
1329 } | |
1330 #endif | |
1305 | 1331 |
1306 // Now attempt to install the forwarding pointer (atomically). | 1332 // Now attempt to install the forwarding pointer (atomically). |
1307 // We have to copy the mark word before overwriting with forwarding | 1333 // We have to copy the mark word before overwriting with forwarding |
1308 // ptr, so we can restore it below in the copy. | 1334 // ptr, so we can restore it below in the copy. |
1309 if (!failed_to_promote) { | 1335 if (!failed_to_promote) { |
1492 } | 1518 } |
1493 assert(prefix != NULL && prefix != BUSY, "Error"); | 1519 assert(prefix != NULL && prefix != BUSY, "Error"); |
1494 size_t i = 1; | 1520 size_t i = 1; |
1495 oop cur = prefix; | 1521 oop cur = prefix; |
1496 while (i < objsFromOverflow && cur->klass_or_null() != NULL) { | 1522 while (i < objsFromOverflow && cur->klass_or_null() != NULL) { |
1497 i++; cur = oop(cur->klass()); | 1523 i++; cur = cur->list_ptr_from_klass(); |
1498 } | 1524 } |
1499 | 1525 |
1500 // Reattach remaining (suffix) to overflow list | 1526 // Reattach remaining (suffix) to overflow list |
1501 if (cur->klass_or_null() == NULL) { | 1527 if (cur->klass_or_null() == NULL) { |
1502 // Write back the NULL in lieu of the BUSY we wrote | 1528 // Write back the NULL in lieu of the BUSY we wrote |
1503 // above and it is still the same value. | 1529 // above and it is still the same value. |
1504 if (_overflow_list == BUSY) { | 1530 if (_overflow_list == BUSY) { |
1505 (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY); | 1531 (void) Atomic::cmpxchg_ptr(NULL, &_overflow_list, BUSY); |
1506 } | 1532 } |
1507 } else { | 1533 } else { |
1508 assert(cur->klass_or_null() != BUSY, "Error"); | 1534 assert(cur->klass_or_null() != (Klass*)(address)BUSY, "Error"); |
1509 oop suffix = oop(cur->klass()); // suffix will be put back on global list | 1535 oop suffix = cur->list_ptr_from_klass(); // suffix will be put back on global list |
1510 cur->set_klass_to_list_ptr(NULL); // break off suffix | 1536 cur->set_klass_to_list_ptr(NULL); // break off suffix |
1511 // It's possible that the list is still in the empty(busy) state | 1537 // It's possible that the list is still in the empty(busy) state |
1512 // we left it in a short while ago; in that case we may be | 1538 // we left it in a short while ago; in that case we may be |
1513 // able to place back the suffix. | 1539 // able to place back the suffix. |
1514 oop observed_overflow_list = _overflow_list; | 1540 oop observed_overflow_list = _overflow_list; |
1525 if (!attached) { | 1551 if (!attached) { |
1526 // Too bad, someone else got in in between; we'll need to do a splice. | 1552 // Too bad, someone else got in in between; we'll need to do a splice. |
1527 // Find the last item of suffix list | 1553 // Find the last item of suffix list |
1528 oop last = suffix; | 1554 oop last = suffix; |
1529 while (last->klass_or_null() != NULL) { | 1555 while (last->klass_or_null() != NULL) { |
1530 last = oop(last->klass()); | 1556 last = last->list_ptr_from_klass(); |
1531 } | 1557 } |
1532 // Atomically prepend suffix to current overflow list | 1558 // Atomically prepend suffix to current overflow list |
1533 observed_overflow_list = _overflow_list; | 1559 observed_overflow_list = _overflow_list; |
1534 do { | 1560 do { |
1535 cur_overflow_list = observed_overflow_list; | 1561 cur_overflow_list = observed_overflow_list; |
1549 assert(prefix != NULL && prefix != BUSY, "program logic"); | 1575 assert(prefix != NULL && prefix != BUSY, "program logic"); |
1550 cur = prefix; | 1576 cur = prefix; |
1551 ssize_t n = 0; | 1577 ssize_t n = 0; |
1552 while (cur != NULL) { | 1578 while (cur != NULL) { |
1553 oop obj_to_push = cur->forwardee(); | 1579 oop obj_to_push = cur->forwardee(); |
1554 oop next = oop(cur->klass_or_null()); | 1580 oop next = cur->list_ptr_from_klass(); |
1555 cur->set_klass(obj_to_push->klass()); | 1581 cur->set_klass(obj_to_push->klass()); |
1556 // This may be an array object that is self-forwarded. In that case, the list pointer | 1582 // This may be an array object that is self-forwarded. In that case, the list pointer |
1557 // space, cur, is not in the Java heap, but rather in the C-heap and should be freed. | 1583 // space, cur, is not in the Java heap, but rather in the C-heap and should be freed. |
1558 if (!is_in_reserved(cur)) { | 1584 if (!is_in_reserved(cur)) { |
1559 // This can become a scaling bottleneck when there is work queue overflow coincident | 1585 // This can become a scaling bottleneck when there is work queue overflow coincident |