< prev index next >
src/hotspot/share/opto/escape.cpp
Print this page
rev 52710 : Upstream/backport Shenandoah to JDK11u
@@ -43,10 +43,13 @@
#include "gc/g1/g1ThreadLocalData.hpp"
#endif // INCLUDE_G1GC
#if INCLUDE_ZGC
#include "gc/z/c2/zBarrierSetC2.hpp"
#endif
+#if INCLUDE_SHENANDOAHGC
+#include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
+#endif
ConnectionGraph::ConnectionGraph(Compile * C, PhaseIterGVN *igvn) :
_nodes(C->comp_arena(), C->unique(), C->unique(), NULL),
_in_worklist(C->comp_arena()),
_next_pidx(0),
@@ -510,19 +513,29 @@
}
break;
}
case Op_CompareAndExchangeP:
case Op_CompareAndExchangeN:
+#if INCLUDE_SHENANDOAHGC
+ case Op_ShenandoahCompareAndExchangeP:
+ case Op_ShenandoahCompareAndExchangeN:
+#endif
case Op_GetAndSetP:
case Op_GetAndSetN: {
add_objload_to_connection_graph(n, delayed_worklist);
// fallthrough
}
case Op_StoreP:
case Op_StoreN:
case Op_StoreNKlass:
case Op_StorePConditional:
+#if INCLUDE_SHENANDOAHGC
+ case Op_ShenandoahWeakCompareAndSwapP:
+ case Op_ShenandoahWeakCompareAndSwapN:
+ case Op_ShenandoahCompareAndSwapP:
+ case Op_ShenandoahCompareAndSwapN:
+#endif
case Op_WeakCompareAndSwapP:
case Op_WeakCompareAndSwapN:
case Op_CompareAndSwapP:
case Op_CompareAndSwapN: {
Node* adr = n->in(MemNode::Address);
@@ -552,20 +565,28 @@
// Stored value escapes in unsafe access.
if ((opcode == Op_StoreP) && adr_type->isa_rawptr()) {
// Pointer stores in G1 barriers looks like unsafe access.
// Ignore such stores to be able scalar replace non-escaping
// allocations.
-#if INCLUDE_G1GC
- if (UseG1GC && adr->is_AddP()) {
+#if INCLUDE_G1GC || INCLUDE_SHENANDOAHGC
+ if ((UseG1GC || UseShenandoahGC) && adr->is_AddP()) {
Node* base = get_addp_base(adr);
if (base->Opcode() == Op_LoadP &&
base->in(MemNode::Address)->is_AddP()) {
adr = base->in(MemNode::Address);
Node* tls = get_addp_base(adr);
if (tls->Opcode() == Op_ThreadLocal) {
int offs = (int)igvn->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot);
- if (offs == in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset())) {
+#if INCLUDE_G1GC && INCLUDE_SHENANDOAHGC
+ const int buf_offset = in_bytes(UseG1GC ? G1ThreadLocalData::satb_mark_queue_buffer_offset()
+ : ShenandoahThreadLocalData::satb_mark_queue_buffer_offset());
+#elif INCLUDE_G1GC
+ const int buf_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset());
+#else
+ const int buf_offset = in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset());
+#endif
+ if (offs == buf_offset) {
break; // G1 pre barrier previous oop value store.
}
if (offs == in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset())) {
break; // G1 post barrier card address store.
}
@@ -598,10 +619,17 @@
}
case Op_ThreadLocal: {
add_java_object(n, PointsToNode::ArgEscape);
break;
}
+#if INCLUDE_SHENANDOAHGC
+ case Op_ShenandoahEnqueueBarrier:
+ add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(1), delayed_worklist);
+ break;
+ case Op_ShenandoahLoadReferenceBarrier:
+ add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(ShenandoahLoadReferenceBarrierNode::ValueIn), delayed_worklist);
+#endif
default:
; // Do nothing for nodes not related to EA.
}
return;
}
@@ -738,10 +766,18 @@
case Op_CompareAndExchangeN:
case Op_CompareAndSwapP:
case Op_CompareAndSwapN:
case Op_WeakCompareAndSwapP:
case Op_WeakCompareAndSwapN:
+#if INCLUDE_SHENANDOAHGC
+ case Op_ShenandoahCompareAndExchangeP:
+ case Op_ShenandoahCompareAndExchangeN:
+ case Op_ShenandoahCompareAndSwapP:
+ case Op_ShenandoahCompareAndSwapN:
+ case Op_ShenandoahWeakCompareAndSwapP:
+ case Op_ShenandoahWeakCompareAndSwapN:
+#endif
case Op_GetAndSetP:
case Op_GetAndSetN: {
Node* adr = n->in(MemNode::Address);
const Type *adr_type = _igvn->type(adr);
adr_type = adr_type->make_ptr();
@@ -751,10 +787,13 @@
assert(adr_type != NULL, "dead node should not be on list");
break;
}
#endif
if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN ||
+#if INCLUDE_SHENANDOAHGC
+ opcode == Op_ShenandoahCompareAndExchangeN || opcode == Op_ShenandoahCompareAndExchangeP ||
+#endif
opcode == Op_CompareAndExchangeN || opcode == Op_CompareAndExchangeP) {
add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
}
if ( adr_type->isa_oopptr()
|| ( (opcode == Op_StoreP || opcode == Op_StoreN || opcode == Op_StoreNKlass)
@@ -813,10 +852,18 @@
add_edge(n_ptn, ptn);
}
}
break;
}
+#if INCLUDE_SHENANDOAHGC
+ case Op_ShenandoahEnqueueBarrier:
+ add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(1), NULL);
+ break;
+ case Op_ShenandoahLoadReferenceBarrier:
+ add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(ShenandoahLoadReferenceBarrierNode::ValueIn), NULL);
+ break;
+#endif
default: {
// This method should be called only for EA specific nodes which may
// miss some edges when they were created.
#ifdef ASSERT
n->dump(1);
@@ -2111,10 +2158,14 @@
bt = field->layout_type();
} else {
// Check for unsafe oop field access
if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
+#if INCLUDE_SHENANDOAHGC
+ n->has_out_with(Op_ShenandoahCompareAndExchangeP) || n->has_out_with(Op_ShenandoahCompareAndExchangeN) ||
+ n->has_out_with(Op_ShenandoahCompareAndSwapP, Op_ShenandoahCompareAndSwapN, Op_ShenandoahWeakCompareAndSwapP, Op_ShenandoahWeakCompareAndSwapN) ||
+#endif
n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN)) {
bt = T_OBJECT;
(*unsafe) = true;
}
}
@@ -2376,11 +2427,12 @@
Node* uncast_base = base->uncast();
int opcode = uncast_base->Opcode();
assert(opcode == Op_ConP || opcode == Op_ThreadLocal ||
opcode == Op_CastX2P || uncast_base->is_DecodeNarrowPtr() ||
(uncast_base->is_Mem() && (uncast_base->bottom_type()->isa_rawptr() != NULL)) ||
- (uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()), "sanity");
+ (uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()) ||
+ uncast_base->Opcode() == Op_ShenandoahLoadReferenceBarrier, "sanity");
}
}
return base;
}
< prev index next >