< prev index next >

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

Print this page




1171                 if (if_ctrl != load_ctrl) {
1172                   // Skip possible CProj->NeverBranch in infinite loops
1173                   if ((if_ctrl->is_Proj() && if_ctrl->Opcode() == Op_CProj)
1174                       && (if_ctrl->in(0)->is_MultiBranch() && if_ctrl->in(0)->Opcode() == Op_NeverBranch)) {
1175                     if_ctrl = if_ctrl->in(0)->in(0);
1176                   }
1177                 }
1178                 assert(load_ctrl != NULL && if_ctrl == load_ctrl, "controls must match");
1179               }
1180             }
1181           }
1182         }
1183       }
1184     }
1185   }
1186 }
1187 #endif
1188 
1189 Node* ShenandoahBarrierSetC2::ideal_node(PhaseGVN* phase, Node* n, bool can_reshape) const {
1190   if (is_shenandoah_wb_pre_call(n)) {
1191     uint cnt = ShenandoahBarrierSetC2::write_ref_field_pre_entry_Type()->domain()->cnt();
1192     if (n->req() > cnt) {
1193       Node* addp = n->in(cnt);
1194       if (has_only_shenandoah_wb_pre_uses(addp)) {
1195         n->del_req(cnt);
1196         if (can_reshape) {
1197           phase->is_IterGVN()->_worklist.push(addp);
1198         }
1199         return n;
1200       }
1201     }
1202   }
1203   if (n->Opcode() == Op_CmpP) {
1204     Node* in1 = n->in(1);
1205     Node* in2 = n->in(2);
1206     if (in1->bottom_type() == TypePtr::NULL_PTR) {
1207       in2 = step_over_gc_barrier(in2);
1208     }
1209     if (in2->bottom_type() == TypePtr::NULL_PTR) {
1210       in1 = step_over_gc_barrier(in1);
1211     }


1295       }
1296     }
1297   }
1298   return n;
1299 }
1300 
1301 bool ShenandoahBarrierSetC2::has_only_shenandoah_wb_pre_uses(Node* n) {
1302   for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
1303     Node* u = n->fast_out(i);
1304     if (!is_shenandoah_wb_pre_call(u)) {
1305       return false;
1306     }
1307   }
1308   return n->outcnt() > 0;
1309 }
1310 
1311 bool ShenandoahBarrierSetC2::flatten_gc_alias_type(const TypePtr*& adr_type) const {
1312   int offset = adr_type->offset();
1313   if (offset == ShenandoahBrooksPointer::byte_offset()) {
1314     if (adr_type->isa_aryptr()) {
1315       adr_type = TypeAryPtr::make(adr_type->ptr(), adr_type->isa_aryptr()->ary(), adr_type->isa_aryptr()->klass(), false, offset);
1316     } else if (adr_type->isa_instptr()) {
1317       adr_type = TypeInstPtr::make(adr_type->ptr(), ciEnv::current()->Object_klass(), false, NULL, offset);
1318     }
1319     return true;
1320   } else {
1321     return false;
1322   }
1323 }
1324 
1325 bool ShenandoahBarrierSetC2::final_graph_reshaping(Compile* compile, Node* n, uint opcode) const {
1326   switch (opcode) {
1327     case Op_CallLeaf:
1328     case Op_CallLeafNoFP: {
1329       assert (n->is_Call(), "");
1330       CallNode *call = n->as_Call();
1331       if (ShenandoahBarrierSetC2::is_shenandoah_wb_pre_call(call)) {
1332         uint cnt = ShenandoahBarrierSetC2::write_ref_field_pre_entry_Type()->domain()->cnt();
1333         if (call->req() > cnt) {
1334           assert(call->req() == cnt + 1, "only one extra input");
1335           Node *addp = call->in(cnt);
1336           assert(!ShenandoahBarrierSetC2::has_only_shenandoah_wb_pre_uses(addp), "useless address computation?");
1337           call->del_req(cnt);
1338         }
1339       }
1340       return false;
1341     }
1342     case Op_ShenandoahCompareAndSwapP:
1343     case Op_ShenandoahCompareAndSwapN:
1344     case Op_ShenandoahWeakCompareAndSwapN:
1345     case Op_ShenandoahWeakCompareAndSwapP:
1346     case Op_ShenandoahCompareAndExchangeP:
1347     case Op_ShenandoahCompareAndExchangeN:
1348 #ifdef ASSERT
1349       if( VerifyOptoOopOffsets ) {
1350         MemNode* mem  = n->as_Mem();
1351         // Check to see if address types have grounded out somehow.
1352         const TypeInstPtr *tp = mem->in(MemNode::Address)->bottom_type()->isa_instptr();




1171                 if (if_ctrl != load_ctrl) {
1172                   // Skip possible CProj->NeverBranch in infinite loops
1173                   if ((if_ctrl->is_Proj() && if_ctrl->Opcode() == Op_CProj)
1174                       && (if_ctrl->in(0)->is_MultiBranch() && if_ctrl->in(0)->Opcode() == Op_NeverBranch)) {
1175                     if_ctrl = if_ctrl->in(0)->in(0);
1176                   }
1177                 }
1178                 assert(load_ctrl != NULL && if_ctrl == load_ctrl, "controls must match");
1179               }
1180             }
1181           }
1182         }
1183       }
1184     }
1185   }
1186 }
1187 #endif
1188 
1189 Node* ShenandoahBarrierSetC2::ideal_node(PhaseGVN* phase, Node* n, bool can_reshape) const {
1190   if (is_shenandoah_wb_pre_call(n)) {
1191     uint cnt = ShenandoahBarrierSetC2::write_ref_field_pre_entry_Type()->domain_sig()->cnt();
1192     if (n->req() > cnt) {
1193       Node* addp = n->in(cnt);
1194       if (has_only_shenandoah_wb_pre_uses(addp)) {
1195         n->del_req(cnt);
1196         if (can_reshape) {
1197           phase->is_IterGVN()->_worklist.push(addp);
1198         }
1199         return n;
1200       }
1201     }
1202   }
1203   if (n->Opcode() == Op_CmpP) {
1204     Node* in1 = n->in(1);
1205     Node* in2 = n->in(2);
1206     if (in1->bottom_type() == TypePtr::NULL_PTR) {
1207       in2 = step_over_gc_barrier(in2);
1208     }
1209     if (in2->bottom_type() == TypePtr::NULL_PTR) {
1210       in1 = step_over_gc_barrier(in1);
1211     }


1295       }
1296     }
1297   }
1298   return n;
1299 }
1300 
1301 bool ShenandoahBarrierSetC2::has_only_shenandoah_wb_pre_uses(Node* n) {
1302   for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
1303     Node* u = n->fast_out(i);
1304     if (!is_shenandoah_wb_pre_call(u)) {
1305       return false;
1306     }
1307   }
1308   return n->outcnt() > 0;
1309 }
1310 
1311 bool ShenandoahBarrierSetC2::flatten_gc_alias_type(const TypePtr*& adr_type) const {
1312   int offset = adr_type->offset();
1313   if (offset == ShenandoahBrooksPointer::byte_offset()) {
1314     if (adr_type->isa_aryptr()) {
1315       adr_type = TypeAryPtr::make(adr_type->ptr(), adr_type->isa_aryptr()->ary(), adr_type->isa_aryptr()->klass(), false, Type::Offset(offset));
1316     } else if (adr_type->isa_instptr()) {
1317       adr_type = TypeInstPtr::make(adr_type->ptr(), ciEnv::current()->Object_klass(), false, NULL, Type::Offset(offset));
1318     }
1319     return true;
1320   } else {
1321     return false;
1322   }
1323 }
1324 
1325 bool ShenandoahBarrierSetC2::final_graph_reshaping(Compile* compile, Node* n, uint opcode) const {
1326   switch (opcode) {
1327     case Op_CallLeaf:
1328     case Op_CallLeafNoFP: {
1329       assert (n->is_Call(), "");
1330       CallNode *call = n->as_Call();
1331       if (ShenandoahBarrierSetC2::is_shenandoah_wb_pre_call(call)) {
1332         uint cnt = ShenandoahBarrierSetC2::write_ref_field_pre_entry_Type()->domain_sig()->cnt();
1333         if (call->req() > cnt) {
1334           assert(call->req() == cnt + 1, "only one extra input");
1335           Node *addp = call->in(cnt);
1336           assert(!ShenandoahBarrierSetC2::has_only_shenandoah_wb_pre_uses(addp), "useless address computation?");
1337           call->del_req(cnt);
1338         }
1339       }
1340       return false;
1341     }
1342     case Op_ShenandoahCompareAndSwapP:
1343     case Op_ShenandoahCompareAndSwapN:
1344     case Op_ShenandoahWeakCompareAndSwapN:
1345     case Op_ShenandoahWeakCompareAndSwapP:
1346     case Op_ShenandoahCompareAndExchangeP:
1347     case Op_ShenandoahCompareAndExchangeN:
1348 #ifdef ASSERT
1349       if( VerifyOptoOopOffsets ) {
1350         MemNode* mem  = n->as_Mem();
1351         // Check to see if address types have grounded out somehow.
1352         const TypeInstPtr *tp = mem->in(MemNode::Address)->bottom_type()->isa_instptr();


< prev index next >