517 #ifndef SERIALGC |
517 #ifndef SERIALGC |
518 |
518 |
519 // Code stubs for Garbage-First barriers. |
519 // Code stubs for Garbage-First barriers. |
520 class G1PreBarrierStub: public CodeStub { |
520 class G1PreBarrierStub: public CodeStub { |
521 private: |
521 private: |
|
522 bool _do_load; |
522 LIR_Opr _addr; |
523 LIR_Opr _addr; |
523 LIR_Opr _pre_val; |
524 LIR_Opr _pre_val; |
524 LIR_PatchCode _patch_code; |
525 LIR_PatchCode _patch_code; |
525 CodeEmitInfo* _info; |
526 CodeEmitInfo* _info; |
526 |
527 |
527 public: |
528 public: |
|
529 // Version that _does_ generate a load of the previous value from addr. |
|
530 // addr (the address of the field to be read) must be a LIR_Address |
528 // pre_val (a temporary register) must be a register; |
531 // pre_val (a temporary register) must be a register; |
529 // addr (the address of the field to be read) must be a LIR_Address |
|
530 G1PreBarrierStub(LIR_Opr addr, LIR_Opr pre_val, LIR_PatchCode patch_code, CodeEmitInfo* info) : |
532 G1PreBarrierStub(LIR_Opr addr, LIR_Opr pre_val, LIR_PatchCode patch_code, CodeEmitInfo* info) : |
531 _addr(addr), _pre_val(pre_val), _patch_code(patch_code), _info(info) |
533 _addr(addr), _pre_val(pre_val), _do_load(true), |
|
534 _patch_code(patch_code), _info(info) |
532 { |
535 { |
533 assert(_pre_val->is_register(), "should be temporary register"); |
536 assert(_pre_val->is_register(), "should be temporary register"); |
534 assert(_addr->is_address(), "should be the address of the field"); |
537 assert(_addr->is_address(), "should be the address of the field"); |
|
538 } |
|
539 |
|
540 // Version that _does not_ generate load of the previous value; the |
|
541 // previous value is assumed to have already been loaded into pre_val. |
|
542 G1PreBarrierStub(LIR_Opr pre_val) : |
|
543 _addr(LIR_OprFact::illegalOpr), _pre_val(pre_val), _do_load(false), |
|
544 _patch_code(lir_patch_none), _info(NULL) |
|
545 { |
|
546 assert(_pre_val->is_register(), "should be a register"); |
535 } |
547 } |
536 |
548 |
537 LIR_Opr addr() const { return _addr; } |
549 LIR_Opr addr() const { return _addr; } |
538 LIR_Opr pre_val() const { return _pre_val; } |
550 LIR_Opr pre_val() const { return _pre_val; } |
539 LIR_PatchCode patch_code() const { return _patch_code; } |
551 LIR_PatchCode patch_code() const { return _patch_code; } |
540 CodeEmitInfo* info() const { return _info; } |
552 CodeEmitInfo* info() const { return _info; } |
541 |
553 bool do_load() const { return _do_load; } |
542 virtual void emit_code(LIR_Assembler* e); |
554 |
543 virtual void visit(LIR_OpVisitState* visitor) { |
555 virtual void emit_code(LIR_Assembler* e); |
544 // don't pass in the code emit info since it's processed in the fast |
556 virtual void visit(LIR_OpVisitState* visitor) { |
545 // path |
557 if (_do_load) { |
546 if (_info != NULL) |
558 // don't pass in the code emit info since it's processed in the fast |
547 visitor->do_slow_case(_info); |
559 // path |
548 else |
560 if (_info != NULL) |
|
561 visitor->do_slow_case(_info); |
|
562 else |
|
563 visitor->do_slow_case(); |
|
564 |
|
565 visitor->do_input(_addr); |
|
566 visitor->do_temp(_pre_val); |
|
567 } else { |
549 visitor->do_slow_case(); |
568 visitor->do_slow_case(); |
550 visitor->do_input(_addr); |
569 visitor->do_input(_pre_val); |
551 visitor->do_temp(_pre_val); |
570 } |
552 } |
571 } |
553 #ifndef PRODUCT |
572 #ifndef PRODUCT |
554 virtual void print_name(outputStream* out) const { out->print("G1PreBarrierStub"); } |
573 virtual void print_name(outputStream* out) const { out->print("G1PreBarrierStub"); } |
|
574 #endif // PRODUCT |
|
575 }; |
|
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"); } |
555 #endif // PRODUCT |
639 #endif // PRODUCT |
556 }; |
640 }; |
557 |
641 |
558 class G1PostBarrierStub: public CodeStub { |
642 class G1PostBarrierStub: public CodeStub { |
559 private: |
643 private: |