Mercurial > hg > truffle
comparison src/share/vm/c1/c1_CodeStubs.hpp @ 6615:09aad8452938
7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
Summary: In C2 add software membar after load from Reference.referent field to prevent commoning of loads across safepoint since GC can change its value. In C1 always generate Reference.get() intrinsic.
Reviewed-by: roland, twisti, dholmes, johnc
author | kvn |
---|---|
date | Mon, 20 Aug 2012 09:58:58 -0700 |
parents | e1162778c1c8 |
children | da91efe96a93 |
comparison
equal
deleted
inserted
replaced
6614:006050192a5a | 6615:09aad8452938 |
---|---|
572 #ifndef PRODUCT | 572 #ifndef PRODUCT |
573 virtual void print_name(outputStream* out) const { out->print("G1PreBarrierStub"); } | 573 virtual void print_name(outputStream* out) const { out->print("G1PreBarrierStub"); } |
574 #endif // PRODUCT | 574 #endif // PRODUCT |
575 }; | 575 }; |
576 | 576 |
577 // This G1 barrier code stub is used in Unsafe.getObject. | |
578 // It generates a sequence of guards around the SATB | |
579 // barrier code that are used to detect when we have | |
580 // the referent field of a Reference object. | |
581 // The first check is assumed to have been generated | |
582 // in the code generated for Unsafe.getObject(). | |
583 | |
584 class G1UnsafeGetObjSATBBarrierStub: public CodeStub { | |
585 private: | |
586 LIR_Opr _val; | |
587 LIR_Opr _src; | |
588 | |
589 LIR_Opr _tmp; | |
590 LIR_Opr _thread; | |
591 | |
592 bool _gen_src_check; | |
593 | |
594 public: | |
595 // A G1 barrier that is guarded by generated guards that determine whether | |
596 // val (which is the result of Unsafe.getObject() should be recorded in an | |
597 // SATB log buffer. We could be reading the referent field of a Reference object | |
598 // using Unsafe.getObject() and we need to record the referent. | |
599 // | |
600 // * val is the operand returned by the unsafe.getObject routine. | |
601 // * src is the base object | |
602 // * tmp is a temp used to load the klass of src, and then reference type | |
603 // * thread is the thread object. | |
604 | |
605 G1UnsafeGetObjSATBBarrierStub(LIR_Opr val, LIR_Opr src, | |
606 LIR_Opr tmp, LIR_Opr thread, | |
607 bool gen_src_check) : | |
608 _val(val), _src(src), | |
609 _tmp(tmp), _thread(thread), | |
610 _gen_src_check(gen_src_check) | |
611 { | |
612 assert(_val->is_register(), "should have already been loaded"); | |
613 assert(_src->is_register(), "should have already been loaded"); | |
614 | |
615 assert(_tmp->is_register(), "should be a temporary register"); | |
616 } | |
617 | |
618 LIR_Opr val() const { return _val; } | |
619 LIR_Opr src() const { return _src; } | |
620 | |
621 LIR_Opr tmp() const { return _tmp; } | |
622 LIR_Opr thread() const { return _thread; } | |
623 | |
624 bool gen_src_check() const { return _gen_src_check; } | |
625 | |
626 virtual void emit_code(LIR_Assembler* e); | |
627 | |
628 virtual void visit(LIR_OpVisitState* visitor) { | |
629 visitor->do_slow_case(); | |
630 visitor->do_input(_val); | |
631 visitor->do_input(_src); | |
632 visitor->do_input(_thread); | |
633 | |
634 visitor->do_temp(_tmp); | |
635 } | |
636 | |
637 #ifndef PRODUCT | |
638 virtual void print_name(outputStream* out) const { out->print("G1UnsafeGetObjSATBBarrierStub"); } | |
639 #endif // PRODUCT | |
640 }; | |
641 | |
642 class G1PostBarrierStub: public CodeStub { | 577 class G1PostBarrierStub: public CodeStub { |
643 private: | 578 private: |
644 LIR_Opr _addr; | 579 LIR_Opr _addr; |
645 LIR_Opr _new_val; | 580 LIR_Opr _new_val; |
646 | 581 |