| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/runtime-profiler.h" | 5 #include "src/runtime-profiler.h" |
| 6 | 6 |
| 7 #include "src/assembler.h" | 7 #include "src/assembler.h" |
| 8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 static const int kOSRCodeSizeAllowancePerTick = | 48 static const int kOSRCodeSizeAllowancePerTick = |
| 49 4 * FullCodeGenerator::kCodeSizeMultiplier; | 49 4 * FullCodeGenerator::kCodeSizeMultiplier; |
| 50 static const int kOSRCodeSizeAllowancePerTickIgnition = | 50 static const int kOSRCodeSizeAllowancePerTickIgnition = |
| 51 4 * interpreter::Interpreter::kCodeSizeMultiplier; | 51 4 * interpreter::Interpreter::kCodeSizeMultiplier; |
| 52 | 52 |
| 53 // Maximum size in bytes of generated code for a function to be optimized | 53 // Maximum size in bytes of generated code for a function to be optimized |
| 54 // the very first time it is seen on the stack. | 54 // the very first time it is seen on the stack. |
| 55 static const int kMaxSizeEarlyOpt = | 55 static const int kMaxSizeEarlyOpt = |
| 56 5 * FullCodeGenerator::kCodeSizeMultiplier; | 56 5 * FullCodeGenerator::kCodeSizeMultiplier; |
| 57 | 57 |
| 58 #define OPTIMIZATION_REASON_LIST(V) \ |
| 59 V(DoNotOptimize, "do not optimize") \ |
| 60 V(HotAndStable, "hot and stable") \ |
| 61 V(HotEnoughForBaseline, "hot enough for baseline") \ |
| 62 V(HotWithoutMuchTypeInfo, "not much type info but very hot") \ |
| 63 V(SmallFunction, "small function") |
| 64 |
| 65 enum class OptimizationReason : uint8_t { |
| 66 #define OPTIMIZATION_REASON_CONSTANTS(Constant, message) k##Constant, |
| 67 OPTIMIZATION_REASON_LIST(OPTIMIZATION_REASON_CONSTANTS) |
| 68 #undef OPTIMIZATION_REASON_CONSTANTS |
| 69 }; |
| 70 |
| 71 char const* OptimizationReasonToString(OptimizationReason reason) { |
| 72 static char const* reasons[] = { |
| 73 #define OPTIMIZATION_REASON_TEXTS(Constant, message) message, |
| 74 OPTIMIZATION_REASON_LIST(OPTIMIZATION_REASON_TEXTS) |
| 75 #undef OPTIMIZATION_REASON_TEXTS |
| 76 }; |
| 77 size_t const index = static_cast<size_t>(reason); |
| 78 DCHECK_LT(index, arraysize(reasons)); |
| 79 return reasons[index]; |
| 80 } |
| 81 |
| 82 std::ostream& operator<<(std::ostream& os, OptimizationReason reason) { |
| 83 return os << OptimizationReasonToString(reason); |
| 84 } |
| 58 | 85 |
| 59 RuntimeProfiler::RuntimeProfiler(Isolate* isolate) | 86 RuntimeProfiler::RuntimeProfiler(Isolate* isolate) |
| 60 : isolate_(isolate), | 87 : isolate_(isolate), |
| 61 any_ic_changed_(false) { | 88 any_ic_changed_(false) { |
| 62 } | 89 } |
| 63 | 90 |
| 64 static void GetICCounts(JSFunction* function, int* ic_with_type_info_count, | 91 static void GetICCounts(JSFunction* function, int* ic_with_type_info_count, |
| 65 int* ic_generic_count, int* ic_total_count, | 92 int* ic_generic_count, int* ic_total_count, |
| 66 int* type_info_percentage, int* generic_percentage) { | 93 int* type_info_percentage, int* generic_percentage) { |
| 67 *ic_total_count = 0; | 94 *ic_total_count = 0; |
| 68 *ic_generic_count = 0; | 95 *ic_generic_count = 0; |
| 69 *ic_with_type_info_count = 0; | 96 *ic_with_type_info_count = 0; |
| 70 if (function->code()->kind() == Code::FUNCTION) { | 97 if (function->code()->kind() == Code::FUNCTION) { |
| 71 Code* shared_code = function->shared()->code(); | 98 Code* shared_code = function->shared()->code(); |
| 72 Object* raw_info = shared_code->type_feedback_info(); | 99 Object* raw_info = shared_code->type_feedback_info(); |
| 73 if (raw_info->IsTypeFeedbackInfo()) { | 100 if (raw_info->IsTypeFeedbackInfo()) { |
| 74 TypeFeedbackInfo* info = TypeFeedbackInfo::cast(raw_info); | 101 TypeFeedbackInfo* info = TypeFeedbackInfo::cast(raw_info); |
| 75 *ic_with_type_info_count = info->ic_with_type_info_count(); | 102 *ic_with_type_info_count = info->ic_with_type_info_count(); |
| 76 *ic_generic_count = info->ic_generic_count(); | 103 *ic_generic_count = info->ic_generic_count(); |
| 77 *ic_total_count = info->ic_total_count(); | 104 *ic_total_count = info->ic_total_count(); |
| 78 } | 105 } |
| 79 } | 106 } |
| 80 | 107 |
| 81 // Harvest vector-ics as well | 108 // Harvest vector-ics as well |
| 82 TypeFeedbackVector* vector = function->feedback_vector(); | 109 TypeFeedbackVector* vector = function->feedback_vector(); |
| 83 int with = 0, gen = 0; | 110 int with = 0, gen = 0, type_vector_ic_count = 0; |
| 84 const bool is_interpreted = | 111 const bool is_interpreted = |
| 85 function->shared()->code()->is_interpreter_trampoline_builtin(); | 112 function->shared()->code()->is_interpreter_trampoline_builtin(); |
| 86 | 113 |
| 87 vector->ComputeCounts(&with, &gen, is_interpreted); | 114 vector->ComputeCounts(&with, &gen, &type_vector_ic_count, is_interpreted); |
| 115 if (is_interpreted) { |
| 116 DCHECK_EQ(*ic_total_count, 0); |
| 117 *ic_total_count = type_vector_ic_count; |
| 118 } |
| 88 *ic_with_type_info_count += with; | 119 *ic_with_type_info_count += with; |
| 89 *ic_generic_count += gen; | 120 *ic_generic_count += gen; |
| 90 | 121 |
| 91 if (*ic_total_count > 0) { | 122 if (*ic_total_count > 0) { |
| 92 *type_info_percentage = 100 * *ic_with_type_info_count / *ic_total_count; | 123 *type_info_percentage = 100 * *ic_with_type_info_count / *ic_total_count; |
| 93 *generic_percentage = 100 * *ic_generic_count / *ic_total_count; | 124 *generic_percentage = 100 * *ic_generic_count / *ic_total_count; |
| 94 } else { | 125 } else { |
| 95 *type_info_percentage = 100; // Compared against lower bound. | 126 *type_info_percentage = 100; // Compared against lower bound. |
| 96 *generic_percentage = 0; // Compared against upper bound. | 127 *generic_percentage = 0; // Compared against upper bound. |
| 97 } | 128 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 109 GetICCounts(function, &typeinfo, &generic, &total, &type_percentage, | 140 GetICCounts(function, &typeinfo, &generic, &total, &type_percentage, |
| 110 &generic_percentage); | 141 &generic_percentage); |
| 111 PrintF(", ICs with typeinfo: %d/%d (%d%%)", typeinfo, total, | 142 PrintF(", ICs with typeinfo: %d/%d (%d%%)", typeinfo, total, |
| 112 type_percentage); | 143 type_percentage); |
| 113 PrintF(", generic ICs: %d/%d (%d%%)", generic, total, generic_percentage); | 144 PrintF(", generic ICs: %d/%d (%d%%)", generic, total, generic_percentage); |
| 114 } | 145 } |
| 115 PrintF("]\n"); | 146 PrintF("]\n"); |
| 116 } | 147 } |
| 117 } | 148 } |
| 118 | 149 |
| 119 void RuntimeProfiler::Optimize(JSFunction* function, const char* reason) { | 150 void RuntimeProfiler::Optimize(JSFunction* function, |
| 120 TraceRecompile(function, reason, "optimized"); | 151 OptimizationReason reason) { |
| 152 DCHECK_NE(reason, OptimizationReason::kDoNotOptimize); |
| 153 TraceRecompile(function, OptimizationReasonToString(reason), "optimized"); |
| 121 function->AttemptConcurrentOptimization(); | 154 function->AttemptConcurrentOptimization(); |
| 122 } | 155 } |
| 123 | 156 |
| 124 void RuntimeProfiler::Baseline(JSFunction* function, const char* reason) { | 157 void RuntimeProfiler::Baseline(JSFunction* function, |
| 125 TraceRecompile(function, reason, "baseline"); | 158 OptimizationReason reason) { |
| 159 DCHECK_NE(reason, OptimizationReason::kDoNotOptimize); |
| 160 TraceRecompile(function, OptimizationReasonToString(reason), "baseline"); |
| 126 | 161 |
| 127 // TODO(4280): Fix this to check function is compiled for the interpreter | 162 // TODO(4280): Fix this to check function is compiled for the interpreter |
| 128 // once we have a standard way to check that. For now function will only | 163 // once we have a standard way to check that. For now function will only |
| 129 // have a bytecode array if compiled for the interpreter. | 164 // have a bytecode array if compiled for the interpreter. |
| 130 DCHECK(function->shared()->HasBytecodeArray()); | 165 DCHECK(function->shared()->HasBytecodeArray()); |
| 131 function->MarkForBaseline(); | 166 function->MarkForBaseline(); |
| 132 } | 167 } |
| 133 | 168 |
| 134 void RuntimeProfiler::AttemptOnStackReplacement(JavaScriptFrame* frame, | 169 void RuntimeProfiler::AttemptOnStackReplacement(JavaScriptFrame* frame, |
| 135 int loop_nesting_levels) { | 170 int loop_nesting_levels) { |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 int ticks = shared_code->profiler_ticks(); | 269 int ticks = shared_code->profiler_ticks(); |
| 235 | 270 |
| 236 if (ticks >= kProfilerTicksBeforeOptimization) { | 271 if (ticks >= kProfilerTicksBeforeOptimization) { |
| 237 int typeinfo, generic, total, type_percentage, generic_percentage; | 272 int typeinfo, generic, total, type_percentage, generic_percentage; |
| 238 GetICCounts(function, &typeinfo, &generic, &total, &type_percentage, | 273 GetICCounts(function, &typeinfo, &generic, &total, &type_percentage, |
| 239 &generic_percentage); | 274 &generic_percentage); |
| 240 if (type_percentage >= FLAG_type_info_threshold && | 275 if (type_percentage >= FLAG_type_info_threshold && |
| 241 generic_percentage <= FLAG_generic_ic_threshold) { | 276 generic_percentage <= FLAG_generic_ic_threshold) { |
| 242 // If this particular function hasn't had any ICs patched for enough | 277 // If this particular function hasn't had any ICs patched for enough |
| 243 // ticks, optimize it now. | 278 // ticks, optimize it now. |
| 244 Optimize(function, "hot and stable"); | 279 Optimize(function, OptimizationReason::kHotAndStable); |
| 245 } else if (ticks >= kTicksWhenNotEnoughTypeInfo) { | 280 } else if (ticks >= kTicksWhenNotEnoughTypeInfo) { |
| 246 Optimize(function, "not much type info but very hot"); | 281 Optimize(function, OptimizationReason::kHotWithoutMuchTypeInfo); |
| 247 } else { | 282 } else { |
| 248 shared_code->set_profiler_ticks(ticks + 1); | 283 shared_code->set_profiler_ticks(ticks + 1); |
| 249 if (FLAG_trace_opt_verbose) { | 284 if (FLAG_trace_opt_verbose) { |
| 250 PrintF("[not yet optimizing "); | 285 PrintF("[not yet optimizing "); |
| 251 function->PrintName(); | 286 function->PrintName(); |
| 252 PrintF(", not enough type info: %d/%d (%d%%)]\n", typeinfo, total, | 287 PrintF(", not enough type info: %d/%d (%d%%)]\n", typeinfo, total, |
| 253 type_percentage); | 288 type_percentage); |
| 254 } | 289 } |
| 255 } | 290 } |
| 256 } else if (!any_ic_changed_ && | 291 } else if (!any_ic_changed_ && |
| 257 shared_code->instruction_size() < kMaxSizeEarlyOpt) { | 292 shared_code->instruction_size() < kMaxSizeEarlyOpt) { |
| 258 // If no IC was patched since the last tick and this function is very | 293 // If no IC was patched since the last tick and this function is very |
| 259 // small, optimistically optimize it now. | 294 // small, optimistically optimize it now. |
| 260 int typeinfo, generic, total, type_percentage, generic_percentage; | 295 int typeinfo, generic, total, type_percentage, generic_percentage; |
| 261 GetICCounts(function, &typeinfo, &generic, &total, &type_percentage, | 296 GetICCounts(function, &typeinfo, &generic, &total, &type_percentage, |
| 262 &generic_percentage); | 297 &generic_percentage); |
| 263 if (type_percentage >= FLAG_type_info_threshold && | 298 if (type_percentage >= FLAG_type_info_threshold && |
| 264 generic_percentage <= FLAG_generic_ic_threshold) { | 299 generic_percentage <= FLAG_generic_ic_threshold) { |
| 265 Optimize(function, "small function"); | 300 Optimize(function, OptimizationReason::kSmallFunction); |
| 266 } else { | 301 } else { |
| 267 shared_code->set_profiler_ticks(ticks + 1); | 302 shared_code->set_profiler_ticks(ticks + 1); |
| 268 } | 303 } |
| 269 } else { | 304 } else { |
| 270 shared_code->set_profiler_ticks(ticks + 1); | 305 shared_code->set_profiler_ticks(ticks + 1); |
| 271 } | 306 } |
| 272 } | 307 } |
| 273 | 308 |
| 274 void RuntimeProfiler::MaybeBaselineIgnition(JSFunction* function, | 309 void RuntimeProfiler::MaybeBaselineIgnition(JSFunction* function, |
| 275 JavaScriptFrame* frame) { | 310 JavaScriptFrame* frame) { |
| 276 if (function->IsInOptimizationQueue()) return; | 311 if (function->IsInOptimizationQueue()) return; |
| 277 | 312 |
| 313 if (FLAG_always_osr) { |
| 314 AttemptOnStackReplacement(frame, AbstractCode::kMaxLoopNestingMarker); |
| 315 // Fall through and do a normal baseline compile as well. |
| 316 } else if (MaybeOSRIgnition(function, frame)) { |
| 317 return; |
| 318 } |
| 319 |
| 278 SharedFunctionInfo* shared = function->shared(); | 320 SharedFunctionInfo* shared = function->shared(); |
| 279 int ticks = shared->profiler_ticks(); | 321 int ticks = shared->profiler_ticks(); |
| 280 | 322 |
| 281 // TODO(rmcilroy): Also ensure we only OSR top-level code if it is smaller | |
| 282 // than kMaxToplevelSourceSize. | |
| 283 | |
| 284 if (FLAG_always_osr) { | |
| 285 AttemptOnStackReplacement(frame, AbstractCode::kMaxLoopNestingMarker); | |
| 286 // Fall through and do a normal baseline compile as well. | |
| 287 } else if (!frame->is_optimized() && | |
| 288 (function->IsMarkedForBaseline() || | |
| 289 function->IsMarkedForOptimization() || | |
| 290 function->IsMarkedForConcurrentOptimization() || | |
| 291 function->IsOptimized())) { | |
| 292 // Attempt OSR if we are still running interpreted code even though the | |
| 293 // the function has long been marked or even already been optimized. | |
| 294 int64_t allowance = | |
| 295 kOSRCodeSizeAllowanceBaseIgnition + | |
| 296 static_cast<int64_t>(ticks) * kOSRCodeSizeAllowancePerTickIgnition; | |
| 297 if (shared->bytecode_array()->Size() <= allowance) { | |
| 298 AttemptOnStackReplacement(frame); | |
| 299 } | |
| 300 return; | |
| 301 } | |
| 302 | |
| 303 if (shared->optimization_disabled() && | 323 if (shared->optimization_disabled() && |
| 304 shared->disable_optimization_reason() == kOptimizationDisabledForTest) { | 324 shared->disable_optimization_reason() == kOptimizationDisabledForTest) { |
| 305 // Don't baseline functions which have been marked by NeverOptimizeFunction | 325 // Don't baseline functions which have been marked by NeverOptimizeFunction |
| 306 // in a test. | 326 // in a test. |
| 307 return; | 327 return; |
| 308 } | 328 } |
| 309 | 329 |
| 310 if (ticks >= kProfilerTicksBeforeBaseline) { | 330 if (ticks >= kProfilerTicksBeforeBaseline) { |
| 311 Baseline(function, "hot enough for baseline"); | 331 Baseline(function, OptimizationReason::kHotEnoughForBaseline); |
| 312 } | 332 } |
| 313 } | 333 } |
| 314 | 334 |
| 315 void RuntimeProfiler::MaybeOptimizeIgnition(JSFunction* function, | 335 void RuntimeProfiler::MaybeOptimizeIgnition(JSFunction* function, |
| 316 JavaScriptFrame* frame) { | 336 JavaScriptFrame* frame) { |
| 317 if (function->IsInOptimizationQueue()) return; | 337 if (function->IsInOptimizationQueue()) return; |
| 318 | 338 |
| 339 if (FLAG_always_osr) { |
| 340 AttemptOnStackReplacement(frame, AbstractCode::kMaxLoopNestingMarker); |
| 341 // Fall through and do a normal optimized compile as well. |
| 342 } else if (MaybeOSRIgnition(function, frame)) { |
| 343 return; |
| 344 } |
| 345 |
| 319 SharedFunctionInfo* shared = function->shared(); | 346 SharedFunctionInfo* shared = function->shared(); |
| 320 int ticks = shared->profiler_ticks(); | 347 int ticks = shared->profiler_ticks(); |
| 321 | 348 |
| 322 // TODO(rmcilroy): Also ensure we only OSR top-level code if it is smaller | |
| 323 // than kMaxToplevelSourceSize. | |
| 324 | |
| 325 if (FLAG_always_osr) { | |
| 326 AttemptOnStackReplacement(frame, AbstractCode::kMaxLoopNestingMarker); | |
| 327 // Fall through and do a normal optimized compile as well. | |
| 328 } else if (!frame->is_optimized() && | |
| 329 (function->IsMarkedForBaseline() || | |
| 330 function->IsMarkedForOptimization() || | |
| 331 function->IsMarkedForConcurrentOptimization() || | |
| 332 function->IsOptimized())) { | |
| 333 // Attempt OSR if we are still running interpreted code even though the | |
| 334 // the function has long been marked or even already been optimized. | |
| 335 int64_t allowance = | |
| 336 kOSRCodeSizeAllowanceBaseIgnition + | |
| 337 static_cast<int64_t>(ticks) * kOSRCodeSizeAllowancePerTickIgnition; | |
| 338 if (shared->bytecode_array()->Size() <= allowance) { | |
| 339 AttemptOnStackReplacement(frame); | |
| 340 } | |
| 341 return; | |
| 342 } | |
| 343 | |
| 344 if (shared->optimization_disabled()) { | 349 if (shared->optimization_disabled()) { |
| 345 if (shared->deopt_count() >= FLAG_max_opt_count) { | 350 if (shared->deopt_count() >= FLAG_max_opt_count) { |
| 346 // If optimization was disabled due to many deoptimizations, | 351 // If optimization was disabled due to many deoptimizations, |
| 347 // then check if the function is hot and try to reenable optimization. | 352 // then check if the function is hot and try to reenable optimization. |
| 348 if (ticks >= kProfilerTicksBeforeReenablingOptimization) { | 353 if (ticks >= kProfilerTicksBeforeReenablingOptimization) { |
| 349 shared->set_profiler_ticks(0); | 354 shared->set_profiler_ticks(0); |
| 350 shared->TryReenableOptimization(); | 355 shared->TryReenableOptimization(); |
| 351 } | 356 } |
| 352 } | 357 } |
| 353 return; | 358 return; |
| 354 } | 359 } |
| 360 |
| 355 if (function->IsOptimized()) return; | 361 if (function->IsOptimized()) return; |
| 356 | 362 |
| 363 OptimizationReason reason = ShouldOptimizeIgnition(function, frame); |
| 364 |
| 365 if (reason != OptimizationReason::kDoNotOptimize) { |
| 366 Optimize(function, reason); |
| 367 } |
| 368 } |
| 369 |
| 370 bool RuntimeProfiler::MaybeOSRIgnition(JSFunction* function, |
| 371 JavaScriptFrame* frame) { |
| 372 if (!FLAG_ignition_osr) return false; |
| 373 |
| 374 SharedFunctionInfo* shared = function->shared(); |
| 375 int ticks = shared->profiler_ticks(); |
| 376 |
| 377 // TODO(rmcilroy): Also ensure we only OSR top-level code if it is smaller |
| 378 // than kMaxToplevelSourceSize. |
| 379 |
| 380 bool osr_before_baselined = function->IsMarkedForBaseline() && |
| 381 ShouldOptimizeIgnition(function, frame) != |
| 382 OptimizationReason::kDoNotOptimize; |
| 383 if (!frame->is_optimized() && |
| 384 (osr_before_baselined || function->IsMarkedForOptimization() || |
| 385 function->IsMarkedForConcurrentOptimization() || |
| 386 function->IsOptimized())) { |
| 387 // Attempt OSR if we are still running interpreted code even though the |
| 388 // the function has long been marked or even already been optimized. |
| 389 int64_t allowance = |
| 390 kOSRCodeSizeAllowanceBaseIgnition + |
| 391 static_cast<int64_t>(ticks) * kOSRCodeSizeAllowancePerTickIgnition; |
| 392 if (shared->bytecode_array()->Size() <= allowance) { |
| 393 AttemptOnStackReplacement(frame); |
| 394 } |
| 395 return true; |
| 396 } |
| 397 return false; |
| 398 } |
| 399 |
| 400 OptimizationReason RuntimeProfiler::ShouldOptimizeIgnition( |
| 401 JSFunction* function, JavaScriptFrame* frame) { |
| 402 SharedFunctionInfo* shared = function->shared(); |
| 403 int ticks = shared->profiler_ticks(); |
| 404 |
| 357 if (ticks >= kProfilerTicksBeforeOptimization) { | 405 if (ticks >= kProfilerTicksBeforeOptimization) { |
| 358 int typeinfo, generic, total, type_percentage, generic_percentage; | 406 int typeinfo, generic, total, type_percentage, generic_percentage; |
| 359 GetICCounts(function, &typeinfo, &generic, &total, &type_percentage, | 407 GetICCounts(function, &typeinfo, &generic, &total, &type_percentage, |
| 360 &generic_percentage); | 408 &generic_percentage); |
| 361 if (type_percentage >= FLAG_type_info_threshold && | 409 if (type_percentage >= FLAG_type_info_threshold && |
| 362 generic_percentage <= FLAG_generic_ic_threshold) { | 410 generic_percentage <= FLAG_generic_ic_threshold) { |
| 363 // If this particular function hasn't had any ICs patched for enough | 411 // If this particular function hasn't had any ICs patched for enough |
| 364 // ticks, optimize it now. | 412 // ticks, optimize it now. |
| 365 Optimize(function, "hot and stable"); | 413 return OptimizationReason::kHotAndStable; |
| 366 } else if (ticks >= kTicksWhenNotEnoughTypeInfo) { | 414 } else if (ticks >= kTicksWhenNotEnoughTypeInfo) { |
| 367 Optimize(function, "not much type info but very hot"); | 415 return OptimizationReason::kHotWithoutMuchTypeInfo; |
| 368 } else { | 416 } else { |
| 369 if (FLAG_trace_opt_verbose) { | 417 if (FLAG_trace_opt_verbose) { |
| 370 PrintF("[not yet optimizing "); | 418 PrintF("[not yet optimizing "); |
| 371 function->PrintName(); | 419 function->PrintName(); |
| 372 PrintF(", not enough type info: %d/%d (%d%%)]\n", typeinfo, total, | 420 PrintF(", not enough type info: %d/%d (%d%%)]\n", typeinfo, total, |
| 373 type_percentage); | 421 type_percentage); |
| 374 } | 422 } |
| 423 return OptimizationReason::kDoNotOptimize; |
| 375 } | 424 } |
| 376 } | 425 } |
| 377 // TODO(rmcilroy): Consider whether we should optimize small functions when | 426 // TODO(rmcilroy): Consider whether we should optimize small functions when |
| 378 // they are first seen on the stack (e.g., kMaxSizeEarlyOpt). | 427 // they are first seen on the stack (e.g., kMaxSizeEarlyOpt). |
| 428 return OptimizationReason::kDoNotOptimize; |
| 379 } | 429 } |
| 380 | 430 |
| 381 void RuntimeProfiler::MarkCandidatesForOptimization() { | 431 void RuntimeProfiler::MarkCandidatesForOptimization() { |
| 382 HandleScope scope(isolate_); | 432 HandleScope scope(isolate_); |
| 383 | 433 |
| 384 if (!isolate_->use_crankshaft()) return; | 434 if (!isolate_->use_crankshaft()) return; |
| 385 | 435 |
| 386 DisallowHeapAllocation no_gc; | 436 DisallowHeapAllocation no_gc; |
| 387 | 437 |
| 388 // Run through the JavaScript frames and collect them. If we already | 438 // Run through the JavaScript frames and collect them. If we already |
| (...skipping 27 matching lines...) Expand all Loading... |
| 416 MaybeOptimizeIgnition(function, frame); | 466 MaybeOptimizeIgnition(function, frame); |
| 417 } | 467 } |
| 418 } else { | 468 } else { |
| 419 DCHECK_EQ(next_tier, Compiler::OPTIMIZED); | 469 DCHECK_EQ(next_tier, Compiler::OPTIMIZED); |
| 420 MaybeOptimizeFullCodegen(function, frame, frame_count); | 470 MaybeOptimizeFullCodegen(function, frame, frame_count); |
| 421 } | 471 } |
| 422 } | 472 } |
| 423 any_ic_changed_ = false; | 473 any_ic_changed_ = false; |
| 424 } | 474 } |
| 425 | 475 |
| 426 | |
| 427 } // namespace internal | 476 } // namespace internal |
| 428 } // namespace v8 | 477 } // namespace v8 |
| OLD | NEW |