runtime-profiler.cc revision 589d6979ff2ef66fca2d8fa51404c369ca5e9250
1257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Redistribution and use in source and binary forms, with or without 3b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// modification, are permitted provided that the following conditions are 4b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// met: 5b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// 6b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// * Redistributions of source code must retain the above copyright 7b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// notice, this list of conditions and the following disclaimer. 8b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// * Redistributions in binary form must reproduce the above 9b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// copyright notice, this list of conditions and the following 10b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// disclaimer in the documentation and/or other materials provided 11b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// with the distribution. 12b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// * Neither the name of Google Inc. nor the names of its 13b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// contributors may be used to endorse or promote products derived 14b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// from this software without specific prior written permission. 15b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// 16b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 28b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "v8.h" 29b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 30b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "runtime-profiler.h" 31b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 32b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "assembler.h" 33b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "code-stubs.h" 34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "compilation-cache.h" 35b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "deoptimizer.h" 36b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "execution.h" 37b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "global-handles.h" 38e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch#include "mark-compact.h" 3944f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "platform.h" 40b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "scopeinfo.h" 41b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 42b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace v8 { 43b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochnamespace internal { 44b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 45b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 46b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Optimization sampler constants. 47b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic const int kSamplerFrameCount = 2; 48b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic const int kSamplerFrameWeight[kSamplerFrameCount] = { 2, 1 }; 49b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 50b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic const int kSamplerTicksBetweenThresholdAdjustment = 32; 51b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 52b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic const int kSamplerThresholdInit = 3; 53b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic const int kSamplerThresholdMin = 1; 54b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic const int kSamplerThresholdDelta = 1; 55b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 56b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic const int kSamplerThresholdSizeFactorInit = 3; 57b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 58b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic const int kSizeLimit = 1500; 59b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 60b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 6144f0eee88ff00398ff7f715fab053374d808c90dSteve BlockAtomic32 RuntimeProfiler::state_ = 0; 6244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// TODO(isolates): Create the semaphore lazily and clean it up when no 6344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// longer required. 6444f0eee88ff00398ff7f715fab053374d808c90dSteve BlockSemaphore* RuntimeProfiler::semaphore_ = OS::CreateSemaphore(0); 6544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#ifdef DEBUG 678b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochbool RuntimeProfiler::has_been_globally_setup_ = false; 688b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#endif 698b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochbool RuntimeProfiler::enabled_ = false; 708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 7144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 7244f0eee88ff00398ff7f715fab053374d808c90dSteve BlockRuntimeProfiler::RuntimeProfiler(Isolate* isolate) 7344f0eee88ff00398ff7f715fab053374d808c90dSteve Block : isolate_(isolate), 7444f0eee88ff00398ff7f715fab053374d808c90dSteve Block sampler_threshold_(kSamplerThresholdInit), 7544f0eee88ff00398ff7f715fab053374d808c90dSteve Block sampler_threshold_size_factor_(kSamplerThresholdSizeFactorInit), 7644f0eee88ff00398ff7f715fab053374d808c90dSteve Block sampler_ticks_until_threshold_adjustment_( 773fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch kSamplerTicksBetweenThresholdAdjustment), 783fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch sampler_window_position_(0) { 7944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ClearSampleBuffer(); 8044f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 8144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 8244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdochvoid RuntimeProfiler::GlobalSetup() { 848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(!has_been_globally_setup_); 858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch enabled_ = V8::UseCrankshaft() && FLAG_opt; 868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#ifdef DEBUG 878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch has_been_globally_setup_ = true; 888b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#endif 8944f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 9044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid RuntimeProfiler::Optimize(JSFunction* function) { 938b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(function->IsOptimizable()); 94b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_opt) { 953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrintF("[marking "); 96b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function->PrintName(); 97257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch PrintF(" 0x%" V8PRIxPTR, reinterpret_cast<intptr_t>(function->address())); 98b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" for recompilation"); 99b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("]\n"); 100b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 101b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 102b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // The next call to the function will trigger optimization. 103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function->MarkForLazyRecompilation(); 104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 106b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 10744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid RuntimeProfiler::AttemptOnStackReplacement(JSFunction* function) { 108b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // See AlwaysFullCompiler (in compiler.cc) comment on why we need 109b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Debug::has_break_points(). 110b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(function->IsMarkedForLazyRecompilation()); 11144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!FLAG_use_osr || 112257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch isolate_->DebuggerHasBreakPoints() || 11344f0eee88ff00398ff7f715fab053374d808c90dSteve Block function->IsBuiltin()) { 114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return; 115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch SharedFunctionInfo* shared = function->shared(); 118589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // If the code is not optimizable, don't try OSR. 119589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch if (!shared->code()->optimizable()) return; 120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We are not prepared to do OSR for a function that already has an 122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // allocated arguments object. The optimized code would bypass it for 123b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // arguments accesses, which is unsound. Don't try OSR. 1243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (shared->uses_arguments()) return; 125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We're using on-stack replacement: patch the unoptimized code so that 127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // any back edge in any unoptimized frame will trigger on-stack 128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // replacement for that frame. 129b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_osr) { 130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("[patching stack checks in "); 131b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function->PrintName(); 132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF(" for on-stack replacement]\n"); 133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 134b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 135b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Get the stack check stub code object to match against. We aren't 136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // prepared to generate it, but we don't expect to have to. 137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch StackCheckStub check_stub; 138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Object* check_code; 139b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch MaybeObject* maybe_check_code = check_stub.TryGetCode(); 140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (maybe_check_code->ToObject(&check_code)) { 14144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Code* replacement_code = 14244f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->builtins()->builtin(Builtins::kOnStackReplacement); 143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Code* unoptimized_code = shared->code(); 1441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Deoptimizer::PatchStackCheckCode(unoptimized_code, 1451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code::cast(check_code), 1461e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block replacement_code); 147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 15144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid RuntimeProfiler::ClearSampleBuffer() { 15244f0eee88ff00398ff7f715fab053374d808c90dSteve Block memset(sampler_window_, 0, sizeof(sampler_window_)); 15344f0eee88ff00398ff7f715fab053374d808c90dSteve Block memset(sampler_window_weight_, 0, sizeof(sampler_window_weight_)); 154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 15744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockint RuntimeProfiler::LookupSample(JSFunction* function) { 158b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int weight = 0; 159b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < kSamplerWindowSize; i++) { 16044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* sample = sampler_window_[i]; 161b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (sample != NULL) { 162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (function == sample) { 16344f0eee88ff00398ff7f715fab053374d808c90dSteve Block weight += sampler_window_weight_[i]; 164b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 165b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 166b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 167b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return weight; 168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 17144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid RuntimeProfiler::AddSample(JSFunction* function, int weight) { 172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(IsPowerOf2(kSamplerWindowSize)); 17344f0eee88ff00398ff7f715fab053374d808c90dSteve Block sampler_window_[sampler_window_position_] = function; 17444f0eee88ff00398ff7f715fab053374d808c90dSteve Block sampler_window_weight_[sampler_window_position_] = weight; 17544f0eee88ff00398ff7f715fab053374d808c90dSteve Block sampler_window_position_ = (sampler_window_position_ + 1) & 176b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch (kSamplerWindowSize - 1); 177b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 178b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid RuntimeProfiler::OptimizeNow() { 18144f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 183b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Run through the JavaScript frames and collect them. If we already 184b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // have a sample of the function, we mark it for optimizations 185b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // (eagerly or lazily). 186b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* samples[kSamplerFrameCount]; 187b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int sample_count = 0; 188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int frame_count = 0; 1898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch for (JavaScriptFrameIterator it(isolate_); 190b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch frame_count++ < kSamplerFrameCount && !it.done(); 191b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch it.Advance()) { 192b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JavaScriptFrame* frame = it.frame(); 193b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JSFunction* function = JSFunction::cast(frame->function()); 194b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Adjust threshold each time we have processed 196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // a certain number of ticks. 19744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (sampler_ticks_until_threshold_adjustment_ > 0) { 19844f0eee88ff00398ff7f715fab053374d808c90dSteve Block sampler_ticks_until_threshold_adjustment_--; 19944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (sampler_ticks_until_threshold_adjustment_ <= 0) { 200b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // If the threshold is not already at the minimum 201b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // modify and reset the ticks until next adjustment. 20244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (sampler_threshold_ > kSamplerThresholdMin) { 20344f0eee88ff00398ff7f715fab053374d808c90dSteve Block sampler_threshold_ -= kSamplerThresholdDelta; 20444f0eee88ff00398ff7f715fab053374d808c90dSteve Block sampler_ticks_until_threshold_adjustment_ = 205b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kSamplerTicksBetweenThresholdAdjustment; 206b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (function->IsMarkedForLazyRecompilation()) { 211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Code* unoptimized = function->shared()->code(); 212b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int nesting = unoptimized->allow_osr_at_loop_nesting_level(); 213b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (nesting == 0) AttemptOnStackReplacement(function); 214b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int new_nesting = Min(nesting + 1, Code::kMaxLoopNestingMarker); 215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch unoptimized->set_allow_osr_at_loop_nesting_level(new_nesting); 216b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Do not record non-optimizable functions. 2198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (!function->IsOptimizable()) continue; 220b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch samples[sample_count++] = function; 221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 222b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int function_size = function->shared()->SourceSize(); 223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int threshold_size_factor = (function_size > kSizeLimit) 22444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ? sampler_threshold_size_factor_ 225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch : 1; 226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 22744f0eee88ff00398ff7f715fab053374d808c90dSteve Block int threshold = sampler_threshold_ * threshold_size_factor; 228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 229b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (LookupSample(function) >= threshold) { 2303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Optimize(function); 231b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 233b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 234b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Add the collected functions as samples. It's important not to do 235b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // this as part of collecting them because this will interfere with 236b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the sample lookup in case of recursive functions. 237b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < sample_count; i++) { 238b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch AddSample(samples[i], kSamplerFrameWeight[i]); 239b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 241b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 242b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid RuntimeProfiler::NotifyTick() { 24444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->stack_guard()->RequestRuntimeProfilerTick(); 245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 248b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid RuntimeProfiler::Setup() { 2498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch ASSERT(has_been_globally_setup_); 250b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ClearSampleBuffer(); 251b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // If the ticker hasn't already started, make sure to do so to get 252b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // the ticks for the runtime profiler. 25344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (IsEnabled()) isolate_->logger()->EnsureTickerStarted(); 254b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 255b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 256b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 257b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid RuntimeProfiler::Reset() { 25844f0eee88ff00398ff7f715fab053374d808c90dSteve Block sampler_threshold_ = kSamplerThresholdInit; 25944f0eee88ff00398ff7f715fab053374d808c90dSteve Block sampler_threshold_size_factor_ = kSamplerThresholdSizeFactorInit; 26044f0eee88ff00398ff7f715fab053374d808c90dSteve Block sampler_ticks_until_threshold_adjustment_ = 261b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch kSamplerTicksBetweenThresholdAdjustment; 262b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 265b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid RuntimeProfiler::TearDown() { 266b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Nothing to do. 267b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 269b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 270e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochint RuntimeProfiler::SamplerWindowSize() { 271e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch return kSamplerWindowSize; 272b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 273b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 274b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 275e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch// Update the pointers in the sampler window after a GC. 276e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid RuntimeProfiler::UpdateSamplesAfterScavenge() { 277e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (int i = 0; i < kSamplerWindowSize; i++) { 27844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* function = sampler_window_[i]; 27944f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (function != NULL && isolate_->heap()->InNewSpace(function)) { 280e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch MapWord map_word = HeapObject::cast(function)->map_word(); 281e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (map_word.IsForwardingAddress()) { 28244f0eee88ff00398ff7f715fab053374d808c90dSteve Block sampler_window_[i] = map_word.ToForwardingAddress(); 283e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 28444f0eee88ff00398ff7f715fab053374d808c90dSteve Block sampler_window_[i] = NULL; 285e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 286e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 287e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 288e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 289e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 290e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 29144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid RuntimeProfiler::HandleWakeUp(Isolate* isolate) { 29244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // The profiler thread must still be waiting. 29344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(NoBarrier_Load(&state_) >= 0); 29444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // In IsolateEnteredJS we have already incremented the counter and 29544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // undid the decrement done by the profiler thread. Increment again 29644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // to get the right count of active isolates. 29744f0eee88ff00398ff7f715fab053374d808c90dSteve Block NoBarrier_AtomicIncrement(&state_, 1); 29844f0eee88ff00398ff7f715fab053374d808c90dSteve Block semaphore_->Signal(); 29944f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 30044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 30144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 30244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool RuntimeProfiler::IsSomeIsolateInJS() { 30344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return NoBarrier_Load(&state_) > 0; 30444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 30544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 30644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 30744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockbool RuntimeProfiler::WaitForSomeIsolateToEnterJS() { 30844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Atomic32 old_state = NoBarrier_CompareAndSwap(&state_, 0, -1); 30944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(old_state >= -1); 31044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (old_state != 0) return false; 31144f0eee88ff00398ff7f715fab053374d808c90dSteve Block semaphore_->Wait(); 31244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return true; 31344f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 31444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 31544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 3163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid RuntimeProfiler::StopRuntimeProfilerThreadBeforeShutdown(Thread* thread) { 3173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Do a fake increment. If the profiler is waiting on the semaphore, 3183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // the returned state is 0, which can be left as an initial state in 3193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // case profiling is restarted later. If the profiler is not 3203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // waiting, the increment will prevent it from waiting, but has to 3213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // be undone after the profiler is stopped. 3223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Atomic32 new_state = NoBarrier_AtomicIncrement(&state_, 1); 3233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(new_state >= 0); 3243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (new_state == 0) { 3253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // The profiler thread is waiting. Wake it up. It must check for 3263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // stop conditions before attempting to wait again. 3273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch semaphore_->Signal(); 3283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 3293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch thread->Join(); 3303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // The profiler thread is now stopped. Undo the increment in case it 3313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // was not waiting. 3323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (new_state != 0) { 3333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch NoBarrier_AtomicIncrement(&state_, -1); 3343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 33544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 33644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 33744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 338e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid RuntimeProfiler::RemoveDeadSamples() { 339e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (int i = 0; i < kSamplerWindowSize; i++) { 34044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* function = sampler_window_[i]; 341e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch if (function != NULL && !HeapObject::cast(function)->IsMarked()) { 34244f0eee88ff00398ff7f715fab053374d808c90dSteve Block sampler_window_[i] = NULL; 343e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 344e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 345e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch} 346e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 347e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch 348e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochvoid RuntimeProfiler::UpdateSamplesAfterCompact(ObjectVisitor* visitor) { 349e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch for (int i = 0; i < kSamplerWindowSize; i++) { 35044f0eee88ff00398ff7f715fab053374d808c90dSteve Block visitor->VisitPointer(&sampler_window_[i]); 351e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 352b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 353b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 354b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 355b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochbool RuntimeProfilerRateLimiter::SuspendIfNecessary() { 3563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!RuntimeProfiler::IsSomeIsolateInJS()) { 3573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return RuntimeProfiler::WaitForSomeIsolateToEnterJS(); 358b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 359b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return false; 360b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 361b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 362b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 363b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} } // namespace v8::internal 364