| 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 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 generic_percentage <= FLAG_generic_ic_threshold) { | 257 generic_percentage <= FLAG_generic_ic_threshold) { |
| 258 Optimize(function, "small function"); | 258 Optimize(function, "small function"); |
| 259 } else { | 259 } else { |
| 260 shared_code->set_profiler_ticks(ticks + 1); | 260 shared_code->set_profiler_ticks(ticks + 1); |
| 261 } | 261 } |
| 262 } else { | 262 } else { |
| 263 shared_code->set_profiler_ticks(ticks + 1); | 263 shared_code->set_profiler_ticks(ticks + 1); |
| 264 } | 264 } |
| 265 } | 265 } |
| 266 | 266 |
| 267 void RuntimeProfiler::MaybeBaselineIgnition(JSFunction* function) { | 267 void RuntimeProfiler::MaybeBaselineIgnition(JSFunction* function, |
| 268 bool frame_optimized) { |
| 268 if (function->IsInOptimizationQueue()) return; | 269 if (function->IsInOptimizationQueue()) return; |
| 269 | 270 |
| 270 SharedFunctionInfo* shared = function->shared(); | 271 SharedFunctionInfo* shared = function->shared(); |
| 271 int ticks = shared->profiler_ticks(); | 272 int ticks = shared->profiler_ticks(); |
| 272 | 273 |
| 273 // TODO(rmcilroy): Also ensure we only OSR top-level code if it is smaller | 274 // TODO(rmcilroy): Also ensure we only OSR top-level code if it is smaller |
| 274 // than kMaxToplevelSourceSize. | 275 // than kMaxToplevelSourceSize. |
| 275 | 276 |
| 276 if (FLAG_ignition_osr && FLAG_always_osr) { | 277 if (FLAG_ignition_osr && FLAG_always_osr) { |
| 277 AttemptOnStackReplacement(function, AbstractCode::kMaxLoopNestingMarker); | 278 AttemptOnStackReplacement(function, AbstractCode::kMaxLoopNestingMarker); |
| 278 // Fall through and do a normal baseline compile as well. | 279 // Fall through and do a normal baseline compile as well. |
| 279 } else if (function->IsMarkedForBaseline() || | 280 } else if (!frame_optimized && |
| 280 function->IsMarkedForOptimization() || | 281 (function->IsMarkedForBaseline() || |
| 281 function->IsMarkedForConcurrentOptimization() || | 282 function->IsMarkedForOptimization() || |
| 282 function->IsOptimized()) { | 283 function->IsMarkedForConcurrentOptimization() || |
| 284 function->IsOptimized())) { |
| 283 // Attempt OSR if we are still running interpreted code even though the | 285 // Attempt OSR if we are still running interpreted code even though the |
| 284 // the function has long been marked or even already been optimized. | 286 // the function has long been marked or even already been optimized. |
| 285 int64_t allowance = | 287 int64_t allowance = |
| 286 kOSRCodeSizeAllowanceBaseIgnition + | 288 kOSRCodeSizeAllowanceBaseIgnition + |
| 287 static_cast<int64_t>(ticks) * kOSRCodeSizeAllowancePerTickIgnition; | 289 static_cast<int64_t>(ticks) * kOSRCodeSizeAllowancePerTickIgnition; |
| 288 if (FLAG_ignition_osr && shared->HasBytecodeArray() && | 290 if (FLAG_ignition_osr && shared->HasBytecodeArray() && |
| 289 shared->bytecode_array()->Size() <= allowance) { | 291 shared->bytecode_array()->Size() <= allowance) { |
| 290 AttemptOnStackReplacement(function); | 292 AttemptOnStackReplacement(function); |
| 291 } | 293 } |
| 292 return; | 294 return; |
| 293 } | 295 } |
| 294 | 296 |
| 295 if (shared->optimization_disabled() && | 297 if (shared->optimization_disabled() && |
| 296 shared->disable_optimization_reason() == kOptimizationDisabledForTest) { | 298 shared->disable_optimization_reason() == kOptimizationDisabledForTest) { |
| 297 // Don't baseline functions which have been marked by NeverOptimizeFunction | 299 // Don't baseline functions which have been marked by NeverOptimizeFunction |
| 298 // in a test. | 300 // in a test. |
| 299 return; | 301 return; |
| 300 } | 302 } |
| 301 | 303 |
| 302 if (ticks >= kProfilerTicksBeforeBaseline) { | 304 if (ticks >= kProfilerTicksBeforeBaseline) { |
| 303 Baseline(function, "hot enough for baseline"); | 305 Baseline(function, "hot enough for baseline"); |
| 304 } | 306 } |
| 305 } | 307 } |
| 306 | 308 |
| 307 void RuntimeProfiler::MaybeOptimizeIgnition(JSFunction* function) { | 309 void RuntimeProfiler::MaybeOptimizeIgnition(JSFunction* function, |
| 310 bool frame_optimized) { |
| 308 if (function->IsInOptimizationQueue()) return; | 311 if (function->IsInOptimizationQueue()) return; |
| 309 | 312 |
| 310 SharedFunctionInfo* shared = function->shared(); | 313 SharedFunctionInfo* shared = function->shared(); |
| 311 int ticks = shared->profiler_ticks(); | 314 int ticks = shared->profiler_ticks(); |
| 312 | 315 |
| 313 // TODO(rmcilroy): Also ensure we only OSR top-level code if it is smaller | 316 // TODO(rmcilroy): Also ensure we only OSR top-level code if it is smaller |
| 314 // than kMaxToplevelSourceSize. | 317 // than kMaxToplevelSourceSize. |
| 315 | 318 |
| 316 if (FLAG_ignition_osr && FLAG_always_osr) { | 319 if (FLAG_ignition_osr && FLAG_always_osr) { |
| 317 AttemptOnStackReplacement(function, AbstractCode::kMaxLoopNestingMarker); | 320 AttemptOnStackReplacement(function, AbstractCode::kMaxLoopNestingMarker); |
| 318 // Fall through and do a normal optimized compile as well. | 321 // Fall through and do a normal optimized compile as well. |
| 319 } else if (function->IsMarkedForBaseline() || | 322 } else if (!frame_optimized && |
| 320 function->IsMarkedForOptimization() || | 323 (function->IsMarkedForBaseline() || |
| 321 function->IsMarkedForConcurrentOptimization() || | 324 function->IsMarkedForOptimization() || |
| 322 function->IsOptimized()) { | 325 function->IsMarkedForConcurrentOptimization() || |
| 326 function->IsOptimized())) { |
| 323 // Attempt OSR if we are still running interpreted code even though the | 327 // Attempt OSR if we are still running interpreted code even though the |
| 324 // the function has long been marked or even already been optimized. | 328 // the function has long been marked or even already been optimized. |
| 325 int64_t allowance = | 329 int64_t allowance = |
| 326 kOSRCodeSizeAllowanceBaseIgnition + | 330 kOSRCodeSizeAllowanceBaseIgnition + |
| 327 static_cast<int64_t>(ticks) * kOSRCodeSizeAllowancePerTickIgnition; | 331 static_cast<int64_t>(ticks) * kOSRCodeSizeAllowancePerTickIgnition; |
| 328 if (FLAG_ignition_osr && shared->HasBytecodeArray() && | 332 if (FLAG_ignition_osr && shared->HasBytecodeArray() && |
| 329 shared->bytecode_array()->Size() <= allowance) { | 333 shared->bytecode_array()->Size() <= allowance) { |
| 330 AttemptOnStackReplacement(function); | 334 AttemptOnStackReplacement(function); |
| 331 } | 335 } |
| 332 return; | 336 return; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 for (int i = functions.length(); --i >= 0; ) { | 396 for (int i = functions.length(); --i >= 0; ) { |
| 393 SharedFunctionInfo* shared_function_info = functions[i]->shared(); | 397 SharedFunctionInfo* shared_function_info = functions[i]->shared(); |
| 394 int ticks = shared_function_info->profiler_ticks(); | 398 int ticks = shared_function_info->profiler_ticks(); |
| 395 if (ticks < Smi::kMaxValue) { | 399 if (ticks < Smi::kMaxValue) { |
| 396 shared_function_info->set_profiler_ticks(ticks + 1); | 400 shared_function_info->set_profiler_ticks(ticks + 1); |
| 397 } | 401 } |
| 398 } | 402 } |
| 399 | 403 |
| 400 Compiler::CompilationTier next_tier = | 404 Compiler::CompilationTier next_tier = |
| 401 Compiler::NextCompilationTier(function); | 405 Compiler::NextCompilationTier(function); |
| 402 if (frame->is_interpreted()) { | 406 if (function->shared()->HasBytecodeArray()) { |
| 403 if (next_tier == Compiler::BASELINE) { | 407 if (next_tier == Compiler::BASELINE) { |
| 404 DCHECK(!frame->is_optimized()); | 408 MaybeBaselineIgnition(function, frame->is_optimized()); |
| 405 MaybeBaselineIgnition(function); | |
| 406 } else { | 409 } else { |
| 407 DCHECK_EQ(next_tier, Compiler::OPTIMIZED); | 410 DCHECK_EQ(next_tier, Compiler::OPTIMIZED); |
| 408 MaybeOptimizeIgnition(function); | 411 MaybeOptimizeIgnition(function, frame->is_optimized()); |
| 409 } | 412 } |
| 410 } else { | 413 } else { |
| 411 DCHECK_EQ(next_tier, Compiler::OPTIMIZED); | 414 DCHECK_EQ(next_tier, Compiler::OPTIMIZED); |
| 412 MaybeOptimizeFullCodegen(function, frame_count, frame->is_optimized()); | 415 MaybeOptimizeFullCodegen(function, frame_count, frame->is_optimized()); |
| 413 } | 416 } |
| 414 } | 417 } |
| 415 any_ic_changed_ = false; | 418 any_ic_changed_ = false; |
| 416 } | 419 } |
| 417 | 420 |
| 418 | 421 |
| 419 } // namespace internal | 422 } // namespace internal |
| 420 } // namespace v8 | 423 } // namespace v8 |
| OLD | NEW |