/*
 * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_RUNTIME_STACKWATERMARK_HPP
#define SHARE_RUNTIME_STACKWATERMARK_HPP

#include "memory/allStatic.hpp"
#include "runtime/mutex.hpp"
#include "runtime/stackWatermarkKind.hpp"
#include "utilities/growableArray.hpp"

class frame;
class JavaThread;
class RegisterMap;
class StackWatermarkFramesIterator;

// The StackWatermark state is a tuple comprising the last epoch in which
// the watermark has been processed, and a boolean denoting whether the whole
// processing of the lazy snapshot has been processed or not. It is written
// in a way that can be used outside of locks, so that fast path checks can
// be performed without the need for any locking. The boolean can only be
// trusted if the epoch of the state is the same as the epoch_id() of the
// watermark. Incrementing the epoch_id() will implicitly initiate a new lazy
// stack snapshot, and trigger processing on it as needed, due to the cached
// epoch of the state being outdated. When the snapshot is_done for the current
// epoch_id(), there is no need to do anything further.
class StackWatermarkState : public AllStatic {
public:
  inline static bool is_done(uint32_t state) {
    return state & 1;
  }

  inline static uint32_t epoch(uint32_t state) {
    return state >> 1;
  }

  inline static uint32_t create(uint32_t epoch, bool is_done) {
    return (epoch << 1) | (is_done ? 1u : 0u);
  }
};

// The StackWatermark allows lazy incremental concurrent processing of a
// snapshot of a stack. The lazy and incremental nature is implemented by
// marking a frame (the watermark) from which returns (or other forms of
// unwinding) will take a slow path to perform additional processing
// required when exposing more frames that were part of the snapshot to
// the system. The watermark pointer always denotes the SP of the watermark.
// However, active frames can grow and shrink arbitrarily compared to the
// snapshot view that is being processed, due to things like c2i adapters,
// and various register saving techniques to get into the runtime. Therefore,
// in order to cope with the frames growing and shrinking, comparisons
// against the watermark are performed with the frame pointer of a given
// frame against the watermark (denoting the SP).
//
//  ----------
// |          |
// |  caller  |
// |          |
//  ----------
// |          | <-- frame fp  (always above the watermark of the same frame,
// |  callee  |                regardless of frame resizing)
// |          |
//  ----------  <-- watermark (callee SP from the snapshot, SP at the
//                             point of unwinding, might be above or below
//                             due to frame resizing)
class StackWatermark : public CHeapObj<mtThread> {
  friend class StackWatermarkFramesIterator;
protected:
  volatile uint32_t _state;
  volatile uintptr_t _watermark;
  StackWatermark* _next;
  JavaThread* _jt;
  StackWatermarkFramesIterator* _iterator;
  Mutex _lock;
  StackWatermarkKind _kind;
  GrowableArrayCHeap<StackWatermark*, mtThread> _linked_watermarks;

  void process_one();

  void update_watermark();
  void yield_processing();
  static bool has_barrier(const frame& f);
  void ensure_safe(const frame& f);
  bool is_frame_safe(const frame& f);

  // API for consumers of the stack watermark barrier.
  // The rule for consumers is: do not perform thread transitions
  // or take locks of rank >= special. This is all very special code.
  virtual uint32_t epoch_id() const = 0;
  virtual void process(const frame& f, RegisterMap& register_map, void* context) = 0;
  virtual void start_processing_impl(void* context);

  // Set process_on_iteration to false if you don't want to move the
  // watermark when new frames are discovered from stack walkers, as
  // opposed to due to frames being unwound by the owning thread.
  virtual bool process_on_iteration() { return true; }

  void process_linked_watermarks();

  bool processing_started(uint32_t state) const;
  bool processing_completed(uint32_t state) const;

public:
  StackWatermark(JavaThread* jt, StackWatermarkKind kind, uint32_t epoch);
  virtual ~StackWatermark();


  // StackWatermarkSet support
  StackWatermarkKind kind() const { return _kind; }
  StackWatermark* next() const { return _next; }
  void set_next(StackWatermark* n) { _next = n; }

  void push_linked_watermark(StackWatermark* watermark);
  void pop_linked_watermark();

  uintptr_t watermark();
  uintptr_t last_processed();
  uintptr_t last_processed_raw();

  bool processing_started() const;
  bool processing_started_acquire() const;
  bool processing_completed() const;
  bool processing_completed_acquire() const;

  void before_unwind();
  void after_unwind();

  void on_iteration(const frame& f);
  void on_safepoint();
  void start_processing();
  void finish_processing(void* context);

  void assert_is_frame_safe(const frame& f) NOT_DEBUG_RETURN;
};

#endif // SHARE_RUNTIME_STACKWATERMARK_HPP
