// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/runtime-profiler.h"

#include "src/assembler.h"
#include "src/base/platform/platform.h"
#include "src/bootstrapper.h"
#include "src/code-stubs.h"
#include "src/compilation-cache.h"
#include "src/compiler.h"
#include "src/execution.h"
#include "src/frames-inl.h"
#include "src/full-codegen/full-codegen.h"
#include "src/global-handles.h"
#include "src/interpreter/interpreter.h"

namespace v8 {
namespace internal {

// Number of times a function has to be seen on the stack before it is
// optimized.
static const int kProfilerTicksBeforeOptimization = 2;
// If the function optimization was disabled due to high deoptimization count,
// but the function is hot and has been seen on the stack this number of times,
// then we try to reenable optimization for this function.
static const int kProfilerTicksBeforeReenablingOptimization = 250;
// If a function does not have enough type info (according to
// FLAG_type_info_threshold), but has seen a huge number of ticks,
// optimize it as it is.
static const int kTicksWhenNotEnoughTypeInfo = 100;
// We only have one byte to store the number of ticks.
STATIC_ASSERT(kProfilerTicksBeforeOptimization < 256);
STATIC_ASSERT(kProfilerTicksBeforeReenablingOptimization < 256);
STATIC_ASSERT(kTicksWhenNotEnoughTypeInfo < 256);

// Maximum size in bytes of generate code for a function to allow OSR.
static const int kOSRCodeSizeAllowanceBase =
    100 * FullCodeGenerator::kCodeSizeMultiplier;
static const int kOSRCodeSizeAllowanceBaseIgnition =
    10 * interpreter::Interpreter::kCodeSizeMultiplier;

static const int kOSRCodeSizeAllowancePerTick =
    4 * FullCodeGenerator::kCodeSizeMultiplier;
static const int kOSRCodeSizeAllowancePerTickIgnition =
    2 * interpreter::Interpreter::kCodeSizeMultiplier;

// Maximum size in bytes of generated code for a function to be optimized
// the very first time it is seen on the stack.
static const int kMaxSizeEarlyOpt =
    5 * FullCodeGenerator::kCodeSizeMultiplier;
static const int kMaxSizeEarlyOptIgnition =
    5 * interpreter::Interpreter::kCodeSizeMultiplier;

// Certain functions are simply too big to be worth optimizing.
// We aren't using the code size multiplier here because there is no
// "kMaxSizeOpt" with which we would need to normalize. This constant is
// only for optimization decisions coming into TurboFan from Ignition.
static const int kMaxSizeOptIgnition = 250 * 1024;

#define OPTIMIZATION_REASON_LIST(V)                            \
  V(DoNotOptimize, "do not optimize")                          \
  V(HotAndStable, "hot and stable")                            \
  V(HotWithoutMuchTypeInfo, "not much type info but very hot") \
  V(SmallFunction, "small function")

enum class OptimizationReason : uint8_t {
#define OPTIMIZATION_REASON_CONSTANTS(Constant, message) k##Constant,
  OPTIMIZATION_REASON_LIST(OPTIMIZATION_REASON_CONSTANTS)
#undef OPTIMIZATION_REASON_CONSTANTS
};

char const* OptimizationReasonToString(OptimizationReason reason) {
  static char const* reasons[] = {
#define OPTIMIZATION_REASON_TEXTS(Constant, message) message,
      OPTIMIZATION_REASON_LIST(OPTIMIZATION_REASON_TEXTS)
#undef OPTIMIZATION_REASON_TEXTS
  };
  size_t const index = static_cast<size_t>(reason);
  DCHECK_LT(index, arraysize(reasons));
  return reasons[index];
}

std::ostream& operator<<(std::ostream& os, OptimizationReason reason) {
  return os << OptimizationReasonToString(reason);
}

RuntimeProfiler::RuntimeProfiler(Isolate* isolate)
    : isolate_(isolate),
      any_ic_changed_(false) {
}

static void GetICCounts(JSFunction* function, int* ic_with_type_info_count,
                        int* ic_generic_count, int* ic_total_count,
                        int* type_info_percentage, int* generic_percentage) {
  *ic_total_count = 0;
  *ic_generic_count = 0;
  *ic_with_type_info_count = 0;
  if (function->code()->kind() == Code::FUNCTION) {
    Code* shared_code = function->shared()->code();
    Object* raw_info = shared_code->type_feedback_info();
    if (raw_info->IsTypeFeedbackInfo()) {
      TypeFeedbackInfo* info = TypeFeedbackInfo::cast(raw_info);
      *ic_with_type_info_count = info->ic_with_type_info_count();
      *ic_generic_count = info->ic_generic_count();
      *ic_total_count = info->ic_total_count();
    }
  }

  // Harvest vector-ics as well
  FeedbackVector* vector = function->feedback_vector();
  int with = 0, gen = 0, type_vector_ic_count = 0;
  const bool is_interpreted = function->shared()->IsInterpreted();

  vector->ComputeCounts(&with, &gen, &type_vector_ic_count, is_interpreted);
  *ic_total_count += type_vector_ic_count;
  *ic_with_type_info_count += with;
  *ic_generic_count += gen;

  if (*ic_total_count > 0) {
    *type_info_percentage = 100 * *ic_with_type_info_count / *ic_total_count;
    *generic_percentage = 100 * *ic_generic_count / *ic_total_count;
  } else {
    *type_info_percentage = 100;  // Compared against lower bound.
    *generic_percentage = 0;      // Compared against upper bound.
  }
}

static void TraceRecompile(JSFunction* function, const char* reason,
                           const char* type) {
  if (FLAG_trace_opt &&
      function->shared()->PassesFilter(FLAG_hydrogen_filter)) {
    PrintF("[marking ");
    function->ShortPrint();
    PrintF(" for %s recompilation, reason: %s", type, reason);
    if (FLAG_type_info_threshold > 0) {
      int typeinfo, generic, total, type_percentage, generic_percentage;
      GetICCounts(function, &typeinfo, &generic, &total, &type_percentage,
                  &generic_percentage);
      PrintF(", ICs with typeinfo: %d/%d (%d%%)", typeinfo, total,
             type_percentage);
      PrintF(", generic ICs: %d/%d (%d%%)", generic, total, generic_percentage);
    }
    PrintF("]\n");
  }
}

void RuntimeProfiler::Optimize(JSFunction* function,
                               OptimizationReason reason) {
  DCHECK_NE(reason, OptimizationReason::kDoNotOptimize);
  TraceRecompile(function, OptimizationReasonToString(reason), "optimized");
  function->AttemptConcurrentOptimization();
}

void RuntimeProfiler::AttemptOnStackReplacement(JavaScriptFrame* frame,
                                                int loop_nesting_levels) {
  JSFunction* function = frame->function();
  SharedFunctionInfo* shared = function->shared();
  if (!FLAG_use_osr || !function->shared()->IsUserJavaScript()) {
    return;
  }

  // If the code is not optimizable, don't try OSR.
  if (shared->optimization_disabled()) return;

  // We are not prepared to do OSR for a function that already has an
  // allocated arguments object.  The optimized code would bypass it for
  // arguments accesses, which is unsound.  Don't try OSR.
  if (shared->uses_arguments()) return;

  // We're using on-stack replacement: modify unoptimized code so that
  // certain back edges in any unoptimized frame will trigger on-stack
  // replacement for that frame.
  //  - Ignition: Store new loop nesting level in BytecodeArray header.
  //  - FullCodegen: Patch back edges up to new level using BackEdgeTable.
  if (FLAG_trace_osr) {
    PrintF("[OSR - arming back edges in ");
    function->PrintName();
    PrintF("]\n");
  }

  if (frame->type() == StackFrame::JAVA_SCRIPT) {
    DCHECK(shared->HasBaselineCode());
    DCHECK(BackEdgeTable::Verify(shared->GetIsolate(), shared->code()));
    for (int i = 0; i < loop_nesting_levels; i++) {
      BackEdgeTable::Patch(isolate_, shared->code());
    }
  } else if (frame->type() == StackFrame::INTERPRETED) {
    DCHECK(shared->HasBytecodeArray());
    if (!FLAG_ignition_osr) return;  // Only use this when enabled.
    int level = shared->bytecode_array()->osr_loop_nesting_level();
    shared->bytecode_array()->set_osr_loop_nesting_level(
        Min(level + loop_nesting_levels, AbstractCode::kMaxLoopNestingMarker));
  } else {
    UNREACHABLE();
  }
}

void RuntimeProfiler::MaybeOptimizeFullCodegen(JSFunction* function,
                                               JavaScriptFrame* frame,
                                               int frame_count) {
  SharedFunctionInfo* shared = function->shared();
  Code* shared_code = shared->code();
  if (shared_code->kind() != Code::FUNCTION) return;
  if (function->IsInOptimizationQueue()) {
    if (FLAG_trace_opt_verbose) {
      PrintF("[function ");
      function->PrintName();
      PrintF(" is already in optimization queue]\n");
    }
    return;
  }

  if (FLAG_always_osr) {
    AttemptOnStackReplacement(frame, AbstractCode::kMaxLoopNestingMarker);
    // Fall through and do a normal optimized compile as well.
  } else if (!frame->is_optimized() &&
             (function->IsMarkedForOptimization() ||
              function->IsMarkedForConcurrentOptimization() ||
              function->IsOptimized())) {
    // Attempt OSR if we are still running unoptimized code even though the
    // the function has long been marked or even already been optimized.
    int ticks = shared_code->profiler_ticks();
    int64_t allowance =
        kOSRCodeSizeAllowanceBase +
        static_cast<int64_t>(ticks) * kOSRCodeSizeAllowancePerTick;
    if (shared_code->CodeSize() > allowance &&
        ticks < Code::ProfilerTicksField::kMax) {
      shared_code->set_profiler_ticks(ticks + 1);
    } else {
      AttemptOnStackReplacement(frame);
    }
    return;
  }

  // Only record top-level code on top of the execution stack and
  // avoid optimizing excessively large scripts since top-level code
  // will be executed only once.
  const int kMaxToplevelSourceSize = 10 * 1024;
  if (shared->is_toplevel() &&
      (frame_count > 1 || shared->SourceSize() > kMaxToplevelSourceSize)) {
    return;
  }

  // Do not record non-optimizable functions.
  if (shared->optimization_disabled()) {
    if (shared->deopt_count() >= FLAG_max_opt_count) {
      // If optimization was disabled due to many deoptimizations,
      // then check if the function is hot and try to reenable optimization.
      int ticks = shared_code->profiler_ticks();
      if (ticks >= kProfilerTicksBeforeReenablingOptimization) {
        shared_code->set_profiler_ticks(0);
        shared->TryReenableOptimization();
      } else {
        shared_code->set_profiler_ticks(ticks + 1);
      }
    }
    return;
  }
  if (frame->is_optimized()) return;

  int ticks = shared_code->profiler_ticks();

  if (ticks >= kProfilerTicksBeforeOptimization) {
    int typeinfo, generic, total, type_percentage, generic_percentage;
    GetICCounts(function, &typeinfo, &generic, &total, &type_percentage,
                &generic_percentage);
    if (type_percentage >= FLAG_type_info_threshold &&
        generic_percentage <= FLAG_generic_ic_threshold) {
      // If this particular function hasn't had any ICs patched for enough
      // ticks, optimize it now.
      Optimize(function, OptimizationReason::kHotAndStable);
    } else if (ticks >= kTicksWhenNotEnoughTypeInfo) {
      Optimize(function, OptimizationReason::kHotWithoutMuchTypeInfo);
    } else {
      shared_code->set_profiler_ticks(ticks + 1);
      if (FLAG_trace_opt_verbose) {
        PrintF("[not yet optimizing ");
        function->PrintName();
        PrintF(", not enough type info: %d/%d (%d%%)]\n", typeinfo, total,
               type_percentage);
      }
    }
  } else if (!any_ic_changed_ &&
             shared_code->instruction_size() < kMaxSizeEarlyOpt) {
    // If no IC was patched since the last tick and this function is very
    // small, optimistically optimize it now.
    int typeinfo, generic, total, type_percentage, generic_percentage;
    GetICCounts(function, &typeinfo, &generic, &total, &type_percentage,
                &generic_percentage);
    if (type_percentage >= FLAG_type_info_threshold &&
        generic_percentage <= FLAG_generic_ic_threshold) {
      Optimize(function, OptimizationReason::kSmallFunction);
    } else {
      shared_code->set_profiler_ticks(ticks + 1);
    }
  } else {
    shared_code->set_profiler_ticks(ticks + 1);
  }
}

void RuntimeProfiler::MaybeOptimizeIgnition(JSFunction* function,
                                            JavaScriptFrame* frame) {
  if (function->IsInOptimizationQueue()) {
    if (FLAG_trace_opt_verbose) {
      PrintF("[function ");
      function->PrintName();
      PrintF(" is already in optimization queue]\n");
    }
    return;
  }

  if (FLAG_always_osr) {
    AttemptOnStackReplacement(frame, AbstractCode::kMaxLoopNestingMarker);
    // Fall through and do a normal optimized compile as well.
  } else if (MaybeOSRIgnition(function, frame)) {
    return;
  }

  SharedFunctionInfo* shared = function->shared();
  int ticks = shared->profiler_ticks();

  if (shared->optimization_disabled()) {
    if (shared->deopt_count() >= FLAG_max_opt_count) {
      // If optimization was disabled due to many deoptimizations,
      // then check if the function is hot and try to reenable optimization.
      if (ticks >= kProfilerTicksBeforeReenablingOptimization) {
        shared->set_profiler_ticks(0);
        shared->TryReenableOptimization();
      }
    }
    return;
  }

  if (frame->is_optimized()) return;

  OptimizationReason reason = ShouldOptimizeIgnition(function, frame);

  if (reason != OptimizationReason::kDoNotOptimize) {
    Optimize(function, reason);
  }
}

bool RuntimeProfiler::MaybeOSRIgnition(JSFunction* function,
                                       JavaScriptFrame* frame) {
  SharedFunctionInfo* shared = function->shared();
  int ticks = shared->profiler_ticks();

  // TODO(rmcilroy): Also ensure we only OSR top-level code if it is smaller
  // than kMaxToplevelSourceSize.

  if (!frame->is_optimized() &&
      (function->IsMarkedForOptimization() ||
       function->IsMarkedForConcurrentOptimization() ||
       function->IsOptimized())) {
    // Attempt OSR if we are still running interpreted code even though the
    // the function has long been marked or even already been optimized.
    int64_t allowance =
        kOSRCodeSizeAllowanceBaseIgnition +
        static_cast<int64_t>(ticks) * kOSRCodeSizeAllowancePerTickIgnition;
    if (shared->bytecode_array()->Size() <= allowance) {
      AttemptOnStackReplacement(frame);
    }
    return true;
  }
  return false;
}

OptimizationReason RuntimeProfiler::ShouldOptimizeIgnition(
    JSFunction* function, JavaScriptFrame* frame) {
  SharedFunctionInfo* shared = function->shared();
  int ticks = shared->profiler_ticks();

  if (shared->bytecode_array()->Size() > kMaxSizeOptIgnition) {
    return OptimizationReason::kDoNotOptimize;
  }

  if (ticks >= kProfilerTicksBeforeOptimization) {
    int typeinfo, generic, total, type_percentage, generic_percentage;
    GetICCounts(function, &typeinfo, &generic, &total, &type_percentage,
                &generic_percentage);
    if (type_percentage >= FLAG_type_info_threshold) {
      // If this particular function hasn't had any ICs patched for enough
      // ticks, optimize it now.
      return OptimizationReason::kHotAndStable;
    } else if (ticks >= kTicksWhenNotEnoughTypeInfo) {
      return OptimizationReason::kHotWithoutMuchTypeInfo;
    } else {
      if (FLAG_trace_opt_verbose) {
        PrintF("[not yet optimizing ");
        function->PrintName();
        PrintF(", not enough type info: %d/%d (%d%%)]\n", typeinfo, total,
               type_percentage);
      }
      return OptimizationReason::kDoNotOptimize;
    }
  } else if (!any_ic_changed_ &&
             shared->bytecode_array()->Size() < kMaxSizeEarlyOptIgnition) {
    // If no IC was patched since the last tick and this function is very
    // small, optimistically optimize it now.
    int typeinfo, generic, total, type_percentage, generic_percentage;
    GetICCounts(function, &typeinfo, &generic, &total, &type_percentage,
                &generic_percentage);
    if (type_percentage >= FLAG_type_info_threshold) {
      return OptimizationReason::kSmallFunction;
    }
  }
  return OptimizationReason::kDoNotOptimize;
}

void RuntimeProfiler::MarkCandidatesForOptimization() {
  HandleScope scope(isolate_);

  if (!isolate_->use_crankshaft()) return;

  DisallowHeapAllocation no_gc;

  // Run through the JavaScript frames and collect them. If we already
  // have a sample of the function, we mark it for optimizations
  // (eagerly or lazily).
  int frame_count = 0;
  int frame_count_limit = FLAG_frame_count;
  for (JavaScriptFrameIterator it(isolate_);
       frame_count++ < frame_count_limit && !it.done();
       it.Advance()) {
    JavaScriptFrame* frame = it.frame();
    JSFunction* function = frame->function();

    if (function->shared()->IsInterpreted()) {
      MaybeOptimizeIgnition(function, frame);
    } else {
      MaybeOptimizeFullCodegen(function, frame, frame_count);
    }

    // Update shared function info ticks after checking for whether functions
    // should be optimized to keep FCG (which updates ticks on code) and
    // Ignition (which updates ticks on shared function info) in sync.
    List<SharedFunctionInfo*> functions(4);
    frame->GetFunctions(&functions);
    for (int i = functions.length(); --i >= 0;) {
      SharedFunctionInfo* shared_function_info = functions[i];
      int ticks = shared_function_info->profiler_ticks();
      if (ticks < Smi::kMaxValue) {
        shared_function_info->set_profiler_ticks(ticks + 1);
      }
    }
  }
  any_ic_changed_ = false;
}

}  // namespace internal
}  // namespace v8
