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