1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_RUNTIME_GC_COLLECTOR_GARBAGE_COLLECTOR_H_
18 #define ART_RUNTIME_GC_COLLECTOR_GARBAGE_COLLECTOR_H_
19 
20 #include "base/histogram.h"
21 #include "base/mutex.h"
22 #include "base/timing_logger.h"
23 #include "gc/collector_type.h"
24 #include "gc/gc_cause.h"
25 #include "gc_type.h"
26 #include <stdint.h>
27 #include <vector>
28 
29 namespace art {
30 namespace gc {
31 
32 class Heap;
33 
34 namespace collector {
35 
36 struct ObjectBytePair {
37   ObjectBytePair(uint64_t num_objects = 0, int64_t num_bytes = 0)
objectsObjectBytePair38       : objects(num_objects), bytes(num_bytes) {}
AddObjectBytePair39   void Add(const ObjectBytePair& other) {
40     objects += other.objects;
41     bytes += other.bytes;
42   }
43   // Number of objects which were freed.
44   uint64_t objects;
45   // Freed bytes are signed since the GC can free negative bytes if it promotes objects to a space
46   // which has a larger allocation size.
47   int64_t bytes;
48 };
49 
50 // A information related single garbage collector iteration. Since we only ever have one GC running
51 // at any given time, we can have a single iteration info.
52 class Iteration {
53  public:
54   Iteration();
55   // Returns how long the mutators were paused in nanoseconds.
GetPauseTimes()56   const std::vector<uint64_t>& GetPauseTimes() const {
57     return pause_times_;
58   }
GetTimings()59   TimingLogger* GetTimings() {
60     return &timings_;
61   }
62   // Returns how long the GC took to complete in nanoseconds.
GetDurationNs()63   uint64_t GetDurationNs() const {
64     return duration_ns_;
65   }
GetFreedBytes()66   int64_t GetFreedBytes() const {
67     return freed_.bytes;
68   }
GetFreedLargeObjectBytes()69   int64_t GetFreedLargeObjectBytes() const {
70     return freed_los_.bytes;
71   }
GetFreedObjects()72   uint64_t GetFreedObjects() const {
73     return freed_.objects;
74   }
GetFreedLargeObjects()75   uint64_t GetFreedLargeObjects() const {
76     return freed_los_.objects;
77   }
78   void Reset(GcCause gc_cause, bool clear_soft_references);
79   // Returns the estimated throughput of the iteration.
80   uint64_t GetEstimatedThroughput() const;
GetClearSoftReferences()81   bool GetClearSoftReferences() const {
82     return clear_soft_references_;
83   }
SetClearSoftReferences(bool clear_soft_references)84   void SetClearSoftReferences(bool clear_soft_references) {
85     clear_soft_references_ = clear_soft_references;
86   }
GetGcCause()87   GcCause GetGcCause() const {
88     return gc_cause_;
89   }
90 
91  private:
SetDurationNs(uint64_t duration)92   void SetDurationNs(uint64_t duration) {
93     duration_ns_ = duration;
94   }
95 
96   GcCause gc_cause_;
97   bool clear_soft_references_;
98   uint64_t duration_ns_;
99   TimingLogger timings_;
100   ObjectBytePair freed_;
101   ObjectBytePair freed_los_;
102   std::vector<uint64_t> pause_times_;
103 
104   friend class GarbageCollector;
105   DISALLOW_COPY_AND_ASSIGN(Iteration);
106 };
107 
108 class GarbageCollector {
109  public:
110   class SCOPED_LOCKABLE ScopedPause {
111    public:
112     explicit ScopedPause(GarbageCollector* collector) EXCLUSIVE_LOCK_FUNCTION(Locks::mutator_lock_);
113     ~ScopedPause() UNLOCK_FUNCTION();
114 
115    private:
116     const uint64_t start_time_;
117     GarbageCollector* const collector_;
118   };
119 
120   GarbageCollector(Heap* heap, const std::string& name);
~GarbageCollector()121   virtual ~GarbageCollector() { }
122 
GetName()123   const char* GetName() const {
124     return name_.c_str();
125   }
126 
127   virtual GcType GetGcType() const = 0;
128 
129   virtual CollectorType GetCollectorType() const = 0;
130 
131   // Run the garbage collector.
132   void Run(GcCause gc_cause, bool clear_soft_references);
133 
GetHeap()134   Heap* GetHeap() const {
135     return heap_;
136   }
137   void RegisterPause(uint64_t nano_length);
GetCumulativeTimings()138   const CumulativeLogger& GetCumulativeTimings() const {
139     return cumulative_timings_;
140   }
141 
142   void ResetCumulativeStatistics();
143 
144   // Swap the live and mark bitmaps of spaces that are active for the collector. For partial GC,
145   // this is the allocation space, for full GC then we swap the zygote bitmaps too.
146   void SwapBitmaps() EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
GetTotalPausedTimeNs()147   uint64_t GetTotalPausedTimeNs() const {
148     return pause_histogram_.AdjustedSum();
149   }
GetTotalFreedBytes()150   int64_t GetTotalFreedBytes() const {
151     return total_freed_bytes_;
152   }
GetTotalFreedObjects()153   uint64_t GetTotalFreedObjects() const {
154     return total_freed_objects_;
155   }
GetPauseHistogram()156   const Histogram<uint64_t>& GetPauseHistogram() const {
157     return pause_histogram_;
158   }
159   // Reset the cumulative timings and pause histogram.
160   void ResetMeasurements();
161   // Returns the estimated throughput in bytes / second.
162   uint64_t GetEstimatedMeanThroughput() const;
163   // Returns how many GC iterations have been run.
NumberOfIterations()164   size_t NumberOfIterations() const {
165     return GetCumulativeTimings().GetIterations();
166   }
167   // Returns the current GC iteration and assocated info.
168   Iteration* GetCurrentIteration();
169   const Iteration* GetCurrentIteration() const;
GetTimings()170   TimingLogger* GetTimings() {
171     return &GetCurrentIteration()->timings_;
172   }
173   // Record a free of normal objects.
174   void RecordFree(const ObjectBytePair& freed);
175   // Record a free of large objects.
176   void RecordFreeLOS(const ObjectBytePair& freed);
177 
178  protected:
179   // Run all of the GC phases.
180   virtual void RunPhases() = 0;
181 
182   // Revoke all the thread-local buffers.
183   virtual void RevokeAllThreadLocalBuffers() = 0;
184 
185   static constexpr size_t kPauseBucketSize = 500;
186   static constexpr size_t kPauseBucketCount = 32;
187 
188   Heap* const heap_;
189   std::string name_;
190   // Cumulative statistics.
191   Histogram<uint64_t> pause_histogram_;
192   uint64_t total_time_ns_;
193   uint64_t total_freed_objects_;
194   int64_t total_freed_bytes_;
195   CumulativeLogger cumulative_timings_;
196 };
197 
198 }  // namespace collector
199 }  // namespace gc
200 }  // namespace art
201 
202 #endif  // ART_RUNTIME_GC_COLLECTOR_GARBAGE_COLLECTOR_H_
203