25 #include "precompiled.hpp"
26 #include "gc/serial/genMarkSweep.hpp"
27 #include "gc/shared/blockOffsetTable.inline.hpp"
28 #include "gc/shared/cardTableRS.hpp"
29 #include "gc/shared/collectedHeap.inline.hpp"
30 #include "gc/shared/gcLocker.inline.hpp"
31 #include "gc/shared/gcTimer.hpp"
32 #include "gc/shared/gcTrace.hpp"
33 #include "gc/shared/genCollectedHeap.hpp"
34 #include "gc/shared/genOopClosures.hpp"
35 #include "gc/shared/genOopClosures.inline.hpp"
36 #include "gc/shared/generation.hpp"
37 #include "gc/shared/space.inline.hpp"
38 #include "gc/shared/spaceDecorator.hpp"
39 #include "memory/allocation.inline.hpp"
40 #include "oops/oop.inline.hpp"
41 #include "runtime/java.hpp"
42 #include "utilities/copy.hpp"
43 #include "utilities/events.hpp"
44
45 Generation::Generation(ReservedSpace rs, size_t initial_size, int level) :
46 _level(level),
47 _ref_processor(NULL) {
48 if (!_virtual_space.initialize(rs, initial_size)) {
49 vm_exit_during_initialization("Could not reserve enough space for "
50 "object heap");
51 }
52 // Mangle all of the the initial generation.
53 if (ZapUnusedHeapArea) {
54 MemRegion mangle_region((HeapWord*)_virtual_space.low(),
55 (HeapWord*)_virtual_space.high());
56 SpaceMangler::mangle_region(mangle_region);
57 }
58 _reserved = MemRegion((HeapWord*)_virtual_space.low_boundary(),
59 (HeapWord*)_virtual_space.high_boundary());
60 }
61
62 GenerationSpec* Generation::spec() {
63 GenCollectedHeap* gch = GenCollectedHeap::heap();
64 assert(level() == 0 || level() == 1, "Bad gen level");
65 return level() == 0 ? gch->gen_policy()->young_gen_spec() : gch->gen_policy()->old_gen_spec();
66 }
67
68 size_t Generation::max_capacity() const {
69 return reserved().byte_size();
70 }
71
72 void Generation::print_heap_change(size_t prev_used) const {
73 if (PrintGCDetails && Verbose) {
74 gclog_or_tty->print(" " SIZE_FORMAT
75 "->" SIZE_FORMAT
76 "(" SIZE_FORMAT ")",
77 prev_used, used(), capacity());
78 } else {
79 gclog_or_tty->print(" " SIZE_FORMAT "K"
80 "->" SIZE_FORMAT "K"
81 "(" SIZE_FORMAT "K)",
82 prev_used / K, used() / K, capacity() / K);
83 }
84 }
85
94 }
95 }
96
97 void Generation::print() const { print_on(tty); }
98
99 void Generation::print_on(outputStream* st) const {
100 st->print(" %-20s", name());
101 st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
102 capacity()/K, used()/K);
103 st->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")",
104 p2i(_virtual_space.low_boundary()),
105 p2i(_virtual_space.high()),
106 p2i(_virtual_space.high_boundary()));
107 }
108
109 void Generation::print_summary_info() { print_summary_info_on(tty); }
110
111 void Generation::print_summary_info_on(outputStream* st) {
112 StatRecord* sr = stat_record();
113 double time = sr->accumulated_time.seconds();
114 st->print_cr("[Accumulated GC generation %d time %3.7f secs, "
115 "%d GC's, avg GC time %3.7f]",
116 level(), time, sr->invocations,
117 sr->invocations > 0 ? time / sr->invocations : 0.0);
118 }
119
120 // Utility iterator classes
121
122 class GenerationIsInReservedClosure : public SpaceClosure {
123 public:
124 const void* _p;
125 Space* sp;
126 virtual void do_space(Space* s) {
127 if (sp == NULL) {
128 if (s->is_in_reserved(_p)) sp = s;
129 }
130 }
131 GenerationIsInReservedClosure(const void* p) : _p(p), sp(NULL) {}
132 };
133
134 class GenerationIsInClosure : public SpaceClosure {
135 public:
136 const void* _p;
137 Space* sp;
138 virtual void do_space(Space* s) {
139 if (sp == NULL) {
140 if (s->is_in(_p)) sp = s;
141 }
142 }
143 GenerationIsInClosure(const void* p) : _p(p), sp(NULL) {}
144 };
145
146 bool Generation::is_in(const void* p) const {
147 GenerationIsInClosure blk(p);
148 ((Generation*)this)->space_iterate(&blk);
149 return blk.sp != NULL;
150 }
151
152 Generation* Generation::next_gen() const {
153 GenCollectedHeap* gch = GenCollectedHeap::heap();
154 if (level() == 0) {
155 return gch->old_gen();
156 } else {
157 return NULL;
158 }
159 }
160
161 size_t Generation::max_contiguous_available() const {
162 // The largest number of contiguous free words in this or any higher generation.
163 size_t max = 0;
164 for (const Generation* gen = this; gen != NULL; gen = gen->next_gen()) {
165 size_t avail = gen->contiguous_available();
166 if (avail > max) {
167 max = avail;
168 }
169 }
170 return max;
171 }
172
173 bool Generation::promotion_attempt_is_safe(size_t max_promotion_in_bytes) const {
174 size_t available = max_contiguous_available();
175 bool res = (available >= max_promotion_in_bytes);
176 if (PrintGC && Verbose) {
177 gclog_or_tty->print_cr(
178 "Generation: promo attempt is%s safe: available("SIZE_FORMAT") %s max_promo("SIZE_FORMAT")",
179 res? "":" not", available, res? ">=":"<",
180 max_promotion_in_bytes);
181 }
182 return res;
183 }
184
185 // Ignores "ref" and calls allocate().
186 oop Generation::promote(oop obj, size_t obj_size) {
187 assert(obj_size == (size_t)obj->size(), "bad obj_size passed in");
188
189 #ifndef PRODUCT
190 if (GenCollectedHeap::heap()->promotion_should_fail()) {
|
25 #include "precompiled.hpp"
26 #include "gc/serial/genMarkSweep.hpp"
27 #include "gc/shared/blockOffsetTable.inline.hpp"
28 #include "gc/shared/cardTableRS.hpp"
29 #include "gc/shared/collectedHeap.inline.hpp"
30 #include "gc/shared/gcLocker.inline.hpp"
31 #include "gc/shared/gcTimer.hpp"
32 #include "gc/shared/gcTrace.hpp"
33 #include "gc/shared/genCollectedHeap.hpp"
34 #include "gc/shared/genOopClosures.hpp"
35 #include "gc/shared/genOopClosures.inline.hpp"
36 #include "gc/shared/generation.hpp"
37 #include "gc/shared/space.inline.hpp"
38 #include "gc/shared/spaceDecorator.hpp"
39 #include "memory/allocation.inline.hpp"
40 #include "oops/oop.inline.hpp"
41 #include "runtime/java.hpp"
42 #include "utilities/copy.hpp"
43 #include "utilities/events.hpp"
44
45 Generation::Generation(ReservedSpace rs, size_t initial_size) :
46 _ref_processor(NULL) {
47 if (!_virtual_space.initialize(rs, initial_size)) {
48 vm_exit_during_initialization("Could not reserve enough space for "
49 "object heap");
50 }
51 // Mangle all of the the initial generation.
52 if (ZapUnusedHeapArea) {
53 MemRegion mangle_region((HeapWord*)_virtual_space.low(),
54 (HeapWord*)_virtual_space.high());
55 SpaceMangler::mangle_region(mangle_region);
56 }
57 _reserved = MemRegion((HeapWord*)_virtual_space.low_boundary(),
58 (HeapWord*)_virtual_space.high_boundary());
59 }
60
61 GenerationSpec* Generation::spec() {
62 GenCollectedHeap* gch = GenCollectedHeap::heap();
63 if (this == gch->young_gen()) {
64 return gch->gen_policy()->young_gen_spec();
65 }
66 return gch->gen_policy()->old_gen_spec();
67 }
68
69 size_t Generation::max_capacity() const {
70 return reserved().byte_size();
71 }
72
73 void Generation::print_heap_change(size_t prev_used) const {
74 if (PrintGCDetails && Verbose) {
75 gclog_or_tty->print(" " SIZE_FORMAT
76 "->" SIZE_FORMAT
77 "(" SIZE_FORMAT ")",
78 prev_used, used(), capacity());
79 } else {
80 gclog_or_tty->print(" " SIZE_FORMAT "K"
81 "->" SIZE_FORMAT "K"
82 "(" SIZE_FORMAT "K)",
83 prev_used / K, used() / K, capacity() / K);
84 }
85 }
86
95 }
96 }
97
98 void Generation::print() const { print_on(tty); }
99
100 void Generation::print_on(outputStream* st) const {
101 st->print(" %-20s", name());
102 st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K",
103 capacity()/K, used()/K);
104 st->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")",
105 p2i(_virtual_space.low_boundary()),
106 p2i(_virtual_space.high()),
107 p2i(_virtual_space.high_boundary()));
108 }
109
110 void Generation::print_summary_info() { print_summary_info_on(tty); }
111
112 void Generation::print_summary_info_on(outputStream* st) {
113 StatRecord* sr = stat_record();
114 double time = sr->accumulated_time.seconds();
115 // I didn't want to change the logging when removing the level concept,
116 // but I guess this logging could say young/old or something instead of 0/1.
117 uint level;
118 if (this == GenCollectedHeap::heap()->young_gen()) {
119 level = 0;
120 } else {
121 level = 1;
122 }
123 st->print_cr("[Accumulated GC generation %d time %3.7f secs, "
124 "%u GC's, avg GC time %3.7f]",
125 level, time, sr->invocations,
126 sr->invocations > 0 ? time / sr->invocations : 0.0);
127 }
128
129 // Utility iterator classes
130
131 class GenerationIsInReservedClosure : public SpaceClosure {
132 public:
133 const void* _p;
134 Space* sp;
135 virtual void do_space(Space* s) {
136 if (sp == NULL) {
137 if (s->is_in_reserved(_p)) sp = s;
138 }
139 }
140 GenerationIsInReservedClosure(const void* p) : _p(p), sp(NULL) {}
141 };
142
143 class GenerationIsInClosure : public SpaceClosure {
144 public:
145 const void* _p;
146 Space* sp;
147 virtual void do_space(Space* s) {
148 if (sp == NULL) {
149 if (s->is_in(_p)) sp = s;
150 }
151 }
152 GenerationIsInClosure(const void* p) : _p(p), sp(NULL) {}
153 };
154
155 bool Generation::is_in(const void* p) const {
156 GenerationIsInClosure blk(p);
157 ((Generation*)this)->space_iterate(&blk);
158 return blk.sp != NULL;
159 }
160
161 size_t Generation::max_contiguous_available() const {
162 // The largest number of contiguous free words in this or any higher generation.
163 size_t avail = contiguous_available();
164 size_t old_avail = 0;
165 if (this == GenCollectedHeap::heap()->young_gen()) {
166 old_avail = GenCollectedHeap::heap()->old_gen()->contiguous_available();
167 }
168 return MAX2(avail, old_avail);
169 }
170
171 bool Generation::promotion_attempt_is_safe(size_t max_promotion_in_bytes) const {
172 size_t available = max_contiguous_available();
173 bool res = (available >= max_promotion_in_bytes);
174 if (PrintGC && Verbose) {
175 gclog_or_tty->print_cr(
176 "Generation: promo attempt is%s safe: available("SIZE_FORMAT") %s max_promo("SIZE_FORMAT")",
177 res? "":" not", available, res? ">=":"<",
178 max_promotion_in_bytes);
179 }
180 return res;
181 }
182
183 // Ignores "ref" and calls allocate().
184 oop Generation::promote(oop obj, size_t obj_size) {
185 assert(obj_size == (size_t)obj->size(), "bad obj_size passed in");
186
187 #ifndef PRODUCT
188 if (GenCollectedHeap::heap()->promotion_should_fail()) {
|