annotate src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp @ 52036:5d6d636cefff

8211776: 8210887 broke arraycopy optimization when ZGC is enabled Reviewed-by: kvn
author roland
date Fri, 05 Oct 2018 16:47:27 +0200
parents 2ef304ee001d
children 4f2215a00ed1
rev   line source
pliden@50525 1 /*
pliden@50525 2 * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
pliden@50525 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
pliden@50525 4 *
pliden@50525 5 * This code is free software; you can redistribute it and/or modify it
pliden@50525 6 * under the terms of the GNU General Public License version 2 only, as
pliden@50525 7 * published by the Free Software Foundation.
pliden@50525 8 *
pliden@50525 9 * This code is distributed in the hope that it will be useful, but WITHOUT
pliden@50525 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
pliden@50525 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
pliden@50525 12 * version 2 for more details (a copy is included in the LICENSE file that
pliden@50525 13 * accompanied this code).
pliden@50525 14 *
pliden@50525 15 * You should have received a copy of the GNU General Public License version
pliden@50525 16 * 2 along with this work; if not, write to the Free Software Foundation,
pliden@50525 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
pliden@50525 18 *
pliden@50525 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
pliden@50525 20 * or visit www.oracle.com if you need additional information or have any
pliden@50525 21 * questions.
pliden@50525 22 */
pliden@50525 23
pliden@50525 24 #ifndef SHARE_GC_Z_C2_ZBARRIERSETC2_HPP
pliden@50525 25 #define SHARE_GC_Z_C2_ZBARRIERSETC2_HPP
pliden@50525 26
pliden@50525 27 #include "gc/shared/c2/barrierSetC2.hpp"
pliden@50525 28 #include "memory/allocation.hpp"
pliden@50525 29 #include "opto/node.hpp"
pliden@50525 30 #include "utilities/growableArray.hpp"
pliden@50525 31
pliden@50525 32 class LoadBarrierNode : public MultiNode {
pliden@50525 33 private:
pliden@50525 34 bool _weak;
pliden@50525 35 bool _writeback; // Controls if the barrier writes the healed oop back to memory
pliden@50525 36 // A swap on a memory location must never write back the healed oop
pliden@50525 37 bool _oop_reload_allowed; // Controls if the barrier are allowed to reload the oop from memory
pliden@50875 38 // before healing, otherwise both the oop and the address must be
pliden@50875 39 // passed to the barrier from the oop
pliden@50525 40
pliden@50525 41 static bool is_dominator(PhaseIdealLoop* phase, bool linear_only, Node *d, Node *n);
pliden@50525 42 void push_dominated_barriers(PhaseIterGVN* igvn) const;
pliden@50525 43
pliden@50525 44 public:
pliden@50525 45 enum {
pliden@50525 46 Control,
pliden@50525 47 Memory,
pliden@50525 48 Oop,
pliden@50525 49 Address,
pliden@50525 50 Number_of_Outputs = Address,
pliden@50525 51 Similar,
pliden@50525 52 Number_of_Inputs
pliden@50525 53 };
pliden@50525 54
pliden@50525 55 LoadBarrierNode(Compile* C,
pliden@50525 56 Node* c,
pliden@50525 57 Node* mem,
pliden@50525 58 Node* val,
pliden@50525 59 Node* adr,
pliden@50525 60 bool weak,
pliden@50525 61 bool writeback,
pliden@50525 62 bool oop_reload_allowed);
pliden@50525 63
pliden@50525 64 virtual int Opcode() const;
pliden@50525 65 virtual const Type *bottom_type() const;
pliden@50525 66 virtual const Type *Value(PhaseGVN *phase) const;
pliden@50525 67 virtual Node *Identity(PhaseGVN *phase);
pliden@50525 68 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
pliden@50525 69
pliden@50525 70 LoadBarrierNode* has_dominating_barrier(PhaseIdealLoop* phase,
pliden@50525 71 bool linear_only,
pliden@50525 72 bool look_for_similar);
pliden@50525 73
pliden@50525 74 void fix_similar_in_uses(PhaseIterGVN* igvn);
pliden@50525 75
pliden@50525 76 bool has_true_uses() const;
pliden@50525 77
pliden@50525 78 bool can_be_eliminated() const {
pliden@50525 79 return !in(Similar)->is_top();
pliden@50525 80 }
pliden@50525 81
pliden@50525 82 bool is_weak() const {
pliden@50525 83 return _weak;
pliden@50525 84 }
pliden@50525 85
pliden@50525 86 bool is_writeback() const {
pliden@50525 87 return _writeback;
pliden@50525 88 }
pliden@50525 89
pliden@50525 90 bool oop_reload_allowed() const {
pliden@50525 91 return _oop_reload_allowed;
pliden@50525 92 }
pliden@50525 93 };
pliden@50525 94
pliden@50525 95 class LoadBarrierSlowRegNode : public LoadPNode {
pliden@50525 96 public:
pliden@50525 97 LoadBarrierSlowRegNode(Node *c,
pliden@50525 98 Node *mem,
pliden@50525 99 Node *adr,
pliden@50525 100 const TypePtr *at,
pliden@50525 101 const TypePtr* t,
pliden@50525 102 MemOrd mo,
pliden@50525 103 ControlDependency control_dependency = DependsOnlyOnTest)
eosterlund@51485 104 : LoadPNode(c, mem, adr, at, t, mo, control_dependency) {
eosterlund@51485 105 init_class_id(Class_LoadBarrierSlowReg);
eosterlund@51485 106 }
pliden@50525 107
pliden@50525 108 virtual const char * name() {
pliden@50525 109 return "LoadBarrierSlowRegNode";
pliden@50525 110 }
pliden@50525 111
pliden@50525 112 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) {
pliden@50525 113 return NULL;
pliden@50525 114 }
pliden@50525 115
pliden@50525 116 virtual int Opcode() const;
pliden@50525 117 };
pliden@50525 118
pliden@50525 119 class LoadBarrierWeakSlowRegNode : public LoadPNode {
pliden@50525 120 public:
pliden@50525 121 LoadBarrierWeakSlowRegNode(Node *c,
pliden@50525 122 Node *mem,
pliden@50525 123 Node *adr,
pliden@50525 124 const TypePtr *at,
pliden@50525 125 const TypePtr* t,
pliden@50525 126 MemOrd mo,
pliden@50525 127 ControlDependency control_dependency = DependsOnlyOnTest)
eosterlund@51485 128 : LoadPNode(c, mem, adr, at, t, mo, control_dependency) {
eosterlund@51485 129 init_class_id(Class_LoadBarrierWeakSlowReg);
eosterlund@51485 130 }
pliden@50525 131
pliden@50525 132 virtual const char * name() {
pliden@50525 133 return "LoadBarrierWeakSlowRegNode";
pliden@50525 134 }
pliden@50525 135
pliden@50525 136 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) {
pliden@50525 137 return NULL;
pliden@50525 138 }
pliden@50525 139
pliden@50525 140 virtual int Opcode() const;
pliden@50525 141 };
pliden@50525 142
pliden@50525 143 class ZBarrierSetC2State : public ResourceObj {
pliden@50525 144 private:
pliden@50525 145 // List of load barrier nodes which need to be expanded before matching
pliden@50525 146 GrowableArray<LoadBarrierNode*>* _load_barrier_nodes;
pliden@50525 147
pliden@50525 148 public:
pliden@50525 149 ZBarrierSetC2State(Arena* comp_arena);
pliden@50525 150 int load_barrier_count() const;
pliden@50525 151 void add_load_barrier_node(LoadBarrierNode* n);
pliden@50525 152 void remove_load_barrier_node(LoadBarrierNode* n);
pliden@50525 153 LoadBarrierNode* load_barrier_node(int idx) const;
pliden@50525 154 };
pliden@50525 155
pliden@50525 156 class ZBarrierSetC2 : public BarrierSetC2 {
pliden@50525 157 private:
pliden@50525 158 ZBarrierSetC2State* state() const;
pliden@50525 159 Node* make_cas_loadbarrier(C2AtomicAccess& access) const;
pliden@50525 160 Node* make_cmpx_loadbarrier(C2AtomicAccess& access) const;
pliden@50525 161 void expand_loadbarrier_basic(PhaseMacroExpand* phase, LoadBarrierNode *barrier) const;
pliden@50525 162 void expand_loadbarrier_node(PhaseMacroExpand* phase, LoadBarrierNode* barrier) const;
pliden@50525 163 void expand_loadbarrier_optimized(PhaseMacroExpand* phase, LoadBarrierNode *barrier) const;
pliden@50525 164 const TypeFunc* load_barrier_Type() const;
pliden@50525 165
pliden@50525 166 protected:
pliden@50525 167 virtual Node* load_at_resolved(C2Access& access, const Type* val_type) const;
pliden@50525 168 virtual Node* atomic_cmpxchg_val_at_resolved(C2AtomicAccess& access,
pliden@50525 169 Node* expected_val,
pliden@50525 170 Node* new_val,
pliden@50525 171 const Type* val_type) const;
pliden@50525 172 virtual Node* atomic_cmpxchg_bool_at_resolved(C2AtomicAccess& access,
pliden@50525 173 Node* expected_val,
pliden@50525 174 Node* new_val,
pliden@50525 175 const Type* value_type) const;
pliden@50525 176 virtual Node* atomic_xchg_at_resolved(C2AtomicAccess& access,
pliden@50525 177 Node* new_val,
pliden@50525 178 const Type* val_type) const;
pliden@50525 179
pliden@50525 180 public:
pliden@50525 181 Node* load_barrier(GraphKit* kit,
pliden@50525 182 Node* val,
pliden@50525 183 Node* adr,
pliden@50525 184 bool weak = false,
pliden@50525 185 bool writeback = true,
pliden@50525 186 bool oop_reload_allowed = true) const;
pliden@50525 187
pliden@50525 188 virtual void* create_barrier_state(Arena* comp_arena) const;
eosterlund@51485 189 virtual bool has_load_barriers() const { return true; }
pliden@50525 190 virtual bool is_gc_barrier_node(Node* node) const;
pliden@50525 191 virtual void eliminate_gc_barrier(PhaseMacroExpand* macro, Node* node) const { }
pliden@50525 192 virtual void eliminate_useless_gc_barriers(Unique_Node_List &useful) const;
pliden@50525 193 virtual void add_users_to_worklist(Unique_Node_List* worklist) const;
pliden@50525 194 virtual void enqueue_useful_gc_barrier(Unique_Node_List &worklist, Node* node) const;
pliden@50525 195 virtual void register_potential_barrier_node(Node* node) const;
pliden@50525 196 virtual void unregister_potential_barrier_node(Node* node) const;
roland@52036 197 virtual bool array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type, bool is_clone, ArrayCopyPhase phase) const;
eosterlund@51485 198 virtual Node* step_over_gc_barrier(Node* c) const;
pliden@50525 199 // If the BarrierSetC2 state has kept macro nodes in its compilation unit state to be
pliden@50525 200 // expanded later, then now is the time to do so.
pliden@50525 201 virtual bool expand_macro_nodes(PhaseMacroExpand* macro) const;
pliden@50525 202
pliden@50525 203 static void find_dominating_barriers(PhaseIterGVN& igvn);
pliden@50525 204 static void loop_optimize_gc_barrier(PhaseIdealLoop* phase, Node* node, bool last_round);
pliden@50525 205
pliden@50525 206 #ifdef ASSERT
pliden@50525 207 virtual void verify_gc_barriers(bool post_parse) const;
pliden@50525 208 #endif
pliden@50525 209 };
pliden@50525 210
pliden@50525 211 #endif // SHARE_GC_Z_C2_ZBARRIERSETC2_HPP