470 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); |
470 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); |
471 |
471 |
472 return TypeFunc::make(domain, range); |
472 return TypeFunc::make(domain, range); |
473 } |
473 } |
474 |
474 |
475 const TypeFunc* ShenandoahBarrierSetC2::oop_load_from_native_barrier_Type() { |
|
476 const Type **fields = TypeTuple::fields(1); |
|
477 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value |
|
478 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); |
|
479 |
|
480 // create result type (range) |
|
481 fields = TypeTuple::fields(1); |
|
482 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; |
|
483 const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields); |
|
484 |
|
485 return TypeFunc::make(domain, range); |
|
486 } |
|
487 |
|
488 const TypeFunc* ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type() { |
475 const TypeFunc* ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type() { |
489 const Type **fields = TypeTuple::fields(1); |
476 const Type **fields = TypeTuple::fields(1); |
490 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value |
477 fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value |
491 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); |
478 const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); |
492 |
479 |
553 Node* top = Compile::current()->top(); |
540 Node* top = Compile::current()->top(); |
554 |
541 |
555 Node* offset = adr->is_AddP() ? adr->in(AddPNode::Offset) : top; |
542 Node* offset = adr->is_AddP() ? adr->in(AddPNode::Offset) : top; |
556 Node* load = BarrierSetC2::load_at_resolved(access, val_type); |
543 Node* load = BarrierSetC2::load_at_resolved(access, val_type); |
557 |
544 |
558 if ((decorators & IN_NATIVE) != 0) { |
|
559 assert(access.is_oop(), "IN_NATIVE access only for oop values"); |
|
560 assert(access.is_parse_access(), "IN_NATIVE access only during parsing"); |
|
561 GraphKit* kit = static_cast<C2ParseAccess &>(access).kit(); |
|
562 Node* call = kit->make_runtime_call(GraphKit::RC_LEAF, |
|
563 oop_load_from_native_barrier_Type(), |
|
564 CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), |
|
565 "ShenandoahRuntime::load_reference_barrier_native", |
|
566 NULL, load); |
|
567 Node* proj = kit->gvn().transform(new ProjNode(call, TypeFunc::Parms+0)); |
|
568 return kit->gvn().transform(new CheckCastPPNode(kit->control(), proj, load->bottom_type())); |
|
569 } |
|
570 |
|
571 if (access.is_oop()) { |
545 if (access.is_oop()) { |
572 if (ShenandoahLoadRefBarrier) { |
546 if (ShenandoahLoadRefBarrier) { |
573 load = new ShenandoahLoadReferenceBarrierNode(NULL, load); |
547 load = new ShenandoahLoadReferenceBarrierNode(NULL, load, (decorators & IN_NATIVE) != 0); |
574 if (access.is_parse_access()) { |
548 if (access.is_parse_access()) { |
575 load = static_cast<C2ParseAccess &>(access).kit()->gvn().transform(load); |
549 load = static_cast<C2ParseAccess &>(access).kit()->gvn().transform(load); |
576 } else { |
550 } else { |
577 load = static_cast<C2OptAccess &>(access).gvn().transform(load); |
551 load = static_cast<C2OptAccess &>(access).gvn().transform(load); |
578 } |
552 } |
653 #ifdef _LP64 |
627 #ifdef _LP64 |
654 if (adr->bottom_type()->is_ptr_to_narrowoop()) { |
628 if (adr->bottom_type()->is_ptr_to_narrowoop()) { |
655 load_store = kit->gvn().transform(new DecodeNNode(load_store, load_store->get_ptr_type())); |
629 load_store = kit->gvn().transform(new DecodeNNode(load_store, load_store->get_ptr_type())); |
656 } |
630 } |
657 #endif |
631 #endif |
658 load_store = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, load_store)); |
632 load_store = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, load_store, false)); |
659 return load_store; |
633 return load_store; |
660 } |
634 } |
661 return BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type); |
635 return BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type); |
662 } |
636 } |
663 |
637 |
721 if (access.is_oop()) { |
695 if (access.is_oop()) { |
722 val = shenandoah_storeval_barrier(kit, val); |
696 val = shenandoah_storeval_barrier(kit, val); |
723 } |
697 } |
724 Node* result = BarrierSetC2::atomic_xchg_at_resolved(access, val, value_type); |
698 Node* result = BarrierSetC2::atomic_xchg_at_resolved(access, val, value_type); |
725 if (access.is_oop()) { |
699 if (access.is_oop()) { |
726 result = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, result)); |
700 result = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, result, false)); |
727 shenandoah_write_barrier_pre(kit, false /* do_load */, |
701 shenandoah_write_barrier_pre(kit, false /* do_load */, |
728 NULL, NULL, max_juint, NULL, NULL, |
702 NULL, NULL, max_juint, NULL, NULL, |
729 result /* pre_val */, T_OBJECT); |
703 result /* pre_val */, T_OBJECT); |
730 } |
704 } |
731 return result; |
705 return result; |
747 return false; |
721 return false; |
748 } |
722 } |
749 |
723 |
750 return strcmp(call->_name, "shenandoah_clone_barrier") == 0 || |
724 return strcmp(call->_name, "shenandoah_clone_barrier") == 0 || |
751 strcmp(call->_name, "shenandoah_cas_obj") == 0 || |
725 strcmp(call->_name, "shenandoah_cas_obj") == 0 || |
752 strcmp(call->_name, "shenandoah_wb_pre") == 0 || |
726 strcmp(call->_name, "shenandoah_wb_pre") == 0; |
753 strcmp(call->_name, "ShenandoahRuntime::load_reference_barrier_native") == 0; |
|
754 } |
727 } |
755 |
728 |
756 Node* ShenandoahBarrierSetC2::step_over_gc_barrier(Node* c) const { |
729 Node* ShenandoahBarrierSetC2::step_over_gc_barrier(Node* c) const { |
757 if (c->Opcode() == Op_ShenandoahLoadReferenceBarrier) { |
730 if (c->Opcode() == Op_ShenandoahLoadReferenceBarrier) { |
758 return c->in(ShenandoahLoadReferenceBarrierNode::ValueIn); |
731 return c->in(ShenandoahLoadReferenceBarrierNode::ValueIn); |
1180 conn_graph->add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(1), delayed_worklist); |
1153 conn_graph->add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(1), delayed_worklist); |
1181 break; |
1154 break; |
1182 case Op_ShenandoahLoadReferenceBarrier: |
1155 case Op_ShenandoahLoadReferenceBarrier: |
1183 conn_graph->add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(ShenandoahLoadReferenceBarrierNode::ValueIn), delayed_worklist); |
1156 conn_graph->add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(ShenandoahLoadReferenceBarrierNode::ValueIn), delayed_worklist); |
1184 return true; |
1157 return true; |
1185 case Op_CallLeaf: |
|
1186 if (strcmp(n->as_CallLeaf()->_name, "ShenandoahRuntime::load_reference_barrier_native") == 0) { |
|
1187 conn_graph->map_ideal_node(n, conn_graph->phantom_obj); |
|
1188 return true; |
|
1189 } |
|
1190 default: |
1158 default: |
1191 // Nothing |
1159 // Nothing |
1192 break; |
1160 break; |
1193 } |
1161 } |
1194 return false; |
1162 return false; |