1/*
2 * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#ifndef SHARE_GC_PARALLEL_PSSCAVENGE_HPP
26#define SHARE_GC_PARALLEL_PSSCAVENGE_HPP
27
28#include "gc/parallel/psCardTable.hpp"
29#include "gc/parallel/psVirtualspace.hpp"
30#include "gc/shared/collectorCounters.hpp"
31#include "gc/shared/gcTrace.hpp"
32#include "memory/allocation.hpp"
33#include "oops/oop.hpp"
34#include "utilities/stack.hpp"
35
36class GCTaskManager;
37class GCTaskQueue;
38class OopStack;
39class ReferenceProcessor;
40class ParallelScavengeHeap;
41class ParallelScavengeTracer;
42class PSIsAliveClosure;
43class PSRefProcTaskExecutor;
44class STWGCTimer;
45
46class PSScavenge: AllStatic {
47 friend class PSIsAliveClosure;
48 friend class PSKeepAliveClosure;
49 friend class PSPromotionManager;
50
51 enum ScavengeSkippedCause {
52 not_skipped = 0,
53 to_space_not_empty,
54 promoted_too_large,
55 full_follows_scavenge
56 };
57
58 // Saved value of to_space->top(), used to prevent objects in to_space from
59 // being rescanned.
60 static HeapWord* _to_space_top_before_gc;
61
62 // Number of consecutive attempts to scavenge that were skipped
63 static int _consecutive_skipped_scavenges;
64
65
66 protected:
67 // Flags/counters
68 static SpanSubjectToDiscoveryClosure _span_based_discoverer;
69 static ReferenceProcessor* _ref_processor; // Reference processor for scavenging.
70 static PSIsAliveClosure _is_alive_closure; // Closure used for reference processing
71 static PSCardTable* _card_table; // We cache the card table for fast access.
72 static bool _survivor_overflow; // Overflow this collection
73 static uint _tenuring_threshold; // tenuring threshold for next scavenge
74 static elapsedTimer _accumulated_time; // total time spent on scavenge
75 static STWGCTimer _gc_timer; // GC time book keeper
76 static ParallelScavengeTracer _gc_tracer; // GC tracing
77 // The lowest address possible for the young_gen.
78 // This is used to decide if an oop should be scavenged,
79 // cards should be marked, etc.
80 static HeapWord* _young_generation_boundary;
81 // Used to optimize compressed oops young gen boundary checking.
82 static uintptr_t _young_generation_boundary_compressed;
83 static CollectorCounters* _counters; // collector performance counters
84
85 static void clean_up_failed_promotion();
86
87 static bool should_attempt_scavenge();
88
89 static HeapWord* to_space_top_before_gc() { return _to_space_top_before_gc; }
90 static inline void save_to_space_top_before_gc();
91
92 // Private accessors
93 static PSCardTable* const card_table() { assert(_card_table != NULL, "Sanity"); return _card_table; }
94 static const ParallelScavengeTracer* gc_tracer() { return &_gc_tracer; }
95
96 public:
97 // Accessors
98 static uint tenuring_threshold() { return _tenuring_threshold; }
99 static elapsedTimer* accumulated_time() { return &_accumulated_time; }
100 static int consecutive_skipped_scavenges()
101 { return _consecutive_skipped_scavenges; }
102
103 // Performance Counters
104 static CollectorCounters* counters() { return _counters; }
105
106 static void set_subject_to_discovery_span(MemRegion mr) {
107 _span_based_discoverer.set_span(mr);
108 }
109 // Used by scavenge_contents && psMarkSweep
110 static ReferenceProcessor* const reference_processor() {
111 assert(_ref_processor != NULL, "Sanity");
112 return _ref_processor;
113 }
114 // Used to add tasks
115 static GCTaskManager* const gc_task_manager();
116 // The promotion managers tell us if they encountered overflow
117 static void set_survivor_overflow(bool state) {
118 _survivor_overflow = state;
119 }
120 // Adaptive size policy support. When the young generation/old generation
121 // boundary moves, _young_generation_boundary must be reset
122 static void set_young_generation_boundary(HeapWord* v);
123
124 // Called by parallelScavengeHeap to init the tenuring threshold
125 static void initialize();
126
127 // Scavenge entry point. This may invoke a full gc; return true if so.
128 static bool invoke();
129 // Return true if a collection was done; false otherwise.
130 static bool invoke_no_policy();
131
132 template <class T> static inline bool should_scavenge(T* p);
133
134 // These call should_scavenge() above and, if it returns true, also check that
135 // the object was not newly copied into to_space. The version with the bool
136 // argument is a convenience wrapper that fetches the to_space pointer from
137 // the heap and calls the other version (if the arg is true).
138 template <class T> static inline bool should_scavenge(T* p, MutableSpace* to_space);
139 template <class T> static inline bool should_scavenge(T* p, bool check_to_space);
140
141 static void copy_and_push_safe_barrier_from_klass(PSPromotionManager* pm, oop* p);
142
143 // Is an object in the young generation
144 // This assumes that the 'o' is in the heap,
145 // so it only checks one side of the complete predicate.
146
147 inline static bool is_obj_in_young(oop o) {
148 return (HeapWord*)o >= _young_generation_boundary;
149 }
150
151 inline static bool is_obj_in_young(narrowOop o) {
152 return (uintptr_t)o >= _young_generation_boundary_compressed;
153 }
154
155 inline static bool is_obj_in_young(HeapWord* o) {
156 return o >= _young_generation_boundary;
157 }
158};
159
160#endif // SHARE_GC_PARALLEL_PSSCAVENGE_HPP
161