< prev index next >

src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp

Print this page
rev 59195 : 8244594: [BACKOUT] 8244523: Shenandoah: Remove null-handling in LRB expansion
rev 59196 : 8244595: [REDO] 8244523: Shenandoah: Remove null-handling in LRB expansion


 464 
 465   // create result type (range)
 466   fields = TypeTuple::fields(0);
 467   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 468 
 469   return TypeFunc::make(domain, range);
 470 }
 471 
 472 const TypeFunc* ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type() {
 473   const Type **fields = TypeTuple::fields(1);
 474   fields[TypeFunc::Parms+0] = TypeOopPtr::NOTNULL; // src oop
 475   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
 476 
 477   // create result type (range)
 478   fields = TypeTuple::fields(0);
 479   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 480 
 481   return TypeFunc::make(domain, range);
 482 }
 483 
 484 const TypeFunc* ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type() {
 485   const Type **fields = TypeTuple::fields(2);
 486   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
 487   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;   // original load address
 488 
 489   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
 490 
 491   // create result type (range)
 492   fields = TypeTuple::fields(1);
 493   fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
 494   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
 495 
 496   return TypeFunc::make(domain, range);
 497 }
 498 
 499 Node* ShenandoahBarrierSetC2::store_at_resolved(C2Access& access, C2AccessValue& val) const {
 500   DecoratorSet decorators = access.decorators();
 501 
 502   const TypePtr* adr_type = access.addr().type();
 503   Node* adr = access.addr().node();
 504 
 505   bool anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0;
 506   bool on_heap = (decorators & IN_HEAP) != 0;
 507 
 508   if (!access.is_oop() || (!on_heap && !anonymous)) {
 509     return BarrierSetC2::store_at_resolved(access, val);
 510   }
 511 
 512   if (access.is_parse_access()) {
 513     C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(access);


1042       }
1043     }
1044   }
1045 }
1046 #endif
1047 
1048 Node* ShenandoahBarrierSetC2::ideal_node(PhaseGVN* phase, Node* n, bool can_reshape) const {
1049   if (is_shenandoah_wb_pre_call(n)) {
1050     uint cnt = ShenandoahBarrierSetC2::write_ref_field_pre_entry_Type()->domain()->cnt();
1051     if (n->req() > cnt) {
1052       Node* addp = n->in(cnt);
1053       if (has_only_shenandoah_wb_pre_uses(addp)) {
1054         n->del_req(cnt);
1055         if (can_reshape) {
1056           phase->is_IterGVN()->_worklist.push(addp);
1057         }
1058         return n;
1059       }
1060     }
1061   }
1062   if (n->Opcode() == Op_CmpP) {
1063     Node* in1 = n->in(1);
1064     Node* in2 = n->in(2);
1065     if (in1->bottom_type() == TypePtr::NULL_PTR) {
1066       in2 = step_over_gc_barrier(in2);
1067     }
1068     if (in2->bottom_type() == TypePtr::NULL_PTR) {
1069       in1 = step_over_gc_barrier(in1);
1070     }
1071     PhaseIterGVN* igvn = phase->is_IterGVN();
1072     if (in1 != n->in(1)) {
1073       if (igvn != NULL) {
1074         n->set_req_X(1, in1, igvn);
1075       } else {
1076         n->set_req(1, in1);
1077       }
1078       assert(in2 == n->in(2), "only one change");
1079       return n;
1080     }
1081     if (in2 != n->in(2)) {
1082       if (igvn != NULL) {
1083         n->set_req_X(2, in2, igvn);
1084       } else {
1085         n->set_req(2, in2);
1086       }
1087       return n;
1088     }
1089   } else if (can_reshape &&
1090              n->Opcode() == Op_If &&
1091              ShenandoahBarrierC2Support::is_heap_stable_test(n) &&
1092              n->in(0) != NULL) {
1093     Node* dom = n->in(0);
1094     Node* prev_dom = n;
1095     int op = n->Opcode();
1096     int dist = 16;
1097     // Search up the dominator tree for another heap stable test
1098     while (dom->Opcode() != op    ||  // Not same opcode?
1099            !ShenandoahBarrierC2Support::is_heap_stable_test(dom) ||  // Not same input 1?
1100            prev_dom->in(0) != dom) {  // One path of test does not dominate?
1101       if (dist < 0) return NULL;
1102 
1103       dist--;
1104       prev_dom = dom;
1105       dom = IfNode::up_one_dom(dom);
1106       if (!dom) return NULL;
1107     }
1108 
1109     // Check that we did not follow a loop back to ourselves




 464 
 465   // create result type (range)
 466   fields = TypeTuple::fields(0);
 467   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 468 
 469   return TypeFunc::make(domain, range);
 470 }
 471 
 472 const TypeFunc* ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type() {
 473   const Type **fields = TypeTuple::fields(1);
 474   fields[TypeFunc::Parms+0] = TypeOopPtr::NOTNULL; // src oop
 475   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
 476 
 477   // create result type (range)
 478   fields = TypeTuple::fields(0);
 479   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
 480 
 481   return TypeFunc::make(domain, range);
 482 }
 483 
 484 const TypeFunc* ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(const Type* value_type) {
 485   const Type **fields = TypeTuple::fields(2);
 486   fields[TypeFunc::Parms+0] = value_type;           // original field value
 487   fields[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM;   // original load address
 488 
 489   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+2, fields);
 490 
 491   // create result type (range)
 492   fields = TypeTuple::fields(1);
 493   fields[TypeFunc::Parms+0] = value_type;
 494   const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
 495 
 496   return TypeFunc::make(domain, range);
 497 }
 498 
 499 Node* ShenandoahBarrierSetC2::store_at_resolved(C2Access& access, C2AccessValue& val) const {
 500   DecoratorSet decorators = access.decorators();
 501 
 502   const TypePtr* adr_type = access.addr().type();
 503   Node* adr = access.addr().node();
 504 
 505   bool anonymous = (decorators & ON_UNKNOWN_OOP_REF) != 0;
 506   bool on_heap = (decorators & IN_HEAP) != 0;
 507 
 508   if (!access.is_oop() || (!on_heap && !anonymous)) {
 509     return BarrierSetC2::store_at_resolved(access, val);
 510   }
 511 
 512   if (access.is_parse_access()) {
 513     C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(access);


1042       }
1043     }
1044   }
1045 }
1046 #endif
1047 
1048 Node* ShenandoahBarrierSetC2::ideal_node(PhaseGVN* phase, Node* n, bool can_reshape) const {
1049   if (is_shenandoah_wb_pre_call(n)) {
1050     uint cnt = ShenandoahBarrierSetC2::write_ref_field_pre_entry_Type()->domain()->cnt();
1051     if (n->req() > cnt) {
1052       Node* addp = n->in(cnt);
1053       if (has_only_shenandoah_wb_pre_uses(addp)) {
1054         n->del_req(cnt);
1055         if (can_reshape) {
1056           phase->is_IterGVN()->_worklist.push(addp);
1057         }
1058         return n;
1059       }
1060     }
1061   }
1062   if (can_reshape &&



























1063       n->Opcode() == Op_If &&
1064       ShenandoahBarrierC2Support::is_heap_stable_test(n) &&
1065       n->in(0) != NULL) {
1066     Node* dom = n->in(0);
1067     Node* prev_dom = n;
1068     int op = n->Opcode();
1069     int dist = 16;
1070     // Search up the dominator tree for another heap stable test
1071     while (dom->Opcode() != op    ||  // Not same opcode?
1072            !ShenandoahBarrierC2Support::is_heap_stable_test(dom) ||  // Not same input 1?
1073            prev_dom->in(0) != dom) {  // One path of test does not dominate?
1074       if (dist < 0) return NULL;
1075 
1076       dist--;
1077       prev_dom = dom;
1078       dom = IfNode::up_one_dom(dom);
1079       if (!dom) return NULL;
1080     }
1081 
1082     // Check that we did not follow a loop back to ourselves


< prev index next >