93 bool is_tlab, |
98 bool is_tlab, |
94 bool first_only); |
99 bool first_only); |
95 |
100 |
96 // Helper function for two callbacks below. |
101 // Helper function for two callbacks below. |
97 // Considers collection of the first max_level+1 generations. |
102 // Considers collection of the first max_level+1 generations. |
98 void do_collection(bool full, |
103 void do_collection(bool full, |
99 bool clear_all_soft_refs, |
104 bool clear_all_soft_refs, |
100 size_t size, |
105 size_t size, |
101 bool is_tlab, |
106 bool is_tlab, |
102 int max_level); |
107 GenerationType max_generation); |
103 |
108 |
104 // Callback from VM_GenCollectForAllocation operation. |
109 // Callback from VM_GenCollectForAllocation operation. |
105 // This function does everything necessary/possible to satisfy an |
110 // This function does everything necessary/possible to satisfy an |
106 // allocation request that failed in the youngest generation that should |
111 // allocation request that failed in the youngest generation that should |
107 // have handled it (including collection, expansion, etc.) |
112 // have handled it (including collection, expansion, etc.) |
108 HeapWord* satisfy_failed_allocation(size_t size, bool is_tlab); |
113 HeapWord* satisfy_failed_allocation(size_t size, bool is_tlab); |
109 |
114 |
110 // Callback from VM_GenCollectFull operation. |
115 // Callback from VM_GenCollectFull operation. |
111 // Perform a full collection of the first max_level+1 generations. |
116 // Perform a full collection of the first max_level+1 generations. |
112 virtual void do_full_collection(bool clear_all_soft_refs); |
117 virtual void do_full_collection(bool clear_all_soft_refs); |
113 void do_full_collection(bool clear_all_soft_refs, int max_level); |
118 void do_full_collection(bool clear_all_soft_refs, GenerationType max_generation); |
114 |
119 |
115 // Does the "cause" of GC indicate that |
120 // Does the "cause" of GC indicate that |
116 // we absolutely __must__ clear soft refs? |
121 // we absolutely __must__ clear soft refs? |
117 bool must_clear_all_soft_refs(); |
122 bool must_clear_all_soft_refs(); |
118 |
123 |
119 public: |
124 public: |
120 GenCollectedHeap(GenCollectorPolicy *policy); |
125 GenCollectedHeap(GenCollectorPolicy *policy); |
121 |
126 |
122 FlexibleWorkGang* workers() const { return _workers; } |
127 FlexibleWorkGang* workers() const { return _workers; } |
123 |
128 |
124 GCStats* gc_stats(int level) const; |
129 GCStats* gc_stats(Generation* generation) const; |
125 |
130 |
126 // Returns JNI_OK on success |
131 // Returns JNI_OK on success |
127 virtual jint initialize(); |
132 virtual jint initialize(); |
128 |
133 |
129 // Reserve aligned space for the heap as needed by the contained generations. |
134 // Reserve aligned space for the heap as needed by the contained generations. |
139 return CollectedHeap::GenCollectedHeap; |
144 return CollectedHeap::GenCollectedHeap; |
140 } |
145 } |
141 |
146 |
142 Generation* young_gen() const { return _young_gen; } |
147 Generation* young_gen() const { return _young_gen; } |
143 Generation* old_gen() const { return _old_gen; } |
148 Generation* old_gen() const { return _old_gen; } |
|
149 |
|
150 bool is_young_gen(const Generation* gen) const { return gen == _young_gen; } |
|
151 bool is_old_gen(const Generation* gen) const { return gen == _old_gen; } |
144 |
152 |
145 // The generational collector policy. |
153 // The generational collector policy. |
146 GenCollectorPolicy* gen_policy() const { return _gen_policy; } |
154 GenCollectorPolicy* gen_policy() const { return _gen_policy; } |
147 |
155 |
148 virtual CollectorPolicy* collector_policy() const { return (CollectorPolicy*) gen_policy(); } |
156 virtual CollectorPolicy* collector_policy() const { return (CollectorPolicy*) gen_policy(); } |
180 void collect(GCCause::Cause cause); |
188 void collect(GCCause::Cause cause); |
181 |
189 |
182 // The same as above but assume that the caller holds the Heap_lock. |
190 // The same as above but assume that the caller holds the Heap_lock. |
183 void collect_locked(GCCause::Cause cause); |
191 void collect_locked(GCCause::Cause cause); |
184 |
192 |
185 // Perform a full collection of the first max_level+1 generations. |
193 // Perform a full collection of generations up to and including max_generation. |
186 // Mostly used for testing purposes. Caller does not hold the Heap_lock on entry. |
194 // Mostly used for testing purposes. Caller does not hold the Heap_lock on entry. |
187 void collect(GCCause::Cause cause, int max_level); |
195 void collect(GCCause::Cause cause, GenerationType max_generation); |
188 |
196 |
189 // Returns "TRUE" iff "p" points into the committed areas of the heap. |
197 // Returns "TRUE" iff "p" points into the committed areas of the heap. |
190 // The methods is_in(), is_in_closed_subset() and is_in_youngest() may |
198 // The methods is_in(), is_in_closed_subset() and is_in_youngest() may |
191 // be expensive to compute in general, so, to prevent |
199 // be expensive to compute in general, so, to prevent |
192 // their inadvertent use in product jvm's, we restrict their use to |
200 // their inadvertent use in product jvm's, we restrict their use to |
312 _young_gen->update_time_of_last_gc(now); |
320 _young_gen->update_time_of_last_gc(now); |
313 _old_gen->update_time_of_last_gc(now); |
321 _old_gen->update_time_of_last_gc(now); |
314 } |
322 } |
315 |
323 |
316 // Update the gc statistics for each generation. |
324 // Update the gc statistics for each generation. |
317 // "level" is the level of the latest collection. |
325 void update_gc_stats(Generation* current_generation, bool full) { |
318 void update_gc_stats(int current_level, bool full) { |
326 _old_gen->update_gc_stats(current_generation, full); |
319 _young_gen->update_gc_stats(current_level, full); |
|
320 _old_gen->update_gc_stats(current_level, full); |
|
321 } |
327 } |
322 |
328 |
323 bool no_gc_in_progress() { return !is_gc_active(); } |
329 bool no_gc_in_progress() { return !is_gc_active(); } |
324 |
330 |
325 // Override. |
331 // Override. |
363 // Convenience function to be used in situations where the heap type can be |
369 // Convenience function to be used in situations where the heap type can be |
364 // asserted to be this type. |
370 // asserted to be this type. |
365 static GenCollectedHeap* heap(); |
371 static GenCollectedHeap* heap(); |
366 |
372 |
367 // Invoke the "do_oop" method of one of the closures "not_older_gens" |
373 // Invoke the "do_oop" method of one of the closures "not_older_gens" |
368 // or "older_gens" on root locations for the generation at |
374 // or "older_gens" on root locations for the generations depending on |
369 // "level". (The "older_gens" closure is used for scanning references |
375 // the type. (The "older_gens" closure is used for scanning references |
370 // from older generations; "not_older_gens" is used everywhere else.) |
376 // from older generations; "not_older_gens" is used everywhere else.) |
371 // If "younger_gens_as_roots" is false, younger generations are |
377 // If "younger_gens_as_roots" is false, younger generations are |
372 // not scanned as roots; in this case, the caller must be arranging to |
378 // not scanned as roots; in this case, the caller must be arranging to |
373 // scan the younger generations itself. (For example, a generation might |
379 // scan the younger generations itself. (For example, a generation might |
374 // explicitly mark reachable objects in younger generations, to avoid |
380 // explicitly mark reachable objects in younger generations, to avoid |
394 public: |
400 public: |
395 static const bool StrongAndWeakRoots = false; |
401 static const bool StrongAndWeakRoots = false; |
396 static const bool StrongRootsOnly = true; |
402 static const bool StrongRootsOnly = true; |
397 |
403 |
398 void gen_process_roots(StrongRootsScope* scope, |
404 void gen_process_roots(StrongRootsScope* scope, |
399 int level, |
405 GenerationType type, |
400 bool younger_gens_as_roots, |
406 bool younger_gens_as_roots, |
401 ScanningOption so, |
407 ScanningOption so, |
402 bool only_strong_roots, |
408 bool only_strong_roots, |
403 OopsInGenClosure* not_older_gens, |
409 OopsInGenClosure* not_older_gens, |
404 OopsInGenClosure* older_gens, |
410 OopsInGenClosure* older_gens, |
418 // allocated since the last call to save_marks in generations at or above |
424 // allocated since the last call to save_marks in generations at or above |
419 // "level". The "cur" closure is |
425 // "level". The "cur" closure is |
420 // applied to references in the generation at "level", and the "older" |
426 // applied to references in the generation at "level", and the "older" |
421 // closure to older generations. |
427 // closure to older generations. |
422 #define GCH_SINCE_SAVE_MARKS_ITERATE_DECL(OopClosureType, nv_suffix) \ |
428 #define GCH_SINCE_SAVE_MARKS_ITERATE_DECL(OopClosureType, nv_suffix) \ |
423 void oop_since_save_marks_iterate(int level, \ |
429 void oop_since_save_marks_iterate(GenerationType start_gen, \ |
424 OopClosureType* cur, \ |
430 OopClosureType* cur, \ |
425 OopClosureType* older); |
431 OopClosureType* older); |
426 |
432 |
427 ALL_SINCE_SAVE_MARKS_CLOSURES(GCH_SINCE_SAVE_MARKS_ITERATE_DECL) |
433 ALL_SINCE_SAVE_MARKS_CLOSURES(GCH_SINCE_SAVE_MARKS_ITERATE_DECL) |
428 |
434 |
429 #undef GCH_SINCE_SAVE_MARKS_ITERATE_DECL |
435 #undef GCH_SINCE_SAVE_MARKS_ITERATE_DECL |
430 |
436 |
431 // Returns "true" iff no allocations have occurred in any generation at |
437 // Returns "true" iff no allocations have occurred since the last |
432 // "level" or above since the last |
|
433 // call to "save_marks". |
438 // call to "save_marks". |
434 bool no_allocs_since_save_marks(int level); |
439 bool no_allocs_since_save_marks(bool include_young); |
435 |
440 |
436 // Returns true if an incremental collection is likely to fail. |
441 // Returns true if an incremental collection is likely to fail. |
437 // We optionally consult the young gen, if asked to do so; |
442 // We optionally consult the young gen, if asked to do so; |
438 // otherwise we base our answer on whether the previous incremental |
443 // otherwise we base our answer on whether the previous incremental |
439 // collection attempt failed with no corrective action as of yet. |
444 // collection attempt failed with no corrective action as of yet. |
440 bool incremental_collection_will_fail(bool consult_young) { |
445 bool incremental_collection_will_fail(bool consult_young) { |
441 // Assumes a 2-generation system; the first disjunct remembers if an |
446 // The first disjunct remembers if an incremental collection failed, even |
442 // incremental collection failed, even when we thought (second disjunct) |
447 // when we thought (second disjunct) that it would not. |
443 // that it would not. |
|
444 assert(heap()->collector_policy()->is_generation_policy(), |
|
445 "the following definition may not be suitable for an n(>2)-generation system"); |
|
446 return incremental_collection_failed() || |
448 return incremental_collection_failed() || |
447 (consult_young && !_young_gen->collection_attempt_is_safe()); |
449 (consult_young && !_young_gen->collection_attempt_is_safe()); |
448 } |
450 } |
449 |
451 |
450 // If a generation bails out of an incremental collection, |
452 // If a generation bails out of an incremental collection, |
480 // For use by mark-sweep. As implemented, mark-sweep-compact is global |
482 // For use by mark-sweep. As implemented, mark-sweep-compact is global |
481 // in an essential way: compaction is performed across generations, by |
483 // in an essential way: compaction is performed across generations, by |
482 // iterating over spaces. |
484 // iterating over spaces. |
483 void prepare_for_compaction(); |
485 void prepare_for_compaction(); |
484 |
486 |
485 // Perform a full collection of the first max_level+1 generations. |
487 // Perform a full collection of the generations up to and including max_generation. |
486 // This is the low level interface used by the public versions of |
488 // This is the low level interface used by the public versions of |
487 // collect() and collect_locked(). Caller holds the Heap_lock on entry. |
489 // collect() and collect_locked(). Caller holds the Heap_lock on entry. |
488 void collect_locked(GCCause::Cause cause, int max_level); |
490 void collect_locked(GCCause::Cause cause, GenerationType max_generation); |
489 |
491 |
490 // Returns success or failure. |
492 // Returns success or failure. |
491 bool create_cms_collector(); |
493 bool create_cms_collector(); |
492 |
494 |
493 // In support of ExplicitGCInvokesConcurrent functionality |
495 // In support of ExplicitGCInvokesConcurrent functionality |