src/share/vm/c1/c1_CodeStubs.hpp

changeset 2781
e1162778c1c8
parent 2488
e4fee0bdaa85
child 4002
09aad8452938
equal deleted inserted replaced
2780:e6beb62de02d 2781:e1162778c1c8
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:

mercurial