// Copyright 2020 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/heap/finalization-registry-cleanup-task.h"

#include "src/execution/frames.h"
#include "src/execution/interrupts-scope.h"
#include "src/execution/stack-guard.h"
#include "src/execution/v8threads.h"
#include "src/heap/heap-inl.h"
#include "src/objects/js-weak-refs-inl.h"
#include "src/tracing/trace-event.h"

namespace v8 {
namespace internal {

FinalizationRegistryCleanupTask::FinalizationRegistryCleanupTask(Heap* heap)
    : CancelableTask(heap->isolate()), heap_(heap) {}

void FinalizationRegistryCleanupTask::SlowAssertNoActiveJavaScript() {
#ifdef ENABLE_SLOW_DCHECKS
  class NoActiveJavaScript : public ThreadVisitor {
   public:
    void VisitThread(Isolate* isolate, ThreadLocalTop* top) override {
      for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) {
        DCHECK(!it.frame()->is_java_script());
      }
    }
  };
  NoActiveJavaScript no_active_js_visitor;
  Isolate* isolate = heap_->isolate();
  no_active_js_visitor.VisitThread(isolate, isolate->thread_local_top());
  isolate->thread_manager()->IterateArchivedThreads(&no_active_js_visitor);
#endif  // ENABLE_SLOW_DCHECKS
}

void FinalizationRegistryCleanupTask::RunInternal() {
  Isolate* isolate = heap_->isolate();
  SlowAssertNoActiveJavaScript();

  TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8",
                                "V8.FinalizationRegistryCleanupTask");

  HandleScope handle_scope(isolate);
  Handle<JSFinalizationRegistry> finalization_registry;
  // There could be no dirty FinalizationRegistries. When a context is disposed
  // by the embedder, its FinalizationRegistries are removed from the dirty
  // list.
  if (!heap_->DequeueDirtyJSFinalizationRegistry().ToHandle(
          &finalization_registry)) {
    return;
  }
  finalization_registry->set_scheduled_for_cleanup(false);

  // Since FinalizationRegistry cleanup callbacks are scheduled by V8, enter the
  // FinalizationRegistry's context.
  Handle<Context> context(
      Context::cast(finalization_registry->native_context()), isolate);
  Handle<Object> callback(finalization_registry->cleanup(), isolate);
  v8::Context::Scope context_scope(v8::Utils::ToLocal(context));
  v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate));
  catcher.SetVerbose(true);

  // Exceptions are reported via the message handler. This is ensured by the
  // verbose TryCatch.
  //
  // Cleanup is interrupted if there is an exception. The HTML spec calls for a
  // microtask checkpoint after each cleanup task, so the task should return
  // after an exception so the host can perform a microtask checkpoint. In case
  // of exception, check if the FinalizationRegistry still needs cleanup
  // and should be requeued.
  //
  // TODO(syg): Implement better scheduling for finalizers.
  InvokeFinalizationRegistryCleanupFromTask(context, finalization_registry,
                                            callback);
  if (finalization_registry->NeedsCleanup() &&
      !finalization_registry->scheduled_for_cleanup()) {
    auto nop = [](HeapObject, ObjectSlot, Object) {};
    heap_->EnqueueDirtyJSFinalizationRegistry(*finalization_registry, nop);
  }

  // Repost if there are remaining dirty FinalizationRegistries.
  heap_->set_is_finalization_registry_cleanup_task_posted(false);
  heap_->PostFinalizationRegistryCleanupTaskIfNeeded();
}

}  // namespace internal
}  // namespace v8
