blob: ab6cb378eabeef85113f25ac1df3b5656f5ebc33 [file] [log] [blame]
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00001// Copyright 2012 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_RUNTIME_PROFILER_H_
29#define V8_RUNTIME_PROFILER_H_
30
kasperl@chromium.orga5551262010-12-07 12:49:48 +000031#include "allocation.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000032#include "atomicops.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000033
34namespace v8 {
35namespace internal {
36
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000037class Isolate;
38class JSFunction;
39class Object;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000040class Semaphore;
41
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000042class RuntimeProfiler {
kasperl@chromium.orga5551262010-12-07 12:49:48 +000043 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000044 explicit RuntimeProfiler(Isolate* isolate);
kasperl@chromium.orga5551262010-12-07 12:49:48 +000045
fschneider@chromium.org7d10be52012-04-10 12:30:14 +000046 static void GlobalSetUp();
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +000047
48 static inline bool IsEnabled() {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +000049 ASSERT(has_been_globally_set_up_);
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +000050 return enabled_;
51 }
kasperl@chromium.orga5551262010-12-07 12:49:48 +000052
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000053 void OptimizeNow();
kasperl@chromium.orga5551262010-12-07 12:49:48 +000054
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000055 void NotifyTick();
kasperl@chromium.orga5551262010-12-07 12:49:48 +000056
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +000057 void SetUp();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000058 void Reset();
59 void TearDown();
60
61 Object** SamplerWindowAddress();
62 int SamplerWindowSize();
63
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +000064 void NotifyICChanged() { any_ic_changed_ = true; }
65
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000066 // Rate limiting support.
67
68 // VM thread interface.
69 //
70 // Called by isolates when their states change.
71 static inline void IsolateEnteredJS(Isolate* isolate);
72 static inline void IsolateExitedJS(Isolate* isolate);
73
74 // Profiler thread interface.
75 //
76 // IsSomeIsolateInJS():
77 // The profiler thread can query whether some isolate is currently
78 // running JavaScript code.
79 //
80 // WaitForSomeIsolateToEnterJS():
81 // When no isolates are running JavaScript code for some time the
82 // profiler thread suspends itself by calling the wait function. The
83 // wait function returns true after it waited or false immediately.
84 // While the function was waiting the profiler may have been
85 // disabled so it *must check* whether it is allowed to continue.
86 static bool IsSomeIsolateInJS();
87 static bool WaitForSomeIsolateToEnterJS();
88
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +000089 // Stops the runtime profiler thread when profiling support is being
90 // turned off.
91 static void StopRuntimeProfilerThreadBeforeShutdown(Thread* thread);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000092
93 void UpdateSamplesAfterScavenge();
94 void RemoveDeadSamples();
95 void UpdateSamplesAfterCompact(ObjectVisitor* visitor);
96
kmillikin@chromium.orgbe6bd102012-02-23 08:45:21 +000097 void AttemptOnStackReplacement(JSFunction* function);
98
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000099 private:
100 static const int kSamplerWindowSize = 16;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000101
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000102 static void HandleWakeUp(Isolate* isolate);
103
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000104 void Optimize(JSFunction* function, const char* reason);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000105
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000106 void ClearSampleBuffer();
107
108 void ClearSampleBufferNewSpaceEntries();
109
110 int LookupSample(JSFunction* function);
111
112 void AddSample(JSFunction* function, int weight);
113
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000114 Isolate* isolate_;
115
116 int sampler_threshold_;
117 int sampler_threshold_size_factor_;
118 int sampler_ticks_until_threshold_adjustment_;
119
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000120 Object* sampler_window_[kSamplerWindowSize];
121 int sampler_window_position_;
122 int sampler_window_weight_[kSamplerWindowSize];
123
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000124 bool any_ic_changed_;
125 bool code_generated_;
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000126
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000127 // Possible state values:
128 // -1 => the profiler thread is waiting on the semaphore
129 // 0 or positive => the number of isolates running JavaScript code.
130 static Atomic32 state_;
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000131
132#ifdef DEBUG
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000133 static bool has_been_globally_set_up_;
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000134#endif
135 static bool enabled_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000136};
137
138
139// Rate limiter intended to be used in the profiler thread.
140class RuntimeProfilerRateLimiter BASE_EMBEDDED {
141 public:
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000142 RuntimeProfilerRateLimiter() {}
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000143
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000144 // Suspends the current thread (which must be the profiler thread)
145 // when not executing JavaScript to minimize CPU usage. Returns
146 // whether the thread was suspended (and so must check whether
147 // profiling is still active.)
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000148 //
149 // Does nothing when runtime profiling is not enabled.
150 bool SuspendIfNecessary();
151
152 private:
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000153 DISALLOW_COPY_AND_ASSIGN(RuntimeProfilerRateLimiter);
154};
155
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000156
157// Implementation of RuntimeProfiler inline functions.
158
159void RuntimeProfiler::IsolateEnteredJS(Isolate* isolate) {
160 Atomic32 new_state = NoBarrier_AtomicIncrement(&state_, 1);
161 if (new_state == 0) {
162 // Just incremented from -1 to 0. -1 can only be set by the
163 // profiler thread before it suspends itself and starts waiting on
164 // the semaphore.
165 HandleWakeUp(isolate);
166 }
167 ASSERT(new_state >= 0);
168}
169
170
171void RuntimeProfiler::IsolateExitedJS(Isolate* isolate) {
172 Atomic32 new_state = NoBarrier_AtomicIncrement(&state_, -1);
173 ASSERT(new_state >= 0);
174 USE(new_state);
175}
176
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000177} } // namespace v8::internal
178
179#endif // V8_RUNTIME_PROFILER_H_