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 BarrierStubC2 {
 45 protected:
 46 static void register_stub(ZBarrierStubC2* stub);
 47 static void inc_trampoline_stubs_count();
 48 static int trampoline_stubs_count();
 49 static int stubs_start_offset();
 50 
 51   ZBarrierStubC2(const MachNode* node);
 52 
 53 public:
 54   virtual void emit_code(MacroAssembler& masm) = 0;
 55 };
 56 
 57 class ZLoadBarrierStubC2 : public ZBarrierStubC2 {
 58 private:
 59   const Address  _ref_addr;
 60   const Register _ref;
 61 
 62 protected:
 63   ZLoadBarrierStubC2(const MachNode* node, Address ref_addr, Register ref);
 64 
 65 public:
 66   static ZLoadBarrierStubC2* create(const MachNode* node, Address ref_addr, Register ref);
 67 
 68   Address ref_addr() const;
 69   Register ref() const;
 70   address slow_path() const;
 71 
 72   virtual void emit_code(MacroAssembler& masm);
 73 };
 74 
 75 class ZStoreBarrierStubC2 : public ZBarrierStubC2 {
 76 private:
 77   const Address  _ref_addr;
 78   const Register _new_zaddress;
 79   const Register _new_zpointer;
 80   const bool     _is_native;
 81   const bool     _is_atomic;
 82   const bool     _is_nokeepalive;
 83 
 84 protected:
 85   ZStoreBarrierStubC2(const MachNode* node, Address ref_addr, Register new_zaddress, Register new_zpointer, bool is_native, bool is_atomic, bool is_nokeepalive);
 86 
 87 public:
 88   static ZStoreBarrierStubC2* create(const MachNode* node, Address ref_addr, Register new_zaddress, Register new_zpointer, bool is_native, bool is_atomic, bool is_nokeepalive);
 89 
 90   Address ref_addr() const;
 91   Register new_zaddress() const;
 92   Register new_zpointer() const;
 93   bool is_native() const;
 94   bool is_atomic() const;
 95   bool is_nokeepalive() const;
 96 
 97   virtual void emit_code(MacroAssembler& masm);
 98 };
 99 
100 class ZBarrierSetC2 : public BarrierSetC2 {
101 private:
102   void analyze_dominating_barriers_impl(Node_List& accesses, Node_List& access_dominators) const;
103   void analyze_dominating_barriers() const;
104 
105 protected:
106   virtual Node* store_at_resolved(C2Access& access, C2AccessValue& val) const;
107   virtual Node* load_at_resolved(C2Access& access, const Type* val_type) const;
108   virtual Node* atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess& access,
109                                                Node* expected_val,
110                                                Node* new_val,
111                                                const Type* val_type) const;
112   virtual Node* atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& access,
113                                                 Node* expected_val,
114                                                 Node* new_val,
115                                                 const Type* value_type) const;
116   virtual Node* atomic_xchg_at_resolved(C2AtomicParseAccess& access,
117                                         Node* new_val,
118                                         const Type* val_type) const;
119 
120 public:
121   virtual uint estimated_barrier_size(const Node* node) const;
122   virtual void* create_barrier_state(Arena* comp_arena) const;
123   virtual bool array_copy_requires_gc_barriers(bool tightly_coupled_alloc,
124                                                BasicType type,
125                                                bool is_clone,
126                                                bool is_clone_instance,
127                                                ArrayCopyPhase phase) const;
128   virtual void clone_at_expansion(PhaseMacroExpand* phase,
129                                   ArrayCopyNode* ac) const;
130 
131   virtual void late_barrier_analysis() const;
132   virtual int estimate_stub_size() const;
133   virtual void emit_stubs(CodeBuffer& cb) const;
134   virtual void eliminate_gc_barrier(PhaseIterGVN* igvn, Node* node) const;
135   virtual void eliminate_gc_barrier_data(Node* node) const;
136 
137 #ifndef PRODUCT
138   virtual void dump_barrier_data(const MachNode* mach, outputStream* st) const;
139 #endif
140 };
141 
142 #endif // SHARE_GC_Z_C2_ZBARRIERSETC2_HPP