< prev index next >
src/share/vm/opto/compile.cpp
Print this page
*** 81,90 ****
--- 81,95 ----
# include "adfiles/ad_zero.hpp"
#elif defined TARGET_ARCH_MODEL_ppc_64
# include "adfiles/ad_ppc_64.hpp"
#endif
+ #if INCLUDE_ALL_GCS
+ #include "gc_implementation/shenandoah/shenandoahForwarding.hpp"
+ #include "gc_implementation/shenandoah/c2/shenandoahSupport.hpp"
+ #endif
+
// -------------------- Compile::mach_constant_base_node -----------------------
// Constant table base node singleton.
MachConstantBaseNode* Compile::mach_constant_base_node() {
if (_mach_constant_base_node == NULL) {
_mach_constant_base_node = new (C) MachConstantBaseNode();
*** 403,412 ****
--- 408,422 ----
}
}
if (n->outcnt() == 1 && n->has_special_unique_user()) {
record_for_igvn(n->unique_out());
}
+ if (n->Opcode() == Op_AddP && CallLeafNode::has_only_g1_wb_pre_uses(n)) {
+ for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+ record_for_igvn(n->fast_out(i));
+ }
+ }
}
// Remove useless macro and predicate opaq nodes
for (int i = C->macro_count()-1; i >= 0; i--) {
Node* n = C->macro_node(i);
if (!useful.member(n)) {
*** 425,434 ****
--- 435,450 ----
Node* n = C->expensive_node(i);
if (!useful.member(n)) {
remove_expensive_node(n);
}
}
+ for (int i = C->shenandoah_barriers_count()-1; i >= 0; i--) {
+ ShenandoahLoadReferenceBarrierNode* n = C->shenandoah_barrier(i);
+ if (!useful.member(n)) {
+ remove_shenandoah_barrier(n);
+ }
+ }
// clean up the late inline lists
remove_useless_late_inlines(&_string_late_inlines, useful);
remove_useless_late_inlines(&_boxing_late_inlines, useful);
remove_useless_late_inlines(&_late_inlines, useful);
debug_only(verify_graph_edges(true/*check for no_dead_code*/);)
*** 768,778 ****
// Normal case.
init_tf(TypeFunc::make(method()));
StartNode* s = new (this) StartNode(root(), tf()->domain());
initial_gvn()->set_type_bottom(s);
init_start(s);
! if (method()->intrinsic_id() == vmIntrinsics::_Reference_get && UseG1GC) {
// With java.lang.ref.reference.get() we must go through the
// intrinsic when G1 is enabled - even when get() is the root
// method of the compile - so that, if necessary, the value in
// the referent field of the reference object gets recorded by
// the pre-barrier code.
--- 784,794 ----
// Normal case.
init_tf(TypeFunc::make(method()));
StartNode* s = new (this) StartNode(root(), tf()->domain());
initial_gvn()->set_type_bottom(s);
init_start(s);
! if (method()->intrinsic_id() == vmIntrinsics::_Reference_get && (UseG1GC || UseShenandoahGC)) {
// With java.lang.ref.reference.get() we must go through the
// intrinsic when G1 is enabled - even when get() is the root
// method of the compile - so that, if necessary, the value in
// the referent field of the reference object gets recorded by
// the pre-barrier code.
*** 1161,1170 ****
--- 1177,1187 ----
_intrinsics = NULL;
_macro_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL);
_predicate_opaqs = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL);
_expensive_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL);
_range_check_casts = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL);
+ _shenandoah_barriers = new(comp_arena()) GrowableArray<ShenandoahLoadReferenceBarrierNode*>(comp_arena(), 8, 0, NULL);
register_library_intrinsics();
#ifdef ASSERT
_type_verify_symmetry = true;
#endif
}
*** 2298,2316 ****
--- 2315,2345 ----
// No more loop optimizations. Remove all range check dependent CastIINodes.
C->remove_range_check_casts(igvn);
igvn.optimize();
}
+ #ifdef ASSERT
+ if (UseShenandoahGC && ShenandoahVerifyOptoBarriers) {
+ ShenandoahBarrierC2Support::verify(C->root());
+ }
+ #endif
+
{
NOT_PRODUCT( TracePhase t2("macroExpand", &_t_macroExpand, TimeCompiler); )
PhaseMacroExpand mex(igvn);
if (mex.expand_macro_nodes()) {
assert(failing(), "must bail out w/ explicit message");
return;
}
}
+ #if INCLUDE_ALL_GCS
+ if (UseShenandoahGC) {
+ ShenandoahBarrierC2Support::expand(this, igvn);
+ }
+ #endif
+
} // (End scope of igvn; run destructor if necessary for asserts.)
dump_inlining();
// A method with only infinite loops has no edges entering loops from root
{
*** 2741,2750 ****
--- 2770,2788 ----
case Op_CallRuntime:
case Op_CallLeaf:
case Op_CallLeafNoFP: {
assert( n->is_Call(), "" );
CallNode *call = n->as_Call();
+ if (UseShenandoahGC && call->is_g1_wb_pre_call()) {
+ uint cnt = OptoRuntime::g1_wb_pre_Type()->domain()->cnt();
+ if (call->req() > cnt) {
+ assert(call->req() == cnt+1, "only one extra input");
+ Node* addp = call->in(cnt);
+ assert(!CallLeafNode::has_only_g1_wb_pre_uses(addp), "useless address computation?");
+ call->del_req(cnt);
+ }
+ }
// Count call sites where the FP mode bit would have to be flipped.
// Do not count uncommon runtime calls:
// uncommon_trap, _complete_monitor_locking, _complete_monitor_unlocking,
// _new_Java, _new_typeArray, _new_objArray, _rethrow_Java, ...
if( !call->is_CallStaticJava() || !call->as_CallStaticJava()->_name ) {
*** 2884,2896 ****
}
#endif
break;
}
! #ifdef _LP64
! case Op_CastPP:
! if (n->in(1)->is_DecodeN() && Matcher::gen_narrow_oop_implicit_null_checks()) {
Node* in1 = n->in(1);
const Type* t = n->bottom_type();
Node* new_in1 = in1->clone();
new_in1->as_DecodeN()->set_type(t);
--- 2922,2963 ----
}
#endif
break;
}
! case Op_CastPP: {
! // Remove CastPP nodes to gain more freedom during scheduling but
! // keep the dependency they encode as control or precedence edges
! // (if control is set already) on memory operations. Some CastPP
! // nodes don't have a control (don't carry a dependency): skip
! // those.
! if (n->in(0) != NULL) {
! ResourceMark rm;
! Unique_Node_List wq;
! wq.push(n);
! for (uint next = 0; next < wq.size(); ++next) {
! Node *m = wq.at(next);
! for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) {
! Node* use = m->fast_out(i);
! if (use->is_Mem() || use->is_EncodeNarrowPtr() || use->Opcode() == Op_ShenandoahLoadReferenceBarrier) {
! use->ensure_control_or_add_prec(n->in(0));
! } else if (use->in(0) == NULL) {
! switch(use->Opcode()) {
! case Op_AddP:
! case Op_DecodeN:
! case Op_DecodeNKlass:
! case Op_CheckCastPP:
! case Op_CastPP:
! wq.push(use);
! break;
! }
! }
! }
! }
! }
! const bool is_LP64 = LP64_ONLY(true) NOT_LP64(false);
! if (is_LP64 && n->in(1)->is_DecodeN() && Matcher::gen_narrow_oop_implicit_null_checks()) {
Node* in1 = n->in(1);
const Type* t = n->bottom_type();
Node* new_in1 = in1->clone();
new_in1->as_DecodeN()->set_type(t);
*** 2919,2931 ****
n->subsume_by(new_in1, this);
if (in1->outcnt() == 0) {
in1->disconnect_inputs(NULL, this);
}
}
break;
!
case Op_CmpP:
// Do this transformation here to preserve CmpPNode::sub() and
// other TypePtr related Ideal optimizations (for example, ptr nullness).
if (n->in(1)->is_DecodeNarrowPtr() || n->in(2)->is_DecodeNarrowPtr()) {
Node* in1 = n->in(1);
--- 2986,3004 ----
n->subsume_by(new_in1, this);
if (in1->outcnt() == 0) {
in1->disconnect_inputs(NULL, this);
}
+ } else {
+ n->subsume_by(n->in(1), this);
+ if (n->outcnt() == 0) {
+ n->disconnect_inputs(NULL, this);
+ }
}
break;
! }
! #ifdef _LP64
case Op_CmpP:
// Do this transformation here to preserve CmpPNode::sub() and
// other TypePtr related Ideal optimizations (for example, ptr nullness).
if (n->in(1)->is_DecodeNarrowPtr() || n->in(2)->is_DecodeNarrowPtr()) {
Node* in1 = n->in(1);
*** 3189,3198 ****
--- 3262,3274 ----
// confuses register allocation.
if (n->req() > MemBarNode::Precedent) {
n->set_req(MemBarNode::Precedent, top());
}
break;
+ case Op_ShenandoahLoadReferenceBarrier:
+ assert(false, "should have been expanded already");
+ break;
default:
assert( !n->is_Call(), "" );
assert( !n->is_Mem(), "" );
assert( nop != Op_ProfileBoolean, "should be eliminated during IGVN");
break;
*** 3555,3565 ****
// Verify GC barriers consistency
// Currently supported:
// - G1 pre-barriers (see GraphKit::g1_write_barrier_pre())
void Compile::verify_barriers() {
! if (UseG1GC) {
// Verify G1 pre-barriers
const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active());
ResourceArea *area = Thread::current()->resource_area();
Unique_Node_List visited(area);
--- 3631,3641 ----
// Verify GC barriers consistency
// Currently supported:
// - G1 pre-barriers (see GraphKit::g1_write_barrier_pre())
void Compile::verify_barriers() {
! if (UseG1GC || UseShenandoahGC) {
// Verify G1 pre-barriers
const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() + PtrQueue::byte_offset_of_active());
ResourceArea *area = Thread::current()->resource_area();
Unique_Node_List visited(area);
*** 4079,4089 ****
TypeNode* tn = n->as_Type();
const Type* t = tn->type();
const Type* t_no_spec = t->remove_speculative();
if (t_no_spec != t) {
bool in_hash = igvn.hash_delete(n);
! assert(in_hash, "node should be in igvn hash table");
tn->set_type(t_no_spec);
igvn.hash_insert(n);
igvn._worklist.push(n); // give it a chance to go away
modified++;
}
--- 4155,4165 ----
TypeNode* tn = n->as_Type();
const Type* t = tn->type();
const Type* t_no_spec = t->remove_speculative();
if (t_no_spec != t) {
bool in_hash = igvn.hash_delete(n);
! assert(in_hash || n->hash() == Node::NO_HASH, "node should be in igvn hash table");
tn->set_type(t_no_spec);
igvn.hash_insert(n);
igvn._worklist.push(n); // give it a chance to go away
modified++;
}
*** 4174,4178 ****
--- 4250,4275 ----
#define RANDOMIZED_DOMAIN_MASK ((1 << (RANDOMIZED_DOMAIN_POW + 1)) - 1)
bool Compile::randomized_select(int count) {
assert(count > 0, "only positive");
return (os::random() & RANDOMIZED_DOMAIN_MASK) < (RANDOMIZED_DOMAIN / count);
}
+
+ void Compile::shenandoah_eliminate_g1_wb_pre(Node* call, PhaseIterGVN* igvn) {
+ assert(UseShenandoahGC && call->is_g1_wb_pre_call(), "");
+ Node* c = call->as_Call()->proj_out(TypeFunc::Control);
+ c = c->unique_ctrl_out();
+ assert(c->is_Region() && c->req() == 3, "where's the pre barrier control flow?");
+ c = c->unique_ctrl_out();
+ assert(c->is_Region() && c->req() == 3, "where's the pre barrier control flow?");
+ Node* iff = c->in(1)->is_IfProj() ? c->in(1)->in(0) : c->in(2)->in(0);
+ assert(iff->is_If(), "expect test");
+ if (!iff->is_shenandoah_marking_if(igvn)) {
+ c = c->unique_ctrl_out();
+ assert(c->is_Region() && c->req() == 3, "where's the pre barrier control flow?");
+ iff = c->in(1)->is_IfProj() ? c->in(1)->in(0) : c->in(2)->in(0);
+ assert(iff->is_shenandoah_marking_if(igvn), "expect marking test");
+ }
+ Node* cmpx = iff->in(1)->in(1);
+ igvn->replace_node(cmpx, igvn->makecon(TypeInt::CC_EQ));
+ igvn->rehash_node_delayed(call);
+ call->del_req(call->req()-1);
+ }
< prev index next >