// Copyright 2017 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/debug/debug-type-profile.h"

#include "src/execution/isolate.h"
#include "src/objects/feedback-vector.h"
#include "src/objects/objects-inl.h"
#include "src/objects/objects.h"

namespace v8 {
namespace internal {

std::unique_ptr<TypeProfile> TypeProfile::Collect(Isolate* isolate) {
  std::unique_ptr<TypeProfile> result(new TypeProfile());

  // Feedback vectors are already listed to prevent losing them to GC.
  DCHECK(isolate->factory()
             ->feedback_vectors_for_profiling_tools()
             ->IsArrayList());
  Handle<ArrayList> list = Handle<ArrayList>::cast(
      isolate->factory()->feedback_vectors_for_profiling_tools());

  Script::Iterator scripts(isolate);

  for (Script script = scripts.Next(); !script.is_null();
       script = scripts.Next()) {
    if (!script.IsUserJavaScript()) {
      continue;
    }

    Handle<Script> script_handle(script, isolate);

    TypeProfileScript type_profile_script(script_handle);
    std::vector<TypeProfileEntry>* entries = &type_profile_script.entries;

    // TODO(franzih): Sort the vectors by script first instead of iterating
    // the list multiple times.
    for (int i = 0; i < list->Length(); i++) {
      FeedbackVector vector = FeedbackVector::cast(list->Get(i));
      SharedFunctionInfo info = vector.shared_function_info();
      DCHECK(info.IsSubjectToDebugging());

      // Match vectors with script.
      if (script != info.script()) {
        continue;
      }
      if (!info.HasFeedbackMetadata() || info.feedback_metadata().is_empty() ||
          !info.feedback_metadata().HasTypeProfileSlot()) {
        continue;
      }
      FeedbackSlot slot = vector.GetTypeProfileSlot();
      FeedbackNexus nexus(vector, slot);
      Handle<String> name(info.DebugName(), isolate);
      std::vector<int> source_positions = nexus.GetSourcePositions();
      for (int position : source_positions) {
        DCHECK_GE(position, 0);
        entries->emplace_back(position, nexus.GetTypesForSourcePositions(
                                            static_cast<uint32_t>(position)));
      }

      // Releases type profile data collected so far.
      nexus.ResetTypeProfile();
    }
    if (!entries->empty()) {
      result->emplace_back(type_profile_script);
    }
  }
  return result;
}

void TypeProfile::SelectMode(Isolate* isolate, debug::TypeProfileMode mode) {
  HandleScope handle_scope(isolate);

  if (mode == debug::TypeProfileMode::kNone) {
    if (!isolate->factory()
             ->feedback_vectors_for_profiling_tools()
             ->IsUndefined(isolate)) {
      // Release type profile data collected so far.

      // Feedback vectors are already listed to prevent losing them to GC.
      DCHECK(isolate->factory()
                 ->feedback_vectors_for_profiling_tools()
                 ->IsArrayList());
      Handle<ArrayList> list = Handle<ArrayList>::cast(
          isolate->factory()->feedback_vectors_for_profiling_tools());

      for (int i = 0; i < list->Length(); i++) {
        FeedbackVector vector = FeedbackVector::cast(list->Get(i));
        SharedFunctionInfo info = vector.shared_function_info();
        DCHECK(info.IsSubjectToDebugging());
        if (info.feedback_metadata().HasTypeProfileSlot()) {
          FeedbackSlot slot = vector.GetTypeProfileSlot();
          FeedbackNexus nexus(vector, slot);
          nexus.ResetTypeProfile();
        }
      }

      // Delete the feedback vectors from the list if they're not used by code
      // coverage.
      if (isolate->is_best_effort_code_coverage()) {
        isolate->SetFeedbackVectorsForProfilingTools(
            ReadOnlyRoots(isolate).undefined_value());
      }
    }
  } else {
    DCHECK_EQ(debug::TypeProfileMode::kCollect, mode);
    isolate->MaybeInitializeVectorListFromHeap();
  }
  isolate->set_type_profile_mode(mode);
}

}  // namespace internal
}  // namespace v8
