< 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


 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);


1028                 Node *load_ctrl = load->in(0);
1029 
1030                 if (if_ctrl != load_ctrl) {
1031                   // Skip possible CProj->NeverBranch in infinite loops
1032                   if ((if_ctrl->is_Proj() && if_ctrl->Opcode() == Op_CProj)
1033                       && (if_ctrl->in(0)->is_MultiBranch() && if_ctrl->in(0)->Opcode() == Op_NeverBranch)) {
1034                     if_ctrl = if_ctrl->in(0)->in(0);
1035                   }
1036                 }
1037                 assert(load_ctrl != NULL && if_ctrl == load_ctrl, "controls must match");
1038               }
1039             }
1040           }
1041         }
1042       }
1043     }
1044   }
1045 }
1046 #endif
1047 
1048 bool ShenandoahBarrierSetC2::maybe_skip_barrier(Node* n, uint i, PhaseGVN* phase) const {
1049   PhaseIterGVN* igvn = phase->is_IterGVN();
1050   Node* in = step_over_gc_barrier(n->in(i));
1051   if (in != n->in(i)) {
1052     if (igvn != NULL) {
1053       n->set_req_X(i, in, igvn);
1054     } else {
1055       n->set_req(i, in);
1056     }
1057     return true;
1058   }
1059   return false;
1060 }
1061 
1062 Node* ShenandoahBarrierSetC2::ideal_node(PhaseGVN* phase, Node* n, bool can_reshape) const {
1063   if (is_shenandoah_wb_pre_call(n)) {
1064     uint cnt = ShenandoahBarrierSetC2::write_ref_field_pre_entry_Type()->domain()->cnt();
1065     if (n->req() > cnt) {
1066       Node* addp = n->in(cnt);
1067       if (has_only_shenandoah_wb_pre_uses(addp)) {
1068         n->del_req(cnt);
1069         if (can_reshape) {
1070           phase->is_IterGVN()->_worklist.push(addp);
1071         }
1072         return n;
1073       }
1074     }
1075   }
1076   if (n->Opcode() == Op_CmpP) {
1077     Node* in1 = n->in(1);
1078     Node* in2 = n->in(2);
1079     if (in1->bottom_type() == TypePtr::NULL_PTR) {
1080       in2 = step_over_gc_barrier(in2);
1081     }
1082     if (in2->bottom_type() == TypePtr::NULL_PTR) {
1083       in1 = step_over_gc_barrier(in1);
1084     }
1085     PhaseIterGVN* igvn = phase->is_IterGVN();
1086     if (in1 != n->in(1)) {
1087       if (igvn != NULL) {
1088         n->set_req_X(1, in1, igvn);
1089       } else {
1090         n->set_req(1, in1);
1091       }
1092       assert(in2 == n->in(2), "only one change");
1093       return n;
1094     }
1095     if (in2 != n->in(2)) {
1096       if (igvn != NULL) {
1097         n->set_req_X(2, in2, igvn);
1098       } else {
1099         n->set_req(2, in2);
1100       }
1101       return n;
1102     }
1103   } else if (n->Opcode() == Op_CallStaticJava) {
1104     if (n->as_CallStaticJava()->uncommon_trap_request() != 0) {
1105       // Uncommon traps don't need barriers, values are handled
1106       // during deoptimization. It also affects optimizing null-checks
1107       // into implicit null-checks.
1108       PhaseIterGVN* igvn = phase->is_IterGVN();
1109       Node* ret = NULL;
1110       for (uint i = TypeFunc::Parms; i < n->len(); i++) {
1111         if (maybe_skip_barrier(n, i, phase)) {
1112           ret = n;
1113         }
1114       }
1115       return ret;
1116     }
1117   } else if (can_reshape &&
1118              n->Opcode() == Op_If &&
1119              ShenandoahBarrierC2Support::is_heap_stable_test(n) &&
1120              n->in(0) != NULL) {
1121     Node* dom = n->in(0);
1122     Node* prev_dom = n;
1123     int op = n->Opcode();
1124     int dist = 16;
1125     // Search up the dominator tree for another heap stable test
1126     while (dom->Opcode() != op    ||  // Not same opcode?
1127            !ShenandoahBarrierC2Support::is_heap_stable_test(dom) ||  // Not same input 1?
1128            prev_dom->in(0) != dom) {  // One path of test does not dominate?
1129       if (dist < 0) return NULL;
1130 
1131       dist--;
1132       prev_dom = dom;
1133       dom = IfNode::up_one_dom(dom);
1134       if (!dom) return NULL;
1135     }




 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);


1028                 Node *load_ctrl = load->in(0);
1029 
1030                 if (if_ctrl != load_ctrl) {
1031                   // Skip possible CProj->NeverBranch in infinite loops
1032                   if ((if_ctrl->is_Proj() && if_ctrl->Opcode() == Op_CProj)
1033                       && (if_ctrl->in(0)->is_MultiBranch() && if_ctrl->in(0)->Opcode() == Op_NeverBranch)) {
1034                     if_ctrl = if_ctrl->in(0)->in(0);
1035                   }
1036                 }
1037                 assert(load_ctrl != NULL && if_ctrl == load_ctrl, "controls must match");
1038               }
1039             }
1040           }
1041         }
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     }


< prev index next >