LCOV - code coverage report
Current view: top level - src - runtime-profiler.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 123 165 74.5 %
Date: 2017-04-26 Functions: 9 12 75.0 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/runtime-profiler.h"
       6             : 
       7             : #include "src/assembler.h"
       8             : #include "src/base/platform/platform.h"
       9             : #include "src/bootstrapper.h"
      10             : #include "src/code-stubs.h"
      11             : #include "src/compilation-cache.h"
      12             : #include "src/compiler.h"
      13             : #include "src/execution.h"
      14             : #include "src/frames-inl.h"
      15             : #include "src/full-codegen/full-codegen.h"
      16             : #include "src/global-handles.h"
      17             : #include "src/interpreter/interpreter.h"
      18             : 
      19             : namespace v8 {
      20             : namespace internal {
      21             : 
      22             : // Number of times a function has to be seen on the stack before it is
      23             : // optimized.
      24             : static const int kProfilerTicksBeforeOptimization = 2;
      25             : // If the function optimization was disabled due to high deoptimization count,
      26             : // but the function is hot and has been seen on the stack this number of times,
      27             : // then we try to reenable optimization for this function.
      28             : static const int kProfilerTicksBeforeReenablingOptimization = 250;
      29             : // If a function does not have enough type info (according to
      30             : // FLAG_type_info_threshold), but has seen a huge number of ticks,
      31             : // optimize it as it is.
      32             : static const int kTicksWhenNotEnoughTypeInfo = 100;
      33             : // We only have one byte to store the number of ticks.
      34             : STATIC_ASSERT(kProfilerTicksBeforeOptimization < 256);
      35             : STATIC_ASSERT(kProfilerTicksBeforeReenablingOptimization < 256);
      36             : STATIC_ASSERT(kTicksWhenNotEnoughTypeInfo < 256);
      37             : 
      38             : // Maximum size in bytes of generate code for a function to allow OSR.
      39             : static const int kOSRCodeSizeAllowanceBase =
      40             :     100 * FullCodeGenerator::kCodeSizeMultiplier;
      41             : static const int kOSRCodeSizeAllowanceBaseIgnition =
      42             :     10 * interpreter::Interpreter::kCodeSizeMultiplier;
      43             : 
      44             : static const int kOSRCodeSizeAllowancePerTick =
      45             :     4 * FullCodeGenerator::kCodeSizeMultiplier;
      46             : static const int kOSRCodeSizeAllowancePerTickIgnition =
      47             :     2 * interpreter::Interpreter::kCodeSizeMultiplier;
      48             : 
      49             : // Maximum size in bytes of generated code for a function to be optimized
      50             : // the very first time it is seen on the stack.
      51             : static const int kMaxSizeEarlyOpt =
      52             :     5 * FullCodeGenerator::kCodeSizeMultiplier;
      53             : static const int kMaxSizeEarlyOptIgnition =
      54             :     5 * interpreter::Interpreter::kCodeSizeMultiplier;
      55             : 
      56             : // Certain functions are simply too big to be worth optimizing.
      57             : // We aren't using the code size multiplier here because there is no
      58             : // "kMaxSizeOpt" with which we would need to normalize. This constant is
      59             : // only for optimization decisions coming into TurboFan from Ignition.
      60             : static const int kMaxSizeOptIgnition = 250 * 1024;
      61             : 
      62             : #define OPTIMIZATION_REASON_LIST(V)                            \
      63             :   V(DoNotOptimize, "do not optimize")                          \
      64             :   V(HotAndStable, "hot and stable")                            \
      65             :   V(HotWithoutMuchTypeInfo, "not much type info but very hot") \
      66             :   V(SmallFunction, "small function")
      67             : 
      68             : enum class OptimizationReason : uint8_t {
      69             : #define OPTIMIZATION_REASON_CONSTANTS(Constant, message) k##Constant,
      70             :   OPTIMIZATION_REASON_LIST(OPTIMIZATION_REASON_CONSTANTS)
      71             : #undef OPTIMIZATION_REASON_CONSTANTS
      72             : };
      73             : 
      74           0 : char const* OptimizationReasonToString(OptimizationReason reason) {
      75             :   static char const* reasons[] = {
      76             : #define OPTIMIZATION_REASON_TEXTS(Constant, message) message,
      77             :       OPTIMIZATION_REASON_LIST(OPTIMIZATION_REASON_TEXTS)
      78             : #undef OPTIMIZATION_REASON_TEXTS
      79             :   };
      80       13475 :   size_t const index = static_cast<size_t>(reason);
      81             :   DCHECK_LT(index, arraysize(reasons));
      82      141012 :   return reasons[index];
      83             : }
      84             : 
      85           0 : std::ostream& operator<<(std::ostream& os, OptimizationReason reason) {
      86           0 :   return os << OptimizationReasonToString(reason);
      87             : }
      88             : 
      89       60782 : RuntimeProfiler::RuntimeProfiler(Isolate* isolate)
      90             :     : isolate_(isolate),
      91       60782 :       any_ic_changed_(false) {
      92       60782 : }
      93             : 
      94      179274 : static void GetICCounts(JSFunction* function, int* ic_with_type_info_count,
      95             :                         int* ic_generic_count, int* ic_total_count,
      96             :                         int* type_info_percentage, int* generic_percentage) {
      97      179274 :   *ic_total_count = 0;
      98      179274 :   *ic_generic_count = 0;
      99      179274 :   *ic_with_type_info_count = 0;
     100      179274 :   if (function->code()->kind() == Code::FUNCTION) {
     101             :     Code* shared_code = function->shared()->code();
     102             :     Object* raw_info = shared_code->type_feedback_info();
     103      161719 :     if (raw_info->IsTypeFeedbackInfo()) {
     104             :       TypeFeedbackInfo* info = TypeFeedbackInfo::cast(raw_info);
     105      161719 :       *ic_with_type_info_count = info->ic_with_type_info_count();
     106      161719 :       *ic_generic_count = info->ic_generic_count();
     107      161719 :       *ic_total_count = info->ic_total_count();
     108             :     }
     109             :   }
     110             : 
     111             :   // Harvest vector-ics as well
     112             :   FeedbackVector* vector = function->feedback_vector();
     113      179274 :   int with = 0, gen = 0, type_vector_ic_count = 0;
     114             :   const bool is_interpreted = function->shared()->IsInterpreted();
     115             : 
     116      179274 :   vector->ComputeCounts(&with, &gen, &type_vector_ic_count, is_interpreted);
     117      179274 :   *ic_total_count += type_vector_ic_count;
     118      179274 :   *ic_with_type_info_count += with;
     119      179274 :   *ic_generic_count += gen;
     120             : 
     121      179274 :   if (*ic_total_count > 0) {
     122      173918 :     *type_info_percentage = 100 * *ic_with_type_info_count / *ic_total_count;
     123      173918 :     *generic_percentage = 100 * *ic_generic_count / *ic_total_count;
     124             :   } else {
     125        5356 :     *type_info_percentage = 100;  // Compared against lower bound.
     126        5356 :     *generic_percentage = 0;      // Compared against upper bound.
     127             :   }
     128      179274 : }
     129             : 
     130      141012 : static void TraceRecompile(JSFunction* function, const char* reason,
     131             :                            const char* type) {
     132      141012 :   if (FLAG_trace_opt &&
     133           0 :       function->shared()->PassesFilter(FLAG_hydrogen_filter)) {
     134           0 :     PrintF("[marking ");
     135           0 :     function->ShortPrint();
     136           0 :     PrintF(" for %s recompilation, reason: %s", type, reason);
     137           0 :     if (FLAG_type_info_threshold > 0) {
     138             :       int typeinfo, generic, total, type_percentage, generic_percentage;
     139             :       GetICCounts(function, &typeinfo, &generic, &total, &type_percentage,
     140           0 :                   &generic_percentage);
     141             :       PrintF(", ICs with typeinfo: %d/%d (%d%%)", typeinfo, total,
     142           0 :              type_percentage);
     143           0 :       PrintF(", generic ICs: %d/%d (%d%%)", generic, total, generic_percentage);
     144             :     }
     145           0 :     PrintF("]\n");
     146             :   }
     147      141012 : }
     148             : 
     149           0 : void RuntimeProfiler::Optimize(JSFunction* function,
     150             :                                OptimizationReason reason) {
     151             :   DCHECK_NE(reason, OptimizationReason::kDoNotOptimize);
     152      141012 :   TraceRecompile(function, OptimizationReasonToString(reason), "optimized");
     153      141012 :   function->AttemptConcurrentOptimization();
     154           0 : }
     155             : 
     156       27700 : void RuntimeProfiler::AttemptOnStackReplacement(JavaScriptFrame* frame,
     157             :                                                 int loop_nesting_levels) {
     158       27700 :   JSFunction* function = frame->function();
     159             :   SharedFunctionInfo* shared = function->shared();
     160       27700 :   if (!FLAG_use_osr || !function->shared()->IsUserJavaScript()) {
     161             :     return;
     162             :   }
     163             : 
     164             :   // If the code is not optimizable, don't try OSR.
     165       16079 :   if (shared->optimization_disabled()) return;
     166             : 
     167             :   // We are not prepared to do OSR for a function that already has an
     168             :   // allocated arguments object.  The optimized code would bypass it for
     169             :   // arguments accesses, which is unsound.  Don't try OSR.
     170       13287 :   if (shared->uses_arguments()) return;
     171             : 
     172             :   // We're using on-stack replacement: modify unoptimized code so that
     173             :   // certain back edges in any unoptimized frame will trigger on-stack
     174             :   // replacement for that frame.
     175             :   //  - Ignition: Store new loop nesting level in BytecodeArray header.
     176             :   //  - FullCodegen: Patch back edges up to new level using BackEdgeTable.
     177       12429 :   if (FLAG_trace_osr) {
     178           0 :     PrintF("[OSR - arming back edges in ");
     179           0 :     function->PrintName();
     180           0 :     PrintF("]\n");
     181             :   }
     182             : 
     183       12429 :   if (frame->type() == StackFrame::JAVA_SCRIPT) {
     184             :     DCHECK(shared->HasBaselineCode());
     185             :     DCHECK(BackEdgeTable::Verify(shared->GetIsolate(), shared->code()));
     186       10638 :     for (int i = 0; i < loop_nesting_levels; i++) {
     187       10638 :       BackEdgeTable::Patch(isolate_, shared->code());
     188             :     }
     189        8431 :   } else if (frame->type() == StackFrame::INTERPRETED) {
     190             :     DCHECK(shared->HasBytecodeArray());
     191        8431 :     if (!FLAG_ignition_osr) return;  // Only use this when enabled.
     192             :     int level = shared->bytecode_array()->osr_loop_nesting_level();
     193             :     shared->bytecode_array()->set_osr_loop_nesting_level(
     194        8431 :         Min(level + loop_nesting_levels, AbstractCode::kMaxLoopNestingMarker));
     195             :   } else {
     196           0 :     UNREACHABLE();
     197             :   }
     198             : }
     199             : 
     200      404756 : void RuntimeProfiler::MaybeOptimizeFullCodegen(JSFunction* function,
     201             :                                                JavaScriptFrame* frame,
     202             :                                                int frame_count) {
     203             :   SharedFunctionInfo* shared = function->shared();
     204             :   Code* shared_code = shared->code();
     205      404756 :   if (shared_code->kind() != Code::FUNCTION) return;
     206      404672 :   if (function->IsInOptimizationQueue()) {
     207       69261 :     if (FLAG_trace_opt_verbose) {
     208           0 :       PrintF("[function ");
     209           0 :       function->PrintName();
     210           0 :       PrintF(" is already in optimization queue]\n");
     211             :     }
     212             :     return;
     213             :   }
     214             : 
     215      335411 :   if (FLAG_always_osr) {
     216           0 :     AttemptOnStackReplacement(frame, AbstractCode::kMaxLoopNestingMarker);
     217             :     // Fall through and do a normal optimized compile as well.
     218     1272248 :   } else if (!frame->is_optimized() &&
     219      266007 :              (function->IsMarkedForOptimization() ||
     220      260865 :               function->IsMarkedForConcurrentOptimization() ||
     221             :               function->IsOptimized())) {
     222             :     // Attempt OSR if we are still running unoptimized code even though the
     223             :     // the function has long been marked or even already been optimized.
     224             :     int ticks = shared_code->profiler_ticks();
     225             :     int64_t allowance =
     226             :         kOSRCodeSizeAllowanceBase +
     227        5722 :         static_cast<int64_t>(ticks) * kOSRCodeSizeAllowancePerTick;
     228        5722 :     if (shared_code->CodeSize() > allowance &&
     229             :         ticks < Code::ProfilerTicksField::kMax) {
     230        1156 :       shared_code->set_profiler_ticks(ticks + 1);
     231             :     } else {
     232        4566 :       AttemptOnStackReplacement(frame);
     233             :     }
     234             :     return;
     235             :   }
     236             : 
     237             :   // Only record top-level code on top of the execution stack and
     238             :   // avoid optimizing excessively large scripts since top-level code
     239             :   // will be executed only once.
     240             :   const int kMaxToplevelSourceSize = 10 * 1024;
     241      659378 :   if (shared->is_toplevel() &&
     242        8653 :       (frame_count > 1 || shared->SourceSize() > kMaxToplevelSourceSize)) {
     243             :     return;
     244             :   }
     245             : 
     246             :   // Do not record non-optimizable functions.
     247      329450 :   if (shared->optimization_disabled()) {
     248       50776 :     if (shared->deopt_count() >= FLAG_max_deopt_count) {
     249             :       // If optimization was disabled due to many deoptimizations,
     250             :       // then check if the function is hot and try to reenable optimization.
     251             :       int ticks = shared_code->profiler_ticks();
     252       19790 :       if (ticks >= kProfilerTicksBeforeReenablingOptimization) {
     253             :         shared_code->set_profiler_ticks(0);
     254          44 :         shared->TryReenableOptimization();
     255             :       } else {
     256       19746 :         shared_code->set_profiler_ticks(ticks + 1);
     257             :       }
     258             :     }
     259             :     return;
     260             :   }
     261      557348 :   if (frame->is_optimized()) return;
     262             : 
     263             :   int ticks = shared_code->profiler_ticks();
     264             : 
     265      209352 :   if (ticks >= kProfilerTicksBeforeOptimization) {
     266             :     int typeinfo, generic, total, type_percentage, generic_percentage;
     267             :     GetICCounts(function, &typeinfo, &generic, &total, &type_percentage,
     268       41985 :                 &generic_percentage);
     269       53789 :     if (type_percentage >= FLAG_type_info_threshold &&
     270       11804 :         generic_percentage <= FLAG_generic_ic_threshold) {
     271             :       // If this particular function hasn't had any ICs patched for enough
     272             :       // ticks, optimize it now.
     273             :       Optimize(function, OptimizationReason::kHotAndStable);
     274       32439 :     } else if (ticks >= kTicksWhenNotEnoughTypeInfo) {
     275             :       Optimize(function, OptimizationReason::kHotWithoutMuchTypeInfo);
     276             :     } else {
     277       32284 :       shared_code->set_profiler_ticks(ticks + 1);
     278       32284 :       if (FLAG_trace_opt_verbose) {
     279           0 :         PrintF("[not yet optimizing ");
     280           0 :         function->PrintName();
     281             :         PrintF(", not enough type info: %d/%d (%d%%)]\n", typeinfo, total,
     282           0 :                type_percentage);
     283             :       }
     284             :     }
     285      301459 :   } else if (!any_ic_changed_ &&
     286             :              shared_code->instruction_size() < kMaxSizeEarlyOpt) {
     287             :     // If no IC was patched since the last tick and this function is very
     288             :     // small, optimistically optimize it now.
     289             :     int typeinfo, generic, total, type_percentage, generic_percentage;
     290             :     GetICCounts(function, &typeinfo, &generic, &total, &type_percentage,
     291      119736 :                 &generic_percentage);
     292      237805 :     if (type_percentage >= FLAG_type_info_threshold &&
     293      118069 :         generic_percentage <= FLAG_generic_ic_threshold) {
     294             :       Optimize(function, OptimizationReason::kSmallFunction);
     295             :     } else {
     296        1900 :       shared_code->set_profiler_ticks(ticks + 1);
     297             :     }
     298             :   } else {
     299       47631 :     shared_code->set_profiler_ticks(ticks + 1);
     300             :   }
     301             : }
     302             : 
     303      205207 : void RuntimeProfiler::MaybeOptimizeIgnition(JSFunction* function,
     304             :                                             JavaScriptFrame* frame) {
     305      205207 :   if (function->IsInOptimizationQueue()) {
     306        8500 :     if (FLAG_trace_opt_verbose) {
     307           0 :       PrintF("[function ");
     308           0 :       function->PrintName();
     309           0 :       PrintF(" is already in optimization queue]\n");
     310             :     }
     311             :     return;
     312             :   }
     313             : 
     314      196707 :   if (FLAG_always_osr) {
     315           0 :     AttemptOnStackReplacement(frame, AbstractCode::kMaxLoopNestingMarker);
     316             :     // Fall through and do a normal optimized compile as well.
     317      196707 :   } else if (MaybeOSRIgnition(function, frame)) {
     318             :     return;
     319             :   }
     320             : 
     321             :   SharedFunctionInfo* shared = function->shared();
     322             :   int ticks = shared->profiler_ticks();
     323             : 
     324      179682 :   if (shared->optimization_disabled()) {
     325       25272 :     if (shared->deopt_count() >= FLAG_max_deopt_count) {
     326             :       // If optimization was disabled due to many deoptimizations,
     327             :       // then check if the function is hot and try to reenable optimization.
     328        6522 :       if (ticks >= kProfilerTicksBeforeReenablingOptimization) {
     329             :         shared->set_profiler_ticks(0);
     330           0 :         shared->TryReenableOptimization();
     331             :       }
     332             :     }
     333             :     return;
     334             :   }
     335             : 
     336      308820 :   if (frame->is_optimized()) return;
     337             : 
     338       47825 :   OptimizationReason reason = ShouldOptimizeIgnition(function, frame);
     339             : 
     340       47825 :   if (reason != OptimizationReason::kDoNotOptimize) {
     341             :     Optimize(function, reason);
     342             :   }
     343             : }
     344             : 
     345      196707 : bool RuntimeProfiler::MaybeOSRIgnition(JSFunction* function,
     346             :                                        JavaScriptFrame* frame) {
     347             :   SharedFunctionInfo* shared = function->shared();
     348             :   int ticks = shared->profiler_ticks();
     349             : 
     350             :   // TODO(rmcilroy): Also ensure we only OSR top-level code if it is smaller
     351             :   // than kMaxToplevelSourceSize.
     352             : 
     353      680243 :   if (!frame->is_optimized() &&
     354       89173 :       (function->IsMarkedForOptimization() ||
     355       75546 :        function->IsMarkedForConcurrentOptimization() ||
     356             :        function->IsOptimized())) {
     357             :     // Attempt OSR if we are still running interpreted code even though the
     358             :     // the function has long been marked or even already been optimized.
     359             :     int64_t allowance =
     360             :         kOSRCodeSizeAllowanceBaseIgnition +
     361       17025 :         static_cast<int64_t>(ticks) * kOSRCodeSizeAllowancePerTickIgnition;
     362       17025 :     if (shared->bytecode_array()->Size() <= allowance) {
     363        8335 :       AttemptOnStackReplacement(frame);
     364             :     }
     365             :     return true;
     366             :   }
     367             :   return false;
     368             : }
     369             : 
     370       47825 : OptimizationReason RuntimeProfiler::ShouldOptimizeIgnition(
     371             :     JSFunction* function, JavaScriptFrame* frame) {
     372             :   SharedFunctionInfo* shared = function->shared();
     373             :   int ticks = shared->profiler_ticks();
     374             : 
     375       47825 :   if (shared->bytecode_array()->Size() > kMaxSizeOptIgnition) {
     376             :     return OptimizationReason::kDoNotOptimize;
     377             :   }
     378             : 
     379       47806 :   if (ticks >= kProfilerTicksBeforeOptimization) {
     380             :     int typeinfo, generic, total, type_percentage, generic_percentage;
     381             :     GetICCounts(function, &typeinfo, &generic, &total, &type_percentage,
     382       12325 :                 &generic_percentage);
     383       12325 :     if (type_percentage >= FLAG_type_info_threshold) {
     384             :       // If this particular function hasn't had any ICs patched for enough
     385             :       // ticks, optimize it now.
     386             :       return OptimizationReason::kHotAndStable;
     387        3885 :     } else if (ticks >= kTicksWhenNotEnoughTypeInfo) {
     388             :       return OptimizationReason::kHotWithoutMuchTypeInfo;
     389             :     } else {
     390        3868 :       if (FLAG_trace_opt_verbose) {
     391           0 :         PrintF("[not yet optimizing ");
     392           0 :         function->PrintName();
     393             :         PrintF(", not enough type info: %d/%d (%d%%)]\n", typeinfo, total,
     394           0 :                type_percentage);
     395             :       }
     396             :       return OptimizationReason::kDoNotOptimize;
     397             :     }
     398       56591 :   } else if (!any_ic_changed_ &&
     399       21110 :              shared->bytecode_array()->Size() < kMaxSizeEarlyOptIgnition) {
     400             :     // If no IC was patched since the last tick and this function is very
     401             :     // small, optimistically optimize it now.
     402             :     int typeinfo, generic, total, type_percentage, generic_percentage;
     403             :     GetICCounts(function, &typeinfo, &generic, &total, &type_percentage,
     404        5228 :                 &generic_percentage);
     405        5228 :     if (type_percentage < FLAG_type_info_threshold) {
     406         210 :       if (FLAG_trace_opt_verbose) {
     407           0 :         PrintF("[not yet optimizing ");
     408           0 :         function->PrintName();
     409             :         PrintF(
     410             :             ", not enough type info for small function optimization: %d/%d "
     411             :             "(%d%%)]\n",
     412           0 :             typeinfo, total, type_percentage);
     413             :       }
     414             :       return OptimizationReason::kDoNotOptimize;
     415             :     }
     416             :     return OptimizationReason::kSmallFunction;
     417       30253 :   } else if (FLAG_trace_opt_verbose) {
     418           0 :     PrintF("[not yet optimizing ");
     419           0 :     function->PrintName();
     420             :     PrintF(", not enough ticks: %d/%d and ", ticks,
     421           0 :            kProfilerTicksBeforeOptimization);
     422           0 :     if (any_ic_changed_) {
     423           0 :       PrintF("ICs changed]\n");
     424             :     } else {
     425             :       PrintF(" too large for small function optimization: %d/%d]\n",
     426           0 :              shared->bytecode_array()->Size(), kMaxSizeEarlyOptIgnition);
     427             :     }
     428             :   }
     429             :   return OptimizationReason::kDoNotOptimize;
     430             : }
     431             : 
     432      716002 : void RuntimeProfiler::MarkCandidatesForOptimization() {
     433      716002 :   HandleScope scope(isolate_);
     434             : 
     435     1432004 :   if (!isolate_->use_crankshaft()) return;
     436             : 
     437             :   DisallowHeapAllocation no_gc;
     438             : 
     439             :   // Run through the JavaScript frames and collect them. If we already
     440             :   // have a sample of the function, we mark it for optimizations
     441             :   // (eagerly or lazily).
     442             :   int frame_count = 0;
     443      609969 :   int frame_count_limit = FLAG_frame_count;
     444     1829901 :   for (JavaScriptFrameIterator it(isolate_);
     445     1829901 :        frame_count++ < frame_count_limit && !it.done();
     446      609963 :        it.Advance()) {
     447             :     JavaScriptFrame* frame = it.frame();
     448      609963 :     JSFunction* function = frame->function();
     449             : 
     450      609963 :     if (function->shared()->IsInterpreted()) {
     451      205207 :       MaybeOptimizeIgnition(function, frame);
     452             :     } else {
     453      404756 :       MaybeOptimizeFullCodegen(function, frame, frame_count);
     454             :     }
     455             : 
     456             :     // Update shared function info ticks after checking for whether functions
     457             :     // should be optimized to keep FCG (which updates ticks on code) and
     458             :     // Ignition (which updates ticks on shared function info) in sync.
     459             :     List<SharedFunctionInfo*> functions(4);
     460      609963 :     frame->GetFunctions(&functions);
     461     1830025 :     for (int i = functions.length(); --i >= 0;) {
     462     1220198 :       SharedFunctionInfo* shared_function_info = functions[i];
     463             :       int ticks = shared_function_info->profiler_ticks();
     464      610099 :       if (ticks < Smi::kMaxValue) {
     465      610099 :         shared_function_info->set_profiler_ticks(ticks + 1);
     466             :       }
     467             :     }
     468             :   }
     469      609969 :   any_ic_changed_ = false;
     470             : }
     471             : 
     472             : }  // namespace internal
     473             : }  // namespace v8

Generated by: LCOV version 1.10