annotate src/share/vm/memory/genCollectedHeap.cpp @ 3772:6747fd0512e0

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