annotate src/share/vm/memory/genCollectedHeap.cpp @ 453:c96030fff130

6684579: SoftReference processing can be made more efficient Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not. Reviewed-by: jmasa
author ysr
date Thu, 20 Nov 2008 16:56:09 -0800
parents 850fdf70db2b
children 27a80744a83b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
196
d1605aabd0a1 6719955: Update copyright year
xdono
parents: 113
diff changeset
2 * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 # include "incls/_genCollectedHeap.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 GenCollectedHeap* GenCollectedHeap::_gch;
a61af66fc99e Initial load
duke
parents:
diff changeset
29 NOT_PRODUCT(size_t GenCollectedHeap::_skip_header_HeapWords = 0;)
a61af66fc99e Initial load
duke
parents:
diff changeset
30
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // The set of potentially parallel tasks in strong root scanning.
a61af66fc99e Initial load
duke
parents:
diff changeset
32 enum GCH_process_strong_roots_tasks {
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // We probably want to parallelize both of these internally, but for now...
a61af66fc99e Initial load
duke
parents:
diff changeset
34 GCH_PS_younger_gens,
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // Leave this one last.
a61af66fc99e Initial load
duke
parents:
diff changeset
36 GCH_PS_NumElements
a61af66fc99e Initial load
duke
parents:
diff changeset
37 };
a61af66fc99e Initial load
duke
parents:
diff changeset
38
a61af66fc99e Initial load
duke
parents:
diff changeset
39 GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy) :
a61af66fc99e Initial load
duke
parents:
diff changeset
40 SharedHeap(policy),
a61af66fc99e Initial load
duke
parents:
diff changeset
41 _gen_policy(policy),
a61af66fc99e Initial load
duke
parents:
diff changeset
42 _gen_process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)),
a61af66fc99e Initial load
duke
parents:
diff changeset
43 _full_collections_completed(0)
a61af66fc99e Initial load
duke
parents:
diff changeset
44 {
a61af66fc99e Initial load
duke
parents:
diff changeset
45 if (_gen_process_strong_tasks == NULL ||
a61af66fc99e Initial load
duke
parents:
diff changeset
46 !_gen_process_strong_tasks->valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
47 vm_exit_during_initialization("Failed necessary allocation.");
a61af66fc99e Initial load
duke
parents:
diff changeset
48 }
a61af66fc99e Initial load
duke
parents:
diff changeset
49 assert(policy != NULL, "Sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
50 _preloading_shared_classes = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
51 }
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53 jint GenCollectedHeap::initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
54 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
55 _n_gens = gen_policy()->number_of_generations();
a61af66fc99e Initial load
duke
parents:
diff changeset
56
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // While there are no constraints in the GC code that HeapWordSize
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // be any particular value, there are multiple other areas in the
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // system which believe this to be true (e.g. oop->object_size in some
a61af66fc99e Initial load
duke
parents:
diff changeset
60 // cases incorrectly returns the size in wordSize units rather than
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // HeapWordSize).
a61af66fc99e Initial load
duke
parents:
diff changeset
62 guarantee(HeapWordSize == wordSize, "HeapWordSize must equal wordSize");
a61af66fc99e Initial load
duke
parents:
diff changeset
63
a61af66fc99e Initial load
duke
parents:
diff changeset
64 // The heap must be at least as aligned as generations.
a61af66fc99e Initial load
duke
parents:
diff changeset
65 size_t alignment = Generation::GenGrain;
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67 _gen_specs = gen_policy()->generations();
a61af66fc99e Initial load
duke
parents:
diff changeset
68 PermanentGenerationSpec *perm_gen_spec =
a61af66fc99e Initial load
duke
parents:
diff changeset
69 collector_policy()->permanent_generation();
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // Make sure the sizes are all aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
72 for (i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
73 _gen_specs[i]->align(alignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
74 }
a61af66fc99e Initial load
duke
parents:
diff changeset
75 perm_gen_spec->align(alignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 // If we are dumping the heap, then allocate a wasted block of address
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // space in order to push the heap to a lower address. This extra
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // address range allows for other (or larger) libraries to be loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // without them occupying the space required for the shared spaces.
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 if (DumpSharedSpaces) {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 uintx reserved = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
84 uintx block_size = 64*1024*1024;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 while (reserved < SharedDummyBlockSize) {
a61af66fc99e Initial load
duke
parents:
diff changeset
86 char* dummy = os::reserve_memory(block_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
87 reserved += block_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
88 }
a61af66fc99e Initial load
duke
parents:
diff changeset
89 }
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 // Allocate space for the heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 char* heap_address;
a61af66fc99e Initial load
duke
parents:
diff changeset
94 size_t total_reserved = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
95 int n_covered_regions = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
96 ReservedSpace heap_rs(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 heap_address = allocate(alignment, perm_gen_spec, &total_reserved,
a61af66fc99e Initial load
duke
parents:
diff changeset
99 &n_covered_regions, &heap_rs);
a61af66fc99e Initial load
duke
parents:
diff changeset
100
a61af66fc99e Initial load
duke
parents:
diff changeset
101 if (UseSharedSpaces) {
a61af66fc99e Initial load
duke
parents:
diff changeset
102 if (!heap_rs.is_reserved() || heap_address != heap_rs.base()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
103 if (heap_rs.is_reserved()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
104 heap_rs.release();
a61af66fc99e Initial load
duke
parents:
diff changeset
105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
106 FileMapInfo* mapinfo = FileMapInfo::current_info();
a61af66fc99e Initial load
duke
parents:
diff changeset
107 mapinfo->fail_continue("Unable to reserve shared region.");
a61af66fc99e Initial load
duke
parents:
diff changeset
108 allocate(alignment, perm_gen_spec, &total_reserved, &n_covered_regions,
a61af66fc99e Initial load
duke
parents:
diff changeset
109 &heap_rs);
a61af66fc99e Initial load
duke
parents:
diff changeset
110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
111 }
a61af66fc99e Initial load
duke
parents:
diff changeset
112
a61af66fc99e Initial load
duke
parents:
diff changeset
113 if (!heap_rs.is_reserved()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
114 vm_shutdown_during_initialization(
a61af66fc99e Initial load
duke
parents:
diff changeset
115 "Could not reserve enough space for object heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
116 return JNI_ENOMEM;
a61af66fc99e Initial load
duke
parents:
diff changeset
117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
118
a61af66fc99e Initial load
duke
parents:
diff changeset
119 _reserved = MemRegion((HeapWord*)heap_rs.base(),
a61af66fc99e Initial load
duke
parents:
diff changeset
120 (HeapWord*)(heap_rs.base() + heap_rs.size()));
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // It is important to do this in a way such that concurrent readers can't
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // temporarily think somethings in the heap. (Seen this happen in asserts.)
a61af66fc99e Initial load
duke
parents:
diff changeset
124 _reserved.set_word_size(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
125 _reserved.set_start((HeapWord*)heap_rs.base());
a61af66fc99e Initial load
duke
parents:
diff changeset
126 size_t actual_heap_size = heap_rs.size() - perm_gen_spec->misc_data_size()
a61af66fc99e Initial load
duke
parents:
diff changeset
127 - perm_gen_spec->misc_code_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
128 _reserved.set_end((HeapWord*)(heap_rs.base() + actual_heap_size));
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 _rem_set = collector_policy()->create_rem_set(_reserved, n_covered_regions);
a61af66fc99e Initial load
duke
parents:
diff changeset
131 set_barrier_set(rem_set()->bs());
a61af66fc99e Initial load
duke
parents:
diff changeset
132 _gch = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
133
a61af66fc99e Initial load
duke
parents:
diff changeset
134 for (i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
135 ReservedSpace this_rs = heap_rs.first_part(_gen_specs[i]->max_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
136 UseSharedSpaces, UseSharedSpaces);
a61af66fc99e Initial load
duke
parents:
diff changeset
137 _gens[i] = _gen_specs[i]->init(this_rs, i, rem_set());
a61af66fc99e Initial load
duke
parents:
diff changeset
138 heap_rs = heap_rs.last_part(_gen_specs[i]->max_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
140 _perm_gen = perm_gen_spec->init(heap_rs, PermSize, rem_set());
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 clear_incremental_collection_will_fail();
a61af66fc99e Initial load
duke
parents:
diff changeset
143 clear_last_incremental_collection_failed();
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 #ifndef SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // If we are running CMS, create the collector responsible
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // for collecting the CMS generations.
a61af66fc99e Initial load
duke
parents:
diff changeset
148 if (collector_policy()->is_concurrent_mark_sweep_policy()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
149 bool success = create_cms_collector();
a61af66fc99e Initial load
duke
parents:
diff changeset
150 if (!success) return JNI_ENOMEM;
a61af66fc99e Initial load
duke
parents:
diff changeset
151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
152 #endif // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154 return JNI_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 char* GenCollectedHeap::allocate(size_t alignment,
a61af66fc99e Initial load
duke
parents:
diff changeset
159 PermanentGenerationSpec* perm_gen_spec,
a61af66fc99e Initial load
duke
parents:
diff changeset
160 size_t* _total_reserved,
a61af66fc99e Initial load
duke
parents:
diff changeset
161 int* _n_covered_regions,
a61af66fc99e Initial load
duke
parents:
diff changeset
162 ReservedSpace* heap_rs){
a61af66fc99e Initial load
duke
parents:
diff changeset
163 const char overflow_msg[] = "The size of the object heap + VM data exceeds "
a61af66fc99e Initial load
duke
parents:
diff changeset
164 "the maximum representable size";
a61af66fc99e Initial load
duke
parents:
diff changeset
165
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // Now figure out the total size.
a61af66fc99e Initial load
duke
parents:
diff changeset
167 size_t total_reserved = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 int n_covered_regions = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
169 const size_t pageSize = UseLargePages ?
a61af66fc99e Initial load
duke
parents:
diff changeset
170 os::large_page_size() : os::vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
173 total_reserved += _gen_specs[i]->max_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
174 if (total_reserved < _gen_specs[i]->max_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
175 vm_exit_during_initialization(overflow_msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
176 }
a61af66fc99e Initial load
duke
parents:
diff changeset
177 n_covered_regions += _gen_specs[i]->n_covered_regions();
a61af66fc99e Initial load
duke
parents:
diff changeset
178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
179 assert(total_reserved % pageSize == 0, "Gen size");
a61af66fc99e Initial load
duke
parents:
diff changeset
180 total_reserved += perm_gen_spec->max_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
181 assert(total_reserved % pageSize == 0, "Perm Gen size");
a61af66fc99e Initial load
duke
parents:
diff changeset
182
a61af66fc99e Initial load
duke
parents:
diff changeset
183 if (total_reserved < perm_gen_spec->max_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
184 vm_exit_during_initialization(overflow_msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
185 }
a61af66fc99e Initial load
duke
parents:
diff changeset
186 n_covered_regions += perm_gen_spec->n_covered_regions();
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // Add the size of the data area which shares the same reserved area
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // as the heap, but which is not actually part of the heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
190 size_t s = perm_gen_spec->misc_data_size() + perm_gen_spec->misc_code_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192 total_reserved += s;
a61af66fc99e Initial load
duke
parents:
diff changeset
193 if (total_reserved < s) {
a61af66fc99e Initial load
duke
parents:
diff changeset
194 vm_exit_during_initialization(overflow_msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 if (UseLargePages) {
a61af66fc99e Initial load
duke
parents:
diff changeset
198 assert(total_reserved != 0, "total_reserved cannot be 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
199 total_reserved = round_to(total_reserved, os::large_page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
200 if (total_reserved < os::large_page_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
201 vm_exit_during_initialization(overflow_msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // Calculate the address at which the heap must reside in order for
a61af66fc99e Initial load
duke
parents:
diff changeset
206 // the shared data to be at the required address.
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 char* heap_address;
a61af66fc99e Initial load
duke
parents:
diff changeset
209 if (UseSharedSpaces) {
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // Calculate the address of the first word beyond the heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
212 FileMapInfo* mapinfo = FileMapInfo::current_info();
a61af66fc99e Initial load
duke
parents:
diff changeset
213 int lr = CompactingPermGenGen::n_regions - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
214 size_t capacity = align_size_up(mapinfo->space_capacity(lr), alignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
215 heap_address = mapinfo->region_base(lr) + capacity;
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // Calculate the address of the first word of the heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
218 heap_address -= total_reserved;
a61af66fc99e Initial load
duke
parents:
diff changeset
219 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
220 heap_address = NULL; // any address will do.
a61af66fc99e Initial load
duke
parents:
diff changeset
221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
222
a61af66fc99e Initial load
duke
parents:
diff changeset
223 *_total_reserved = total_reserved;
a61af66fc99e Initial load
duke
parents:
diff changeset
224 *_n_covered_regions = n_covered_regions;
237
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
225 *heap_rs = ReservedHeapSpace(total_reserved, alignment,
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
226 UseLargePages, heap_address);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
227
a61af66fc99e Initial load
duke
parents:
diff changeset
228 return heap_address;
a61af66fc99e Initial load
duke
parents:
diff changeset
229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
230
a61af66fc99e Initial load
duke
parents:
diff changeset
231
a61af66fc99e Initial load
duke
parents:
diff changeset
232 void GenCollectedHeap::post_initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
233 SharedHeap::post_initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
234 TwoGenerationCollectorPolicy *policy =
a61af66fc99e Initial load
duke
parents:
diff changeset
235 (TwoGenerationCollectorPolicy *)collector_policy();
a61af66fc99e Initial load
duke
parents:
diff changeset
236 guarantee(policy->is_two_generation_policy(), "Illegal policy type");
a61af66fc99e Initial load
duke
parents:
diff changeset
237 DefNewGeneration* def_new_gen = (DefNewGeneration*) get_gen(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
238 assert(def_new_gen->kind() == Generation::DefNew ||
a61af66fc99e Initial load
duke
parents:
diff changeset
239 def_new_gen->kind() == Generation::ParNew ||
a61af66fc99e Initial load
duke
parents:
diff changeset
240 def_new_gen->kind() == Generation::ASParNew,
a61af66fc99e Initial load
duke
parents:
diff changeset
241 "Wrong generation kind");
a61af66fc99e Initial load
duke
parents:
diff changeset
242
a61af66fc99e Initial load
duke
parents:
diff changeset
243 Generation* old_gen = get_gen(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
244 assert(old_gen->kind() == Generation::ConcurrentMarkSweep ||
a61af66fc99e Initial load
duke
parents:
diff changeset
245 old_gen->kind() == Generation::ASConcurrentMarkSweep ||
a61af66fc99e Initial load
duke
parents:
diff changeset
246 old_gen->kind() == Generation::MarkSweepCompact,
a61af66fc99e Initial load
duke
parents:
diff changeset
247 "Wrong generation kind");
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 policy->initialize_size_policy(def_new_gen->eden()->capacity(),
a61af66fc99e Initial load
duke
parents:
diff changeset
250 old_gen->capacity(),
a61af66fc99e Initial load
duke
parents:
diff changeset
251 def_new_gen->from()->capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
252 policy->initialize_gc_policy_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
253 }
a61af66fc99e Initial load
duke
parents:
diff changeset
254
a61af66fc99e Initial load
duke
parents:
diff changeset
255 void GenCollectedHeap::ref_processing_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
256 SharedHeap::ref_processing_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
257 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
258 _gens[i]->ref_processor_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
260 }
a61af66fc99e Initial load
duke
parents:
diff changeset
261
a61af66fc99e Initial load
duke
parents:
diff changeset
262 size_t GenCollectedHeap::capacity() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
263 size_t res = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
264 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
265 res += _gens[i]->capacity();
a61af66fc99e Initial load
duke
parents:
diff changeset
266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
267 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
269
a61af66fc99e Initial load
duke
parents:
diff changeset
270 size_t GenCollectedHeap::used() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
271 size_t res = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
272 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
273 res += _gens[i]->used();
a61af66fc99e Initial load
duke
parents:
diff changeset
274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
275 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
277
a61af66fc99e Initial load
duke
parents:
diff changeset
278 // Save the "used_region" for generations level and lower,
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // and, if perm is true, for perm gen.
a61af66fc99e Initial load
duke
parents:
diff changeset
280 void GenCollectedHeap::save_used_regions(int level, bool perm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
281 assert(level < _n_gens, "Illegal level parameter");
a61af66fc99e Initial load
duke
parents:
diff changeset
282 for (int i = level; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
283 _gens[i]->save_used_region();
a61af66fc99e Initial load
duke
parents:
diff changeset
284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
285 if (perm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
286 perm_gen()->save_used_region();
a61af66fc99e Initial load
duke
parents:
diff changeset
287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
289
a61af66fc99e Initial load
duke
parents:
diff changeset
290 size_t GenCollectedHeap::max_capacity() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
291 size_t res = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
292 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
293 res += _gens[i]->max_capacity();
a61af66fc99e Initial load
duke
parents:
diff changeset
294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
295 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
296 }
a61af66fc99e Initial load
duke
parents:
diff changeset
297
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // Update the _full_collections_completed counter
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // at the end of a stop-world full GC.
a61af66fc99e Initial load
duke
parents:
diff changeset
300 unsigned int GenCollectedHeap::update_full_collections_completed() {
a61af66fc99e Initial load
duke
parents:
diff changeset
301 MonitorLockerEx ml(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
302 assert(_full_collections_completed <= _total_full_collections,
a61af66fc99e Initial load
duke
parents:
diff changeset
303 "Can't complete more collections than were started");
a61af66fc99e Initial load
duke
parents:
diff changeset
304 _full_collections_completed = _total_full_collections;
a61af66fc99e Initial load
duke
parents:
diff changeset
305 ml.notify_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
306 return _full_collections_completed;
a61af66fc99e Initial load
duke
parents:
diff changeset
307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
308
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // Update the _full_collections_completed counter, as appropriate,
a61af66fc99e Initial load
duke
parents:
diff changeset
310 // at the end of a concurrent GC cycle. Note the conditional update
a61af66fc99e Initial load
duke
parents:
diff changeset
311 // below to allow this method to be called by a concurrent collector
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // without synchronizing in any manner with the VM thread (which
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // may already have initiated a STW full collection "concurrently").
a61af66fc99e Initial load
duke
parents:
diff changeset
314 unsigned int GenCollectedHeap::update_full_collections_completed(unsigned int count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 MonitorLockerEx ml(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
316 assert((_full_collections_completed <= _total_full_collections) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
317 (count <= _total_full_collections),
a61af66fc99e Initial load
duke
parents:
diff changeset
318 "Can't complete more collections than were started");
a61af66fc99e Initial load
duke
parents:
diff changeset
319 if (count > _full_collections_completed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
320 _full_collections_completed = count;
a61af66fc99e Initial load
duke
parents:
diff changeset
321 ml.notify_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323 return _full_collections_completed;
a61af66fc99e Initial load
duke
parents:
diff changeset
324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
325
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // Override of memory state checking method in CollectedHeap:
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // Some collectors (CMS for example) can't have badHeapWordVal written
a61af66fc99e Initial load
duke
parents:
diff changeset
330 // in the first two words of an object. (For instance , in the case of
a61af66fc99e Initial load
duke
parents:
diff changeset
331 // CMS these words hold state used to synchronize between certain
a61af66fc99e Initial load
duke
parents:
diff changeset
332 // (concurrent) GC steps and direct allocating mutators.)
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // The skip_header_HeapWords() method below, allows us to skip
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // over the requisite number of HeapWord's. Note that (for
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // generational collectors) this means that those many words are
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // skipped in each object, irrespective of the generation in which
a61af66fc99e Initial load
duke
parents:
diff changeset
337 // that object lives. The resultant loss of precision seems to be
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // harmless and the pain of avoiding that imprecision appears somewhat
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // higher than we are prepared to pay for such rudimentary debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // support.
a61af66fc99e Initial load
duke
parents:
diff changeset
341 void GenCollectedHeap::check_for_non_bad_heap_word_value(HeapWord* addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
342 size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
343 if (CheckMemoryInitialization && ZapUnusedHeapArea) {
a61af66fc99e Initial load
duke
parents:
diff changeset
344 // We are asked to check a size in HeapWords,
a61af66fc99e Initial load
duke
parents:
diff changeset
345 // but the memory is mangled in juint words.
a61af66fc99e Initial load
duke
parents:
diff changeset
346 juint* start = (juint*) (addr + skip_header_HeapWords());
a61af66fc99e Initial load
duke
parents:
diff changeset
347 juint* end = (juint*) (addr + size);
a61af66fc99e Initial load
duke
parents:
diff changeset
348 for (juint* slot = start; slot < end; slot += 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
349 assert(*slot == badHeapWordVal,
a61af66fc99e Initial load
duke
parents:
diff changeset
350 "Found non badHeapWordValue in pre-allocation check");
a61af66fc99e Initial load
duke
parents:
diff changeset
351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
354 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
355
a61af66fc99e Initial load
duke
parents:
diff changeset
356 HeapWord* GenCollectedHeap::attempt_allocation(size_t size,
a61af66fc99e Initial load
duke
parents:
diff changeset
357 bool is_tlab,
a61af66fc99e Initial load
duke
parents:
diff changeset
358 bool first_only) {
a61af66fc99e Initial load
duke
parents:
diff changeset
359 HeapWord* res;
a61af66fc99e Initial load
duke
parents:
diff changeset
360 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
361 if (_gens[i]->should_allocate(size, is_tlab)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
362 res = _gens[i]->allocate(size, is_tlab);
a61af66fc99e Initial load
duke
parents:
diff changeset
363 if (res != NULL) return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
364 else if (first_only) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // Otherwise...
a61af66fc99e Initial load
duke
parents:
diff changeset
368 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
369 }
a61af66fc99e Initial load
duke
parents:
diff changeset
370
a61af66fc99e Initial load
duke
parents:
diff changeset
371 HeapWord* GenCollectedHeap::mem_allocate(size_t size,
a61af66fc99e Initial load
duke
parents:
diff changeset
372 bool is_large_noref,
a61af66fc99e Initial load
duke
parents:
diff changeset
373 bool is_tlab,
a61af66fc99e Initial load
duke
parents:
diff changeset
374 bool* gc_overhead_limit_was_exceeded) {
a61af66fc99e Initial load
duke
parents:
diff changeset
375 return collector_policy()->mem_allocate_work(size,
a61af66fc99e Initial load
duke
parents:
diff changeset
376 is_tlab,
a61af66fc99e Initial load
duke
parents:
diff changeset
377 gc_overhead_limit_was_exceeded);
a61af66fc99e Initial load
duke
parents:
diff changeset
378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
379
a61af66fc99e Initial load
duke
parents:
diff changeset
380 bool GenCollectedHeap::must_clear_all_soft_refs() {
a61af66fc99e Initial load
duke
parents:
diff changeset
381 return _gc_cause == GCCause::_last_ditch_collection;
a61af66fc99e Initial load
duke
parents:
diff changeset
382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
383
a61af66fc99e Initial load
duke
parents:
diff changeset
384 bool GenCollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) {
a61af66fc99e Initial load
duke
parents:
diff changeset
385 return (cause == GCCause::_java_lang_system_gc ||
a61af66fc99e Initial load
duke
parents:
diff changeset
386 cause == GCCause::_gc_locker) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
387 UseConcMarkSweepGC && ExplicitGCInvokesConcurrent;
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389
a61af66fc99e Initial load
duke
parents:
diff changeset
390 void GenCollectedHeap::do_collection(bool full,
a61af66fc99e Initial load
duke
parents:
diff changeset
391 bool clear_all_soft_refs,
a61af66fc99e Initial load
duke
parents:
diff changeset
392 size_t size,
a61af66fc99e Initial load
duke
parents:
diff changeset
393 bool is_tlab,
a61af66fc99e Initial load
duke
parents:
diff changeset
394 int max_level) {
a61af66fc99e Initial load
duke
parents:
diff changeset
395 bool prepared_for_verification = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
396 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
397 DEBUG_ONLY(Thread* my_thread = Thread::current();)
a61af66fc99e Initial load
duke
parents:
diff changeset
398
a61af66fc99e Initial load
duke
parents:
diff changeset
399 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
400 assert(my_thread->is_VM_thread() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
401 my_thread->is_ConcurrentGC_thread(),
a61af66fc99e Initial load
duke
parents:
diff changeset
402 "incorrect thread type capability");
a61af66fc99e Initial load
duke
parents:
diff changeset
403 assert(Heap_lock->is_locked(), "the requesting thread should have the Heap_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
404 guarantee(!is_gc_active(), "collection is not reentrant");
a61af66fc99e Initial load
duke
parents:
diff changeset
405 assert(max_level < n_gens(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
406
a61af66fc99e Initial load
duke
parents:
diff changeset
407 if (GC_locker::check_active_before_gc()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
408 return; // GC is disabled (e.g. JNI GetXXXCritical operation)
a61af66fc99e Initial load
duke
parents:
diff changeset
409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
410
a61af66fc99e Initial load
duke
parents:
diff changeset
411 const size_t perm_prev_used = perm_gen()->used();
a61af66fc99e Initial load
duke
parents:
diff changeset
412
a61af66fc99e Initial load
duke
parents:
diff changeset
413 if (PrintHeapAtGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
414 Universe::print_heap_before_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
415 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
416 gclog_or_tty->print_cr("GC Cause: %s", GCCause::to_string(gc_cause()));
a61af66fc99e Initial load
duke
parents:
diff changeset
417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
419
a61af66fc99e Initial load
duke
parents:
diff changeset
420 {
a61af66fc99e Initial load
duke
parents:
diff changeset
421 FlagSetting fl(_is_gc_active, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
422
a61af66fc99e Initial load
duke
parents:
diff changeset
423 bool complete = full && (max_level == (n_gens()-1));
a61af66fc99e Initial load
duke
parents:
diff changeset
424 const char* gc_cause_str = "GC ";
a61af66fc99e Initial load
duke
parents:
diff changeset
425 if (complete) {
a61af66fc99e Initial load
duke
parents:
diff changeset
426 GCCause::Cause cause = gc_cause();
a61af66fc99e Initial load
duke
parents:
diff changeset
427 if (cause == GCCause::_java_lang_system_gc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
428 gc_cause_str = "Full GC (System) ";
a61af66fc99e Initial load
duke
parents:
diff changeset
429 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
430 gc_cause_str = "Full GC ";
a61af66fc99e Initial load
duke
parents:
diff changeset
431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
433 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
a61af66fc99e Initial load
duke
parents:
diff changeset
434 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
435 TraceTime t(gc_cause_str, PrintGCDetails, false, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
436
a61af66fc99e Initial load
duke
parents:
diff changeset
437 gc_prologue(complete);
a61af66fc99e Initial load
duke
parents:
diff changeset
438 increment_total_collections(complete);
a61af66fc99e Initial load
duke
parents:
diff changeset
439
a61af66fc99e Initial load
duke
parents:
diff changeset
440 size_t gch_prev_used = used();
a61af66fc99e Initial load
duke
parents:
diff changeset
441
a61af66fc99e Initial load
duke
parents:
diff changeset
442 int starting_level = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
443 if (full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // Search for the oldest generation which will collect all younger
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // generations, and start collection loop there.
a61af66fc99e Initial load
duke
parents:
diff changeset
446 for (int i = max_level; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
447 if (_gens[i]->full_collects_younger_generations()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
448 starting_level = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
449 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
450 }
a61af66fc99e Initial load
duke
parents:
diff changeset
451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454 bool must_restore_marks_for_biased_locking = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
455
a61af66fc99e Initial load
duke
parents:
diff changeset
456 int max_level_collected = starting_level;
a61af66fc99e Initial load
duke
parents:
diff changeset
457 for (int i = starting_level; i <= max_level; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 if (_gens[i]->should_collect(full, size, is_tlab)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
459 // Timer for individual generations. Last argument is false: no CR
a61af66fc99e Initial load
duke
parents:
diff changeset
460 TraceTime t1(_gens[i]->short_name(), PrintGCDetails, false, gclog_or_tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
461 TraceCollectorStats tcs(_gens[i]->counters());
a61af66fc99e Initial load
duke
parents:
diff changeset
462 TraceMemoryManagerStats tmms(_gens[i]->kind());
a61af66fc99e Initial load
duke
parents:
diff changeset
463
a61af66fc99e Initial load
duke
parents:
diff changeset
464 size_t prev_used = _gens[i]->used();
a61af66fc99e Initial load
duke
parents:
diff changeset
465 _gens[i]->stat_record()->invocations++;
a61af66fc99e Initial load
duke
parents:
diff changeset
466 _gens[i]->stat_record()->accumulated_time.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
467
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
468 // Must be done anew before each collection because
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
469 // a previous collection will do mangling and will
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
470 // change top of some spaces.
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
471 record_gen_tops_before_GC();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
472
0
a61af66fc99e Initial load
duke
parents:
diff changeset
473 if (PrintGC && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
474 gclog_or_tty->print("level=%d invoke=%d size=" SIZE_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
475 i,
a61af66fc99e Initial load
duke
parents:
diff changeset
476 _gens[i]->stat_record()->invocations,
a61af66fc99e Initial load
duke
parents:
diff changeset
477 size*HeapWordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
478 }
a61af66fc99e Initial load
duke
parents:
diff changeset
479
a61af66fc99e Initial load
duke
parents:
diff changeset
480 if (VerifyBeforeGC && i >= VerifyGCLevel &&
a61af66fc99e Initial load
duke
parents:
diff changeset
481 total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
482 HandleMark hm; // Discard invalid handles created during verification
a61af66fc99e Initial load
duke
parents:
diff changeset
483 if (!prepared_for_verification) {
a61af66fc99e Initial load
duke
parents:
diff changeset
484 prepare_for_verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
485 prepared_for_verification = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
487 gclog_or_tty->print(" VerifyBeforeGC:");
a61af66fc99e Initial load
duke
parents:
diff changeset
488 Universe::verify(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
490 COMPILER2_PRESENT(DerivedPointerTable::clear());
a61af66fc99e Initial load
duke
parents:
diff changeset
491
a61af66fc99e Initial load
duke
parents:
diff changeset
492 if (!must_restore_marks_for_biased_locking &&
a61af66fc99e Initial load
duke
parents:
diff changeset
493 _gens[i]->performs_in_place_marking()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
494 // We perform this mark word preservation work lazily
a61af66fc99e Initial load
duke
parents:
diff changeset
495 // because it's only at this point that we know whether we
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // absolutely have to do it; we want to avoid doing it for
a61af66fc99e Initial load
duke
parents:
diff changeset
497 // scavenge-only collections where it's unnecessary
a61af66fc99e Initial load
duke
parents:
diff changeset
498 must_restore_marks_for_biased_locking = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
499 BiasedLocking::preserve_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
501
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // Do collection work
a61af66fc99e Initial load
duke
parents:
diff changeset
503 {
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // Note on ref discovery: For what appear to be historical reasons,
a61af66fc99e Initial load
duke
parents:
diff changeset
505 // GCH enables and disabled (by enqueing) refs discovery.
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // In the future this should be moved into the generation's
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // collect method so that ref discovery and enqueueing concerns
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // are local to a generation. The collect method could return
a61af66fc99e Initial load
duke
parents:
diff changeset
509 // an appropriate indication in the case that notification on
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // the ref lock was needed. This will make the treatment of
a61af66fc99e Initial load
duke
parents:
diff changeset
511 // weak refs more uniform (and indeed remove such concerns
a61af66fc99e Initial load
duke
parents:
diff changeset
512 // from GCH). XXX
a61af66fc99e Initial load
duke
parents:
diff changeset
513
a61af66fc99e Initial load
duke
parents:
diff changeset
514 HandleMark hm; // Discard invalid handles created during gc
a61af66fc99e Initial load
duke
parents:
diff changeset
515 save_marks(); // save marks for all gens
a61af66fc99e Initial load
duke
parents:
diff changeset
516 // We want to discover references, but not process them yet.
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // This mode is disabled in process_discovered_references if the
a61af66fc99e Initial load
duke
parents:
diff changeset
518 // generation does some collection work, or in
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // enqueue_discovered_references if the generation returns
a61af66fc99e Initial load
duke
parents:
diff changeset
520 // without doing any work.
a61af66fc99e Initial load
duke
parents:
diff changeset
521 ReferenceProcessor* rp = _gens[i]->ref_processor();
a61af66fc99e Initial load
duke
parents:
diff changeset
522 // If the discovery of ("weak") refs in this generation is
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // atomic wrt other collectors in this configuration, we
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // are guaranteed to have empty discovered ref lists.
a61af66fc99e Initial load
duke
parents:
diff changeset
525 if (rp->discovery_is_atomic()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
526 rp->verify_no_references_recorded();
a61af66fc99e Initial load
duke
parents:
diff changeset
527 rp->enable_discovery();
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
528 rp->snap_policy(clear_all_soft_refs);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
529 } else {
453
c96030fff130 6684579: SoftReference processing can be made more efficient
ysr
parents: 269
diff changeset
530 // collect() below will enable discovery as appropriate
0
a61af66fc99e Initial load
duke
parents:
diff changeset
531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
532 _gens[i]->collect(full, clear_all_soft_refs, size, is_tlab);
a61af66fc99e Initial load
duke
parents:
diff changeset
533 if (!rp->enqueuing_is_done()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
534 rp->enqueue_discovered_references();
a61af66fc99e Initial load
duke
parents:
diff changeset
535 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
536 rp->set_enqueuing_is_done(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
537 }
a61af66fc99e Initial load
duke
parents:
diff changeset
538 rp->verify_no_references_recorded();
a61af66fc99e Initial load
duke
parents:
diff changeset
539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
540 max_level_collected = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 // Determine if allocation request was met.
a61af66fc99e Initial load
duke
parents:
diff changeset
543 if (size > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
544 if (!is_tlab || _gens[i]->supports_tlab_allocation()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
545 if (size*HeapWordSize <= _gens[i]->unsafe_max_alloc_nogc()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
546 size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
547 }
a61af66fc99e Initial load
duke
parents:
diff changeset
548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
550
a61af66fc99e Initial load
duke
parents:
diff changeset
551 COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
a61af66fc99e Initial load
duke
parents:
diff changeset
552
a61af66fc99e Initial load
duke
parents:
diff changeset
553 _gens[i]->stat_record()->accumulated_time.stop();
a61af66fc99e Initial load
duke
parents:
diff changeset
554
a61af66fc99e Initial load
duke
parents:
diff changeset
555 update_gc_stats(i, full);
a61af66fc99e Initial load
duke
parents:
diff changeset
556
a61af66fc99e Initial load
duke
parents:
diff changeset
557 if (VerifyAfterGC && i >= VerifyGCLevel &&
a61af66fc99e Initial load
duke
parents:
diff changeset
558 total_collections() >= VerifyGCStartAt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
559 HandleMark hm; // Discard invalid handles created during verification
a61af66fc99e Initial load
duke
parents:
diff changeset
560 gclog_or_tty->print(" VerifyAfterGC:");
a61af66fc99e Initial load
duke
parents:
diff changeset
561 Universe::verify(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
562 }
a61af66fc99e Initial load
duke
parents:
diff changeset
563
a61af66fc99e Initial load
duke
parents:
diff changeset
564 if (PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
565 gclog_or_tty->print(":");
a61af66fc99e Initial load
duke
parents:
diff changeset
566 _gens[i]->print_heap_change(prev_used);
a61af66fc99e Initial load
duke
parents:
diff changeset
567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // Update "complete" boolean wrt what actually transpired --
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // for instance, a promotion failure could have led to
a61af66fc99e Initial load
duke
parents:
diff changeset
573 // a whole heap collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
574 complete = complete || (max_level_collected == n_gens() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
575
a61af66fc99e Initial load
duke
parents:
diff changeset
576 if (PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
577 print_heap_change(gch_prev_used);
a61af66fc99e Initial load
duke
parents:
diff changeset
578
a61af66fc99e Initial load
duke
parents:
diff changeset
579 // Print perm gen info for full GC with PrintGCDetails flag.
a61af66fc99e Initial load
duke
parents:
diff changeset
580 if (complete) {
a61af66fc99e Initial load
duke
parents:
diff changeset
581 print_perm_heap_change(perm_prev_used);
a61af66fc99e Initial load
duke
parents:
diff changeset
582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
583 }
a61af66fc99e Initial load
duke
parents:
diff changeset
584
a61af66fc99e Initial load
duke
parents:
diff changeset
585 for (int j = max_level_collected; j >= 0; j -= 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
586 // Adjust generation sizes.
a61af66fc99e Initial load
duke
parents:
diff changeset
587 _gens[j]->compute_new_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
588 }
a61af66fc99e Initial load
duke
parents:
diff changeset
589
a61af66fc99e Initial load
duke
parents:
diff changeset
590 if (complete) {
a61af66fc99e Initial load
duke
parents:
diff changeset
591 // Ask the permanent generation to adjust size for full collections
a61af66fc99e Initial load
duke
parents:
diff changeset
592 perm()->compute_new_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
593 update_full_collections_completed();
a61af66fc99e Initial load
duke
parents:
diff changeset
594 }
a61af66fc99e Initial load
duke
parents:
diff changeset
595
a61af66fc99e Initial load
duke
parents:
diff changeset
596 // Track memory usage and detect low memory after GC finishes
a61af66fc99e Initial load
duke
parents:
diff changeset
597 MemoryService::track_memory_usage();
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 gc_epilogue(complete);
a61af66fc99e Initial load
duke
parents:
diff changeset
600
a61af66fc99e Initial load
duke
parents:
diff changeset
601 if (must_restore_marks_for_biased_locking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
602 BiasedLocking::restore_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
603 }
a61af66fc99e Initial load
duke
parents:
diff changeset
604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
605
a61af66fc99e Initial load
duke
parents:
diff changeset
606 AdaptiveSizePolicy* sp = gen_policy()->size_policy();
a61af66fc99e Initial load
duke
parents:
diff changeset
607 AdaptiveSizePolicyOutput(sp, total_collections());
a61af66fc99e Initial load
duke
parents:
diff changeset
608
a61af66fc99e Initial load
duke
parents:
diff changeset
609 if (PrintHeapAtGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
610 Universe::print_heap_after_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
612
a61af66fc99e Initial load
duke
parents:
diff changeset
613 if (ExitAfterGCNum > 0 && total_collections() == ExitAfterGCNum) {
a61af66fc99e Initial load
duke
parents:
diff changeset
614 tty->print_cr("Stopping after GC #%d", ExitAfterGCNum);
a61af66fc99e Initial load
duke
parents:
diff changeset
615 vm_exit(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
617 }
a61af66fc99e Initial load
duke
parents:
diff changeset
618
a61af66fc99e Initial load
duke
parents:
diff changeset
619 HeapWord* GenCollectedHeap::satisfy_failed_allocation(size_t size, bool is_tlab) {
a61af66fc99e Initial load
duke
parents:
diff changeset
620 return collector_policy()->satisfy_failed_allocation(size, is_tlab);
a61af66fc99e Initial load
duke
parents:
diff changeset
621 }
a61af66fc99e Initial load
duke
parents:
diff changeset
622
a61af66fc99e Initial load
duke
parents:
diff changeset
623 void GenCollectedHeap::set_par_threads(int t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
624 SharedHeap::set_par_threads(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
625 _gen_process_strong_tasks->set_par_threads(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
627
a61af66fc99e Initial load
duke
parents:
diff changeset
628 class AssertIsPermClosure: public OopClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
629 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
630 void do_oop(oop* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
631 assert((*p) == NULL || (*p)->is_perm(), "Referent should be perm.");
a61af66fc99e Initial load
duke
parents:
diff changeset
632 }
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
633 void do_oop(narrowOop* p) { ShouldNotReachHere(); }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
634 };
a61af66fc99e Initial load
duke
parents:
diff changeset
635 static AssertIsPermClosure assert_is_perm_closure;
a61af66fc99e Initial load
duke
parents:
diff changeset
636
a61af66fc99e Initial load
duke
parents:
diff changeset
637 void GenCollectedHeap::
a61af66fc99e Initial load
duke
parents:
diff changeset
638 gen_process_strong_roots(int level,
a61af66fc99e Initial load
duke
parents:
diff changeset
639 bool younger_gens_as_roots,
a61af66fc99e Initial load
duke
parents:
diff changeset
640 bool collecting_perm_gen,
a61af66fc99e Initial load
duke
parents:
diff changeset
641 SharedHeap::ScanningOption so,
a61af66fc99e Initial load
duke
parents:
diff changeset
642 OopsInGenClosure* older_gens,
a61af66fc99e Initial load
duke
parents:
diff changeset
643 OopsInGenClosure* not_older_gens) {
a61af66fc99e Initial load
duke
parents:
diff changeset
644 // General strong roots.
a61af66fc99e Initial load
duke
parents:
diff changeset
645 SharedHeap::process_strong_roots(collecting_perm_gen, so,
a61af66fc99e Initial load
duke
parents:
diff changeset
646 not_older_gens, older_gens);
a61af66fc99e Initial load
duke
parents:
diff changeset
647
a61af66fc99e Initial load
duke
parents:
diff changeset
648 if (younger_gens_as_roots) {
a61af66fc99e Initial load
duke
parents:
diff changeset
649 if (!_gen_process_strong_tasks->is_task_claimed(GCH_PS_younger_gens)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
650 for (int i = 0; i < level; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
651 not_older_gens->set_generation(_gens[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
652 _gens[i]->oop_iterate(not_older_gens);
a61af66fc99e Initial load
duke
parents:
diff changeset
653 }
a61af66fc99e Initial load
duke
parents:
diff changeset
654 not_older_gens->reset_generation();
a61af66fc99e Initial load
duke
parents:
diff changeset
655 }
a61af66fc99e Initial load
duke
parents:
diff changeset
656 }
a61af66fc99e Initial load
duke
parents:
diff changeset
657 // When collection is parallel, all threads get to cooperate to do
a61af66fc99e Initial load
duke
parents:
diff changeset
658 // older-gen scanning.
a61af66fc99e Initial load
duke
parents:
diff changeset
659 for (int i = level+1; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
660 older_gens->set_generation(_gens[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
661 rem_set()->younger_refs_iterate(_gens[i], older_gens);
a61af66fc99e Initial load
duke
parents:
diff changeset
662 older_gens->reset_generation();
a61af66fc99e Initial load
duke
parents:
diff changeset
663 }
a61af66fc99e Initial load
duke
parents:
diff changeset
664
a61af66fc99e Initial load
duke
parents:
diff changeset
665 _gen_process_strong_tasks->all_tasks_completed();
a61af66fc99e Initial load
duke
parents:
diff changeset
666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
667
a61af66fc99e Initial load
duke
parents:
diff changeset
668 void GenCollectedHeap::gen_process_weak_roots(OopClosure* root_closure,
a61af66fc99e Initial load
duke
parents:
diff changeset
669 OopClosure* non_root_closure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
670 SharedHeap::process_weak_roots(root_closure, non_root_closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
671 // "Local" "weak" refs
a61af66fc99e Initial load
duke
parents:
diff changeset
672 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
673 _gens[i]->ref_processor()->weak_oops_do(root_closure);
a61af66fc99e Initial load
duke
parents:
diff changeset
674 }
a61af66fc99e Initial load
duke
parents:
diff changeset
675 }
a61af66fc99e Initial load
duke
parents:
diff changeset
676
a61af66fc99e Initial load
duke
parents:
diff changeset
677 #define GCH_SINCE_SAVE_MARKS_ITERATE_DEFN(OopClosureType, nv_suffix) \
a61af66fc99e Initial load
duke
parents:
diff changeset
678 void GenCollectedHeap:: \
a61af66fc99e Initial load
duke
parents:
diff changeset
679 oop_since_save_marks_iterate(int level, \
a61af66fc99e Initial load
duke
parents:
diff changeset
680 OopClosureType* cur, \
a61af66fc99e Initial load
duke
parents:
diff changeset
681 OopClosureType* older) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
682 _gens[level]->oop_since_save_marks_iterate##nv_suffix(cur); \
a61af66fc99e Initial load
duke
parents:
diff changeset
683 for (int i = level+1; i < n_gens(); i++) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
684 _gens[i]->oop_since_save_marks_iterate##nv_suffix(older); \
a61af66fc99e Initial load
duke
parents:
diff changeset
685 } \
a61af66fc99e Initial load
duke
parents:
diff changeset
686 perm_gen()->oop_since_save_marks_iterate##nv_suffix(older); \
a61af66fc99e Initial load
duke
parents:
diff changeset
687 }
a61af66fc99e Initial load
duke
parents:
diff changeset
688
a61af66fc99e Initial load
duke
parents:
diff changeset
689 ALL_SINCE_SAVE_MARKS_CLOSURES(GCH_SINCE_SAVE_MARKS_ITERATE_DEFN)
a61af66fc99e Initial load
duke
parents:
diff changeset
690
a61af66fc99e Initial load
duke
parents:
diff changeset
691 #undef GCH_SINCE_SAVE_MARKS_ITERATE_DEFN
a61af66fc99e Initial load
duke
parents:
diff changeset
692
a61af66fc99e Initial load
duke
parents:
diff changeset
693 bool GenCollectedHeap::no_allocs_since_save_marks(int level) {
a61af66fc99e Initial load
duke
parents:
diff changeset
694 for (int i = level; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
695 if (!_gens[i]->no_allocs_since_save_marks()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
697 return perm_gen()->no_allocs_since_save_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
698 }
a61af66fc99e Initial load
duke
parents:
diff changeset
699
a61af66fc99e Initial load
duke
parents:
diff changeset
700 bool GenCollectedHeap::supports_inline_contig_alloc() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
701 return _gens[0]->supports_inline_contig_alloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
703
a61af66fc99e Initial load
duke
parents:
diff changeset
704 HeapWord** GenCollectedHeap::top_addr() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
705 return _gens[0]->top_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
706 }
a61af66fc99e Initial load
duke
parents:
diff changeset
707
a61af66fc99e Initial load
duke
parents:
diff changeset
708 HeapWord** GenCollectedHeap::end_addr() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
709 return _gens[0]->end_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
710 }
a61af66fc99e Initial load
duke
parents:
diff changeset
711
a61af66fc99e Initial load
duke
parents:
diff changeset
712 size_t GenCollectedHeap::unsafe_max_alloc() {
a61af66fc99e Initial load
duke
parents:
diff changeset
713 return _gens[0]->unsafe_max_alloc_nogc();
a61af66fc99e Initial load
duke
parents:
diff changeset
714 }
a61af66fc99e Initial load
duke
parents:
diff changeset
715
a61af66fc99e Initial load
duke
parents:
diff changeset
716 // public collection interfaces
a61af66fc99e Initial load
duke
parents:
diff changeset
717
a61af66fc99e Initial load
duke
parents:
diff changeset
718 void GenCollectedHeap::collect(GCCause::Cause cause) {
a61af66fc99e Initial load
duke
parents:
diff changeset
719 if (should_do_concurrent_full_gc(cause)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
720 #ifndef SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // mostly concurrent full collection
a61af66fc99e Initial load
duke
parents:
diff changeset
722 collect_mostly_concurrent(cause);
a61af66fc99e Initial load
duke
parents:
diff changeset
723 #else // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
724 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
725 #endif // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
726 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
727 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
728 if (cause == GCCause::_scavenge_alot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
729 // minor collection only
a61af66fc99e Initial load
duke
parents:
diff changeset
730 collect(cause, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
731 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
732 // Stop-the-world full collection
a61af66fc99e Initial load
duke
parents:
diff changeset
733 collect(cause, n_gens() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
734 }
a61af66fc99e Initial load
duke
parents:
diff changeset
735 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // Stop-the-world full collection
a61af66fc99e Initial load
duke
parents:
diff changeset
737 collect(cause, n_gens() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
738 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
739 }
a61af66fc99e Initial load
duke
parents:
diff changeset
740 }
a61af66fc99e Initial load
duke
parents:
diff changeset
741
a61af66fc99e Initial load
duke
parents:
diff changeset
742 void GenCollectedHeap::collect(GCCause::Cause cause, int max_level) {
a61af66fc99e Initial load
duke
parents:
diff changeset
743 // The caller doesn't have the Heap_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
744 assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
745 MutexLocker ml(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
746 collect_locked(cause, max_level);
a61af66fc99e Initial load
duke
parents:
diff changeset
747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
748
a61af66fc99e Initial load
duke
parents:
diff changeset
749 // This interface assumes that it's being called by the
a61af66fc99e Initial load
duke
parents:
diff changeset
750 // vm thread. It collects the heap assuming that the
a61af66fc99e Initial load
duke
parents:
diff changeset
751 // heap lock is already held and that we are executing in
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // the context of the vm thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
753 void GenCollectedHeap::collect_as_vm_thread(GCCause::Cause cause) {
a61af66fc99e Initial load
duke
parents:
diff changeset
754 assert(Thread::current()->is_VM_thread(), "Precondition#1");
a61af66fc99e Initial load
duke
parents:
diff changeset
755 assert(Heap_lock->is_locked(), "Precondition#2");
a61af66fc99e Initial load
duke
parents:
diff changeset
756 GCCauseSetter gcs(this, cause);
a61af66fc99e Initial load
duke
parents:
diff changeset
757 switch (cause) {
a61af66fc99e Initial load
duke
parents:
diff changeset
758 case GCCause::_heap_inspection:
a61af66fc99e Initial load
duke
parents:
diff changeset
759 case GCCause::_heap_dump: {
a61af66fc99e Initial load
duke
parents:
diff changeset
760 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
761 do_full_collection(false, // don't clear all soft refs
a61af66fc99e Initial load
duke
parents:
diff changeset
762 n_gens() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
763 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
764 }
a61af66fc99e Initial load
duke
parents:
diff changeset
765 default: // XXX FIX ME
a61af66fc99e Initial load
duke
parents:
diff changeset
766 ShouldNotReachHere(); // Unexpected use of this function
a61af66fc99e Initial load
duke
parents:
diff changeset
767 }
a61af66fc99e Initial load
duke
parents:
diff changeset
768 }
a61af66fc99e Initial load
duke
parents:
diff changeset
769
a61af66fc99e Initial load
duke
parents:
diff changeset
770 void GenCollectedHeap::collect_locked(GCCause::Cause cause) {
a61af66fc99e Initial load
duke
parents:
diff changeset
771 // The caller has the Heap_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
772 assert(Heap_lock->owned_by_self(), "this thread should own the Heap_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
773 collect_locked(cause, n_gens() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
774 }
a61af66fc99e Initial load
duke
parents:
diff changeset
775
a61af66fc99e Initial load
duke
parents:
diff changeset
776 // this is the private collection interface
a61af66fc99e Initial load
duke
parents:
diff changeset
777 // The Heap_lock is expected to be held on entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
778
a61af66fc99e Initial load
duke
parents:
diff changeset
779 void GenCollectedHeap::collect_locked(GCCause::Cause cause, int max_level) {
a61af66fc99e Initial load
duke
parents:
diff changeset
780 if (_preloading_shared_classes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
781 warning("\nThe permanent generation is not large enough to preload "
a61af66fc99e Initial load
duke
parents:
diff changeset
782 "requested classes.\nUse -XX:PermSize= to increase the initial "
a61af66fc99e Initial load
duke
parents:
diff changeset
783 "size of the permanent generation.\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
784 vm_exit(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
785 }
a61af66fc99e Initial load
duke
parents:
diff changeset
786 // Read the GC count while holding the Heap_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
787 unsigned int gc_count_before = total_collections();
a61af66fc99e Initial load
duke
parents:
diff changeset
788 unsigned int full_gc_count_before = total_full_collections();
a61af66fc99e Initial load
duke
parents:
diff changeset
789 {
a61af66fc99e Initial load
duke
parents:
diff changeset
790 MutexUnlocker mu(Heap_lock); // give up heap lock, execute gets it back
a61af66fc99e Initial load
duke
parents:
diff changeset
791 VM_GenCollectFull op(gc_count_before, full_gc_count_before,
a61af66fc99e Initial load
duke
parents:
diff changeset
792 cause, max_level);
a61af66fc99e Initial load
duke
parents:
diff changeset
793 VMThread::execute(&op);
a61af66fc99e Initial load
duke
parents:
diff changeset
794 }
a61af66fc99e Initial load
duke
parents:
diff changeset
795 }
a61af66fc99e Initial load
duke
parents:
diff changeset
796
a61af66fc99e Initial load
duke
parents:
diff changeset
797 #ifndef SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
798 bool GenCollectedHeap::create_cms_collector() {
a61af66fc99e Initial load
duke
parents:
diff changeset
799
a61af66fc99e Initial load
duke
parents:
diff changeset
800 assert(((_gens[1]->kind() == Generation::ConcurrentMarkSweep) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
801 (_gens[1]->kind() == Generation::ASConcurrentMarkSweep)) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
802 _perm_gen->as_gen()->kind() == Generation::ConcurrentMarkSweep,
a61af66fc99e Initial load
duke
parents:
diff changeset
803 "Unexpected generation kinds");
a61af66fc99e Initial load
duke
parents:
diff changeset
804 // Skip two header words in the block content verification
a61af66fc99e Initial load
duke
parents:
diff changeset
805 NOT_PRODUCT(_skip_header_HeapWords = CMSCollector::skip_header_HeapWords();)
a61af66fc99e Initial load
duke
parents:
diff changeset
806 CMSCollector* collector = new CMSCollector(
a61af66fc99e Initial load
duke
parents:
diff changeset
807 (ConcurrentMarkSweepGeneration*)_gens[1],
a61af66fc99e Initial load
duke
parents:
diff changeset
808 (ConcurrentMarkSweepGeneration*)_perm_gen->as_gen(),
a61af66fc99e Initial load
duke
parents:
diff changeset
809 _rem_set->as_CardTableRS(),
a61af66fc99e Initial load
duke
parents:
diff changeset
810 (ConcurrentMarkSweepPolicy*) collector_policy());
a61af66fc99e Initial load
duke
parents:
diff changeset
811
a61af66fc99e Initial load
duke
parents:
diff changeset
812 if (collector == NULL || !collector->completed_initialization()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
813 if (collector) {
a61af66fc99e Initial load
duke
parents:
diff changeset
814 delete collector; // Be nice in embedded situation
a61af66fc99e Initial load
duke
parents:
diff changeset
815 }
a61af66fc99e Initial load
duke
parents:
diff changeset
816 vm_shutdown_during_initialization("Could not create CMS collector");
a61af66fc99e Initial load
duke
parents:
diff changeset
817 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
818 }
a61af66fc99e Initial load
duke
parents:
diff changeset
819 return true; // success
a61af66fc99e Initial load
duke
parents:
diff changeset
820 }
a61af66fc99e Initial load
duke
parents:
diff changeset
821
a61af66fc99e Initial load
duke
parents:
diff changeset
822 void GenCollectedHeap::collect_mostly_concurrent(GCCause::Cause cause) {
a61af66fc99e Initial load
duke
parents:
diff changeset
823 assert(!Heap_lock->owned_by_self(), "Should not own Heap_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
824
a61af66fc99e Initial load
duke
parents:
diff changeset
825 MutexLocker ml(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
826 // Read the GC counts while holding the Heap_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
827 unsigned int full_gc_count_before = total_full_collections();
a61af66fc99e Initial load
duke
parents:
diff changeset
828 unsigned int gc_count_before = total_collections();
a61af66fc99e Initial load
duke
parents:
diff changeset
829 {
a61af66fc99e Initial load
duke
parents:
diff changeset
830 MutexUnlocker mu(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
831 VM_GenCollectFullConcurrent op(gc_count_before, full_gc_count_before, cause);
a61af66fc99e Initial load
duke
parents:
diff changeset
832 VMThread::execute(&op);
a61af66fc99e Initial load
duke
parents:
diff changeset
833 }
a61af66fc99e Initial load
duke
parents:
diff changeset
834 }
a61af66fc99e Initial load
duke
parents:
diff changeset
835 #endif // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
836
a61af66fc99e Initial load
duke
parents:
diff changeset
837
a61af66fc99e Initial load
duke
parents:
diff changeset
838 void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs,
a61af66fc99e Initial load
duke
parents:
diff changeset
839 int max_level) {
a61af66fc99e Initial load
duke
parents:
diff changeset
840 int local_max_level;
a61af66fc99e Initial load
duke
parents:
diff changeset
841 if (!incremental_collection_will_fail() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
842 gc_cause() == GCCause::_gc_locker) {
a61af66fc99e Initial load
duke
parents:
diff changeset
843 local_max_level = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
844 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
845 local_max_level = max_level;
a61af66fc99e Initial load
duke
parents:
diff changeset
846 }
a61af66fc99e Initial load
duke
parents:
diff changeset
847
a61af66fc99e Initial load
duke
parents:
diff changeset
848 do_collection(true /* full */,
a61af66fc99e Initial load
duke
parents:
diff changeset
849 clear_all_soft_refs /* clear_all_soft_refs */,
a61af66fc99e Initial load
duke
parents:
diff changeset
850 0 /* size */,
a61af66fc99e Initial load
duke
parents:
diff changeset
851 false /* is_tlab */,
a61af66fc99e Initial load
duke
parents:
diff changeset
852 local_max_level /* max_level */);
a61af66fc99e Initial load
duke
parents:
diff changeset
853 // Hack XXX FIX ME !!!
a61af66fc99e Initial load
duke
parents:
diff changeset
854 // A scavenge may not have been attempted, or may have
a61af66fc99e Initial load
duke
parents:
diff changeset
855 // been attempted and failed, because the old gen was too full
a61af66fc99e Initial load
duke
parents:
diff changeset
856 if (local_max_level == 0 && gc_cause() == GCCause::_gc_locker &&
a61af66fc99e Initial load
duke
parents:
diff changeset
857 incremental_collection_will_fail()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
858 if (PrintGCDetails) {
a61af66fc99e Initial load
duke
parents:
diff changeset
859 gclog_or_tty->print_cr("GC locker: Trying a full collection "
a61af66fc99e Initial load
duke
parents:
diff changeset
860 "because scavenge failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
862 // This time allow the old gen to be collected as well
a61af66fc99e Initial load
duke
parents:
diff changeset
863 do_collection(true /* full */,
a61af66fc99e Initial load
duke
parents:
diff changeset
864 clear_all_soft_refs /* clear_all_soft_refs */,
a61af66fc99e Initial load
duke
parents:
diff changeset
865 0 /* size */,
a61af66fc99e Initial load
duke
parents:
diff changeset
866 false /* is_tlab */,
a61af66fc99e Initial load
duke
parents:
diff changeset
867 n_gens() - 1 /* max_level */);
a61af66fc99e Initial load
duke
parents:
diff changeset
868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
869 }
a61af66fc99e Initial load
duke
parents:
diff changeset
870
a61af66fc99e Initial load
duke
parents:
diff changeset
871 // Returns "TRUE" iff "p" points into the allocated area of the heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
872 bool GenCollectedHeap::is_in(const void* p) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
873 #ifndef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
874 guarantee(VerifyBeforeGC ||
a61af66fc99e Initial load
duke
parents:
diff changeset
875 VerifyDuringGC ||
a61af66fc99e Initial load
duke
parents:
diff changeset
876 VerifyBeforeExit ||
a61af66fc99e Initial load
duke
parents:
diff changeset
877 VerifyAfterGC, "too expensive");
a61af66fc99e Initial load
duke
parents:
diff changeset
878 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
879 // This might be sped up with a cache of the last generation that
a61af66fc99e Initial load
duke
parents:
diff changeset
880 // answered yes.
a61af66fc99e Initial load
duke
parents:
diff changeset
881 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
882 if (_gens[i]->is_in(p)) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
883 }
a61af66fc99e Initial load
duke
parents:
diff changeset
884 if (_perm_gen->as_gen()->is_in(p)) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
885 // Otherwise...
a61af66fc99e Initial load
duke
parents:
diff changeset
886 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
887 }
a61af66fc99e Initial load
duke
parents:
diff changeset
888
a61af66fc99e Initial load
duke
parents:
diff changeset
889 // Returns "TRUE" iff "p" points into the allocated area of the heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
890 bool GenCollectedHeap::is_in_youngest(void* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
891 return _gens[0]->is_in(p);
a61af66fc99e Initial load
duke
parents:
diff changeset
892 }
a61af66fc99e Initial load
duke
parents:
diff changeset
893
a61af66fc99e Initial load
duke
parents:
diff changeset
894 void GenCollectedHeap::oop_iterate(OopClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
895 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
896 _gens[i]->oop_iterate(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
899
a61af66fc99e Initial load
duke
parents:
diff changeset
900 void GenCollectedHeap::oop_iterate(MemRegion mr, OopClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
901 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
902 _gens[i]->oop_iterate(mr, cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
903 }
a61af66fc99e Initial load
duke
parents:
diff changeset
904 }
a61af66fc99e Initial load
duke
parents:
diff changeset
905
a61af66fc99e Initial load
duke
parents:
diff changeset
906 void GenCollectedHeap::object_iterate(ObjectClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
907 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
908 _gens[i]->object_iterate(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
909 }
a61af66fc99e Initial load
duke
parents:
diff changeset
910 perm_gen()->object_iterate(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
911 }
a61af66fc99e Initial load
duke
parents:
diff changeset
912
a61af66fc99e Initial load
duke
parents:
diff changeset
913 void GenCollectedHeap::object_iterate_since_last_GC(ObjectClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
914 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
915 _gens[i]->object_iterate_since_last_GC(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
917 }
a61af66fc99e Initial load
duke
parents:
diff changeset
918
a61af66fc99e Initial load
duke
parents:
diff changeset
919 Space* GenCollectedHeap::space_containing(const void* addr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
920 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
921 Space* res = _gens[i]->space_containing(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
922 if (res != NULL) return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
924 Space* res = perm_gen()->space_containing(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
925 if (res != NULL) return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
926 // Otherwise...
a61af66fc99e Initial load
duke
parents:
diff changeset
927 assert(false, "Could not find containing space");
a61af66fc99e Initial load
duke
parents:
diff changeset
928 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
929 }
a61af66fc99e Initial load
duke
parents:
diff changeset
930
a61af66fc99e Initial load
duke
parents:
diff changeset
931
a61af66fc99e Initial load
duke
parents:
diff changeset
932 HeapWord* GenCollectedHeap::block_start(const void* addr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
933 assert(is_in_reserved(addr), "block_start of address outside of heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
934 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
935 if (_gens[i]->is_in_reserved(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
936 assert(_gens[i]->is_in(addr),
a61af66fc99e Initial load
duke
parents:
diff changeset
937 "addr should be in allocated part of generation");
a61af66fc99e Initial load
duke
parents:
diff changeset
938 return _gens[i]->block_start(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
939 }
a61af66fc99e Initial load
duke
parents:
diff changeset
940 }
a61af66fc99e Initial load
duke
parents:
diff changeset
941 if (perm_gen()->is_in_reserved(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
942 assert(perm_gen()->is_in(addr),
a61af66fc99e Initial load
duke
parents:
diff changeset
943 "addr should be in allocated part of perm gen");
a61af66fc99e Initial load
duke
parents:
diff changeset
944 return perm_gen()->block_start(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
945 }
a61af66fc99e Initial load
duke
parents:
diff changeset
946 assert(false, "Some generation should contain the address");
a61af66fc99e Initial load
duke
parents:
diff changeset
947 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
949
a61af66fc99e Initial load
duke
parents:
diff changeset
950 size_t GenCollectedHeap::block_size(const HeapWord* addr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
951 assert(is_in_reserved(addr), "block_size of address outside of heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
952 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
953 if (_gens[i]->is_in_reserved(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
954 assert(_gens[i]->is_in(addr),
a61af66fc99e Initial load
duke
parents:
diff changeset
955 "addr should be in allocated part of generation");
a61af66fc99e Initial load
duke
parents:
diff changeset
956 return _gens[i]->block_size(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
957 }
a61af66fc99e Initial load
duke
parents:
diff changeset
958 }
a61af66fc99e Initial load
duke
parents:
diff changeset
959 if (perm_gen()->is_in_reserved(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
960 assert(perm_gen()->is_in(addr),
a61af66fc99e Initial load
duke
parents:
diff changeset
961 "addr should be in allocated part of perm gen");
a61af66fc99e Initial load
duke
parents:
diff changeset
962 return perm_gen()->block_size(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
963 }
a61af66fc99e Initial load
duke
parents:
diff changeset
964 assert(false, "Some generation should contain the address");
a61af66fc99e Initial load
duke
parents:
diff changeset
965 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
967
a61af66fc99e Initial load
duke
parents:
diff changeset
968 bool GenCollectedHeap::block_is_obj(const HeapWord* addr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
969 assert(is_in_reserved(addr), "block_is_obj of address outside of heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
970 assert(block_start(addr) == addr, "addr must be a block start");
a61af66fc99e Initial load
duke
parents:
diff changeset
971 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
972 if (_gens[i]->is_in_reserved(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
973 return _gens[i]->block_is_obj(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
974 }
a61af66fc99e Initial load
duke
parents:
diff changeset
975 }
a61af66fc99e Initial load
duke
parents:
diff changeset
976 if (perm_gen()->is_in_reserved(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
977 return perm_gen()->block_is_obj(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
978 }
a61af66fc99e Initial load
duke
parents:
diff changeset
979 assert(false, "Some generation should contain the address");
a61af66fc99e Initial load
duke
parents:
diff changeset
980 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
981 }
a61af66fc99e Initial load
duke
parents:
diff changeset
982
a61af66fc99e Initial load
duke
parents:
diff changeset
983 bool GenCollectedHeap::supports_tlab_allocation() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
984 for (int i = 0; i < _n_gens; i += 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
985 if (_gens[i]->supports_tlab_allocation()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
986 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
987 }
a61af66fc99e Initial load
duke
parents:
diff changeset
988 }
a61af66fc99e Initial load
duke
parents:
diff changeset
989 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
991
a61af66fc99e Initial load
duke
parents:
diff changeset
992 size_t GenCollectedHeap::tlab_capacity(Thread* thr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
993 size_t result = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
994 for (int i = 0; i < _n_gens; i += 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
995 if (_gens[i]->supports_tlab_allocation()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
996 result += _gens[i]->tlab_capacity();
a61af66fc99e Initial load
duke
parents:
diff changeset
997 }
a61af66fc99e Initial load
duke
parents:
diff changeset
998 }
a61af66fc99e Initial load
duke
parents:
diff changeset
999 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1001
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 size_t GenCollectedHeap::unsafe_max_tlab_alloc(Thread* thr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 size_t result = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 for (int i = 0; i < _n_gens; i += 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 if (_gens[i]->supports_tlab_allocation()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 result += _gens[i]->unsafe_max_tlab_alloc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1011
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 HeapWord* GenCollectedHeap::allocate_new_tlab(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 bool gc_overhead_limit_was_exceeded;
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 HeapWord* result = mem_allocate(size /* size */,
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 false /* is_large_noref */,
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 true /* is_tlab */,
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 &gc_overhead_limit_was_exceeded);
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1020
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 // Requires "*prev_ptr" to be non-NULL. Deletes and a block of minimal size
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 // from the list headed by "*prev_ptr".
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 static ScratchBlock *removeSmallestScratch(ScratchBlock **prev_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 bool first = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 size_t min_size = 0; // "first" makes this conceptually infinite.
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 ScratchBlock **smallest_ptr, *smallest;
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 ScratchBlock *cur = *prev_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 while (cur) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 assert(*prev_ptr == cur, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 if (first || cur->num_words < min_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 smallest_ptr = prev_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 smallest = cur;
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 min_size = smallest->num_words;
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 first = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 prev_ptr = &cur->next;
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 cur = cur->next;
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 smallest = *smallest_ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 *smallest_ptr = smallest->next;
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 return smallest;
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1043
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 // Sort the scratch block list headed by res into decreasing size order,
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 // and set "res" to the result.
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 static void sort_scratch_list(ScratchBlock*& list) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 ScratchBlock* sorted = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 ScratchBlock* unsorted = list;
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 while (unsorted) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 ScratchBlock *smallest = removeSmallestScratch(&unsorted);
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 smallest->next = sorted;
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 sorted = smallest;
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 list = sorted;
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1056
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 ScratchBlock* GenCollectedHeap::gather_scratch(Generation* requestor,
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 size_t max_alloc_words) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 ScratchBlock* res = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 _gens[i]->contribute_scratch(res, requestor, max_alloc_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 sort_scratch_list(res);
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1066
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1067 void GenCollectedHeap::release_scratch() {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1068 for (int i = 0; i < _n_gens; i++) {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1069 _gens[i]->reset_scratch();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1070 }
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1071 }
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1072
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 size_t GenCollectedHeap::large_typearray_limit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 return gen_policy()->large_typearray_limit();
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1076
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 class GenPrepareForVerifyClosure: public GenCollectedHeap::GenClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 void do_generation(Generation* gen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 gen->prepare_for_verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1082
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 void GenCollectedHeap::prepare_for_verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 ensure_parsability(false); // no need to retire TLABs
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 GenPrepareForVerifyClosure blk;
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 generation_iterate(&blk, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 perm_gen()->prepare_for_verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1089
a61af66fc99e Initial load
duke
parents:
diff changeset
1090
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 void GenCollectedHeap::generation_iterate(GenClosure* cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 bool old_to_young) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 if (old_to_young) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 for (int i = _n_gens-1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 cl->do_generation(_gens[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 cl->do_generation(_gens[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1103
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 void GenCollectedHeap::space_iterate(SpaceClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 _gens[i]->space_iterate(cl, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 perm_gen()->space_iterate(cl, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1110
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 bool GenCollectedHeap::is_maximal_no_gc() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 for (int i = 0; i < _n_gens; i++) { // skip perm gen
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 if (!_gens[i]->is_maximal_no_gc()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1119
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 void GenCollectedHeap::save_marks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 _gens[i]->save_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 perm_gen()->save_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1126
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 void GenCollectedHeap::compute_new_generation_sizes(int collectedGen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 for (int i = 0; i <= collectedGen; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 _gens[i]->compute_new_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1132
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 GenCollectedHeap* GenCollectedHeap::heap() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 assert(_gch != NULL, "Uninitialized access to GenCollectedHeap::heap()");
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 assert(_gch->kind() == CollectedHeap::GenCollectedHeap, "not a generational heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 return _gch;
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1138
a61af66fc99e Initial load
duke
parents:
diff changeset
1139
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 void GenCollectedHeap::prepare_for_compaction() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 Generation* scanning_gen = _gens[_n_gens-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 // Start by compacting into same gen.
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 CompactPoint cp(scanning_gen, NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 while (scanning_gen != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 scanning_gen->prepare_for_compaction(&cp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 scanning_gen = prev_gen(scanning_gen);
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1149
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 GCStats* GenCollectedHeap::gc_stats(int level) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 return _gens[level]->gc_stats();
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1153
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 void GenCollectedHeap::verify(bool allow_dirty, bool silent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 if (!silent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 gclog_or_tty->print("permgen ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 perm_gen()->verify(allow_dirty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 for (int i = _n_gens-1; i >= 0; i--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 Generation* g = _gens[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 if (!silent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 gclog_or_tty->print(g->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 gclog_or_tty->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 g->verify(allow_dirty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 if (!silent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 gclog_or_tty->print("remset ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 rem_set()->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 if (!silent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 gclog_or_tty->print("ref_proc ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 ReferenceProcessor::verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1176
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 void GenCollectedHeap::print() const { print_on(tty); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 void GenCollectedHeap::print_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 for (int i = 0; i < _n_gens; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 _gens[i]->print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 perm_gen()->print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1184
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 void GenCollectedHeap::gc_threads_do(ThreadClosure* tc) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 if (workers() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 workers()->threads_do(tc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 #ifndef SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 if (UseConcMarkSweepGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 ConcurrentMarkSweepThread::threads_do(tc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 #endif // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1195
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 void GenCollectedHeap::print_gc_threads_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 #ifndef SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 if (UseParNewGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 workers()->print_worker_threads_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 if (UseConcMarkSweepGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 ConcurrentMarkSweepThread::print_all_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 #endif // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1206
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 void GenCollectedHeap::print_tracing_info() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 if (TraceGen0Time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 get_gen(0)->print_summary_info();
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 if (TraceGen1Time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 get_gen(1)->print_summary_info();
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1215
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 void GenCollectedHeap::print_heap_change(size_t prev_used) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 if (PrintGCDetails && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 gclog_or_tty->print(" " SIZE_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 "->" SIZE_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 "(" SIZE_FORMAT ")",
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 prev_used, used(), capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 gclog_or_tty->print(" " SIZE_FORMAT "K"
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 "->" SIZE_FORMAT "K"
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 "(" SIZE_FORMAT "K)",
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 prev_used / K, used() / K, capacity() / K);
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1229
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 //New method to print perm gen info with PrintGCDetails flag
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 void GenCollectedHeap::print_perm_heap_change(size_t perm_prev_used) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 gclog_or_tty->print(", [%s :", perm_gen()->short_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 perm_gen()->print_heap_change(perm_prev_used);
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 gclog_or_tty->print("]");
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1236
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 class GenGCPrologueClosure: public GenCollectedHeap::GenClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 bool _full;
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 void do_generation(Generation* gen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 gen->gc_prologue(_full);
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 GenGCPrologueClosure(bool full) : _full(full) {};
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1246
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 void GenCollectedHeap::gc_prologue(bool full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer");
a61af66fc99e Initial load
duke
parents:
diff changeset
1249
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 always_do_update_barrier = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 // Fill TLAB's and such
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 CollectedHeap::accumulate_statistics_all_tlabs();
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 ensure_parsability(true); // retire TLABs
a61af66fc99e Initial load
duke
parents:
diff changeset
1254
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 // Call allocation profiler
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 AllocationProfiler::iterate_since_last_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 // Walk generations
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 GenGCPrologueClosure blk(full);
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 generation_iterate(&blk, false); // not old-to-young.
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 perm_gen()->gc_prologue(full);
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1262
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 class GenGCEpilogueClosure: public GenCollectedHeap::GenClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 bool _full;
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 void do_generation(Generation* gen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 gen->gc_epilogue(_full);
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 GenGCEpilogueClosure(bool full) : _full(full) {};
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1272
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 void GenCollectedHeap::gc_epilogue(bool full) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 // Remember if a partial collection of the heap failed, and
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 // we did a complete collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 if (full && incremental_collection_will_fail()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 set_last_incremental_collection_failed();
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 clear_last_incremental_collection_failed();
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 // Clear the flag, if set; the generation gc_epilogues will set the
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 // flag again if the condition persists despite the collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 clear_incremental_collection_will_fail();
a61af66fc99e Initial load
duke
parents:
diff changeset
1284
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 #ifdef COMPILER2
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 assert(DerivedPointerTable::is_empty(), "derived pointer present");
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 size_t actual_gap = pointer_delta((HeapWord*) (max_uintx-3), *(end_addr()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 guarantee(actual_gap > (size_t)FastAllocateSizeLimit, "inline allocation wraps");
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 #endif /* COMPILER2 */
a61af66fc99e Initial load
duke
parents:
diff changeset
1290
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 resize_all_tlabs();
a61af66fc99e Initial load
duke
parents:
diff changeset
1292
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 GenGCEpilogueClosure blk(full);
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 generation_iterate(&blk, false); // not old-to-young.
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 perm_gen()->gc_epilogue(full);
a61af66fc99e Initial load
duke
parents:
diff changeset
1296
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 always_do_update_barrier = UseConcMarkSweepGC;
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1299
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1300 #ifndef PRODUCT
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1301 class GenGCSaveTopsBeforeGCClosure: public GenCollectedHeap::GenClosure {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1302 private:
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1303 public:
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1304 void do_generation(Generation* gen) {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1305 gen->record_spaces_top();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1306 }
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1307 };
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1308
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1309 void GenCollectedHeap::record_gen_tops_before_GC() {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1310 if (ZapUnusedHeapArea) {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1311 GenGCSaveTopsBeforeGCClosure blk;
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1312 generation_iterate(&blk, false); // not old-to-young.
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1313 perm_gen()->record_spaces_top();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1314 }
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1315 }
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1316 #endif // not PRODUCT
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 113
diff changeset
1317
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 class GenEnsureParsabilityClosure: public GenCollectedHeap::GenClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 void do_generation(Generation* gen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 gen->ensure_parsability();
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1324
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 void GenCollectedHeap::ensure_parsability(bool retire_tlabs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 CollectedHeap::ensure_parsability(retire_tlabs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 GenEnsureParsabilityClosure ep_cl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 generation_iterate(&ep_cl, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 perm_gen()->ensure_parsability();
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1331
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 oop GenCollectedHeap::handle_failed_promotion(Generation* gen,
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 oop obj,
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
1334 size_t obj_size) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 assert(obj_size == (size_t)obj->size(), "bad obj_size passed in");
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 HeapWord* result = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1337
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 // First give each higher generation a chance to allocate the promoted object.
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 Generation* allocator = next_gen(gen);
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 if (allocator != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 result = allocator->allocate(obj_size, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 } while (result == NULL && (allocator = next_gen(allocator)) != NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1345
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 if (result == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 // Then give gen and higher generations a chance to expand and allocate the
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 // object.
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 result = gen->expand_and_allocate(obj_size, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 } while (result == NULL && (gen = next_gen(gen)) != NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1353
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 if (result != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 Copy::aligned_disjoint_words((HeapWord*)obj, result, obj_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 return oop(result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1359
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 class GenTimeOfLastGCClosure: public GenCollectedHeap::GenClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 jlong _time; // in ms
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 jlong _now; // in ms
a61af66fc99e Initial load
duke
parents:
diff changeset
1363
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 GenTimeOfLastGCClosure(jlong now) : _time(now), _now(now) { }
a61af66fc99e Initial load
duke
parents:
diff changeset
1366
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 jlong time() { return _time; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1368
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 void do_generation(Generation* gen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 _time = MIN2(_time, gen->time_of_last_gc(_now));
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1373
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 jlong GenCollectedHeap::millis_since_last_gc() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 jlong now = os::javaTimeMillis();
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 GenTimeOfLastGCClosure tolgc_cl(now);
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 // iterate over generations getting the oldest
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 // time that a generation was collected
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 generation_iterate(&tolgc_cl, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 tolgc_cl.do_generation(perm_gen());
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 // XXX Despite the assert above, since javaTimeMillis()
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 // doesnot guarantee monotonically increasing return
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 // values (note, i didn't say "strictly monotonic"),
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 // we need to guard against getting back a time
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 // later than now. This should be fixed by basing
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 // on someting like gethrtime() which guarantees
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 // monotonicity. Note that cond_wait() is susceptible
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 // to a similar problem, because its interface is
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 // based on absolute time in the form of the
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 // system time's notion of UCT. See also 4506635
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 // for yet another problem of similar nature. XXX
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 jlong retVal = now - tolgc_cl.time();
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 if (retVal < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 NOT_PRODUCT(warning("time warp: %d", retVal);)
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 return retVal;
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 }