1 /*
  2  * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 #ifndef SHARE_GC_Z_C2_ZBARRIERSETC2_HPP
 25 #define SHARE_GC_Z_C2_ZBARRIERSETC2_HPP
 26 
 27 #include "gc/shared/c2/barrierSetC2.hpp"
 28 #include "memory/allocation.hpp"
 29 #include "opto/node.hpp"
 30 #include "utilities/growableArray.hpp"
 31 
 32 const uint8_t ZBarrierStrong      =  1;
 33 const uint8_t ZBarrierWeak        =  2;
 34 const uint8_t ZBarrierPhantom     =  4;
 35 const uint8_t ZBarrierNoKeepalive =  8;
 36 const uint8_t ZBarrierNative      = 16;
 37 const uint8_t ZBarrierElided      = 32;
 38 
 39 class Block;
 40 class MachNode;
 41 
 42 class MacroAssembler;
 43 
 44 class ZBarrierStubC2 : public ArenaObj {
 45 protected:
 46   const MachNode* _node;
 47   Label           _entry;
 48   Label           _continuation;
 49 
 50 static void register_stub(ZBarrierStubC2* stub);
 51 static void inc_trampoline_stubs_count();
 52 static int trampoline_stubs_count();
 53 static int stubs_start_offset();
 54 
 55 public:
 56   ZBarrierStubC2(const MachNode* node);
 57 
 58   RegMask& live() const;
 59   Label* entry();
 60   Label* continuation();
 61 
 62   virtual Register result() const = 0;
 63   virtual void emit_code(MacroAssembler& masm) = 0;
 64 };
 65 
 66 class ZLoadBarrierStubC2 : public ZBarrierStubC2 {
 67 private:
 68   const Address  _ref_addr;
 69   const Register _ref;
 70 
 71 protected:
 72   ZLoadBarrierStubC2(const MachNode* node, Address ref_addr, Register ref);
 73 
 74 public:
 75   static ZLoadBarrierStubC2* create(const MachNode* node, Address ref_addr, Register ref);
 76 
 77   Address ref_addr() const;
 78   Register ref() const;
 79   address slow_path() const;
 80 
 81   virtual Register result() const;
 82   virtual void emit_code(MacroAssembler& masm);
 83 };
 84 
 85 class ZStoreBarrierStubC2 : public ZBarrierStubC2 {
 86 private:
 87   const Address  _ref_addr;
 88   const Register _new_zaddress;
 89   const Register _new_zpointer;
 90   const bool     _is_native;
 91   const bool     _is_atomic;
 92 
 93 protected:
 94   ZStoreBarrierStubC2(const MachNode* node, Address ref_addr, Register new_zaddress, Register new_zpointer, bool is_native, bool is_atomic);
 95 
 96 public:
 97   static ZStoreBarrierStubC2* create(const MachNode* node, Address ref_addr, Register new_zaddress, Register new_zpointer, bool is_native, bool is_atomic);
 98 
 99   Address ref_addr() const;
100   Register new_zaddress() const;
101   Register new_zpointer() const;
102   bool is_native() const;
103   bool is_atomic() const;
104 
105   virtual Register result() const;
106   virtual void emit_code(MacroAssembler& masm);
107 };
108 
109 class ZBarrierSetC2 : public BarrierSetC2 {
110 private:
111   void compute_liveness_at_stubs() const;
112   void analyze_dominating_barriers_impl(Node_List& accesses, Node_List& access_dominators) const;
113   void analyze_dominating_barriers() const;
114 
115 protected:
116   virtual Node* store_at_resolved(C2Access& access, C2AccessValue& val) const;
117   virtual Node* load_at_resolved(C2Access& access, const Type* val_type) const;
118   virtual Node* atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess& access,
119                                                Node* expected_val,
120                                                Node* new_val,
121                                                const Type* val_type) const;
122   virtual Node* atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& access,
123                                                 Node* expected_val,
124                                                 Node* new_val,
125                                                 const Type* value_type) const;
126   virtual Node* atomic_xchg_at_resolved(C2AtomicParseAccess& access,
127                                         Node* new_val,
128                                         const Type* val_type) const;
129 
130 public:
131   virtual void* create_barrier_state(Arena* comp_arena) const;
132   virtual bool array_copy_requires_gc_barriers(bool tightly_coupled_alloc,
133                                                BasicType type,
134                                                bool is_clone,
135                                                bool is_clone_instance,
136                                                ArrayCopyPhase phase) const;
137   virtual void clone_at_expansion(PhaseMacroExpand* phase,
138                                   ArrayCopyNode* ac) const;
139 
140   virtual void late_barrier_analysis() const;
141   virtual int estimate_stub_size() const;
142   virtual void emit_stubs(CodeBuffer& cb) const;
143   virtual void eliminate_gc_barrier(PhaseMacroExpand* macro, Node* node) const;
144   virtual void eliminate_gc_barrier_data(Node* node) const;
145 
146 #ifndef PRODUCT
147   virtual void dump_barrier_data(const MachNode* mach, outputStream* st) const;
148 #endif
149 };
150 
151 #endif // SHARE_GC_Z_C2_ZBARRIERSETC2_HPP