src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp
changeset 57904 4f38fcd65577
parent 57854 8b8d8a1621f2
child 58273 08a5148e7c4e
equal deleted inserted replaced
57903:5e2576c303a2 57904:4f38fcd65577
  1215   // Now we should be home
  1215   // Now we should be home
  1216   phase->igvn().set_delay_transform(false);
  1216   phase->igvn().set_delay_transform(false);
  1217 }
  1217 }
  1218 
  1218 
  1219 // Sort out the loads that are between a call ant its catch blocks
  1219 // Sort out the loads that are between a call ant its catch blocks
  1220 static void process_catch_cleanup_candidate(PhaseIdealLoop* phase, LoadNode* load) {
  1220 static void process_catch_cleanup_candidate(PhaseIdealLoop* phase, LoadNode* load, bool verify) {
  1221   bool trace = phase->C->directive()->ZTraceLoadBarriersOption;
  1221   bool trace = phase->C->directive()->ZTraceLoadBarriersOption;
  1222 
  1222 
  1223   Node* ctrl = get_ctrl_normalized(phase, load);
  1223   Node* ctrl = get_ctrl_normalized(phase, load);
  1224   if (!ctrl->is_Proj() || (ctrl->in(0) == NULL) || !ctrl->in(0)->isa_Call()) {
  1224   if (!ctrl->is_Proj() || (ctrl->in(0) == NULL) || !ctrl->in(0)->isa_Call()) {
  1225     return;
  1225     return;
  1226   }
  1226   }
  1227 
  1227 
  1228   Node* catch_node = ctrl->isa_Proj()->raw_out(0);
  1228   Node* catch_node = ctrl->isa_Proj()->raw_out(0);
  1229   if (catch_node->is_Catch()) {
  1229   if (catch_node->is_Catch()) {
  1230     if (catch_node->outcnt() > 1) {
  1230     if (catch_node->outcnt() > 1) {
       
  1231       assert(!verify, "All loads should already have been moved");
  1231       call_catch_cleanup_one(phase, load, ctrl);
  1232       call_catch_cleanup_one(phase, load, ctrl);
  1232     } else {
  1233     } else {
  1233       if (trace) tty->print_cr("Call catch cleanup with only one catch: load %i ", load->_idx);
  1234       if (trace) tty->print_cr("Call catch cleanup with only one catch: load %i ", load->_idx);
  1234     }
  1235     }
  1235   }
  1236   }
  1243 bool ZBarrierSetC2::optimize_loops(PhaseIdealLoop* phase, LoopOptsMode mode, VectorSet& visited, Node_Stack& nstack, Node_List& worklist) const {
  1244 bool ZBarrierSetC2::optimize_loops(PhaseIdealLoop* phase, LoopOptsMode mode, VectorSet& visited, Node_Stack& nstack, Node_List& worklist) const {
  1244 
  1245 
  1245   if (mode == LoopOptsZBarrierInsertion) {
  1246   if (mode == LoopOptsZBarrierInsertion) {
  1246     // First make sure all loads between call and catch are moved to the catch block
  1247     // First make sure all loads between call and catch are moved to the catch block
  1247     clean_catch_blocks(phase);
  1248     clean_catch_blocks(phase);
       
  1249     DEBUG_ONLY(clean_catch_blocks(phase, true /* verify */);)
  1248 
  1250 
  1249     // Then expand barriers on all loads
  1251     // Then expand barriers on all loads
  1250     insert_load_barriers(phase);
  1252     insert_load_barriers(phase);
  1251 
  1253 
  1252     // Handle all Unsafe that need barriers.
  1254     // Handle all Unsafe that need barriers.
  1396 // before any store.
  1398 // before any store.
  1397 //
  1399 //
  1398 // Sometimes the loads use will be at a place dominated by all catch blocks, then we need
  1400 // Sometimes the loads use will be at a place dominated by all catch blocks, then we need
  1399 // a load in each catch block, and a Phi at the dominated use.
  1401 // a load in each catch block, and a Phi at the dominated use.
  1400 
  1402 
  1401 void ZBarrierSetC2::clean_catch_blocks(PhaseIdealLoop* phase) const {
  1403 void ZBarrierSetC2::clean_catch_blocks(PhaseIdealLoop* phase, bool verify) const {
  1402 
  1404 
  1403   Compile *C = phase->C;
  1405   Compile *C = phase->C;
  1404   uint new_ids = C->unique();
  1406   uint new_ids = C->unique();
  1405   PhaseIterGVN &igvn = phase->igvn();
  1407   PhaseIterGVN &igvn = phase->igvn();
  1406   VectorSet visited(Thread::current()->resource_area());
  1408   VectorSet visited(Thread::current()->resource_area());
  1423     bool is_old_node = (n->_idx < new_ids); // don't process nodes that were created during cleanup
  1425     bool is_old_node = (n->_idx < new_ids); // don't process nodes that were created during cleanup
  1424     if (n->is_Load() && is_old_node) {
  1426     if (n->is_Load() && is_old_node) {
  1425       LoadNode* load = n->isa_Load();
  1427       LoadNode* load = n->isa_Load();
  1426       // only care about loads that will have a barrier
  1428       // only care about loads that will have a barrier
  1427       if (load_require_barrier(load)) {
  1429       if (load_require_barrier(load)) {
  1428         process_catch_cleanup_candidate(phase, load);
  1430         process_catch_cleanup_candidate(phase, load, verify);
  1429       }
  1431       }
  1430     }
  1432     }
  1431   }
  1433   }
  1432 
  1434 
  1433   C->print_method(PHASE_CALL_CATCH_CLEANUP, 2);
  1435   C->print_method(PHASE_CALL_CATCH_CLEANUP, 2);