534 Node* obj = access.base(); |
534 Node* obj = access.base(); |
535 |
535 |
536 bool mismatched = (decorators & C2_MISMATCHED) != 0; |
536 bool mismatched = (decorators & C2_MISMATCHED) != 0; |
537 bool unknown = (decorators & ON_UNKNOWN_OOP_REF) != 0; |
537 bool unknown = (decorators & ON_UNKNOWN_OOP_REF) != 0; |
538 bool on_heap = (decorators & IN_HEAP) != 0; |
538 bool on_heap = (decorators & IN_HEAP) != 0; |
539 bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0; |
539 bool on_weak_ref = (decorators & (ON_WEAK_OOP_REF | ON_PHANTOM_OOP_REF)) != 0; |
540 bool is_unordered = (decorators & MO_UNORDERED) != 0; |
540 bool is_unordered = (decorators & MO_UNORDERED) != 0; |
541 bool need_cpu_mem_bar = !is_unordered || mismatched || !on_heap; |
541 bool need_cpu_mem_bar = !is_unordered || mismatched || !on_heap; |
|
542 bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); |
|
543 bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; |
|
544 bool in_native = (decorators & IN_NATIVE) != 0; |
542 |
545 |
543 Node* top = Compile::current()->top(); |
546 Node* top = Compile::current()->top(); |
544 |
547 |
545 Node* offset = adr->is_AddP() ? adr->in(AddPNode::Offset) : top; |
548 Node* offset = adr->is_AddP() ? adr->in(AddPNode::Offset) : top; |
546 Node* load = BarrierSetC2::load_at_resolved(access, val_type); |
549 Node* load = BarrierSetC2::load_at_resolved(access, val_type); |
547 |
550 |
548 if (access.is_oop()) { |
551 if (access.is_oop()) { |
549 if (ShenandoahLoadRefBarrier) { |
552 if (ShenandoahLoadRefBarrier) { |
550 load = new ShenandoahLoadReferenceBarrierNode(NULL, load, (decorators & IN_NATIVE) != 0); |
553 load = new ShenandoahLoadReferenceBarrierNode(NULL, load, in_native && !is_traversal_mode); |
551 if (access.is_parse_access()) { |
554 if (access.is_parse_access()) { |
552 load = static_cast<C2ParseAccess &>(access).kit()->gvn().transform(load); |
555 load = static_cast<C2ParseAccess &>(access).kit()->gvn().transform(load); |
553 } else { |
556 } else { |
554 load = static_cast<C2OptAccess &>(access).gvn().transform(load); |
557 load = static_cast<C2OptAccess &>(access).gvn().transform(load); |
555 } |
558 } |
561 // then, if SATB is enabled, we need to record the referent in an |
564 // then, if SATB is enabled, we need to record the referent in an |
562 // SATB log buffer using the pre-barrier mechanism. |
565 // SATB log buffer using the pre-barrier mechanism. |
563 // Also we need to add memory barrier to prevent commoning reads |
566 // Also we need to add memory barrier to prevent commoning reads |
564 // from this field across safepoint since GC can change its value. |
567 // from this field across safepoint since GC can change its value. |
565 bool need_read_barrier = ShenandoahKeepAliveBarrier && |
568 bool need_read_barrier = ShenandoahKeepAliveBarrier && |
566 (on_heap && (on_weak || (unknown && offset != top && obj != top))); |
569 (on_weak_ref || (unknown && offset != top && obj != top)); |
567 |
570 |
568 if (!access.is_oop() || !need_read_barrier) { |
571 if (!access.is_oop() || !need_read_barrier) { |
569 return load; |
572 return load; |
570 } |
573 } |
571 |
574 |
572 assert(access.is_parse_access(), "entry not supported at optimization time"); |
575 assert(access.is_parse_access(), "entry not supported at optimization time"); |
573 C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(access); |
576 C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(access); |
574 GraphKit* kit = parse_access.kit(); |
577 GraphKit* kit = parse_access.kit(); |
575 |
578 |
576 if (on_weak) { |
579 if (on_weak_ref && keep_alive) { |
577 // Use the pre-barrier to record the value in the referent field |
580 // Use the pre-barrier to record the value in the referent field |
578 satb_write_barrier_pre(kit, false /* do_load */, |
581 satb_write_barrier_pre(kit, false /* do_load */, |
579 NULL /* obj */, NULL /* adr */, max_juint /* alias_idx */, NULL /* val */, NULL /* val_type */, |
582 NULL /* obj */, NULL /* adr */, max_juint /* alias_idx */, NULL /* val */, NULL /* val_type */, |
580 load /* pre_val */, T_OBJECT); |
583 load /* pre_val */, T_OBJECT); |
581 // Add memory barrier to prevent commoning reads from this field |
584 // Add memory barrier to prevent commoning reads from this field |