/*
 * Copyright (c) 1997, 2025, 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_OPTO_CALLNODE_HPP
#define SHARE_OPTO_CALLNODE_HPP

#include "opto/connode.hpp"
#include "opto/mulnode.hpp"
#include "opto/multnode.hpp"
#include "opto/opcodes.hpp"
#include "opto/phaseX.hpp"
#include "opto/replacednodes.hpp"
#include "opto/type.hpp"
#include "utilities/growableArray.hpp"

// Portions of code courtesy of Clifford Click

// Optimization - Graph Style

class NamedCounter;
class MultiNode;
class  SafePointNode;
class   CallNode;
class     CallJavaNode;
class       CallStaticJavaNode;
class       CallDynamicJavaNode;
class     CallRuntimeNode;
class       CallLeafNode;
class         CallLeafNoFPNode;
class         CallLeafVectorNode;
class     AllocateNode;
class       AllocateArrayNode;
class     AbstractLockNode;
class       LockNode;
class       UnlockNode;
class FastLockNode;

//------------------------------StartNode--------------------------------------
// The method start node
class StartNode : public MultiNode {
  virtual bool cmp( const Node &n ) const;
  virtual uint size_of() const; // Size is bigger
public:
  const TypeTuple *_domain;
  StartNode( Node *root, const TypeTuple *domain ) : MultiNode(2), _domain(domain) {
    init_class_id(Class_Start);
    init_req(0,this);
    init_req(1,root);
  }
  virtual int Opcode() const;
  virtual bool pinned() const { return true; };
  virtual const Type *bottom_type() const;
  virtual const TypePtr *adr_type() const { return TypePtr::BOTTOM; }
  virtual const Type* Value(PhaseGVN* phase) const;
  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
  virtual void  calling_convention( BasicType* sig_bt, VMRegPair *parm_reg, uint length ) const;
  virtual const RegMask &in_RegMask(uint) const;
  virtual Node *match( const ProjNode *proj, const Matcher *m );
  virtual uint ideal_reg() const { return 0; }
#ifndef PRODUCT
  virtual void  dump_spec(outputStream *st) const;
  virtual void  dump_compact_spec(outputStream *st) const;
#endif
};

//------------------------------StartOSRNode-----------------------------------
// The method start node for on stack replacement code
class StartOSRNode : public StartNode {
public:
  StartOSRNode( Node *root, const TypeTuple *domain ) : StartNode(root, domain) {}
  virtual int   Opcode() const;
  static  const TypeTuple *osr_domain();
};


//------------------------------ParmNode---------------------------------------
// Incoming parameters
class ParmNode : public ProjNode {
  static const char * const names[TypeFunc::Parms+1];
public:
  ParmNode( StartNode *src, uint con ) : ProjNode(src,con) {
    init_class_id(Class_Parm);
  }
  virtual int Opcode() const;
  virtual bool  is_CFG() const { return (_con == TypeFunc::Control); }
  virtual uint ideal_reg() const;
#ifndef PRODUCT
  virtual void dump_spec(outputStream *st) const;
  virtual void dump_compact_spec(outputStream *st) const;
#endif
};


//------------------------------ReturnNode-------------------------------------
// Return from subroutine node
class ReturnNode : public Node {
public:
  ReturnNode(uint edges, Node* cntrl, Node* i_o, Node* memory, Node* frameptr, Node* retadr);
  virtual int Opcode() const;
  virtual bool  is_CFG() const { return true; }
  virtual uint hash() const { return NO_HASH; }  // CFG nodes do not hash
  virtual bool depends_only_on_test() const { return false; }
  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
  virtual const Type* Value(PhaseGVN* phase) const;
  virtual uint ideal_reg() const { return NotAMachineReg; }
  virtual uint match_edge(uint idx) const;
#ifndef PRODUCT
  virtual void dump_req(outputStream *st = tty, DumpConfig* dc = nullptr) const;
#endif
};


//------------------------------RethrowNode------------------------------------
// Rethrow of exception at call site.  Ends a procedure before rethrowing;
// ends the current basic block like a ReturnNode.  Restores registers and
// unwinds stack.  Rethrow happens in the caller's method.
class RethrowNode : public Node {
 public:
  RethrowNode( Node *cntrl, Node *i_o, Node *memory, Node *frameptr, Node *ret_adr, Node *exception );
  virtual int Opcode() const;
  virtual bool  is_CFG() const { return true; }
  virtual uint hash() const { return NO_HASH; }  // CFG nodes do not hash
  virtual bool depends_only_on_test() const { return false; }
  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
  virtual const Type* Value(PhaseGVN* phase) const;
  virtual uint match_edge(uint idx) const;
  virtual uint ideal_reg() const { return NotAMachineReg; }
#ifndef PRODUCT
  virtual void dump_req(outputStream *st = tty, DumpConfig* dc = nullptr) const;
#endif
};


//------------------------------ForwardExceptionNode---------------------------
// Pop stack frame and jump to StubRoutines::forward_exception_entry()
class ForwardExceptionNode : public ReturnNode {
public:
  ForwardExceptionNode(Node* cntrl, Node* i_o, Node* memory, Node* frameptr, Node* retadr)
    : ReturnNode(TypeFunc::Parms, cntrl, i_o, memory, frameptr, retadr) {
  }

  virtual int Opcode() const;
};

//------------------------------TailCallNode-----------------------------------
// Pop stack frame and jump indirect
class TailCallNode : public ReturnNode {
public:
  TailCallNode( Node *cntrl, Node *i_o, Node *memory, Node *frameptr, Node *retadr, Node *target, Node *moop )
    : ReturnNode( TypeFunc::Parms+2, cntrl, i_o, memory, frameptr, retadr ) {
    init_req(TypeFunc::Parms, target);
    init_req(TypeFunc::Parms+1, moop);
  }

  virtual int Opcode() const;
  virtual uint match_edge(uint idx) const;
};

//------------------------------TailJumpNode-----------------------------------
// Pop stack frame and jump indirect
class TailJumpNode : public ReturnNode {
public:
  TailJumpNode( Node *cntrl, Node *i_o, Node *memory, Node *frameptr, Node *target, Node *ex_oop)
    : ReturnNode(TypeFunc::Parms+2, cntrl, i_o, memory, frameptr, Compile::current()->top()) {
    init_req(TypeFunc::Parms, target);
    init_req(TypeFunc::Parms+1, ex_oop);
  }

  virtual int Opcode() const;
  virtual uint match_edge(uint idx) const;
};

//-------------------------------JVMState-------------------------------------
// A linked list of JVMState nodes captures the whole interpreter state,
// plus GC roots, for all active calls at some call site in this compilation
// unit.  (If there is no inlining, then the list has exactly one link.)
// This provides a way to map the optimized program back into the interpreter,
// or to let the GC mark the stack.
class JVMState : public ResourceObj {
public:
  typedef enum {
    Reexecute_Undefined = -1, // not defined -- will be translated into false later
    Reexecute_False     =  0, // false       -- do not reexecute
    Reexecute_True      =  1  // true        -- reexecute the bytecode
  } ReexecuteState; //Reexecute State

private:
  JVMState*         _caller;    // List pointer for forming scope chains
  uint              _depth;     // One more than caller depth, or one.
  uint              _locoff;    // Offset to locals in input edge mapping
  uint              _stkoff;    // Offset to stack in input edge mapping
  uint              _monoff;    // Offset to monitors in input edge mapping
  uint              _scloff;    // Offset to fields of scalar objs in input edge mapping
  uint              _endoff;    // Offset to end of input edge mapping
  uint              _sp;        // Java Expression Stack Pointer for this state
  int               _bci;       // Byte Code Index of this JVM point
  ReexecuteState    _reexecute; // Whether this bytecode need to be re-executed
  ciMethod*         _method;    // Method Pointer
  ciInstance*       _receiver_info; // Constant receiver instance for compiled lambda forms
  SafePointNode*    _map;       // Map node associated with this scope
public:
  friend class Compile;
  friend class PreserveReexecuteState;

  // Because JVMState objects live over the entire lifetime of the
  // Compile object, they are allocated into the comp_arena, which
  // does not get resource marked or reset during the compile process
  void *operator new( size_t x, Compile* C ) throw() { return C->comp_arena()->Amalloc(x); }
  void operator delete( void * ) { } // fast deallocation

  // Create a new JVMState, ready for abstract interpretation.
  JVMState(ciMethod* method, JVMState* caller);
  JVMState(int stack_size);  // root state; has a null method

  // Access functions for the JVM
  // ... --|--- loc ---|--- stk ---|--- arg ---|--- mon ---|--- scl ---|
  //       \ locoff    \ stkoff    \ argoff    \ monoff    \ scloff    \ endoff
  uint              locoff() const { return _locoff; }
  uint              stkoff() const { return _stkoff; }
  uint              argoff() const { return _stkoff + _sp; }
  uint              monoff() const { return _monoff; }
  uint              scloff() const { return _scloff; }
  uint              endoff() const { return _endoff; }
  uint              oopoff() const { return debug_end(); }

  int            loc_size() const { return stkoff() - locoff(); }
  int            stk_size() const { return monoff() - stkoff(); }
  int            mon_size() const { return scloff() - monoff(); }
  int            scl_size() const { return endoff() - scloff(); }

  bool        is_loc(uint i) const { return locoff() <= i && i < stkoff(); }
  bool        is_stk(uint i) const { return stkoff() <= i && i < monoff(); }
  bool        is_mon(uint i) const { return monoff() <= i && i < scloff(); }
  bool        is_scl(uint i) const { return scloff() <= i && i < endoff(); }

  uint                      sp() const { return _sp; }
  int                      bci() const { return _bci; }
  bool        should_reexecute() const { return _reexecute==Reexecute_True; }
  bool  is_reexecute_undefined() const { return _reexecute==Reexecute_Undefined; }
  bool              has_method() const { return _method != nullptr; }
  ciMethod*             method() const { assert(has_method(), ""); return _method; }
  ciInstance*    receiver_info() const { assert(has_method(), ""); return _receiver_info; }
  JVMState*             caller() const { return _caller; }
  SafePointNode*           map() const { return _map; }
  uint                   depth() const { return _depth; }
  uint             debug_start() const; // returns locoff of root caller
  uint               debug_end() const; // returns endoff of self
  uint              debug_size() const {
    return loc_size() + sp() + mon_size() + scl_size();
  }
  uint        debug_depth()  const; // returns sum of debug_size values at all depths

  // Returns the JVM state at the desired depth (1 == root).
  JVMState* of_depth(int d) const;

  // Tells if two JVM states have the same call chain (depth, methods, & bcis).
  bool same_calls_as(const JVMState* that) const;

  // Monitors (monitors are stored as (boxNode, objNode) pairs
  enum { logMonitorEdges = 1 };
  int  nof_monitors()              const { return mon_size() >> logMonitorEdges; }
  int  monitor_depth()             const { return nof_monitors() + (caller() ? caller()->monitor_depth() : 0); }
  int  monitor_box_offset(int idx) const { return monoff() + (idx << logMonitorEdges) + 0; }
  int  monitor_obj_offset(int idx) const { return monoff() + (idx << logMonitorEdges) + 1; }
  bool is_monitor_box(uint off)    const {
    assert(is_mon(off), "should be called only for monitor edge");
    return (0 == bitfield(off - monoff(), 0, logMonitorEdges));
  }
  bool is_monitor_use(uint off)    const { return (is_mon(off)
                                                   && is_monitor_box(off))
                                             || (caller() && caller()->is_monitor_use(off)); }

  // Initialization functions for the JVM
  void              set_locoff(uint off) { _locoff = off; }
  void              set_stkoff(uint off) { _stkoff = off; }
  void              set_monoff(uint off) { _monoff = off; }
  void              set_scloff(uint off) { _scloff = off; }
  void              set_endoff(uint off) { _endoff = off; }
  void              set_offsets(uint off) {
    _locoff = _stkoff = _monoff = _scloff = _endoff = off;
  }
  void              set_map(SafePointNode* map) { _map = map; }
  void              bind_map(SafePointNode* map); // set_map() and set_jvms() for the SafePointNode
  void              set_sp(uint sp) { _sp = sp; }
                    // _reexecute is initialized to "undefined" for a new bci
  void              set_bci(int bci) {if(_bci != bci)_reexecute=Reexecute_Undefined; _bci = bci; }
  void              set_should_reexecute(bool reexec) {_reexecute = reexec ? Reexecute_True : Reexecute_False;}
  void              set_receiver_info(ciInstance* recv) { assert(has_method() || recv == nullptr, ""); _receiver_info = recv; }

  // Miscellaneous utility functions
  JVMState* clone_deep(Compile* C) const;    // recursively clones caller chain
  JVMState* clone_shallow(Compile* C) const; // retains uncloned caller
  void      set_map_deep(SafePointNode *map);// reset map for all callers
  void      adapt_position(int delta);       // Adapt offsets in in-array after adding an edge.
  int       interpreter_frame_size() const;
  ciInstance* compute_receiver_info(ciMethod* callee) const;

#ifndef PRODUCT
  void      print_method_with_lineno(outputStream* st, bool show_name) const;
  void      format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const;
  void      dump_spec(outputStream *st) const;
  void      dump_on(outputStream* st) const;
  void      dump() const {
    dump_on(tty);
  }
#endif
};

//------------------------------SafePointNode----------------------------------
// A SafePointNode is a subclass of a MultiNode for convenience (and
// potential code sharing) only - conceptually it is independent of
// the Node semantics.
class SafePointNode : public MultiNode {
  friend JVMState;
  friend class GraphKit;

  virtual bool           cmp( const Node &n ) const;
  virtual uint           size_of() const;       // Size is bigger

protected:
  JVMState* const _jvms;      // Pointer to list of JVM State objects
  // Many calls take *all* of memory as input,
  // but some produce a limited subset of that memory as output.
  // The adr_type reports the call's behavior as a store, not a load.
  const TypePtr*  _adr_type;  // What type of memory does this node produce?
  ReplacedNodes   _replaced_nodes; // During parsing: list of pair of nodes from calls to GraphKit::replace_in_map()
  bool            _has_ea_local_in_scope; // NoEscape or ArgEscape objects in JVM States

  void set_jvms(JVMState* s) {
  assert(s != nullptr, "assign null value to _jvms");
    *(JVMState**)&_jvms = s;  // override const attribute in the accessor
  }
public:
  SafePointNode(uint edges, JVMState* jvms,
                // A plain safepoint advertises no memory effects (null):
                const TypePtr* adr_type = nullptr)
    : MultiNode( edges ),
      _jvms(jvms),
      _adr_type(adr_type),
      _has_ea_local_in_scope(false)
  {
    init_class_id(Class_SafePoint);
  }

  JVMState* jvms() const { return _jvms; }
  virtual bool needs_deep_clone_jvms(Compile* C) { return false; }
  void clone_jvms(Compile* C) {
    if (jvms() != nullptr) {
      if (needs_deep_clone_jvms(C)) {
        set_jvms(jvms()->clone_deep(C));
        jvms()->set_map_deep(this);
      } else {
        jvms()->clone_shallow(C)->bind_map(this);
      }
    }
  }

 private:
  void verify_input(const JVMState* jvms, uint idx) const {
    assert(verify_jvms(jvms), "jvms must match");
    Node* n = in(idx);
    assert((!n->bottom_type()->isa_long() && !n->bottom_type()->isa_double()) ||
           in(idx + 1)->is_top(), "2nd half of long/double");
  }

 public:
  // Functionality from old debug nodes which has changed
  Node* local(const JVMState* jvms, uint idx) const {
    uint loc_idx = jvms->locoff() + idx;
    assert(jvms->is_loc(loc_idx), "not a local slot");
    verify_input(jvms, loc_idx);
    return in(loc_idx);
  }
  Node* stack(const JVMState* jvms, uint idx) const {
    uint stk_idx = jvms->stkoff() + idx;
    assert(jvms->is_stk(stk_idx), "not a stack slot");
    verify_input(jvms, stk_idx);
    return in(stk_idx);
  }
  Node* argument(const JVMState* jvms, uint idx) const {
    uint arg_idx = jvms->argoff() + idx;
    assert(jvms->is_stk(arg_idx), "not an argument slot");
    verify_input(jvms, arg_idx);
    return in(jvms->argoff() + idx);
  }
  Node* monitor_box(const JVMState* jvms, uint idx) const {
    assert(verify_jvms(jvms), "jvms must match");
    uint mon_box_idx = jvms->monitor_box_offset(idx);
    assert(jvms->is_monitor_box(mon_box_idx), "not a monitor box offset");
    return in(mon_box_idx);
  }
  Node* monitor_obj(const JVMState* jvms, uint idx) const {
    assert(verify_jvms(jvms), "jvms must match");
    uint mon_obj_idx = jvms->monitor_obj_offset(idx);
    assert(jvms->is_mon(mon_obj_idx) && !jvms->is_monitor_box(mon_obj_idx), "not a monitor obj offset");
    return in(mon_obj_idx);
  }

  void  set_local(const JVMState* jvms, uint idx, Node *c);

  void  set_stack(const JVMState* jvms, uint idx, Node *c) {
    assert(verify_jvms(jvms), "jvms must match");
    set_req(jvms->stkoff() + idx, c);
  }
  void  set_argument(const JVMState* jvms, uint idx, Node *c) {
    assert(verify_jvms(jvms), "jvms must match");
    set_req(jvms->argoff() + idx, c);
  }
  void ensure_stack(JVMState* jvms, uint stk_size) {
    assert(verify_jvms(jvms), "jvms must match");
    int grow_by = (int)stk_size - (int)jvms->stk_size();
    if (grow_by > 0)  grow_stack(jvms, grow_by);
  }
  void grow_stack(JVMState* jvms, uint grow_by);
  // Handle monitor stack
  void push_monitor( const FastLockNode *lock );
  void pop_monitor ();
  Node *peek_monitor_box() const;
  Node *peek_monitor_obj() const;
  // Peek Operand Stacks, JVMS 2.6.2
  Node* peek_operand(uint off = 0) const;

  // Access functions for the JVM
  Node *control  () const { return in(TypeFunc::Control  ); }
  Node *i_o      () const { return in(TypeFunc::I_O      ); }
  Node *memory   () const { return in(TypeFunc::Memory   ); }
  Node *returnadr() const { return in(TypeFunc::ReturnAdr); }
  Node *frameptr () const { return in(TypeFunc::FramePtr ); }

  void set_control  ( Node *c ) { set_req(TypeFunc::Control,c); }
  void set_i_o      ( Node *c ) { set_req(TypeFunc::I_O    ,c); }
  void set_memory   ( Node *c ) { set_req(TypeFunc::Memory ,c); }

  MergeMemNode* merged_memory() const {
    return in(TypeFunc::Memory)->as_MergeMem();
  }

  // The parser marks useless maps as dead when it's done with them:
  bool is_killed() { return in(TypeFunc::Control) == nullptr; }

  // Exception states bubbling out of subgraphs such as inlined calls
  // are recorded here.  (There might be more than one, hence the "next".)
  // This feature is used only for safepoints which serve as "maps"
  // for JVM states during parsing, intrinsic expansion, etc.
  SafePointNode*         next_exception() const;
  void               set_next_exception(SafePointNode* n);
  bool                   has_exceptions() const { return next_exception() != nullptr; }

  // Helper methods to operate on replaced nodes
  ReplacedNodes replaced_nodes() const {
    return _replaced_nodes;
  }

  void set_replaced_nodes(ReplacedNodes replaced_nodes) {
    _replaced_nodes = replaced_nodes;
  }

  void clone_replaced_nodes() {
    _replaced_nodes.clone();
  }
  void record_replaced_node(Node* initial, Node* improved) {
    _replaced_nodes.record(initial, improved);
  }
  void transfer_replaced_nodes_from(SafePointNode* sfpt, uint idx = 0) {
    _replaced_nodes.transfer_from(sfpt->_replaced_nodes, idx);
  }
  void delete_replaced_nodes() {
    _replaced_nodes.reset();
  }
  void apply_replaced_nodes(uint idx) {
    _replaced_nodes.apply(this, idx);
  }
  void merge_replaced_nodes_with(SafePointNode* sfpt) {
    _replaced_nodes.merge_with(sfpt->_replaced_nodes);
  }
  bool has_replaced_nodes() const {
    return !_replaced_nodes.is_empty();
  }
  void set_has_ea_local_in_scope(bool b) {
    _has_ea_local_in_scope = b;
  }
  bool has_ea_local_in_scope() const {
    return _has_ea_local_in_scope;
  }

  void disconnect_from_root(PhaseIterGVN *igvn);

  // Standard Node stuff
  virtual int            Opcode() const;
  virtual bool           pinned() const { return true; }
  virtual const Type*    Value(PhaseGVN* phase) const;
  virtual const Type*    bottom_type() const { return Type::CONTROL; }
  virtual const TypePtr* adr_type() const { return _adr_type; }
  void set_adr_type(const TypePtr* adr_type) { _adr_type = adr_type; }
  virtual Node          *Ideal(PhaseGVN *phase, bool can_reshape);
  virtual Node*          Identity(PhaseGVN* phase);
  virtual uint           ideal_reg() const { return 0; }
  virtual const RegMask &in_RegMask(uint) const;
  virtual const RegMask &out_RegMask() const;
  virtual uint           match_edge(uint idx) const;

#ifndef PRODUCT
  virtual void           dump_spec(outputStream *st) const;
#endif
};

//------------------------------SafePointScalarObjectNode----------------------
// A SafePointScalarObjectNode represents the state of a scalarized object
// at a safepoint.
class SafePointScalarObjectNode: public TypeNode {
  uint _first_index;              // First input edge relative index of a SafePoint node where
                                  // states of the scalarized object fields are collected.
  uint _depth;                    // Depth of the JVM state the _first_index field refers to
  uint _n_fields;                 // Number of non-static fields of the scalarized object.

  Node* _alloc;                   // Just for debugging purposes.

  virtual uint hash() const;
  virtual bool cmp( const Node &n ) const;

  uint first_index() const { return _first_index; }

public:
  SafePointScalarObjectNode(const TypeOopPtr* tp, Node* alloc, uint first_index, uint depth, uint n_fields);

  virtual int Opcode() const;
  virtual uint           ideal_reg() const;
  virtual const RegMask &in_RegMask(uint) const;
  virtual const RegMask &out_RegMask() const;
  virtual uint           match_edge(uint idx) const;

  uint first_index(JVMState* jvms) const {
    assert(jvms != nullptr, "missed JVMS");
    return jvms->of_depth(_depth)->scloff() + _first_index;
  }
  uint n_fields()    const { return _n_fields; }

#ifdef ASSERT
  Node* alloc() const { return _alloc; }
#endif

  virtual uint size_of() const { return sizeof(*this); }

  // Assumes that "this" is an argument to a safepoint node "s", and that
  // "new_call" is being created to correspond to "s".  But the difference
  // between the start index of the jvmstates of "new_call" and "s" is
  // "jvms_adj".  Produce and return a SafePointScalarObjectNode that
  // corresponds appropriately to "this" in "new_call".  Assumes that
  // "sosn_map" is a map, specific to the translation of "s" to "new_call",
  // mapping old SafePointScalarObjectNodes to new, to avoid multiple copies.
  SafePointScalarObjectNode* clone(Dict* sosn_map, bool& new_node) const;

#ifndef PRODUCT
  virtual void              dump_spec(outputStream *st) const;
#endif
};

//------------------------------SafePointScalarMergeNode----------------------
//
// This class represents an allocation merge that is used as debug information
// and had at least one of its input scalar replaced.
//
// The required inputs of this node, except the control, are pointers to
// SafePointScalarObjectNodes that describe scalarized inputs of the original
// allocation merge. The other(s) properties of the class are described below.
//
// _merge_pointer_idx : index in the SafePointNode's input array where the
//   description of the _allocation merge_ starts. The index is zero based and
//   relative to the SafePoint's scloff. The two entries in the SafePointNode's
//   input array starting at '_merge_pointer_idx` are Phi nodes representing:
//
//   1) The original merge Phi. During rematerialization this input will only be
//   used if the "selector Phi" (see below) indicates that the execution of the
//   Phi took the path of a non scalarized input.
//
//   2) A "selector Phi". The output of this Phi will be '-1' if the execution
//   of the method exercised a non scalarized input of the original Phi.
//   Otherwise, the output will be >=0, and it will indicate the index-1 in the
//   SafePointScalarMergeNode input array where the description of the
//   scalarized object that should be used is.
//
// As an example, consider a Phi merging 3 inputs, of which the last 2 are
// scalar replaceable.
//
//    Phi(Region, NSR, SR, SR)
//
// During scalar replacement the SR inputs will be changed to null:
//
//    Phi(Region, NSR, nullptr, nullptr)
//
// A corresponding selector Phi will be created with a configuration like this:
//
//    Phi(Region, -1, 0, 1)
//
// During execution of the compiled method, if the execution reaches a Trap, the
// output of the selector Phi will tell if we need to rematerialize one of the
// scalar replaced inputs or if we should just use the pointer returned by the
// original Phi.

class SafePointScalarMergeNode: public TypeNode {
  int _merge_pointer_idx;         // This is the first input edge relative
                                  // index of a SafePoint node where metadata information relative
                                  // to restoring the merge is stored. The corresponding input
                                  // in the associated SafePoint will point to a Phi representing
                                  // potential non-scalar replaced objects.

  virtual uint hash() const;
  virtual bool cmp( const Node &n ) const;

public:
  SafePointScalarMergeNode(const TypeOopPtr* tp, int merge_pointer_idx);

  virtual int            Opcode() const;
  virtual uint           ideal_reg() const;
  virtual const RegMask &in_RegMask(uint) const;
  virtual const RegMask &out_RegMask() const;
  virtual uint           match_edge(uint idx) const;

  virtual uint size_of() const { return sizeof(*this); }

  int merge_pointer_idx(JVMState* jvms) const {
    assert(jvms != nullptr, "JVMS reference is null.");
    return jvms->scloff() + _merge_pointer_idx;
  }

  int selector_idx(JVMState* jvms) const {
    assert(jvms != nullptr, "JVMS reference is null.");
    return jvms->scloff() + _merge_pointer_idx + 1;
  }

  // Assumes that "this" is an argument to a safepoint node "s", and that
  // "new_call" is being created to correspond to "s".  But the difference
  // between the start index of the jvmstates of "new_call" and "s" is
  // "jvms_adj".  Produce and return a SafePointScalarObjectNode that
  // corresponds appropriately to "this" in "new_call".  Assumes that
  // "sosn_map" is a map, specific to the translation of "s" to "new_call",
  // mapping old SafePointScalarObjectNodes to new, to avoid multiple copies.
  SafePointScalarMergeNode* clone(Dict* sosn_map, bool& new_node) const;

#ifndef PRODUCT
  virtual void              dump_spec(outputStream *st) const;
#endif
};

// Simple container for the outgoing projections of a call.  Useful
// for serious surgery on calls.
class CallProjections : public StackObj {
public:
  Node* fallthrough_proj;
  Node* fallthrough_catchproj;
  Node* fallthrough_memproj;
  Node* fallthrough_ioproj;
  Node* catchall_catchproj;
  Node* catchall_memproj;
  Node* catchall_ioproj;
  Node* resproj;
  Node* exobj;
};

class CallGenerator;

//------------------------------CallNode---------------------------------------
// Call nodes now subsume the function of debug nodes at callsites, so they
// contain the functionality of a full scope chain of debug nodes.
class CallNode : public SafePointNode {

protected:
  bool may_modify_arraycopy_helper(const TypeOopPtr* dest_t, const TypeOopPtr* t_oop, PhaseValues* phase);

public:
  const TypeFunc* _tf;          // Function type
  address         _entry_point; // Address of method being called
  float           _cnt;         // Estimate of number of times called
  CallGenerator*  _generator;   // corresponding CallGenerator for some late inline calls
  const char*     _name;        // Printable name, if _method is null

  CallNode(const TypeFunc* tf, address addr, const TypePtr* adr_type, JVMState* jvms = nullptr)
    : SafePointNode(tf->domain()->cnt(), jvms, adr_type),
      _tf(tf),
      _entry_point(addr),
      _cnt(COUNT_UNKNOWN),
      _generator(nullptr),
      _name(nullptr)
  {
    init_class_id(Class_Call);
  }

  const TypeFunc* tf()         const { return _tf; }
  address  entry_point()       const { return _entry_point; }
  float    cnt()               const { return _cnt; }
  CallGenerator* generator()   const { return _generator; }

  void set_tf(const TypeFunc* tf)       { _tf = tf; }
  void set_entry_point(address p)       { _entry_point = p; }
  void set_cnt(float c)                 { _cnt = c; }
  void set_generator(CallGenerator* cg) { _generator = cg; }

  virtual const Type* bottom_type() const;
  virtual const Type* Value(PhaseGVN* phase) const;
  virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
  virtual Node* Identity(PhaseGVN* phase) { return this; }
  virtual bool        cmp(const Node &n) const;
  virtual uint        size_of() const = 0;
  virtual void        calling_convention(BasicType* sig_bt, VMRegPair* parm_regs, uint argcnt) const;
  virtual Node*       match(const ProjNode* proj, const Matcher* m);
  virtual uint        ideal_reg() const { return NotAMachineReg; }
  // Are we guaranteed that this node is a safepoint?  Not true for leaf calls and
  // for some macro nodes whose expansion does not have a safepoint on the fast path.
  virtual bool        guaranteed_safepoint()  { return true; }
  // For macro nodes, the JVMState gets modified during expansion. If calls
  // use MachConstantBase, it gets modified during matching. So when cloning
  // the node the JVMState must be deep cloned. Default is to shallow clone.
  virtual bool needs_deep_clone_jvms(Compile* C) { return C->needs_deep_clone_jvms(); }

  // Returns true if the call may modify n
  virtual bool        may_modify(const TypeOopPtr* t_oop, PhaseValues* phase);
  // Does this node have a use of n other than in debug information?
  bool                has_non_debug_use(Node* n);
  // Returns the unique CheckCastPP of a call
  // or result projection is there are several CheckCastPP
  // or returns null if there is no one.
  Node* result_cast();
  // Does this node returns pointer?
  bool returns_pointer() const {
    const TypeTuple* r = tf()->range();
    return (r->cnt() > TypeFunc::Parms &&
            r->field_at(TypeFunc::Parms)->isa_ptr());
  }

  // Collect all the interesting edges from a call for use in
  // replacing the call by something else.  Used by macro expansion
  // and the late inlining support.
  void extract_projections(CallProjections* projs, bool separate_io_proj, bool do_asserts = true);

  virtual uint match_edge(uint idx) const;

  bool is_call_to_arraycopystub() const;

  virtual void copy_call_debug_info(PhaseIterGVN* phase, SafePointNode* sfpt) {}

#ifndef PRODUCT
  virtual void        dump_req(outputStream* st = tty, DumpConfig* dc = nullptr) const;
  virtual void        dump_spec(outputStream* st) const;
#endif
};


//------------------------------CallJavaNode-----------------------------------
// Make a static or dynamic subroutine call node using Java calling
// convention.  (The "Java" calling convention is the compiler's calling
// convention, as opposed to the interpreter's or that of native C.)
class CallJavaNode : public CallNode {
protected:
  virtual bool cmp( const Node &n ) const;
  virtual uint size_of() const; // Size is bigger

  ciMethod* _method;               // Method being direct called
  bool    _optimized_virtual;
  bool    _method_handle_invoke;
  bool    _override_symbolic_info; // Override symbolic call site info from bytecode
  bool    _arg_escape;             // ArgEscape in parameter list
public:
  CallJavaNode(const TypeFunc* tf , address addr, ciMethod* method)
    : CallNode(tf, addr, TypePtr::BOTTOM),
      _method(method),
      _optimized_virtual(false),
      _method_handle_invoke(false),
      _override_symbolic_info(false),
      _arg_escape(false)
  {
    init_class_id(Class_CallJava);
  }

  virtual int   Opcode() const;
  ciMethod* method() const                 { return _method; }
  void  set_method(ciMethod *m)            { _method = m; }
  void  set_optimized_virtual(bool f)      { _optimized_virtual = f; }
  bool  is_optimized_virtual() const       { return _optimized_virtual; }
  void  set_method_handle_invoke(bool f)   { _method_handle_invoke = f; }
  bool  is_method_handle_invoke() const    { return _method_handle_invoke; }
  void  set_override_symbolic_info(bool f) { _override_symbolic_info = f; }
  bool  override_symbolic_info() const     { return _override_symbolic_info; }
  void  set_arg_escape(bool f)             { _arg_escape = f; }
  bool  arg_escape() const                 { return _arg_escape; }
  void copy_call_debug_info(PhaseIterGVN* phase, SafePointNode *sfpt);
  void register_for_late_inline();

  DEBUG_ONLY( bool validate_symbolic_info() const; )

#ifndef PRODUCT
  virtual void  dump_spec(outputStream *st) const;
  virtual void  dump_compact_spec(outputStream *st) const;
#endif
};

//------------------------------CallStaticJavaNode-----------------------------
// Make a direct subroutine call using Java calling convention (for static
// calls and optimized virtual calls, plus calls to wrappers for run-time
// routines); generates static stub.
class CallStaticJavaNode : public CallJavaNode {
  virtual bool cmp( const Node &n ) const;
  virtual uint size_of() const; // Size is bigger
public:
  CallStaticJavaNode(Compile* C, const TypeFunc* tf, address addr, ciMethod* method)
    : CallJavaNode(tf, addr, method) {
    init_class_id(Class_CallStaticJava);
    if (C->eliminate_boxing() && (method != nullptr) && method->is_boxing_method()) {
      init_flags(Flag_is_macro);
      C->add_macro_node(this);
    }
  }
  CallStaticJavaNode(const TypeFunc* tf, address addr, const char* name, const TypePtr* adr_type)
    : CallJavaNode(tf, addr, nullptr) {
    init_class_id(Class_CallStaticJava);
    // This node calls a runtime stub, which often has narrow memory effects.
    _adr_type = adr_type;
    _name = name;
  }

  // If this is an uncommon trap, return the request code, else zero.
  int uncommon_trap_request() const;
  bool is_uncommon_trap() const;
  static int extract_uncommon_trap_request(const Node* call);

  bool is_boxing_method() const {
    return is_macro() && (method() != nullptr) && method()->is_boxing_method();
  }
  // Late inlining modifies the JVMState, so we need to deep clone it
  // when the call node is cloned (because it is macro node).
  virtual bool needs_deep_clone_jvms(Compile* C) {
    return is_boxing_method() || CallNode::needs_deep_clone_jvms(C);
  }

  virtual int         Opcode() const;
  virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);

#ifndef PRODUCT
  virtual void        dump_spec(outputStream *st) const;
  virtual void        dump_compact_spec(outputStream *st) const;
#endif
};

//------------------------------CallDynamicJavaNode----------------------------
// Make a dispatched call using Java calling convention.
class CallDynamicJavaNode : public CallJavaNode {
  virtual bool cmp( const Node &n ) const;
  virtual uint size_of() const; // Size is bigger
public:
  CallDynamicJavaNode(const TypeFunc* tf , address addr, ciMethod* method, int vtable_index)
    : CallJavaNode(tf,addr,method), _vtable_index(vtable_index) {
    init_class_id(Class_CallDynamicJava);
  }

  // Late inlining modifies the JVMState, so we need to deep clone it
  // when the call node is cloned.
  virtual bool needs_deep_clone_jvms(Compile* C) {
    return IncrementalInlineVirtual || CallNode::needs_deep_clone_jvms(C);
  }

  int _vtable_index;
  virtual int   Opcode() const;
  virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
#ifndef PRODUCT
  virtual void  dump_spec(outputStream *st) const;
#endif
};

//------------------------------CallRuntimeNode--------------------------------
// Make a direct subroutine call node into compiled C++ code.
class CallRuntimeNode : public CallNode {
protected:
  virtual bool cmp( const Node &n ) const;
  virtual uint size_of() const; // Size is bigger
public:
  CallRuntimeNode(const TypeFunc* tf, address addr, const char* name,
                  const TypePtr* adr_type, JVMState* jvms = nullptr)
    : CallNode(tf, addr, adr_type, jvms)
  {
    init_class_id(Class_CallRuntime);
    _name = name;
  }

  virtual int   Opcode() const;
  virtual void  calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const;

#ifndef PRODUCT
  virtual void  dump_spec(outputStream *st) const;
#endif
};

//------------------------------CallLeafNode-----------------------------------
// Make a direct subroutine call node into compiled C++ code, without
// safepoints
class CallLeafNode : public CallRuntimeNode {
public:
  CallLeafNode(const TypeFunc* tf, address addr, const char* name,
               const TypePtr* adr_type)
    : CallRuntimeNode(tf, addr, name, adr_type)
  {
    init_class_id(Class_CallLeaf);
  }
  virtual int   Opcode() const;
  virtual bool        guaranteed_safepoint()  { return false; }
#ifndef PRODUCT
  virtual void  dump_spec(outputStream *st) const;
#endif
};

//------------------------------CallLeafNoFPNode-------------------------------
// CallLeafNode, not using floating point or using it in the same manner as
// the generated code
class CallLeafNoFPNode : public CallLeafNode {
public:
  CallLeafNoFPNode(const TypeFunc* tf, address addr, const char* name,
                   const TypePtr* adr_type)
    : CallLeafNode(tf, addr, name, adr_type)
  {
    init_class_id(Class_CallLeafNoFP);
  }
  virtual int   Opcode() const;
};

//------------------------------CallLeafVectorNode-------------------------------
// CallLeafNode but calling with vector calling convention instead.
class CallLeafVectorNode : public CallLeafNode {
private:
  uint _num_bits;
protected:
  virtual bool cmp( const Node &n ) const;
  virtual uint size_of() const; // Size is bigger
public:
  CallLeafVectorNode(const TypeFunc* tf, address addr, const char* name,
                   const TypePtr* adr_type, uint num_bits)
    : CallLeafNode(tf, addr, name, adr_type), _num_bits(num_bits)
  {
  }
  virtual int   Opcode() const;
  virtual void  calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const;
};


//------------------------------Allocate---------------------------------------
// High-level memory allocation
//
//  AllocateNode and AllocateArrayNode are subclasses of CallNode because they will
//  get expanded into a code sequence containing a call.  Unlike other CallNodes,
//  they have 2 memory projections and 2 i_o projections (which are distinguished by
//  the _is_io_use flag in the projection.)  This is needed when expanding the node in
//  order to differentiate the uses of the projection on the normal control path from
//  those on the exception return path.
//
class AllocateNode : public CallNode {
public:
  enum {
    // Output:
    RawAddress  = TypeFunc::Parms,    // the newly-allocated raw address
    // Inputs:
    AllocSize   = TypeFunc::Parms,    // size (in bytes) of the new object
    KlassNode,                        // type (maybe dynamic) of the obj.
    InitialTest,                      // slow-path test (may be constant)
    ALength,                          // array length (or TOP if none)
    ValidLengthTest,
    ParmLimit
  };

  static const TypeFunc* alloc_type(const Type* t) {
    const Type** fields = TypeTuple::fields(ParmLimit - TypeFunc::Parms);
    fields[AllocSize]   = TypeInt::POS;
    fields[KlassNode]   = TypeInstPtr::NOTNULL;
    fields[InitialTest] = TypeInt::BOOL;
    fields[ALength]     = t;  // length (can be a bad length)
    fields[ValidLengthTest] = TypeInt::BOOL;

    const TypeTuple *domain = TypeTuple::make(ParmLimit, fields);

    // create result type (range)
    fields = TypeTuple::fields(1);
    fields[TypeFunc::Parms+0] = TypeRawPtr::NOTNULL; // Returned oop

    const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);

    return TypeFunc::make(domain, range);
  }

  // Result of Escape Analysis
  bool _is_scalar_replaceable;
  bool _is_non_escaping;
  // True when MemBar for new is redundant with MemBar at initialzer exit
  bool _is_allocation_MemBar_redundant;

  virtual uint size_of() const; // Size is bigger
  AllocateNode(Compile* C, const TypeFunc *atype, Node *ctrl, Node *mem, Node *abio,
               Node *size, Node *klass_node, Node *initial_test);
  // Expansion modifies the JVMState, so we need to deep clone it
  virtual bool needs_deep_clone_jvms(Compile* C) { return true; }
  virtual int Opcode() const;
  virtual uint ideal_reg() const { return Op_RegP; }
  virtual bool        guaranteed_safepoint()  { return false; }

  // allocations do not modify their arguments
  virtual bool        may_modify(const TypeOopPtr* t_oop, PhaseValues* phase) { return false;}

  // Pattern-match a possible usage of AllocateNode.
  // Return null if no allocation is recognized.
  // The operand is the pointer produced by the (possible) allocation.
  // It must be a projection of the Allocate or its subsequent CastPP.
  // (Note:  This function is defined in file graphKit.cpp, near
  // GraphKit::new_instance/new_array, whose output it recognizes.)
  // The 'ptr' may not have an offset unless the 'offset' argument is given.
  static AllocateNode* Ideal_allocation(Node* ptr);

  // Fancy version which uses AddPNode::Ideal_base_and_offset to strip
  // an offset, which is reported back to the caller.
  // (Note:  AllocateNode::Ideal_allocation is defined in graphKit.cpp.)
  static AllocateNode* Ideal_allocation(Node* ptr, PhaseValues* phase,
                                        intptr_t& offset);

  // Dig the klass operand out of a (possible) allocation site.
  static Node* Ideal_klass(Node* ptr, PhaseValues* phase) {
    AllocateNode* allo = Ideal_allocation(ptr);
    return (allo == nullptr) ? nullptr : allo->in(KlassNode);
  }

  // Conservatively small estimate of offset of first non-header byte.
  int minimum_header_size() {
    return is_AllocateArray() ? arrayOopDesc::base_offset_in_bytes(T_BYTE) :
                                instanceOopDesc::base_offset_in_bytes();
  }

  // Return the corresponding initialization barrier (or null if none).
  // Walks out edges to find it...
  // (Note: Both InitializeNode::allocation and AllocateNode::initialization
  // are defined in graphKit.cpp, which sets up the bidirectional relation.)
  InitializeNode* initialization();

  // Convenience for initialization->maybe_set_complete(phase)
  bool maybe_set_complete(PhaseGVN* phase);

  // Return true if allocation doesn't escape thread, its escape state
  // needs be noEscape or ArgEscape. InitializeNode._does_not_escape
  // is true when its allocation's escape state is noEscape or
  // ArgEscape. In case allocation's InitializeNode is null, check
  // AlllocateNode._is_non_escaping flag.
  // AlllocateNode._is_non_escaping is true when its escape state is
  // noEscape.
  bool does_not_escape_thread() {
    InitializeNode* init = nullptr;
    return _is_non_escaping || (((init = initialization()) != nullptr) && init->does_not_escape());
  }

  // If object doesn't escape in <.init> method and there is memory barrier
  // inserted at exit of its <.init>, memory barrier for new is not necessary.
  // Inovke this method when MemBar at exit of initializer and post-dominate
  // allocation node.
  void compute_MemBar_redundancy(ciMethod* initializer);
  bool is_allocation_MemBar_redundant() { return _is_allocation_MemBar_redundant; }

  Node* make_ideal_mark(PhaseGVN *phase, Node* obj, Node* control, Node* mem);

  NOT_PRODUCT(virtual void dump_spec(outputStream* st) const;)
};

//------------------------------AllocateArray---------------------------------
//
// High-level array allocation
//
class AllocateArrayNode : public AllocateNode {
public:
  AllocateArrayNode(Compile* C, const TypeFunc* atype, Node* ctrl, Node* mem, Node* abio, Node* size, Node* klass_node,
                    Node* initial_test, Node* count_val, Node* valid_length_test)
    : AllocateNode(C, atype, ctrl, mem, abio, size, klass_node,
                   initial_test)
  {
    init_class_id(Class_AllocateArray);
    set_req(AllocateNode::ALength,        count_val);
    set_req(AllocateNode::ValidLengthTest, valid_length_test);
  }
  virtual int Opcode() const;

  // Dig the length operand out of a array allocation site.
  Node* Ideal_length() {
    return in(AllocateNode::ALength);
  }

  // Dig the length operand out of a array allocation site and narrow the
  // type with a CastII, if necesssary
  Node* make_ideal_length(const TypeOopPtr* ary_type, PhaseValues* phase, bool can_create = true);

  // Pattern-match a possible usage of AllocateArrayNode.
  // Return null if no allocation is recognized.
  static AllocateArrayNode* Ideal_array_allocation(Node* ptr) {
    AllocateNode* allo = Ideal_allocation(ptr);
    return (allo == nullptr || !allo->is_AllocateArray())
           ? nullptr : allo->as_AllocateArray();
  }
};

//------------------------------AbstractLockNode-----------------------------------
class AbstractLockNode: public CallNode {
private:
  enum {
    Regular = 0,  // Normal lock
    NonEscObj,    // Lock is used for non escaping object
    Coarsened,    // Lock was coarsened
    Nested        // Nested lock
  } _kind;

  static const char* _kind_names[Nested+1];

#ifndef PRODUCT
  NamedCounter* _counter;
#endif

protected:
  // helper functions for lock elimination
  //

  bool find_matching_unlock(const Node* ctrl, LockNode* lock,
                            GrowableArray<AbstractLockNode*> &lock_ops);
  bool find_lock_and_unlock_through_if(Node* node, LockNode* lock,
                                       GrowableArray<AbstractLockNode*> &lock_ops);
  bool find_unlocks_for_region(const RegionNode* region, LockNode* lock,
                               GrowableArray<AbstractLockNode*> &lock_ops);
  LockNode *find_matching_lock(UnlockNode* unlock);

  // Update the counter to indicate that this lock was eliminated.
  void set_eliminated_lock_counter() PRODUCT_RETURN;

public:
  AbstractLockNode(const TypeFunc *tf)
    : CallNode(tf, nullptr, TypeRawPtr::BOTTOM),
      _kind(Regular)
  {
#ifndef PRODUCT
    _counter = nullptr;
#endif
  }
  virtual int Opcode() const = 0;
  Node *   obj_node() const       {return in(TypeFunc::Parms + 0); }
  Node *   box_node() const       {return in(TypeFunc::Parms + 1); }
  Node *   fastlock_node() const  {return in(TypeFunc::Parms + 2); }
  void     set_box_node(Node* box) { set_req(TypeFunc::Parms + 1, box); }

  const Type *sub(const Type *t1, const Type *t2) const { return TypeInt::CC;}

  virtual uint size_of() const { return sizeof(*this); }

  bool is_eliminated()  const { return (_kind != Regular); }
  bool is_non_esc_obj() const { return (_kind == NonEscObj); }
  bool is_coarsened()   const { return (_kind == Coarsened); }
  bool is_nested()      const { return (_kind == Nested); }

  const char * kind_as_string() const;
  void log_lock_optimization(Compile* c, const char * tag, Node* bad_lock = nullptr) const;

  void set_non_esc_obj() { _kind = NonEscObj; set_eliminated_lock_counter(); }
  void set_coarsened()   { _kind = Coarsened; set_eliminated_lock_counter(); }
  void set_nested()      { _kind = Nested; set_eliminated_lock_counter(); }

  // Check that all locks/unlocks associated with object come from balanced regions.
  // They can become unbalanced after coarsening optimization or on OSR entry.
  bool is_balanced();

  // locking does not modify its arguments
  virtual bool may_modify(const TypeOopPtr* t_oop, PhaseValues* phase){ return false; }

#ifndef PRODUCT
  void create_lock_counter(JVMState* s);
  NamedCounter* counter() const { return _counter; }
  virtual void dump_spec(outputStream* st) const;
  virtual void dump_compact_spec(outputStream* st) const;
#endif
};

//------------------------------Lock---------------------------------------
// High-level lock operation
//
// This is a subclass of CallNode because it is a macro node which gets expanded
// into a code sequence containing a call.  This node takes 3 "parameters":
//    0  -  object to lock
//    1 -   a BoxLockNode
//    2 -   a FastLockNode
//
class LockNode : public AbstractLockNode {
  static const TypeFunc* _lock_type_Type;
public:

  static inline const TypeFunc* lock_type() {
    assert(_lock_type_Type != nullptr, "should be initialized");
    return _lock_type_Type;
  }

  static void initialize_lock_Type() {
    assert(_lock_type_Type == nullptr, "should be called once");
    // create input type (domain)
    const Type **fields = TypeTuple::fields(3);
    fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;  // Object to be Locked
    fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;    // Address of stack location for lock
    fields[TypeFunc::Parms+2] = TypeInt::BOOL;         // FastLock
    const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3,fields);

    // create result type (range)
    fields = TypeTuple::fields(0);

    const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0,fields);

    _lock_type_Type = TypeFunc::make(domain,range);
  }

  virtual int Opcode() const;
  virtual uint size_of() const; // Size is bigger
  LockNode(Compile* C, const TypeFunc *tf) : AbstractLockNode( tf ) {
    init_class_id(Class_Lock);
    init_flags(Flag_is_macro);
    C->add_macro_node(this);
  }
  virtual bool        guaranteed_safepoint()  { return false; }

  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
  // Expansion modifies the JVMState, so we need to deep clone it
  virtual bool needs_deep_clone_jvms(Compile* C) { return true; }

  bool is_nested_lock_region(); // Is this Lock nested?
  bool is_nested_lock_region(Compile * c); // Why isn't this Lock nested?
};

//------------------------------Unlock---------------------------------------
// High-level unlock operation
class UnlockNode : public AbstractLockNode {
private:
#ifdef ASSERT
  JVMState* const _dbg_jvms;      // Pointer to list of JVM State objects
#endif
public:
  virtual int Opcode() const;
  virtual uint size_of() const; // Size is bigger
  UnlockNode(Compile* C, const TypeFunc *tf) : AbstractLockNode( tf )
#ifdef ASSERT
    , _dbg_jvms(nullptr)
#endif
  {
    init_class_id(Class_Unlock);
    init_flags(Flag_is_macro);
    C->add_macro_node(this);
  }
  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
  // unlock is never a safepoint
  virtual bool        guaranteed_safepoint()  { return false; }
#ifdef ASSERT
  void set_dbg_jvms(JVMState* s) {
    *(JVMState**)&_dbg_jvms = s;  // override const attribute in the accessor
  }
  JVMState* dbg_jvms() const { return _dbg_jvms; }
#else
  JVMState* dbg_jvms() const { return nullptr; }
#endif
};
#endif // SHARE_OPTO_CALLNODE_HPP
