// 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.

#ifndef V8_HEAP_ARRAY_BUFFER_SWEEPER_H_
#define V8_HEAP_ARRAY_BUFFER_SWEEPER_H_

#include "src/base/platform/mutex.h"
#include "src/objects/js-array-buffer.h"
#include "src/tasks/cancelable-task.h"

namespace v8 {
namespace internal {

class ArrayBufferExtension;
class Heap;

// Singly linked-list of ArrayBufferExtensions that stores head and tail of the
// list to allow for concatenation of lists.
struct ArrayBufferList {
  ArrayBufferList() : head_(nullptr), tail_(nullptr), bytes_(0) {}

  ArrayBufferExtension* head_;
  ArrayBufferExtension* tail_;
  size_t bytes_;

  bool IsEmpty() {
    DCHECK_IMPLIES(head_, tail_);
    return head_ == nullptr;
  }

  size_t Bytes() { return bytes_; }
  size_t BytesSlow();

  void Reset() {
    head_ = tail_ = nullptr;
    bytes_ = 0;
  }

  void Append(ArrayBufferExtension* extension);
  void Append(ArrayBufferList* list);

  V8_EXPORT_PRIVATE bool Contains(ArrayBufferExtension* extension);
};

// The ArrayBufferSweeper iterates and deletes ArrayBufferExtensions
// concurrently to the application.
class ArrayBufferSweeper {
 public:
  explicit ArrayBufferSweeper(Heap* heap)
      : heap_(heap),
        sweeping_in_progress_(false),
        freed_bytes_(0),
        young_bytes_(0),
        old_bytes_(0) {}
  ~ArrayBufferSweeper() { ReleaseAll(); }

  void EnsureFinished();
  void RequestSweepYoung();
  void RequestSweepFull();

  void Append(JSArrayBuffer object, ArrayBufferExtension* extension);

  ArrayBufferList young() { return young_; }
  ArrayBufferList old() { return old_; }

  size_t YoungBytes();
  size_t OldBytes();

 private:
  enum class SweepingScope { kYoung, kFull };

  enum class SweepingState { kInProgress, kDone };

  struct SweepingJob {
    ArrayBufferSweeper* sweeper_;
    CancelableTaskManager::Id id_;
    std::atomic<SweepingState> state_;
    ArrayBufferList young_;
    ArrayBufferList old_;
    SweepingScope scope_;

    SweepingJob(ArrayBufferSweeper* sweeper, ArrayBufferList young,
                ArrayBufferList old, SweepingScope scope)
        : sweeper_(sweeper),
          id_(0),
          state_(SweepingState::kInProgress),
          young_(young),
          old_(old),
          scope_(scope) {}

    void Sweep();
    void SweepYoung();
    void SweepFull();
    ArrayBufferList SweepListFull(ArrayBufferList* list);
  };

  base::Optional<SweepingJob> job_;

  void Merge();
  void AdjustCountersAndMergeIfPossible();

  void DecrementExternalMemoryCounters();
  void IncrementExternalMemoryCounters(size_t bytes);
  void IncrementFreedBytes(size_t bytes);
  void IncrementFreedYoungBytes(size_t bytes);

  void RequestSweep(SweepingScope sweeping_task);
  void Prepare(SweepingScope sweeping_task);

  ArrayBufferList SweepYoungGen();
  void SweepOldGen(ArrayBufferExtension* extension);

  void ReleaseAll();
  void ReleaseAll(ArrayBufferList* extension);

  Heap* const heap_;
  bool sweeping_in_progress_;
  base::Mutex sweeping_mutex_;
  base::ConditionVariable job_finished_;
  std::atomic<size_t> freed_bytes_;

  ArrayBufferList young_;
  ArrayBufferList old_;

  size_t young_bytes_;
  size_t old_bytes_;
};

}  // namespace internal
}  // namespace v8

#endif  // V8_HEAP_ARRAY_BUFFER_SWEEPER_H_
