8226287: Make process_users_of_allocation handle gc barriers
Reviewed-by: kvn, roland
This commit is contained in:
parent
a7511da8af
commit
ccbc87cc31
@ -267,6 +267,7 @@ public:
|
||||
virtual bool has_load_barriers() const { return false; }
|
||||
virtual bool is_gc_barrier_node(Node* node) const { return false; }
|
||||
virtual Node* step_over_gc_barrier(Node* c) const { return c; }
|
||||
virtual Node* step_over_gc_barrier_ctrl(Node* c) const { return c; }
|
||||
|
||||
// Support for macro expanded GC barriers
|
||||
virtual void register_potential_barrier_node(Node* node) const { }
|
||||
|
@ -522,7 +522,7 @@ void ZBarrierSetC2::expand_loadbarrier_node(PhaseMacroExpand* phase, LoadBarrier
|
||||
Node* in_val = barrier->in(LoadBarrierNode::Oop);
|
||||
Node* in_adr = barrier->in(LoadBarrierNode::Address);
|
||||
|
||||
Node* out_ctrl = barrier->proj_out_or_null(LoadBarrierNode::Control);
|
||||
Node* out_ctrl = barrier->proj_out(LoadBarrierNode::Control);
|
||||
Node* out_res = barrier->proj_out(LoadBarrierNode::Oop);
|
||||
|
||||
assert(barrier->in(LoadBarrierNode::Oop) != NULL, "oop to loadbarrier node cannot be null");
|
||||
@ -552,9 +552,8 @@ void ZBarrierSetC2::expand_loadbarrier_node(PhaseMacroExpand* phase, LoadBarrier
|
||||
result_phi->set_req(1, new_loadp);
|
||||
result_phi->set_req(2, barrier->in(LoadBarrierNode::Oop));
|
||||
|
||||
if (out_ctrl != NULL) {
|
||||
igvn.replace_node(out_ctrl, result_region);
|
||||
}
|
||||
|
||||
igvn.replace_node(out_ctrl, result_region);
|
||||
igvn.replace_node(out_res, result_phi);
|
||||
|
||||
assert(barrier->outcnt() == 0,"LoadBarrier macro node has non-null outputs after expansion!");
|
||||
@ -640,6 +639,22 @@ Node* ZBarrierSetC2::step_over_gc_barrier(Node* c) const {
|
||||
return c;
|
||||
}
|
||||
|
||||
Node* ZBarrierSetC2::step_over_gc_barrier_ctrl(Node* c) const {
|
||||
Node* node = c;
|
||||
|
||||
// 1. This step follows potential ctrl projections of a load barrier before expansion
|
||||
if (node->is_Proj()) {
|
||||
node = node->in(0);
|
||||
}
|
||||
|
||||
// 2. This step checks for unexpanded load barriers
|
||||
if (node->is_LoadBarrier()) {
|
||||
return node->in(LoadBarrierNode::Control);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
bool ZBarrierSetC2::array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type, bool is_clone, ArrayCopyPhase phase) const {
|
||||
return type == T_OBJECT || type == T_ARRAY;
|
||||
}
|
||||
|
@ -182,6 +182,7 @@ public:
|
||||
virtual bool has_load_barriers() const { return true; }
|
||||
virtual bool is_gc_barrier_node(Node* node) const;
|
||||
virtual Node* step_over_gc_barrier(Node* c) const;
|
||||
virtual Node* step_over_gc_barrier_ctrl(Node* c) const;
|
||||
|
||||
virtual void register_potential_barrier_node(Node* node) const;
|
||||
virtual void unregister_potential_barrier_node(Node* node) const;
|
||||
|
@ -1008,8 +1008,17 @@ void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) {
|
||||
assert(init->outcnt() <= 2, "only a control and memory projection expected");
|
||||
Node *ctrl_proj = init->proj_out_or_null(TypeFunc::Control);
|
||||
if (ctrl_proj != NULL) {
|
||||
assert(init->in(TypeFunc::Control) == _fallthroughcatchproj, "allocation control projection");
|
||||
_igvn.replace_node(ctrl_proj, _fallthroughcatchproj);
|
||||
_igvn.replace_node(ctrl_proj, init->in(TypeFunc::Control));
|
||||
#ifdef ASSERT
|
||||
BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
|
||||
Node* tmp = init->in(TypeFunc::Control);
|
||||
while (bs->is_gc_barrier_node(tmp)) {
|
||||
Node* tmp2 = bs->step_over_gc_barrier_ctrl(tmp);
|
||||
assert(tmp != tmp2, "Must make progress");
|
||||
tmp = tmp2;
|
||||
}
|
||||
assert(tmp == _fallthroughcatchproj, "allocation control projection");
|
||||
#endif
|
||||
}
|
||||
Node *mem_proj = init->proj_out_or_null(TypeFunc::Memory);
|
||||
if (mem_proj != NULL) {
|
||||
|
Loading…
Reference in New Issue
Block a user