0
|
1 /*
|
|
2 * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved.
|
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
4 *
|
|
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
|
|
7 * published by the Free Software Foundation.
|
|
8 *
|
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT
|
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
12 * version 2 for more details (a copy is included in the LICENSE file that
|
|
13 * accompanied this code).
|
|
14 *
|
|
15 * You should have received a copy of the GNU General Public License version
|
|
16 * 2 along with this work; if not, write to the Free Software Foundation,
|
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
18 *
|
|
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 * CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 * have any questions.
|
|
22 *
|
|
23 */
|
|
24
|
|
25 inline PSPromotionManager* PSPromotionManager::manager_array(int index) {
|
|
26 assert(_manager_array != NULL, "access of NULL manager_array");
|
|
27 assert(index >= 0 && index <= (int)ParallelGCThreads, "out of range manager_array access");
|
|
28 return _manager_array[index];
|
|
29 }
|
|
30
|
|
31 inline void PSPromotionManager::claim_or_forward_internal_depth(oop* p) {
|
|
32 if (p != NULL) {
|
|
33 oop o = *p;
|
|
34 if (o->is_forwarded()) {
|
|
35 o = o->forwardee();
|
|
36
|
|
37 // Card mark
|
|
38 if (PSScavenge::is_obj_in_young((HeapWord*) o)) {
|
|
39 PSScavenge::card_table()->inline_write_ref_field_gc(p, o);
|
|
40 }
|
|
41 *p = o;
|
|
42 } else {
|
|
43 push_depth(p);
|
|
44 }
|
|
45 }
|
|
46 }
|
|
47
|
|
48 inline void PSPromotionManager::claim_or_forward_internal_breadth(oop* p) {
|
|
49 if (p != NULL) {
|
|
50 oop o = *p;
|
|
51 if (o->is_forwarded()) {
|
|
52 o = o->forwardee();
|
|
53 } else {
|
|
54 o = copy_to_survivor_space(o, false);
|
|
55 }
|
|
56
|
|
57 // Card mark
|
|
58 if (PSScavenge::is_obj_in_young((HeapWord*) o)) {
|
|
59 PSScavenge::card_table()->inline_write_ref_field_gc(p, o);
|
|
60 }
|
|
61 *p = o;
|
|
62 }
|
|
63 }
|
|
64
|
|
65 inline void PSPromotionManager::flush_prefetch_queue() {
|
|
66 assert(!depth_first(), "invariant");
|
|
67 for (int i=0; i<_prefetch_queue.length(); i++) {
|
|
68 claim_or_forward_internal_breadth(_prefetch_queue.pop());
|
|
69 }
|
|
70 }
|
|
71
|
|
72 inline void PSPromotionManager::claim_or_forward_depth(oop* p) {
|
|
73 assert(depth_first(), "invariant");
|
|
74 assert(PSScavenge::should_scavenge(*p, true), "revisiting object?");
|
|
75 assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
|
|
76 assert(Universe::heap()->is_in(p), "pointer outside heap");
|
|
77
|
|
78 claim_or_forward_internal_depth(p);
|
|
79 }
|
|
80
|
|
81 inline void PSPromotionManager::claim_or_forward_breadth(oop* p) {
|
|
82 assert(!depth_first(), "invariant");
|
|
83 assert(PSScavenge::should_scavenge(*p, true), "revisiting object?");
|
|
84 assert(Universe::heap()->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity");
|
|
85 assert(Universe::heap()->is_in(p), "pointer outside heap");
|
|
86
|
|
87 if (UsePrefetchQueue) {
|
|
88 claim_or_forward_internal_breadth(_prefetch_queue.push_and_pop(p));
|
|
89 } else {
|
|
90 // This option is used for testing. The use of the prefetch
|
|
91 // queue can delay the processing of the objects and thus
|
|
92 // change the order of object scans. For example, remembered
|
|
93 // set updates are typically the clearing of the remembered
|
|
94 // set (the cards) followed by updates of the remembered set
|
|
95 // for young-to-old pointers. In a situation where there
|
|
96 // is an error in the sequence of clearing and updating
|
|
97 // (e.g. clear card A, update card A, erroneously clear
|
|
98 // card A again) the error can be obscured by a delay
|
|
99 // in the update due to the use of the prefetch queue
|
|
100 // (e.g., clear card A, erroneously clear card A again,
|
|
101 // update card A that was pushed into the prefetch queue
|
|
102 // and thus delayed until after the erronous clear). The
|
|
103 // length of the delay is random depending on the objects
|
|
104 // in the queue and the delay can be zero.
|
|
105 claim_or_forward_internal_breadth(p);
|
|
106 }
|
|
107 }
|
|
108
|
|
109 inline void PSPromotionManager::process_popped_location_depth(oop* p) {
|
|
110 if (is_oop_masked(p)) {
|
|
111 assert(PSChunkLargeArrays, "invariant");
|
|
112 oop const old = unmask_chunked_array_oop(p);
|
|
113 process_array_chunk(old);
|
|
114 } else {
|
|
115 PSScavenge::copy_and_push_safe_barrier(this, p);
|
|
116 }
|
|
117 }
|