annotate src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.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 /*
2251
336d17dff7cc 7014874: Incorrect COOPs modes on solaris-{sparcv9,amd64} with ParallelGC
kvn
parents: 1972
diff changeset
2 * Copyright (c) 2001, 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: 1387
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1387
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: 1387
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: 1907
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
26 #include "gc_implementation/parallelScavenge/adjoiningGenerations.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
27 #include "gc_implementation/parallelScavenge/adjoiningVirtualSpaces.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
28 #include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
29 #include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
30 #include "gc_implementation/parallelScavenge/generationSizer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
31 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
32 #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
33 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
34 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
35 #include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
36 #include "gc_implementation/parallelScavenge/psScavenge.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
37 #include "gc_implementation/parallelScavenge/vmPSOperations.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
38 #include "memory/gcLocker.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
39 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
40 #include "runtime/handles.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
41 #include "runtime/java.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
42 #include "runtime/vmThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1907
diff changeset
43 #include "utilities/vmError.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
44
a61af66fc99e Initial load
duke
parents:
diff changeset
45 PSYoungGen* ParallelScavengeHeap::_young_gen = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
46 PSOldGen* ParallelScavengeHeap::_old_gen = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
47 PSPermGen* ParallelScavengeHeap::_perm_gen = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
48 PSAdaptiveSizePolicy* ParallelScavengeHeap::_size_policy = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
49 PSGCAdaptivePolicyCounters* ParallelScavengeHeap::_gc_policy_counters = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
50 ParallelScavengeHeap* ParallelScavengeHeap::_psh = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
51 GCTaskManager* ParallelScavengeHeap::_gc_task_manager = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53 static void trace_gen_sizes(const char* const str,
a61af66fc99e Initial load
duke
parents:
diff changeset
54 size_t pg_min, size_t pg_max,
a61af66fc99e Initial load
duke
parents:
diff changeset
55 size_t og_min, size_t og_max,
a61af66fc99e Initial load
duke
parents:
diff changeset
56 size_t yg_min, size_t yg_max)
a61af66fc99e Initial load
duke
parents:
diff changeset
57 {
a61af66fc99e Initial load
duke
parents:
diff changeset
58 if (TracePageSizes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
59 tty->print_cr("%s: " SIZE_FORMAT "," SIZE_FORMAT " "
a61af66fc99e Initial load
duke
parents:
diff changeset
60 SIZE_FORMAT "," SIZE_FORMAT " "
a61af66fc99e Initial load
duke
parents:
diff changeset
61 SIZE_FORMAT "," SIZE_FORMAT " "
a61af66fc99e Initial load
duke
parents:
diff changeset
62 SIZE_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
63 str, pg_min / K, pg_max / K,
a61af66fc99e Initial load
duke
parents:
diff changeset
64 og_min / K, og_max / K,
a61af66fc99e Initial load
duke
parents:
diff changeset
65 yg_min / K, yg_max / K,
a61af66fc99e Initial load
duke
parents:
diff changeset
66 (pg_max + og_max + yg_max) / K);
a61af66fc99e Initial load
duke
parents:
diff changeset
67 }
a61af66fc99e Initial load
duke
parents:
diff changeset
68 }
a61af66fc99e Initial load
duke
parents:
diff changeset
69
a61af66fc99e Initial load
duke
parents:
diff changeset
70 jint ParallelScavengeHeap::initialize() {
1166
7b0e9cba0307 6896647: card marks can be deferred too long
ysr
parents: 1027
diff changeset
71 CollectedHeap::pre_initialize();
7b0e9cba0307 6896647: card marks can be deferred too long
ysr
parents: 1027
diff changeset
72
0
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // Cannot be initialized until after the flags are parsed
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
74 // GenerationSizer flag_parser;
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
75 _collector_policy = new GenerationSizer();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
76
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
77 size_t yg_min_size = _collector_policy->min_young_gen_size();
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
78 size_t yg_max_size = _collector_policy->max_young_gen_size();
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
79 size_t og_min_size = _collector_policy->min_old_gen_size();
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
80 size_t og_max_size = _collector_policy->max_old_gen_size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // Why isn't there a min_perm_gen_size()?
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
82 size_t pg_min_size = _collector_policy->perm_gen_size();
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
83 size_t pg_max_size = _collector_policy->max_perm_gen_size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 trace_gen_sizes("ps heap raw",
a61af66fc99e Initial load
duke
parents:
diff changeset
86 pg_min_size, pg_max_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
87 og_min_size, og_max_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
88 yg_min_size, yg_max_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
89
a61af66fc99e Initial load
duke
parents:
diff changeset
90 // The ReservedSpace ctor used below requires that the page size for the perm
a61af66fc99e Initial load
duke
parents:
diff changeset
91 // gen is <= the page size for the rest of the heap (young + old gens).
a61af66fc99e Initial load
duke
parents:
diff changeset
92 const size_t og_page_sz = os::page_size_for_region(yg_min_size + og_min_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
93 yg_max_size + og_max_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
94 8);
a61af66fc99e Initial load
duke
parents:
diff changeset
95 const size_t pg_page_sz = MIN2(os::page_size_for_region(pg_min_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
96 pg_max_size, 16),
a61af66fc99e Initial load
duke
parents:
diff changeset
97 og_page_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
98
a61af66fc99e Initial load
duke
parents:
diff changeset
99 const size_t pg_align = set_alignment(_perm_gen_alignment, pg_page_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
100 const size_t og_align = set_alignment(_old_gen_alignment, og_page_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
101 const size_t yg_align = set_alignment(_young_gen_alignment, og_page_sz);
a61af66fc99e Initial load
duke
parents:
diff changeset
102
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // Update sizes to reflect the selected page size(s).
a61af66fc99e Initial load
duke
parents:
diff changeset
104 //
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // NEEDS_CLEANUP. The default TwoGenerationCollectorPolicy uses NewRatio; it
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // should check UseAdaptiveSizePolicy. Changes from generationSizer could
a61af66fc99e Initial load
duke
parents:
diff changeset
107 // move to the common code.
a61af66fc99e Initial load
duke
parents:
diff changeset
108 yg_min_size = align_size_up(yg_min_size, yg_align);
a61af66fc99e Initial load
duke
parents:
diff changeset
109 yg_max_size = align_size_up(yg_max_size, yg_align);
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
110 size_t yg_cur_size =
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
111 align_size_up(_collector_policy->young_gen_size(), yg_align);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
112 yg_cur_size = MAX2(yg_cur_size, yg_min_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
113
a61af66fc99e Initial load
duke
parents:
diff changeset
114 og_min_size = align_size_up(og_min_size, og_align);
2251
336d17dff7cc 7014874: Incorrect COOPs modes on solaris-{sparcv9,amd64} with ParallelGC
kvn
parents: 1972
diff changeset
115 // Align old gen size down to preserve specified heap size.
336d17dff7cc 7014874: Incorrect COOPs modes on solaris-{sparcv9,amd64} with ParallelGC
kvn
parents: 1972
diff changeset
116 assert(og_align == yg_align, "sanity");
336d17dff7cc 7014874: Incorrect COOPs modes on solaris-{sparcv9,amd64} with ParallelGC
kvn
parents: 1972
diff changeset
117 og_max_size = align_size_down(og_max_size, og_align);
336d17dff7cc 7014874: Incorrect COOPs modes on solaris-{sparcv9,amd64} with ParallelGC
kvn
parents: 1972
diff changeset
118 og_max_size = MAX2(og_max_size, og_min_size);
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
119 size_t og_cur_size =
2251
336d17dff7cc 7014874: Incorrect COOPs modes on solaris-{sparcv9,amd64} with ParallelGC
kvn
parents: 1972
diff changeset
120 align_size_down(_collector_policy->old_gen_size(), og_align);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
121 og_cur_size = MAX2(og_cur_size, og_min_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
122
a61af66fc99e Initial load
duke
parents:
diff changeset
123 pg_min_size = align_size_up(pg_min_size, pg_align);
a61af66fc99e Initial load
duke
parents:
diff changeset
124 pg_max_size = align_size_up(pg_max_size, pg_align);
a61af66fc99e Initial load
duke
parents:
diff changeset
125 size_t pg_cur_size = pg_min_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
126
a61af66fc99e Initial load
duke
parents:
diff changeset
127 trace_gen_sizes("ps heap rnd",
a61af66fc99e Initial load
duke
parents:
diff changeset
128 pg_min_size, pg_max_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
129 og_min_size, og_max_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
130 yg_min_size, yg_max_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
131
642
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
132 const size_t total_reserved = pg_max_size + og_max_size + yg_max_size;
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
133 char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop);
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
134
0
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // The main part of the heap (old gen + young gen) can often use a larger page
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // size than is needed or wanted for the perm gen. Use the "compound
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // alignment" ReservedSpace ctor to avoid having to use the same page size for
a61af66fc99e Initial load
duke
parents:
diff changeset
138 // all gens.
642
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
139
237
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
140 ReservedHeapSpace heap_rs(pg_max_size, pg_align, og_max_size + yg_max_size,
642
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
141 og_align, addr);
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
142
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
143 if (UseCompressedOops) {
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
144 if (addr != NULL && !heap_rs.is_reserved()) {
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
145 // Failed to reserve at specified address - the requested memory
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
146 // region is taken already, for example, by 'java' launcher.
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
147 // Try again to reserver heap higher.
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
148 addr = Universe::preferred_heap_base(total_reserved, Universe::ZeroBasedNarrowOop);
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
149 ReservedHeapSpace heap_rs0(pg_max_size, pg_align, og_max_size + yg_max_size,
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
150 og_align, addr);
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
151 if (addr != NULL && !heap_rs0.is_reserved()) {
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
152 // Failed to reserve at specified address again - give up.
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
153 addr = Universe::preferred_heap_base(total_reserved, Universe::HeapBasedNarrowOop);
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
154 assert(addr == NULL, "");
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
155 ReservedHeapSpace heap_rs1(pg_max_size, pg_align, og_max_size + yg_max_size,
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
156 og_align, addr);
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
157 heap_rs = heap_rs1;
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
158 } else {
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
159 heap_rs = heap_rs0;
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
160 }
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
161 }
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
162 }
660978a2a31a 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 374
diff changeset
163
0
a61af66fc99e Initial load
duke
parents:
diff changeset
164 os::trace_page_sizes("ps perm", pg_min_size, pg_max_size, pg_page_sz,
a61af66fc99e Initial load
duke
parents:
diff changeset
165 heap_rs.base(), pg_max_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
166 os::trace_page_sizes("ps main", og_min_size + yg_min_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
167 og_max_size + yg_max_size, og_page_sz,
a61af66fc99e Initial load
duke
parents:
diff changeset
168 heap_rs.base() + pg_max_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
169 heap_rs.size() - pg_max_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
170 if (!heap_rs.is_reserved()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 vm_shutdown_during_initialization(
a61af66fc99e Initial load
duke
parents:
diff changeset
172 "Could not reserve enough space for object heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
173 return JNI_ENOMEM;
a61af66fc99e Initial load
duke
parents:
diff changeset
174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
175
a61af66fc99e Initial load
duke
parents:
diff changeset
176 _reserved = MemRegion((HeapWord*)heap_rs.base(),
a61af66fc99e Initial load
duke
parents:
diff changeset
177 (HeapWord*)(heap_rs.base() + heap_rs.size()));
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 CardTableExtension* const barrier_set = new CardTableExtension(_reserved, 3);
a61af66fc99e Initial load
duke
parents:
diff changeset
180 _barrier_set = barrier_set;
a61af66fc99e Initial load
duke
parents:
diff changeset
181 oopDesc::set_bs(_barrier_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
182 if (_barrier_set == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
183 vm_shutdown_during_initialization(
a61af66fc99e Initial load
duke
parents:
diff changeset
184 "Could not reserve enough space for barrier set");
a61af66fc99e Initial load
duke
parents:
diff changeset
185 return JNI_ENOMEM;
a61af66fc99e Initial load
duke
parents:
diff changeset
186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // Initial young gen size is 4 Mb
a61af66fc99e Initial load
duke
parents:
diff changeset
189 //
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // XXX - what about flag_parser.young_gen_size()?
a61af66fc99e Initial load
duke
parents:
diff changeset
191 const size_t init_young_size = align_size_up(4 * M, yg_align);
a61af66fc99e Initial load
duke
parents:
diff changeset
192 yg_cur_size = MAX2(MIN2(init_young_size, yg_max_size), yg_cur_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
193
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // Split the reserved space into perm gen and the main heap (everything else).
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // The main heap uses a different alignment.
a61af66fc99e Initial load
duke
parents:
diff changeset
196 ReservedSpace perm_rs = heap_rs.first_part(pg_max_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
197 ReservedSpace main_rs = heap_rs.last_part(pg_max_size, og_align);
a61af66fc99e Initial load
duke
parents:
diff changeset
198
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // Make up the generations
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // Calculate the maximum size that a generation can grow. This
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // includes growth into the other generation. Note that the
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // parameter _max_gen_size is kept as the maximum
a61af66fc99e Initial load
duke
parents:
diff changeset
203 // size of the generation as the boundaries currently stand.
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // _max_gen_size is still used as that value.
a61af66fc99e Initial load
duke
parents:
diff changeset
205 double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0;
a61af66fc99e Initial load
duke
parents:
diff changeset
206 double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0;
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 _gens = new AdjoiningGenerations(main_rs,
a61af66fc99e Initial load
duke
parents:
diff changeset
209 og_cur_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
210 og_min_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
211 og_max_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
212 yg_cur_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
213 yg_min_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
214 yg_max_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
215 yg_align);
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 _old_gen = _gens->old_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
218 _young_gen = _gens->young_gen();
a61af66fc99e Initial load
duke
parents:
diff changeset
219
a61af66fc99e Initial load
duke
parents:
diff changeset
220 const size_t eden_capacity = _young_gen->eden_space()->capacity_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
221 const size_t old_capacity = _old_gen->capacity_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
222 const size_t initial_promo_size = MIN2(eden_capacity, old_capacity);
a61af66fc99e Initial load
duke
parents:
diff changeset
223 _size_policy =
a61af66fc99e Initial load
duke
parents:
diff changeset
224 new PSAdaptiveSizePolicy(eden_capacity,
a61af66fc99e Initial load
duke
parents:
diff changeset
225 initial_promo_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
226 young_gen()->to_space()->capacity_in_bytes(),
13
183f41cf8bfe 6557851: CMS: ergonomics defaults are not set with FLAG_SET_ERGO
jmasa
parents: 0
diff changeset
227 intra_heap_alignment(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
228 max_gc_pause_sec,
a61af66fc99e Initial load
duke
parents:
diff changeset
229 max_gc_minor_pause_sec,
a61af66fc99e Initial load
duke
parents:
diff changeset
230 GCTimeRatio
a61af66fc99e Initial load
duke
parents:
diff changeset
231 );
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 _perm_gen = new PSPermGen(perm_rs,
a61af66fc99e Initial load
duke
parents:
diff changeset
234 pg_align,
a61af66fc99e Initial load
duke
parents:
diff changeset
235 pg_cur_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
236 pg_cur_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
237 pg_max_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
238 "perm", 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240 assert(!UseAdaptiveGCBoundary ||
a61af66fc99e Initial load
duke
parents:
diff changeset
241 (old_gen()->virtual_space()->high_boundary() ==
a61af66fc99e Initial load
duke
parents:
diff changeset
242 young_gen()->virtual_space()->low_boundary()),
a61af66fc99e Initial load
duke
parents:
diff changeset
243 "Boundaries must meet");
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // initialize the policy counters - 2 collectors, 3 generations
a61af66fc99e Initial load
duke
parents:
diff changeset
245 _gc_policy_counters =
a61af66fc99e Initial load
duke
parents:
diff changeset
246 new PSGCAdaptivePolicyCounters("ParScav:MSC", 2, 3, _size_policy);
a61af66fc99e Initial load
duke
parents:
diff changeset
247 _psh = this;
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // Set up the GCTaskManager
a61af66fc99e Initial load
duke
parents:
diff changeset
250 _gc_task_manager = GCTaskManager::create(ParallelGCThreads);
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252 if (UseParallelOldGC && !PSParallelCompact::initialize()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
253 return JNI_ENOMEM;
a61af66fc99e Initial load
duke
parents:
diff changeset
254 }
a61af66fc99e Initial load
duke
parents:
diff changeset
255
a61af66fc99e Initial load
duke
parents:
diff changeset
256 return JNI_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258
a61af66fc99e Initial load
duke
parents:
diff changeset
259 void ParallelScavengeHeap::post_initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // Need to init the tenuring threshold
a61af66fc99e Initial load
duke
parents:
diff changeset
261 PSScavenge::initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
262 if (UseParallelOldGC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
263 PSParallelCompact::post_initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
264 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
265 PSMarkSweep::initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
267 PSPromotionManager::initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
269
a61af66fc99e Initial load
duke
parents:
diff changeset
270 void ParallelScavengeHeap::update_counters() {
a61af66fc99e Initial load
duke
parents:
diff changeset
271 young_gen()->update_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
272 old_gen()->update_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
273 perm_gen()->update_counters();
a61af66fc99e Initial load
duke
parents:
diff changeset
274 }
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 size_t ParallelScavengeHeap::capacity() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
277 size_t value = young_gen()->capacity_in_bytes() + old_gen()->capacity_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
278 return value;
a61af66fc99e Initial load
duke
parents:
diff changeset
279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
280
a61af66fc99e Initial load
duke
parents:
diff changeset
281 size_t ParallelScavengeHeap::used() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
282 size_t value = young_gen()->used_in_bytes() + old_gen()->used_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
283 return value;
a61af66fc99e Initial load
duke
parents:
diff changeset
284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
285
a61af66fc99e Initial load
duke
parents:
diff changeset
286 bool ParallelScavengeHeap::is_maximal_no_gc() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
287 return old_gen()->is_maximal_no_gc() && young_gen()->is_maximal_no_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
289
a61af66fc99e Initial load
duke
parents:
diff changeset
290
a61af66fc99e Initial load
duke
parents:
diff changeset
291 size_t ParallelScavengeHeap::permanent_capacity() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
292 return perm_gen()->capacity_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
294
a61af66fc99e Initial load
duke
parents:
diff changeset
295 size_t ParallelScavengeHeap::permanent_used() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
296 return perm_gen()->used_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
298
a61af66fc99e Initial load
duke
parents:
diff changeset
299 size_t ParallelScavengeHeap::max_capacity() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
300 size_t estimated = reserved_region().byte_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
301 estimated -= perm_gen()->reserved().byte_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
302 if (UseAdaptiveSizePolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
303 estimated -= _size_policy->max_survivor_size(young_gen()->max_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
304 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
305 estimated -= young_gen()->to_space()->capacity_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
307 return MAX2(estimated, capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
309
a61af66fc99e Initial load
duke
parents:
diff changeset
310 bool ParallelScavengeHeap::is_in(const void* p) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
311 if (young_gen()->is_in(p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
312 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
314
a61af66fc99e Initial load
duke
parents:
diff changeset
315 if (old_gen()->is_in(p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
316 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 if (perm_gen()->is_in(p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
320 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
322
a61af66fc99e Initial load
duke
parents:
diff changeset
323 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
325
a61af66fc99e Initial load
duke
parents:
diff changeset
326 bool ParallelScavengeHeap::is_in_reserved(const void* p) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
327 if (young_gen()->is_in_reserved(p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
328 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
329 }
a61af66fc99e Initial load
duke
parents:
diff changeset
330
a61af66fc99e Initial load
duke
parents:
diff changeset
331 if (old_gen()->is_in_reserved(p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
332 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335 if (perm_gen()->is_in_reserved(p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
336 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
338
a61af66fc99e Initial load
duke
parents:
diff changeset
339 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
341
3377
2aa9ddbb9e60 7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents: 2251
diff changeset
342 bool ParallelScavengeHeap::is_scavengable(const void* addr) {
2aa9ddbb9e60 7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents: 2251
diff changeset
343 return is_in_young((oop)addr);
2aa9ddbb9e60 7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents: 2251
diff changeset
344 }
2aa9ddbb9e60 7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents: 2251
diff changeset
345
2aa9ddbb9e60 7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents: 2251
diff changeset
346 #ifdef ASSERT
2aa9ddbb9e60 7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents: 2251
diff changeset
347 // 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: 2251
diff changeset
348 // in some cases to check that is_in_young() is correct.
2aa9ddbb9e60 7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents: 2251
diff changeset
349 bool ParallelScavengeHeap::is_in_partial_collection(const void *p) {
2aa9ddbb9e60 7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents: 2251
diff changeset
350 assert(is_in_reserved(p) || p == NULL,
2aa9ddbb9e60 7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents: 2251
diff changeset
351 "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: 2251
diff changeset
352 // The order of the generations is perm (low addr), old, young (high addr)
2aa9ddbb9e60 7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents: 2251
diff changeset
353 return p >= old_gen()->reserved().end();
2aa9ddbb9e60 7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents: 2251
diff changeset
354 }
2aa9ddbb9e60 7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents: 2251
diff changeset
355 #endif
2aa9ddbb9e60 7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents: 2251
diff changeset
356
0
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // There are two levels of allocation policy here.
a61af66fc99e Initial load
duke
parents:
diff changeset
358 //
a61af66fc99e Initial load
duke
parents:
diff changeset
359 // When an allocation request fails, the requesting thread must invoke a VM
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // operation, transfer control to the VM thread, and await the results of a
a61af66fc99e Initial load
duke
parents:
diff changeset
361 // garbage collection. That is quite expensive, and we should avoid doing it
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // multiple times if possible.
a61af66fc99e Initial load
duke
parents:
diff changeset
363 //
a61af66fc99e Initial load
duke
parents:
diff changeset
364 // To accomplish this, we have a basic allocation policy, and also a
a61af66fc99e Initial load
duke
parents:
diff changeset
365 // failed allocation policy.
a61af66fc99e Initial load
duke
parents:
diff changeset
366 //
a61af66fc99e Initial load
duke
parents:
diff changeset
367 // The basic allocation policy controls how you allocate memory without
a61af66fc99e Initial load
duke
parents:
diff changeset
368 // attempting garbage collection. It is okay to grab locks and
a61af66fc99e Initial load
duke
parents:
diff changeset
369 // expand the heap, if that can be done without coming to a safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
370 // It is likely that the basic allocation policy will not be very
a61af66fc99e Initial load
duke
parents:
diff changeset
371 // aggressive.
a61af66fc99e Initial load
duke
parents:
diff changeset
372 //
a61af66fc99e Initial load
duke
parents:
diff changeset
373 // The failed allocation policy is invoked from the VM thread after
a61af66fc99e Initial load
duke
parents:
diff changeset
374 // the basic allocation policy is unable to satisfy a mem_allocate
a61af66fc99e Initial load
duke
parents:
diff changeset
375 // request. This policy needs to cover the entire range of collection,
a61af66fc99e Initial load
duke
parents:
diff changeset
376 // heap expansion, and out-of-memory conditions. It should make every
a61af66fc99e Initial load
duke
parents:
diff changeset
377 // attempt to allocate the requested memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
378
a61af66fc99e Initial load
duke
parents:
diff changeset
379 // Basic allocation policy. Should never be called at a safepoint, or
a61af66fc99e Initial load
duke
parents:
diff changeset
380 // from the VM thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
381 //
a61af66fc99e Initial load
duke
parents:
diff changeset
382 // This method must handle cases where many mem_allocate requests fail
a61af66fc99e Initial load
duke
parents:
diff changeset
383 // simultaneously. When that happens, only one VM operation will succeed,
a61af66fc99e Initial load
duke
parents:
diff changeset
384 // and the rest will not be executed. For that reason, this method loops
a61af66fc99e Initial load
duke
parents:
diff changeset
385 // during failed allocation attempts. If the java heap becomes exhausted,
a61af66fc99e Initial load
duke
parents:
diff changeset
386 // we rely on the size_policy object to force a bail out.
a61af66fc99e Initial load
duke
parents:
diff changeset
387 HeapWord* ParallelScavengeHeap::mem_allocate(
a61af66fc99e Initial load
duke
parents:
diff changeset
388 size_t size,
a61af66fc99e Initial load
duke
parents:
diff changeset
389 bool is_noref,
a61af66fc99e Initial load
duke
parents:
diff changeset
390 bool is_tlab,
a61af66fc99e Initial load
duke
parents:
diff changeset
391 bool* gc_overhead_limit_was_exceeded) {
a61af66fc99e Initial load
duke
parents:
diff changeset
392 assert(!SafepointSynchronize::is_at_safepoint(), "should not be at safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
393 assert(Thread::current() != (Thread*)VMThread::vm_thread(), "should not be in vm thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
394 assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
395
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
396 // In general gc_overhead_limit_was_exceeded should be false so
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
397 // set it so here and reset it to true only if the gc time
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
398 // limit is being exceeded as checked below.
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
399 *gc_overhead_limit_was_exceeded = false;
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
400
0
a61af66fc99e Initial load
duke
parents:
diff changeset
401 HeapWord* result = young_gen()->allocate(size, is_tlab);
a61af66fc99e Initial load
duke
parents:
diff changeset
402
a61af66fc99e Initial load
duke
parents:
diff changeset
403 uint loop_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
404 uint gc_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
405
a61af66fc99e Initial load
duke
parents:
diff changeset
406 while (result == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
407 // We don't want to have multiple collections for a single filled generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
408 // To prevent this, each thread tracks the total_collections() value, and if
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // the count has changed, does not do a new collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
410 //
a61af66fc99e Initial load
duke
parents:
diff changeset
411 // The collection count must be read only while holding the heap lock. VM
a61af66fc99e Initial load
duke
parents:
diff changeset
412 // operations also hold the heap lock during collections. There is a lock
a61af66fc99e Initial load
duke
parents:
diff changeset
413 // contention case where thread A blocks waiting on the Heap_lock, while
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // thread B is holding it doing a collection. When thread A gets the lock,
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // the collection count has already changed. To prevent duplicate collections,
a61af66fc99e Initial load
duke
parents:
diff changeset
416 // The policy MUST attempt allocations during the same period it reads the
a61af66fc99e Initial load
duke
parents:
diff changeset
417 // total_collections() value!
a61af66fc99e Initial load
duke
parents:
diff changeset
418 {
a61af66fc99e Initial load
duke
parents:
diff changeset
419 MutexLocker ml(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
420 gc_count = Universe::heap()->total_collections();
a61af66fc99e Initial load
duke
parents:
diff changeset
421
a61af66fc99e Initial load
duke
parents:
diff changeset
422 result = young_gen()->allocate(size, is_tlab);
a61af66fc99e Initial load
duke
parents:
diff changeset
423
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // (1) If the requested object is too large to easily fit in the
a61af66fc99e Initial load
duke
parents:
diff changeset
425 // young_gen, or
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // (2) If GC is locked out via GCLocker, young gen is full and
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // the need for a GC already signalled to GCLocker (done
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // at a safepoint),
a61af66fc99e Initial load
duke
parents:
diff changeset
429 // ... then, rather than force a safepoint and (a potentially futile)
a61af66fc99e Initial load
duke
parents:
diff changeset
430 // collection (attempt) for each allocation, try allocation directly
a61af66fc99e Initial load
duke
parents:
diff changeset
431 // in old_gen. For case (2) above, we may in the future allow
a61af66fc99e Initial load
duke
parents:
diff changeset
432 // TLAB allocation directly in the old gen.
a61af66fc99e Initial load
duke
parents:
diff changeset
433 if (result != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
434 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
435 }
a61af66fc99e Initial load
duke
parents:
diff changeset
436 if (!is_tlab &&
373
06df86c2ec37 6740923: NUMA allocator: Ensure the progress of adaptive chunk resizing
iveresov
parents: 269
diff changeset
437 size >= (young_gen()->eden_space()->capacity_in_words(Thread::current()) / 2)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
438 result = old_gen()->allocate(size, is_tlab);
a61af66fc99e Initial load
duke
parents:
diff changeset
439 if (result != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
440 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
443 if (GC_locker::is_active_and_needs_gc()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // GC is locked out. If this is a TLAB allocation,
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // return NULL; the requestor will retry allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
446 // of an idividual object at a time.
a61af66fc99e Initial load
duke
parents:
diff changeset
447 if (is_tlab) {
a61af66fc99e Initial load
duke
parents:
diff changeset
448 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
449 }
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // If this thread is not in a jni critical section, we stall
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // the requestor until the critical section has cleared and
a61af66fc99e Initial load
duke
parents:
diff changeset
453 // GC allowed. When the critical section clears, a GC is
a61af66fc99e Initial load
duke
parents:
diff changeset
454 // initiated by the last thread exiting the critical section; so
a61af66fc99e Initial load
duke
parents:
diff changeset
455 // we retry the allocation sequence from the beginning of the loop,
a61af66fc99e Initial load
duke
parents:
diff changeset
456 // rather than causing more, now probably unnecessary, GC attempts.
a61af66fc99e Initial load
duke
parents:
diff changeset
457 JavaThread* jthr = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
458 if (!jthr->in_critical()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
459 MutexUnlocker mul(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
460 GC_locker::stall_until_clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
461 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
462 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
463 if (CheckJNICalls) {
a61af66fc99e Initial load
duke
parents:
diff changeset
464 fatal("Possible deadlock due to allocating while"
a61af66fc99e Initial load
duke
parents:
diff changeset
465 " in jni critical section");
a61af66fc99e Initial load
duke
parents:
diff changeset
466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
467 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
468 }
a61af66fc99e Initial load
duke
parents:
diff changeset
469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
470 }
a61af66fc99e Initial load
duke
parents:
diff changeset
471
a61af66fc99e Initial load
duke
parents:
diff changeset
472 if (result == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
473
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // Generate a VM operation
a61af66fc99e Initial load
duke
parents:
diff changeset
475 VM_ParallelGCFailedAllocation op(size, is_tlab, gc_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
476 VMThread::execute(&op);
a61af66fc99e Initial load
duke
parents:
diff changeset
477
a61af66fc99e Initial load
duke
parents:
diff changeset
478 // Did the VM operation execute? If so, return the result directly.
a61af66fc99e Initial load
duke
parents:
diff changeset
479 // This prevents us from looping until time out on requests that can
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // not be satisfied.
a61af66fc99e Initial load
duke
parents:
diff changeset
481 if (op.prologue_succeeded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
482 assert(Universe::heap()->is_in_or_null(op.result()),
a61af66fc99e Initial load
duke
parents:
diff changeset
483 "result not in heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
484
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // If GC was locked out during VM operation then retry allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
486 // and/or stall as necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
487 if (op.gc_locked()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
488 assert(op.result() == NULL, "must be NULL if gc_locked() is true");
a61af66fc99e Initial load
duke
parents:
diff changeset
489 continue; // retry and/or stall as necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
490 }
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
491
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
492 // Exit the loop if the gc time limit has been exceeded.
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
493 // The allocation must have failed above ("result" guarding
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
494 // this path is NULL) and the most recent collection has exceeded the
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
495 // gc overhead limit (although enough may have been collected to
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
496 // satisfy the allocation). Exit the loop so that an out-of-memory
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
497 // will be thrown (return a NULL ignoring the contents of
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
498 // op.result()),
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
499 // but clear gc_overhead_limit_exceeded so that the next collection
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
500 // starts with a clean slate (i.e., forgets about previous overhead
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
501 // excesses). Fill op.result() with a filler object so that the
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
502 // heap remains parsable.
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
503 const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
504 const bool softrefs_clear = collector_policy()->all_soft_refs_clear();
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
505 assert(!limit_exceeded || softrefs_clear, "Should have been cleared");
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
506 if (limit_exceeded && softrefs_clear) {
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
507 *gc_overhead_limit_was_exceeded = true;
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
508 size_policy()->set_gc_overhead_limit_exceeded(false);
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
509 if (PrintGCDetails && Verbose) {
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
510 gclog_or_tty->print_cr("ParallelScavengeHeap::mem_allocate: "
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
511 "return NULL because gc_overhead_limit_exceeded is set");
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
512 }
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
513 if (op.result() != NULL) {
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
514 CollectedHeap::fill_with_object(op.result(), size);
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
515 }
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
516 return NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
517 }
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
518
0
a61af66fc99e Initial load
duke
parents:
diff changeset
519 return op.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // The policy object will prevent us from looping forever. If the
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // time spent in gc crosses a threshold, we will bail out.
a61af66fc99e Initial load
duke
parents:
diff changeset
525 loop_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
526 if ((result == NULL) && (QueuedAllocationWarningCount > 0) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
527 (loop_count % QueuedAllocationWarningCount == 0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
528 warning("ParallelScavengeHeap::mem_allocate retries %d times \n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
529 " size=%d %s", loop_count, size, is_tlab ? "(TLAB)" : "");
a61af66fc99e Initial load
duke
parents:
diff changeset
530 }
a61af66fc99e Initial load
duke
parents:
diff changeset
531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
532
a61af66fc99e Initial load
duke
parents:
diff changeset
533 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
535
a61af66fc99e Initial load
duke
parents:
diff changeset
536 // Failed allocation policy. Must be called from the VM thread, and
a61af66fc99e Initial load
duke
parents:
diff changeset
537 // only at a safepoint! Note that this method has policy for allocation
a61af66fc99e Initial load
duke
parents:
diff changeset
538 // flow, and NOT collection policy. So we do not check for gc collection
a61af66fc99e Initial load
duke
parents:
diff changeset
539 // time over limit here, that is the responsibility of the heap specific
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // collection methods. This method decides where to attempt allocations,
a61af66fc99e Initial load
duke
parents:
diff changeset
541 // and when to attempt collections, but no collection specific policy.
a61af66fc99e Initial load
duke
parents:
diff changeset
542 HeapWord* ParallelScavengeHeap::failed_mem_allocate(size_t size, bool is_tlab) {
a61af66fc99e Initial load
duke
parents:
diff changeset
543 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
544 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
545 assert(!Universe::heap()->is_gc_active(), "not reentrant");
a61af66fc99e Initial load
duke
parents:
diff changeset
546 assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
547
a61af66fc99e Initial load
duke
parents:
diff changeset
548 size_t mark_sweep_invocation_count = total_invocations();
a61af66fc99e Initial load
duke
parents:
diff changeset
549
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // We assume (and assert!) that an allocation at this point will fail
a61af66fc99e Initial load
duke
parents:
diff changeset
551 // unless we collect.
a61af66fc99e Initial load
duke
parents:
diff changeset
552
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // First level allocation failure, scavenge and allocate in young gen.
a61af66fc99e Initial load
duke
parents:
diff changeset
554 GCCauseSetter gccs(this, GCCause::_allocation_failure);
a61af66fc99e Initial load
duke
parents:
diff changeset
555 PSScavenge::invoke();
a61af66fc99e Initial load
duke
parents:
diff changeset
556 HeapWord* result = young_gen()->allocate(size, is_tlab);
a61af66fc99e Initial load
duke
parents:
diff changeset
557
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // Second level allocation failure.
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // Mark sweep and allocate in young generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
560 if (result == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // There is some chance the scavenge method decided to invoke mark_sweep.
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // Don't mark sweep twice if so.
a61af66fc99e Initial load
duke
parents:
diff changeset
563 if (mark_sweep_invocation_count == total_invocations()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
564 invoke_full_gc(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
565 result = young_gen()->allocate(size, is_tlab);
a61af66fc99e Initial load
duke
parents:
diff changeset
566 }
a61af66fc99e Initial load
duke
parents:
diff changeset
567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
568
a61af66fc99e Initial load
duke
parents:
diff changeset
569 // Third level allocation failure.
a61af66fc99e Initial load
duke
parents:
diff changeset
570 // After mark sweep and young generation allocation failure,
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // allocate in old generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
572 if (result == NULL && !is_tlab) {
a61af66fc99e Initial load
duke
parents:
diff changeset
573 result = old_gen()->allocate(size, is_tlab);
a61af66fc99e Initial load
duke
parents:
diff changeset
574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
575
a61af66fc99e Initial load
duke
parents:
diff changeset
576 // Fourth level allocation failure. We're running out of memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
577 // More complete mark sweep and allocate in young generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
578 if (result == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
579 invoke_full_gc(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
580 result = young_gen()->allocate(size, is_tlab);
a61af66fc99e Initial load
duke
parents:
diff changeset
581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
582
a61af66fc99e Initial load
duke
parents:
diff changeset
583 // Fifth level allocation failure.
a61af66fc99e Initial load
duke
parents:
diff changeset
584 // After more complete mark sweep, allocate in old generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
585 if (result == NULL && !is_tlab) {
a61af66fc99e Initial load
duke
parents:
diff changeset
586 result = old_gen()->allocate(size, is_tlab);
a61af66fc99e Initial load
duke
parents:
diff changeset
587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
588
a61af66fc99e Initial load
duke
parents:
diff changeset
589 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
590 }
a61af66fc99e Initial load
duke
parents:
diff changeset
591
a61af66fc99e Initial load
duke
parents:
diff changeset
592 //
a61af66fc99e Initial load
duke
parents:
diff changeset
593 // This is the policy loop for allocating in the permanent generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
594 // If the initial allocation fails, we create a vm operation which will
a61af66fc99e Initial load
duke
parents:
diff changeset
595 // cause a collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
596 HeapWord* ParallelScavengeHeap::permanent_mem_allocate(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
597 assert(!SafepointSynchronize::is_at_safepoint(), "should not be at safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
598 assert(Thread::current() != (Thread*)VMThread::vm_thread(), "should not be in vm thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
599 assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
600
a61af66fc99e Initial load
duke
parents:
diff changeset
601 HeapWord* result;
a61af66fc99e Initial load
duke
parents:
diff changeset
602
a61af66fc99e Initial load
duke
parents:
diff changeset
603 uint loop_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
604 uint gc_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
605 uint full_gc_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
606
a61af66fc99e Initial load
duke
parents:
diff changeset
607 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
608 // We don't want to have multiple collections for a single filled generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
609 // To prevent this, each thread tracks the total_collections() value, and if
a61af66fc99e Initial load
duke
parents:
diff changeset
610 // the count has changed, does not do a new collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
611 //
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // The collection count must be read only while holding the heap lock. VM
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // operations also hold the heap lock during collections. There is a lock
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // contention case where thread A blocks waiting on the Heap_lock, while
a61af66fc99e Initial load
duke
parents:
diff changeset
615 // thread B is holding it doing a collection. When thread A gets the lock,
a61af66fc99e Initial load
duke
parents:
diff changeset
616 // the collection count has already changed. To prevent duplicate collections,
a61af66fc99e Initial load
duke
parents:
diff changeset
617 // The policy MUST attempt allocations during the same period it reads the
a61af66fc99e Initial load
duke
parents:
diff changeset
618 // total_collections() value!
a61af66fc99e Initial load
duke
parents:
diff changeset
619 {
a61af66fc99e Initial load
duke
parents:
diff changeset
620 MutexLocker ml(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
621 gc_count = Universe::heap()->total_collections();
a61af66fc99e Initial load
duke
parents:
diff changeset
622 full_gc_count = Universe::heap()->total_full_collections();
a61af66fc99e Initial load
duke
parents:
diff changeset
623
a61af66fc99e Initial load
duke
parents:
diff changeset
624 result = perm_gen()->allocate_permanent(size);
139
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
625
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
626 if (result != NULL) {
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
627 return result;
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
628 }
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
629
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
630 if (GC_locker::is_active_and_needs_gc()) {
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
631 // If this thread is not in a jni critical section, we stall
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
632 // the requestor until the critical section has cleared and
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
633 // GC allowed. When the critical section clears, a GC is
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
634 // initiated by the last thread exiting the critical section; so
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
635 // we retry the allocation sequence from the beginning of the loop,
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
636 // rather than causing more, now probably unnecessary, GC attempts.
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
637 JavaThread* jthr = JavaThread::current();
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
638 if (!jthr->in_critical()) {
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
639 MutexUnlocker mul(Heap_lock);
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
640 GC_locker::stall_until_clear();
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
641 continue;
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
642 } else {
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
643 if (CheckJNICalls) {
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
644 fatal("Possible deadlock due to allocating while"
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
645 " in jni critical section");
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
646 }
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
647 return NULL;
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
648 }
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
649 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
650 }
a61af66fc99e Initial load
duke
parents:
diff changeset
651
a61af66fc99e Initial load
duke
parents:
diff changeset
652 if (result == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
653
a61af66fc99e Initial load
duke
parents:
diff changeset
654 // Exit the loop if the gc time limit has been exceeded.
a61af66fc99e Initial load
duke
parents:
diff changeset
655 // The allocation must have failed above (result must be NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
656 // and the most recent collection must have exceeded the
a61af66fc99e Initial load
duke
parents:
diff changeset
657 // gc time limit. Exit the loop so that an out-of-memory
a61af66fc99e Initial load
duke
parents:
diff changeset
658 // will be thrown (returning a NULL will do that), but
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
659 // clear gc_overhead_limit_exceeded so that the next collection
0
a61af66fc99e Initial load
duke
parents:
diff changeset
660 // will succeeded if the applications decides to handle the
a61af66fc99e Initial load
duke
parents:
diff changeset
661 // out-of-memory and tries to go on.
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
662 const bool limit_exceeded = size_policy()->gc_overhead_limit_exceeded();
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
663 if (limit_exceeded) {
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
664 size_policy()->set_gc_overhead_limit_exceeded(false);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
665 if (PrintGCDetails && Verbose) {
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
666 gclog_or_tty->print_cr("ParallelScavengeHeap::permanent_mem_allocate:"
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
667 " return NULL because gc_overhead_limit_exceeded is set");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
668 }
a61af66fc99e Initial load
duke
parents:
diff changeset
669 assert(result == NULL, "Allocation did not fail");
a61af66fc99e Initial load
duke
parents:
diff changeset
670 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
671 }
a61af66fc99e Initial load
duke
parents:
diff changeset
672
a61af66fc99e Initial load
duke
parents:
diff changeset
673 // Generate a VM operation
a61af66fc99e Initial load
duke
parents:
diff changeset
674 VM_ParallelGCFailedPermanentAllocation op(size, gc_count, full_gc_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
675 VMThread::execute(&op);
a61af66fc99e Initial load
duke
parents:
diff changeset
676
a61af66fc99e Initial load
duke
parents:
diff changeset
677 // Did the VM operation execute? If so, return the result directly.
a61af66fc99e Initial load
duke
parents:
diff changeset
678 // This prevents us from looping until time out on requests that can
a61af66fc99e Initial load
duke
parents:
diff changeset
679 // not be satisfied.
a61af66fc99e Initial load
duke
parents:
diff changeset
680 if (op.prologue_succeeded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
681 assert(Universe::heap()->is_in_permanent_or_null(op.result()),
a61af66fc99e Initial load
duke
parents:
diff changeset
682 "result not in heap");
139
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
683 // If GC was locked out during VM operation then retry allocation
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
684 // and/or stall as necessary.
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
685 if (op.gc_locked()) {
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
686 assert(op.result() == NULL, "must be NULL if gc_locked() is true");
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
687 continue; // retry and/or stall as necessary
c0492d52d55b 6539517: CR 6186200 should be extended to perm gen allocation to prevent spurious OOM's from perm gen
apetrusenko
parents: 13
diff changeset
688 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
689 // If a NULL results is being returned, an out-of-memory
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
690 // will be thrown now. Clear the gc_overhead_limit_exceeded
0
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // flag to avoid the following situation.
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
692 // gc_overhead_limit_exceeded is set during a collection
0
a61af66fc99e Initial load
duke
parents:
diff changeset
693 // the collection fails to return enough space and an OOM is thrown
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
694 // a subsequent GC prematurely throws an out-of-memory because
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
695 // the gc_overhead_limit_exceeded counts did not start
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
696 // again from 0.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
697 if (op.result() == NULL) {
1387
0bfd3fb24150 6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents: 1166
diff changeset
698 size_policy()->reset_gc_overhead_limit_count();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
699 }
a61af66fc99e Initial load
duke
parents:
diff changeset
700 return op.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
701 }
a61af66fc99e Initial load
duke
parents:
diff changeset
702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
703
a61af66fc99e Initial load
duke
parents:
diff changeset
704 // The policy object will prevent us from looping forever. If the
a61af66fc99e Initial load
duke
parents:
diff changeset
705 // time spent in gc crosses a threshold, we will bail out.
a61af66fc99e Initial load
duke
parents:
diff changeset
706 loop_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
707 if ((QueuedAllocationWarningCount > 0) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
708 (loop_count % QueuedAllocationWarningCount == 0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
709 warning("ParallelScavengeHeap::permanent_mem_allocate retries %d times \n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
710 " size=%d", loop_count, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
711 }
a61af66fc99e Initial load
duke
parents:
diff changeset
712 } while (result == NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
713
a61af66fc99e Initial load
duke
parents:
diff changeset
714 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
715 }
a61af66fc99e Initial load
duke
parents:
diff changeset
716
a61af66fc99e Initial load
duke
parents:
diff changeset
717 //
a61af66fc99e Initial load
duke
parents:
diff changeset
718 // This is the policy code for permanent allocations which have failed
a61af66fc99e Initial load
duke
parents:
diff changeset
719 // and require a collection. Note that just as in failed_mem_allocate,
a61af66fc99e Initial load
duke
parents:
diff changeset
720 // we do not set collection policy, only where & when to allocate and
a61af66fc99e Initial load
duke
parents:
diff changeset
721 // collect.
a61af66fc99e Initial load
duke
parents:
diff changeset
722 HeapWord* ParallelScavengeHeap::failed_permanent_mem_allocate(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
723 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
724 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
725 assert(!Universe::heap()->is_gc_active(), "not reentrant");
a61af66fc99e Initial load
duke
parents:
diff changeset
726 assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
727 assert(size > perm_gen()->free_in_words(), "Allocation should fail");
a61af66fc99e Initial load
duke
parents:
diff changeset
728
a61af66fc99e Initial load
duke
parents:
diff changeset
729 // We assume (and assert!) that an allocation at this point will fail
a61af66fc99e Initial load
duke
parents:
diff changeset
730 // unless we collect.
a61af66fc99e Initial load
duke
parents:
diff changeset
731
a61af66fc99e Initial load
duke
parents:
diff changeset
732 // First level allocation failure. Mark-sweep and allocate in perm gen.
a61af66fc99e Initial load
duke
parents:
diff changeset
733 GCCauseSetter gccs(this, GCCause::_allocation_failure);
a61af66fc99e Initial load
duke
parents:
diff changeset
734 invoke_full_gc(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
735 HeapWord* result = perm_gen()->allocate_permanent(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
736
a61af66fc99e Initial load
duke
parents:
diff changeset
737 // Second level allocation failure. We're running out of memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
738 if (result == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
739 invoke_full_gc(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
740 result = perm_gen()->allocate_permanent(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
742
a61af66fc99e Initial load
duke
parents:
diff changeset
743 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
744 }
a61af66fc99e Initial load
duke
parents:
diff changeset
745
a61af66fc99e Initial load
duke
parents:
diff changeset
746 void ParallelScavengeHeap::ensure_parsability(bool retire_tlabs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
747 CollectedHeap::ensure_parsability(retire_tlabs);
a61af66fc99e Initial load
duke
parents:
diff changeset
748 young_gen()->eden_space()->ensure_parsability();
a61af66fc99e Initial load
duke
parents:
diff changeset
749 }
a61af66fc99e Initial load
duke
parents:
diff changeset
750
a61af66fc99e Initial load
duke
parents:
diff changeset
751 size_t ParallelScavengeHeap::unsafe_max_alloc() {
a61af66fc99e Initial load
duke
parents:
diff changeset
752 return young_gen()->eden_space()->free_in_bytes();
a61af66fc99e Initial load
duke
parents:
diff changeset
753 }
a61af66fc99e Initial load
duke
parents:
diff changeset
754
a61af66fc99e Initial load
duke
parents:
diff changeset
755 size_t ParallelScavengeHeap::tlab_capacity(Thread* thr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
756 return young_gen()->eden_space()->tlab_capacity(thr);
a61af66fc99e Initial load
duke
parents:
diff changeset
757 }
a61af66fc99e Initial load
duke
parents:
diff changeset
758
a61af66fc99e Initial load
duke
parents:
diff changeset
759 size_t ParallelScavengeHeap::unsafe_max_tlab_alloc(Thread* thr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
760 return young_gen()->eden_space()->unsafe_max_tlab_alloc(thr);
a61af66fc99e Initial load
duke
parents:
diff changeset
761 }
a61af66fc99e Initial load
duke
parents:
diff changeset
762
a61af66fc99e Initial load
duke
parents:
diff changeset
763 HeapWord* ParallelScavengeHeap::allocate_new_tlab(size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
764 return young_gen()->allocate(size, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
765 }
a61af66fc99e Initial load
duke
parents:
diff changeset
766
a61af66fc99e Initial load
duke
parents:
diff changeset
767 void ParallelScavengeHeap::accumulate_statistics_all_tlabs() {
a61af66fc99e Initial load
duke
parents:
diff changeset
768 CollectedHeap::accumulate_statistics_all_tlabs();
a61af66fc99e Initial load
duke
parents:
diff changeset
769 }
a61af66fc99e Initial load
duke
parents:
diff changeset
770
a61af66fc99e Initial load
duke
parents:
diff changeset
771 void ParallelScavengeHeap::resize_all_tlabs() {
a61af66fc99e Initial load
duke
parents:
diff changeset
772 CollectedHeap::resize_all_tlabs();
a61af66fc99e Initial load
duke
parents:
diff changeset
773 }
a61af66fc99e Initial load
duke
parents:
diff changeset
774
1027
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 989
diff changeset
775 bool ParallelScavengeHeap::can_elide_initializing_store_barrier(oop new_obj) {
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 989
diff changeset
776 // We don't need barriers for stores to objects in the
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 989
diff changeset
777 // young gen and, a fortiori, for initializing stores to
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 989
diff changeset
778 // objects therein.
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 989
diff changeset
779 return is_in_young(new_obj);
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 989
diff changeset
780 }
39b01ab7035a 6888898: CMS: ReduceInitialCardMarks unsafe in the presence of cms precleaning
ysr
parents: 989
diff changeset
781
0
a61af66fc99e Initial load
duke
parents:
diff changeset
782 // This method is used by System.gc() and JVMTI.
a61af66fc99e Initial load
duke
parents:
diff changeset
783 void ParallelScavengeHeap::collect(GCCause::Cause cause) {
a61af66fc99e Initial load
duke
parents:
diff changeset
784 assert(!Heap_lock->owned_by_self(),
a61af66fc99e Initial load
duke
parents:
diff changeset
785 "this thread should not own the Heap_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
786
a61af66fc99e Initial load
duke
parents:
diff changeset
787 unsigned int gc_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
788 unsigned int full_gc_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
789 {
a61af66fc99e Initial load
duke
parents:
diff changeset
790 MutexLocker ml(Heap_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
791 // This value is guarded by the Heap_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
792 gc_count = Universe::heap()->total_collections();
a61af66fc99e Initial load
duke
parents:
diff changeset
793 full_gc_count = Universe::heap()->total_full_collections();
a61af66fc99e Initial load
duke
parents:
diff changeset
794 }
a61af66fc99e Initial load
duke
parents:
diff changeset
795
a61af66fc99e Initial load
duke
parents:
diff changeset
796 VM_ParallelGCSystemGC op(gc_count, full_gc_count, cause);
a61af66fc99e Initial load
duke
parents:
diff changeset
797 VMThread::execute(&op);
a61af66fc99e Initial load
duke
parents:
diff changeset
798 }
a61af66fc99e Initial load
duke
parents:
diff changeset
799
a61af66fc99e Initial load
duke
parents:
diff changeset
800 // This interface assumes that it's being called by the
a61af66fc99e Initial load
duke
parents:
diff changeset
801 // vm thread. It collects the heap assuming that the
a61af66fc99e Initial load
duke
parents:
diff changeset
802 // heap lock is already held and that we are executing in
a61af66fc99e Initial load
duke
parents:
diff changeset
803 // the context of the vm thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
804 void ParallelScavengeHeap::collect_as_vm_thread(GCCause::Cause cause) {
a61af66fc99e Initial load
duke
parents:
diff changeset
805 assert(Thread::current()->is_VM_thread(), "Precondition#1");
a61af66fc99e Initial load
duke
parents:
diff changeset
806 assert(Heap_lock->is_locked(), "Precondition#2");
a61af66fc99e Initial load
duke
parents:
diff changeset
807 GCCauseSetter gcs(this, cause);
a61af66fc99e Initial load
duke
parents:
diff changeset
808 switch (cause) {
a61af66fc99e Initial load
duke
parents:
diff changeset
809 case GCCause::_heap_inspection:
a61af66fc99e Initial load
duke
parents:
diff changeset
810 case GCCause::_heap_dump: {
a61af66fc99e Initial load
duke
parents:
diff changeset
811 HandleMark hm;
a61af66fc99e Initial load
duke
parents:
diff changeset
812 invoke_full_gc(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
813 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
814 }
a61af66fc99e Initial load
duke
parents:
diff changeset
815 default: // XXX FIX ME
a61af66fc99e Initial load
duke
parents:
diff changeset
816 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
817 }
a61af66fc99e Initial load
duke
parents:
diff changeset
818 }
a61af66fc99e Initial load
duke
parents:
diff changeset
819
a61af66fc99e Initial load
duke
parents:
diff changeset
820
a61af66fc99e Initial load
duke
parents:
diff changeset
821 void ParallelScavengeHeap::oop_iterate(OopClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
822 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
823 }
a61af66fc99e Initial load
duke
parents:
diff changeset
824
a61af66fc99e Initial load
duke
parents:
diff changeset
825 void ParallelScavengeHeap::object_iterate(ObjectClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
826 young_gen()->object_iterate(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
827 old_gen()->object_iterate(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
828 perm_gen()->object_iterate(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
829 }
a61af66fc99e Initial load
duke
parents:
diff changeset
830
a61af66fc99e Initial load
duke
parents:
diff changeset
831 void ParallelScavengeHeap::permanent_oop_iterate(OopClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
832 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
833 }
a61af66fc99e Initial load
duke
parents:
diff changeset
834
a61af66fc99e Initial load
duke
parents:
diff changeset
835 void ParallelScavengeHeap::permanent_object_iterate(ObjectClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
836 perm_gen()->object_iterate(cl);
a61af66fc99e Initial load
duke
parents:
diff changeset
837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
838
a61af66fc99e Initial load
duke
parents:
diff changeset
839 HeapWord* ParallelScavengeHeap::block_start(const void* addr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
840 if (young_gen()->is_in_reserved(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
841 assert(young_gen()->is_in(addr),
a61af66fc99e Initial load
duke
parents:
diff changeset
842 "addr should be in allocated part of young gen");
1907
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1552
diff changeset
843 // called from os::print_location by find or VMError
1e9a9d2e6509 6970683: improvements to hs_err output
never
parents: 1552
diff changeset
844 if (Debugging || VMError::fatal_error_in_progress()) return NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
845 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
846 } else if (old_gen()->is_in_reserved(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
847 assert(old_gen()->is_in(addr),
a61af66fc99e Initial load
duke
parents:
diff changeset
848 "addr should be in allocated part of old gen");
a61af66fc99e Initial load
duke
parents:
diff changeset
849 return old_gen()->start_array()->object_start((HeapWord*)addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
850 } else if (perm_gen()->is_in_reserved(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
851 assert(perm_gen()->is_in(addr),
a61af66fc99e Initial load
duke
parents:
diff changeset
852 "addr should be in allocated part of perm gen");
a61af66fc99e Initial load
duke
parents:
diff changeset
853 return perm_gen()->start_array()->object_start((HeapWord*)addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
854 }
a61af66fc99e Initial load
duke
parents:
diff changeset
855 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
856 }
a61af66fc99e Initial load
duke
parents:
diff changeset
857
a61af66fc99e Initial load
duke
parents:
diff changeset
858 size_t ParallelScavengeHeap::block_size(const HeapWord* addr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
859 return oop(addr)->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
860 }
a61af66fc99e Initial load
duke
parents:
diff changeset
861
a61af66fc99e Initial load
duke
parents:
diff changeset
862 bool ParallelScavengeHeap::block_is_obj(const HeapWord* addr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
863 return block_start(addr) == addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
865
a61af66fc99e Initial load
duke
parents:
diff changeset
866 jlong ParallelScavengeHeap::millis_since_last_gc() {
a61af66fc99e Initial load
duke
parents:
diff changeset
867 return UseParallelOldGC ?
a61af66fc99e Initial load
duke
parents:
diff changeset
868 PSParallelCompact::millis_since_last_gc() :
a61af66fc99e Initial load
duke
parents:
diff changeset
869 PSMarkSweep::millis_since_last_gc();
a61af66fc99e Initial load
duke
parents:
diff changeset
870 }
a61af66fc99e Initial load
duke
parents:
diff changeset
871
a61af66fc99e Initial load
duke
parents:
diff changeset
872 void ParallelScavengeHeap::prepare_for_verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
873 ensure_parsability(false); // no need to retire TLABs for verification
a61af66fc99e Initial load
duke
parents:
diff changeset
874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
875
a61af66fc99e Initial load
duke
parents:
diff changeset
876 void ParallelScavengeHeap::print() const { print_on(tty); }
a61af66fc99e Initial load
duke
parents:
diff changeset
877
a61af66fc99e Initial load
duke
parents:
diff changeset
878 void ParallelScavengeHeap::print_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
879 young_gen()->print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
880 old_gen()->print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
881 perm_gen()->print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
882 }
a61af66fc99e Initial load
duke
parents:
diff changeset
883
a61af66fc99e Initial load
duke
parents:
diff changeset
884 void ParallelScavengeHeap::gc_threads_do(ThreadClosure* tc) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
885 PSScavenge::gc_task_manager()->threads_do(tc);
a61af66fc99e Initial load
duke
parents:
diff changeset
886 }
a61af66fc99e Initial load
duke
parents:
diff changeset
887
a61af66fc99e Initial load
duke
parents:
diff changeset
888 void ParallelScavengeHeap::print_gc_threads_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
889 PSScavenge::gc_task_manager()->print_threads_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
890 }
a61af66fc99e Initial load
duke
parents:
diff changeset
891
a61af66fc99e Initial load
duke
parents:
diff changeset
892 void ParallelScavengeHeap::print_tracing_info() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
893 if (TraceGen0Time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
894 double time = PSScavenge::accumulated_time()->seconds();
a61af66fc99e Initial load
duke
parents:
diff changeset
895 tty->print_cr("[Accumulated GC generation 0 time %3.7f secs]", time);
a61af66fc99e Initial load
duke
parents:
diff changeset
896 }
a61af66fc99e Initial load
duke
parents:
diff changeset
897 if (TraceGen1Time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
898 double time = PSMarkSweep::accumulated_time()->seconds();
a61af66fc99e Initial load
duke
parents:
diff changeset
899 tty->print_cr("[Accumulated GC generation 1 time %3.7f secs]", time);
a61af66fc99e Initial load
duke
parents:
diff changeset
900 }
a61af66fc99e Initial load
duke
parents:
diff changeset
901 }
a61af66fc99e Initial load
duke
parents:
diff changeset
902
a61af66fc99e Initial load
duke
parents:
diff changeset
903
3772
6747fd0512e0 7004681: G1: Extend marking verification to Full GCs
johnc
parents: 3377
diff changeset
904 void ParallelScavengeHeap::verify(bool allow_dirty, bool silent, VerifyOption option /* ignored */) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
905 // Why do we need the total_collections()-filter below?
a61af66fc99e Initial load
duke
parents:
diff changeset
906 if (total_collections() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
907 if (!silent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
908 gclog_or_tty->print("permanent ");
a61af66fc99e Initial load
duke
parents:
diff changeset
909 }
a61af66fc99e Initial load
duke
parents:
diff changeset
910 perm_gen()->verify(allow_dirty);
a61af66fc99e Initial load
duke
parents:
diff changeset
911
a61af66fc99e Initial load
duke
parents:
diff changeset
912 if (!silent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
913 gclog_or_tty->print("tenured ");
a61af66fc99e Initial load
duke
parents:
diff changeset
914 }
a61af66fc99e Initial load
duke
parents:
diff changeset
915 old_gen()->verify(allow_dirty);
a61af66fc99e Initial load
duke
parents:
diff changeset
916
a61af66fc99e Initial load
duke
parents:
diff changeset
917 if (!silent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
918 gclog_or_tty->print("eden ");
a61af66fc99e Initial load
duke
parents:
diff changeset
919 }
a61af66fc99e Initial load
duke
parents:
diff changeset
920 young_gen()->verify(allow_dirty);
a61af66fc99e Initial load
duke
parents:
diff changeset
921 }
a61af66fc99e Initial load
duke
parents:
diff changeset
922 if (!silent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
923 gclog_or_tty->print("ref_proc ");
a61af66fc99e Initial load
duke
parents:
diff changeset
924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
925 ReferenceProcessor::verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
926 }
a61af66fc99e Initial load
duke
parents:
diff changeset
927
a61af66fc99e Initial load
duke
parents:
diff changeset
928 void ParallelScavengeHeap::print_heap_change(size_t prev_used) {
a61af66fc99e Initial load
duke
parents:
diff changeset
929 if (PrintGCDetails && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
930 gclog_or_tty->print(" " SIZE_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
931 "->" SIZE_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
932 "(" SIZE_FORMAT ")",
a61af66fc99e Initial load
duke
parents:
diff changeset
933 prev_used, used(), capacity());
a61af66fc99e Initial load
duke
parents:
diff changeset
934 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
935 gclog_or_tty->print(" " SIZE_FORMAT "K"
a61af66fc99e Initial load
duke
parents:
diff changeset
936 "->" SIZE_FORMAT "K"
a61af66fc99e Initial load
duke
parents:
diff changeset
937 "(" SIZE_FORMAT "K)",
a61af66fc99e Initial load
duke
parents:
diff changeset
938 prev_used / K, used() / K, capacity() / K);
a61af66fc99e Initial load
duke
parents:
diff changeset
939 }
a61af66fc99e Initial load
duke
parents:
diff changeset
940 }
a61af66fc99e Initial load
duke
parents:
diff changeset
941
a61af66fc99e Initial load
duke
parents:
diff changeset
942 ParallelScavengeHeap* ParallelScavengeHeap::heap() {
a61af66fc99e Initial load
duke
parents:
diff changeset
943 assert(_psh != NULL, "Uninitialized access to ParallelScavengeHeap::heap()");
a61af66fc99e Initial load
duke
parents:
diff changeset
944 assert(_psh->kind() == CollectedHeap::ParallelScavengeHeap, "not a parallel scavenge heap");
a61af66fc99e Initial load
duke
parents:
diff changeset
945 return _psh;
a61af66fc99e Initial load
duke
parents:
diff changeset
946 }
a61af66fc99e Initial load
duke
parents:
diff changeset
947
a61af66fc99e Initial load
duke
parents:
diff changeset
948 // Before delegating the resize to the young generation,
a61af66fc99e Initial load
duke
parents:
diff changeset
949 // the reserved space for the young and old generations
a61af66fc99e Initial load
duke
parents:
diff changeset
950 // may be changed to accomodate the desired resize.
a61af66fc99e Initial load
duke
parents:
diff changeset
951 void ParallelScavengeHeap::resize_young_gen(size_t eden_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
952 size_t survivor_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
953 if (UseAdaptiveGCBoundary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
954 if (size_policy()->bytes_absorbed_from_eden() != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
955 size_policy()->reset_bytes_absorbed_from_eden();
a61af66fc99e Initial load
duke
parents:
diff changeset
956 return; // The generation changed size already.
a61af66fc99e Initial load
duke
parents:
diff changeset
957 }
a61af66fc99e Initial load
duke
parents:
diff changeset
958 gens()->adjust_boundary_for_young_gen_needs(eden_size, survivor_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
960
a61af66fc99e Initial load
duke
parents:
diff changeset
961 // Delegate the resize to the generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
962 _young_gen->resize(eden_size, survivor_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
963 }
a61af66fc99e Initial load
duke
parents:
diff changeset
964
a61af66fc99e Initial load
duke
parents:
diff changeset
965 // Before delegating the resize to the old generation,
a61af66fc99e Initial load
duke
parents:
diff changeset
966 // the reserved space for the young and old generations
a61af66fc99e Initial load
duke
parents:
diff changeset
967 // may be changed to accomodate the desired resize.
a61af66fc99e Initial load
duke
parents:
diff changeset
968 void ParallelScavengeHeap::resize_old_gen(size_t desired_free_space) {
a61af66fc99e Initial load
duke
parents:
diff changeset
969 if (UseAdaptiveGCBoundary) {
a61af66fc99e Initial load
duke
parents:
diff changeset
970 if (size_policy()->bytes_absorbed_from_eden() != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
971 size_policy()->reset_bytes_absorbed_from_eden();
a61af66fc99e Initial load
duke
parents:
diff changeset
972 return; // The generation changed size already.
a61af66fc99e Initial load
duke
parents:
diff changeset
973 }
a61af66fc99e Initial load
duke
parents:
diff changeset
974 gens()->adjust_boundary_for_old_gen_needs(desired_free_space);
a61af66fc99e Initial load
duke
parents:
diff changeset
975 }
a61af66fc99e Initial load
duke
parents:
diff changeset
976
a61af66fc99e Initial load
duke
parents:
diff changeset
977 // Delegate the resize to the generation.
a61af66fc99e Initial load
duke
parents:
diff changeset
978 _old_gen->resize(desired_free_space);
a61af66fc99e Initial load
duke
parents:
diff changeset
979 }
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
980
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 845
diff changeset
981 ParallelScavengeHeap::ParStrongRootsScope::ParStrongRootsScope() {
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 845
diff changeset
982 // nothing particular
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 845
diff changeset
983 }
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 845
diff changeset
984
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 845
diff changeset
985 ParallelScavengeHeap::ParStrongRootsScope::~ParStrongRootsScope() {
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 845
diff changeset
986 // nothing particular
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 845
diff changeset
987 }
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 845
diff changeset
988
263
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
989 #ifndef PRODUCT
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
990 void ParallelScavengeHeap::record_gen_tops_before_GC() {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
991 if (ZapUnusedHeapArea) {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
992 young_gen()->record_spaces_top();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
993 old_gen()->record_spaces_top();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
994 perm_gen()->record_spaces_top();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
995 }
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
996 }
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
997
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
998 void ParallelScavengeHeap::gen_mangle_unused_area() {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
999 if (ZapUnusedHeapArea) {
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
1000 young_gen()->eden_space()->mangle_unused_area();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
1001 young_gen()->to_space()->mangle_unused_area();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
1002 young_gen()->from_space()->mangle_unused_area();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
1003 old_gen()->object_space()->mangle_unused_area();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
1004 perm_gen()->object_space()->mangle_unused_area();
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
1005 }
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
1006 }
12eea04c8b06 6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents: 139
diff changeset
1007 #endif