13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/runtime-profiler.h" 6b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/assembler.h" 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/scopeinfo.h" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/platform.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/bootstrapper.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/code-stubs.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compilation-cache.h" 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/execution.h" 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/frames-inl.h" 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/full-codegen/full-codegen.h" 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/global-handles.h" 17b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 20b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Number of times a function has to be seen on the stack before it is 233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// optimized. 243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic const int kProfilerTicksBeforeOptimization = 2; 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// If the function optimization was disabled due to high deoptimization count, 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// but the function is hot and has been seen on the stack this number of times, 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// then we try to reenable optimization for this function. 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kProfilerTicksBeforeReenablingOptimization = 250; 298f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch// If a function does not have enough type info (according to 308f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch// FLAG_type_info_threshold), but has seen a huge number of ticks, 318f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch// optimize it as it is. 328f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdochstatic const int kTicksWhenNotEnoughTypeInfo = 100; 338f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch// We only have one byte to store the number of ticks. 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSTATIC_ASSERT(kProfilerTicksBeforeOptimization < 256); 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSTATIC_ASSERT(kProfilerTicksBeforeReenablingOptimization < 256); 368f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben MurdochSTATIC_ASSERT(kTicksWhenNotEnoughTypeInfo < 256); 373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Maximum size in bytes of generate code for a function to allow OSR. 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kOSRCodeSizeAllowanceBase = 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 100 * FullCodeGenerator::kCodeSizeMultiplier; 413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kOSRCodeSizeAllowancePerTick = 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 4 * FullCodeGenerator::kCodeSizeMultiplier; 4444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Maximum size in bytes of generated code for a function to be optimized 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the very first time it is seen on the stack. 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const int kMaxSizeEarlyOpt = 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5 * FullCodeGenerator::kCodeSizeMultiplier; 498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 5044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5144f0eee88ff00398ff7f715fab053374d808c90dSteve BlockRuntimeProfiler::RuntimeProfiler(Isolate* isolate) 5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block : isolate_(isolate), 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch any_ic_changed_(false) { 5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 5544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 57958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void GetICCounts(SharedFunctionInfo* shared, 58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int* ic_with_type_info_count, int* ic_generic_count, 59958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int* ic_total_count, int* type_info_percentage, 60958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int* generic_percentage) { 61958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Code* shared_code = shared->code(); 623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *ic_total_count = 0; 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *ic_generic_count = 0; 648f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch *ic_with_type_info_count = 0; 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* raw_info = shared_code->type_feedback_info(); 663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (raw_info->IsTypeFeedbackInfo()) { 673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TypeFeedbackInfo* info = TypeFeedbackInfo::cast(raw_info); 688f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch *ic_with_type_info_count = info->ic_with_type_info_count(); 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *ic_generic_count = info->ic_generic_count(); 703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *ic_total_count = info->ic_total_count(); 713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 73958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Harvest vector-ics as well 74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TypeFeedbackVector* vector = shared->feedback_vector(); 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int with = 0, gen = 0; 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch vector->ComputeCounts(&with, &gen); 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *ic_with_type_info_count += with; 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch *ic_generic_count += gen; 79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (*ic_total_count > 0) { 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *type_info_percentage = 100 * *ic_with_type_info_count / *ic_total_count; 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *generic_percentage = 100 * *ic_generic_count / *ic_total_count; 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *type_info_percentage = 100; // Compared against lower bound. 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch *generic_percentage = 0; // Compared against upper bound. 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid RuntimeProfiler::Optimize(JSFunction* function, const char* reason) { 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_opt && function->PassesFilter(FLAG_hydrogen_filter)) { 923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PrintF("[marking "); 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function->ShortPrint(); 943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PrintF(" for recompilation, reason: %s", reason); 953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_type_info_threshold > 0) { 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int typeinfo, generic, total, type_percentage, generic_percentage; 97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GetICCounts(function->shared(), &typeinfo, &generic, &total, 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &type_percentage, &generic_percentage); 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF(", ICs with typeinfo: %d/%d (%d%%)", typeinfo, total, 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch type_percentage); 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF(", generic ICs: %d/%d (%d%%)", generic, total, generic_percentage); 1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch PrintF("]\n"); 104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier function->AttemptConcurrentOptimization(); 107b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 108b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 109b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RuntimeProfiler::AttemptOnStackReplacement(JSFunction* function, 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int loop_nesting_levels) { 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedFunctionInfo* shared = function->shared(); 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!FLAG_use_osr || function->shared()->IsBuiltin()) { 114b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return; 115b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 117589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch // If the code is not optimizable, don't try OSR. 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (shared->optimization_disabled()) return; 119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We are not prepared to do OSR for a function that already has an 121b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // allocated arguments object. The optimized code would bypass it for 122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // arguments accesses, which is unsound. Don't try OSR. 1233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (shared->uses_arguments()) return; 124b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 125b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // We're using on-stack replacement: patch the unoptimized code so that 126b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // any back edge in any unoptimized frame will trigger on-stack 127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // replacement for that frame. 128b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (FLAG_trace_osr) { 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("[OSR - patching back edges in "); 130b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch function->PrintName(); 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("]\n"); 132b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 133b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < loop_nesting_levels; i++) { 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BackEdgeTable::Patch(isolate_, shared->code()); 136b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 138b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 139b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 140b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid RuntimeProfiler::OptimizeNow() { 14144f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate_); 142b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!isolate_->use_crankshaft()) return; 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DisallowHeapAllocation no_gc; 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Run through the JavaScript frames and collect them. If we already 148b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // have a sample of the function, we mark it for optimizations 149b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // (eagerly or lazily). 150b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int frame_count = 0; 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int frame_count_limit = FLAG_frame_count; 1528b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch for (JavaScriptFrameIterator it(isolate_); 1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch frame_count++ < frame_count_limit && !it.done(); 154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch it.Advance()) { 155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch JavaScriptFrame* frame = it.frame(); 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch JSFunction* function = frame->function(); 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedFunctionInfo* shared = function->shared(); 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code* shared_code = shared->code(); 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch List<JSFunction*> functions(4); 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch frame->GetFunctions(&functions); 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = functions.length(); --i >= 0; ) { 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SharedFunctionInfo* shared_function_info = functions[i]->shared(); 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int ticks = shared_function_info->profiler_ticks(); 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ticks < Smi::kMaxValue) { 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared_function_info->set_profiler_ticks(ticks + 1); 168b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1718f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch if (shared_code->kind() != Code::FUNCTION) continue; 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (function->IsInOptimizationQueue()) continue; 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_always_osr) { 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AttemptOnStackReplacement(function, Code::kMaxLoopNestingMarker); 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Fall through and do a normal optimized compile as well. 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (!frame->is_optimized() && 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (function->IsMarkedForOptimization() || 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function->IsMarkedForConcurrentOptimization() || 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function->IsOptimized())) { 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Attempt OSR if we are still running unoptimized code even though the 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the function has long been marked or even already been optimized. 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int ticks = shared_code->profiler_ticks(); 184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int64_t allowance = 185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch kOSRCodeSizeAllowanceBase + 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<int64_t>(ticks) * kOSRCodeSizeAllowancePerTick; 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (shared_code->CodeSize() > allowance && 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ticks < Code::ProfilerTicksField::kMax) { 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch shared_code->set_profiler_ticks(ticks + 1); 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AttemptOnStackReplacement(function); 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue; 194b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Only record top-level code on top of the execution stack and 1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // avoid optimizing excessively large scripts since top-level code 1983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // will be executed only once. 1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const int kMaxToplevelSourceSize = 10 * 1024; 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shared->is_toplevel() && 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (frame_count > 1 || shared->SourceSize() > kMaxToplevelSourceSize)) { 2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch continue; 2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Do not record non-optimizable functions. 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shared->optimization_disabled()) { 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (shared->deopt_count() >= FLAG_max_opt_count) { 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If optimization was disabled due to many deoptimizations, 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // then check if the function is hot and try to reenable optimization. 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int ticks = shared_code->profiler_ticks(); 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ticks >= kProfilerTicksBeforeReenablingOptimization) { 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared_code->set_profiler_ticks(0); 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared->TryReenableOptimization(); 2143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 2158f9999fcc44cfd4f5e1140c6678bbca4cf8ea1c7Ben Murdoch shared_code->set_profiler_ticks(ticks + 1); 2163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue; 2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (function->IsOptimized()) continue; 221b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int ticks = shared_code->profiler_ticks(); 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (ticks >= kProfilerTicksBeforeOptimization) { 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int typeinfo, generic, total, type_percentage, generic_percentage; 226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GetICCounts(shared, &typeinfo, &generic, &total, &type_percentage, 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &generic_percentage); 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type_percentage >= FLAG_type_info_threshold && 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch generic_percentage <= FLAG_generic_ic_threshold) { 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If this particular function hasn't had any ICs patched for enough 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ticks, optimize it now. 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Optimize(function, "hot and stable"); 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (ticks >= kTicksWhenNotEnoughTypeInfo) { 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Optimize(function, "not much type info but very hot"); 235e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } else { 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared_code->set_profiler_ticks(ticks + 1); 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (FLAG_trace_opt_verbose) { 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF("[not yet optimizing "); 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch function->PrintName(); 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PrintF(", not enough type info: %d/%d (%d%%)]\n", typeinfo, total, 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch type_percentage); 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 243e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (!any_ic_changed_ && 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared_code->instruction_size() < kMaxSizeEarlyOpt) { 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If no IC was patched since the last tick and this function is very 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // small, optimistically optimize it now. 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int typeinfo, generic, total, type_percentage, generic_percentage; 249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GetICCounts(shared, &typeinfo, &generic, &total, &type_percentage, 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &generic_percentage); 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (type_percentage >= FLAG_type_info_threshold && 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch generic_percentage <= FLAG_generic_ic_threshold) { 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Optimize(function, "small function"); 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared_code->set_profiler_ticks(ticks + 1); 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch shared_code->set_profiler_ticks(ticks + 1); 259e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 260e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch any_ic_changed_ = false; 262b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 263b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 264b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 267