blob: 6ea6c84f085d5f12f27e8229c43599a3e9465ae0 [file] [log] [blame]
Dave Allison0aded082013-11-07 13:15:11 -08001/*
2 * Copyright (C) 2011 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_PROFILER_H_
18#define ART_RUNTIME_PROFILER_H_
19
20#include <ostream>
21#include <set>
22#include <string>
23#include <vector>
24
Ian Rogers719d1a32014-03-06 12:13:39 -080025#include "barrier.h"
Dave Allison0aded082013-11-07 13:15:11 -080026#include "base/macros.h"
Ian Rogers719d1a32014-03-06 12:13:39 -080027#include "base/mutex.h"
Dave Allison0aded082013-11-07 13:15:11 -080028#include "globals.h"
29#include "instrumentation.h"
30#include "os.h"
31#include "safe_map.h"
Dave Allison0aded082013-11-07 13:15:11 -080032#include "UniquePtr.h"
Dave Allison0aded082013-11-07 13:15:11 -080033
34namespace art {
35
36namespace mirror {
37 class ArtMethod;
38 class Class;
39} // namespace mirror
40class Thread;
41
42
43//
44// This class holds all the results for all runs of the profiler. It also
45// counts the number of null methods (where we can't determine the method) and
46// the number of methods in the boot path (where we have already compiled the method).
47//
48// This object is an internal profiler object and uses the same locking as the profiler
49// itself.
50class ProfileSampleResults {
51 public:
52 explicit ProfileSampleResults(Mutex& lock);
53 ~ProfileSampleResults();
54
55 void Put(mirror::ArtMethod* method);
56 uint32_t Write(std::ostream &os);
57 void Clear();
58 uint32_t GetNumSamples() { return num_samples_; }
59 void NullMethod() { ++num_null_methods_; }
60 void BootMethod() { ++num_boot_methods_; }
61 private:
62 uint32_t Hash(mirror::ArtMethod* method);
63 static constexpr int kHashSize = 17;
64 Mutex& lock_; // Reference to the main profiler lock - we don't need two of them.
65 uint32_t num_samples_; // Total number of samples taken.
66 uint32_t num_null_methods_; // Number of samples where can don't know the method.
67 uint32_t num_boot_methods_; // Number of samples in the boot path.
68
69 typedef std::map<mirror::ArtMethod*, uint32_t> Map; // Map of method vs its count.
70 Map *table[kHashSize];
71};
72
73//
74// The BackgroundMethodSamplingProfiler runs in a thread. Most of the time it is sleeping but
75// occasionally wakes up and counts the number of times a method is called. Each time
76// it ticks, it looks at the current method and records it in the ProfileSampleResults
77// table.
78//
79// The timing is controlled by a number of variables:
80// 1. Period: the time between sampling runs.
81// 2. Interval: the time between each sample in a run.
82// 3. Duration: the duration of a run.
83//
84// So the profiler thread is sleeping for the 'period' time. It wakes up and runs for the
85// 'duration'. The run consists of a series of samples, each of which is 'interval' microseconds
86// apart. At the end of a run, it writes the results table to a file and goes back to sleep.
87
88class BackgroundMethodSamplingProfiler {
89 public:
90 static void Start(int period, int duration, std::string profile_filename, int interval_us,
91 double backoff_coefficient, bool startImmediately)
92 LOCKS_EXCLUDED(Locks::mutator_lock_,
93 Locks::thread_list_lock_,
94 Locks::thread_suspend_count_lock_,
95 Locks::profiler_lock_);
96
97 static void Stop() LOCKS_EXCLUDED(Locks::profiler_lock_, wait_lock_);
98 static void Shutdown() LOCKS_EXCLUDED(Locks::profiler_lock_);
99
100 void RecordMethod(mirror::ArtMethod *method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
101
102 Barrier& GetBarrier() {
103 return *profiler_barrier_;
104 }
105
106 private:
107 explicit BackgroundMethodSamplingProfiler(int period, int duration, std::string profile_filename,
108 double backoff_coefficient, int interval_us, bool startImmediately);
109
110 // The sampling interval in microseconds is passed as an argument.
111 static void* RunProfilerThread(void* arg) LOCKS_EXCLUDED(Locks::profiler_lock_);
112
113 uint32_t WriteProfile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
114
115 void CleanProfile();
116 uint32_t DumpProfile(std::ostream& os) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
117 static bool ShuttingDown(Thread* self) LOCKS_EXCLUDED(Locks::profiler_lock_);
118
119 static BackgroundMethodSamplingProfiler* profiler_ GUARDED_BY(Locks::profiler_lock_);
120
121 // We need to shut the sample thread down at exit. Setting this to true will do that.
122 static volatile bool shutting_down_ GUARDED_BY(Locks::profiler_lock_);
123
124 // Sampling thread, non-zero when sampling.
125 static pthread_t profiler_pthread_;
126
127 // Some measure of the number of samples that are significant
128 static constexpr uint32_t kSignificantSamples = 10;
129
130 // File to write profile data out to. Cannot be empty if we are profiling.
131 std::string profile_file_name_;
132
133 // Number of seconds between profile runs.
134 uint32_t period_s_;
135
136 // Most of the time we want to delay the profiler startup to prevent everything
137 // running at the same time (all processes). This is the default, but if we
138 // want to override this, set the 'start_immediately_' to true. This is done
139 // if the -Xprofile option is given on the command line.
140 bool start_immediately_;
141
142 uint32_t interval_us_;
143
144 // A backoff coefficent to adjust the profile period based on time.
145 double backoff_factor_;
146
147 // How much to increase the backoff by on each profile iteration.
148 double backoff_coefficient_;
149
150 // Duration of each profile run. The profile file will be written at the end
151 // of each run.
152 uint32_t duration_s_;
153
154 // Profile condition support.
155 Mutex wait_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
156 ConditionVariable period_condition_ GUARDED_BY(wait_lock_);
157
158 ProfileSampleResults profile_table_;
159
160 UniquePtr<Barrier> profiler_barrier_;
161
162 // Set of methods to be filtered out. This will probably be rare because
163 // most of the methods we want to be filtered reside in the boot path and
164 // are automatically filtered.
165 typedef std::set<std::string> FilteredMethods;
166 FilteredMethods filtered_methods_;
167
168 DISALLOW_COPY_AND_ASSIGN(BackgroundMethodSamplingProfiler);
169};
170
171} // namespace art
172
173#endif // ART_RUNTIME_PROFILER_H_