src/share/vm/opto/stringopts.cpp

Print this page
rev 3898 : 8005031: Some cleanup in c2 to prepare for incremental inlining support
Summary: collection of small changes to prepare for incremental inlining.
Reviewed-by:


 727   Unique_Node_List ctrl_path;
 728 
 729   assert(_control.contains(_begin), "missing");
 730   assert(_control.contains(_end), "missing");
 731 
 732   // Collect the nodes that we know about and will eliminate into ctrl_path
 733   for (uint i = 0; i < _control.size(); i++) {
 734     // Push the call and it's control projection
 735     Node* n = _control.at(i);
 736     if (n->is_Allocate()) {
 737       AllocateNode* an = n->as_Allocate();
 738       InitializeNode* init = an->initialization();
 739       ctrl_path.push(init);
 740       ctrl_path.push(init->as_Multi()->proj_out(0));
 741     }
 742     if (n->is_Call()) {
 743       CallNode* cn = n->as_Call();
 744       ctrl_path.push(cn);
 745       ctrl_path.push(cn->proj_out(0));
 746       ctrl_path.push(cn->proj_out(0)->unique_out());

 747       ctrl_path.push(cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0));

 748     } else {
 749       ShouldNotReachHere();
 750     }
 751   }
 752 
 753   // Skip backwards through the control checking for unexpected contro flow
 754   Node* ptr = _end;
 755   bool fail = false;
 756   while (ptr != _begin) {
 757     if (ptr->is_Call() && ctrl_path.member(ptr)) {
 758       ptr = ptr->in(0);
 759     } else if (ptr->is_CatchProj() && ctrl_path.member(ptr)) {
 760       ptr = ptr->in(0)->in(0)->in(0);
 761       assert(ctrl_path.member(ptr), "should be a known piece of control");
 762     } else if (ptr->is_IfTrue()) {
 763       IfNode* iff = ptr->in(0)->as_If();
 764       BoolNode* b = iff->in(1)->isa_Bool();






 765       Node* cmp = b->in(1);
 766       Node* v1 = cmp->in(1);
 767       Node* v2 = cmp->in(2);
 768       Node* otherproj = iff->proj_out(1 - ptr->as_Proj()->_con);
 769 
 770       // Null check of the return of append which can simply be eliminated
 771       if (b->_test._test == BoolTest::ne &&
 772           v2->bottom_type() == TypePtr::NULL_PTR &&
 773           v1->is_Proj() && ctrl_path.member(v1->in(0))) {
 774         // NULL check of the return value of the append
 775         null_check_count++;
 776         if (otherproj->outcnt() == 1) {
 777           CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava();
 778           if (call != NULL && call->_name != NULL && strcmp(call->_name, "uncommon_trap") == 0) {
 779             ctrl_path.push(call);
 780           }
 781         }
 782         _control.push(ptr);
 783         ptr = ptr->in(0)->in(0);
 784         continue;


1391     }
1392     if (argi > 0) {
1393       // Check that the sum hasn't overflowed
1394       IfNode* iff = kit.create_and_map_if(kit.control(),
1395                                           __ Bool(__ CmpI(length, __ intcon(0)), BoolTest::lt),
1396                                           PROB_MIN, COUNT_UNKNOWN);
1397       kit.set_control(__ IfFalse(iff));
1398       overflow->set_req(argi, __ IfTrue(iff));
1399     }
1400   }
1401 
1402   {
1403     // Hook
1404     PreserveJVMState pjvms(&kit);
1405     kit.set_control(overflow);
1406     C->record_for_igvn(overflow);
1407     kit.uncommon_trap(Deoptimization::Reason_intrinsic,
1408                       Deoptimization::Action_make_not_entrant);
1409   }
1410 



1411   // length now contains the number of characters needed for the
1412   // char[] so create a new AllocateArray for the char[]
1413   Node* char_array = NULL;
1414   {
1415     PreserveReexecuteState preexecs(&kit);
1416     // The original jvms is for an allocation of either a String or
1417     // StringBuffer so no stack adjustment is necessary for proper
1418     // reexecution.  If we deoptimize in the slow path the bytecode
1419     // will be reexecuted and the char[] allocation will be thrown away.
1420     kit.jvms()->set_should_reexecute(true);
1421     char_array = kit.new_array(__ makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_CHAR))),
1422                                length, 1);
1423   }
1424 
1425   // Mark the allocation so that zeroing is skipped since the code
1426   // below will overwrite the entire array
1427   AllocateArrayNode* char_alloc = AllocateArrayNode::Ideal_array_allocation(char_array, _gvn);
1428   char_alloc->maybe_set_complete(_gvn);
1429 
1430   // Now copy the string representations into the final char[]


1439         start = end;
1440         break;
1441       }
1442       case StringConcat::StringNullCheckMode:
1443       case StringConcat::StringMode: {
1444         start = copy_string(kit, arg, char_array, start);
1445         break;
1446       }
1447       case StringConcat::CharMode: {
1448         __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
1449                            arg, T_CHAR, char_adr_idx);
1450         start = __ AddI(start, __ intcon(1));
1451         break;
1452       }
1453       default:
1454         ShouldNotReachHere();
1455     }
1456   }
1457 
1458   // If we're not reusing an existing String allocation then allocate one here.
1459   Node* result = sc->string_alloc();
1460   if (result == NULL) {
1461     PreserveReexecuteState preexecs(&kit);
1462     // The original jvms is for an allocation of either a String or
1463     // StringBuffer so no stack adjustment is necessary for proper
1464     // reexecution.
1465     kit.jvms()->set_should_reexecute(true);
1466     result = kit.new_instance(__ makecon(TypeKlassPtr::make(C->env()->String_klass())));
1467   }
1468 
1469   // Intialize the string
1470   if (java_lang_String::has_offset_field()) {
1471     kit.store_String_offset(kit.control(), result, __ intcon(0));
1472     kit.store_String_length(kit.control(), result, length);
1473   }
1474   kit.store_String_value(kit.control(), result, char_array);
1475 


1476   // hook up the outgoing control and result
1477   kit.replace_call(sc->end(), result);
1478 
1479   // Unhook any hook nodes
1480   string_sizes->disconnect_inputs(NULL, C);
1481   sc->cleanup();
1482 }


 727   Unique_Node_List ctrl_path;
 728 
 729   assert(_control.contains(_begin), "missing");
 730   assert(_control.contains(_end), "missing");
 731 
 732   // Collect the nodes that we know about and will eliminate into ctrl_path
 733   for (uint i = 0; i < _control.size(); i++) {
 734     // Push the call and it's control projection
 735     Node* n = _control.at(i);
 736     if (n->is_Allocate()) {
 737       AllocateNode* an = n->as_Allocate();
 738       InitializeNode* init = an->initialization();
 739       ctrl_path.push(init);
 740       ctrl_path.push(init->as_Multi()->proj_out(0));
 741     }
 742     if (n->is_Call()) {
 743       CallNode* cn = n->as_Call();
 744       ctrl_path.push(cn);
 745       ctrl_path.push(cn->proj_out(0));
 746       ctrl_path.push(cn->proj_out(0)->unique_out());
 747       if (cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0) != NULL) {
 748         ctrl_path.push(cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0));
 749       }
 750     } else {
 751       ShouldNotReachHere();
 752     }
 753   }
 754 
 755   // Skip backwards through the control checking for unexpected contro flow
 756   Node* ptr = _end;
 757   bool fail = false;
 758   while (ptr != _begin) {
 759     if (ptr->is_Call() && ctrl_path.member(ptr)) {
 760       ptr = ptr->in(0);
 761     } else if (ptr->is_CatchProj() && ctrl_path.member(ptr)) {
 762       ptr = ptr->in(0)->in(0)->in(0);
 763       assert(ctrl_path.member(ptr), "should be a known piece of control");
 764     } else if (ptr->is_IfTrue()) {
 765       IfNode* iff = ptr->in(0)->as_If();
 766       BoolNode* b = iff->in(1)->isa_Bool();
 767       
 768       if (b == NULL) {
 769         fail = true;
 770         break;
 771       }
 772 
 773       Node* cmp = b->in(1);
 774       Node* v1 = cmp->in(1);
 775       Node* v2 = cmp->in(2);
 776       Node* otherproj = iff->proj_out(1 - ptr->as_Proj()->_con);
 777 
 778       // Null check of the return of append which can simply be eliminated
 779       if (b->_test._test == BoolTest::ne &&
 780           v2->bottom_type() == TypePtr::NULL_PTR &&
 781           v1->is_Proj() && ctrl_path.member(v1->in(0))) {
 782         // NULL check of the return value of the append
 783         null_check_count++;
 784         if (otherproj->outcnt() == 1) {
 785           CallStaticJavaNode* call = otherproj->unique_out()->isa_CallStaticJava();
 786           if (call != NULL && call->_name != NULL && strcmp(call->_name, "uncommon_trap") == 0) {
 787             ctrl_path.push(call);
 788           }
 789         }
 790         _control.push(ptr);
 791         ptr = ptr->in(0)->in(0);
 792         continue;


1399     }
1400     if (argi > 0) {
1401       // Check that the sum hasn't overflowed
1402       IfNode* iff = kit.create_and_map_if(kit.control(),
1403                                           __ Bool(__ CmpI(length, __ intcon(0)), BoolTest::lt),
1404                                           PROB_MIN, COUNT_UNKNOWN);
1405       kit.set_control(__ IfFalse(iff));
1406       overflow->set_req(argi, __ IfTrue(iff));
1407     }
1408   }
1409 
1410   {
1411     // Hook
1412     PreserveJVMState pjvms(&kit);
1413     kit.set_control(overflow);
1414     C->record_for_igvn(overflow);
1415     kit.uncommon_trap(Deoptimization::Reason_intrinsic,
1416                       Deoptimization::Action_make_not_entrant);
1417   }
1418 
1419   Node* result;
1420   if (!kit.stopped()) {
1421 
1422     // length now contains the number of characters needed for the
1423     // char[] so create a new AllocateArray for the char[]
1424     Node* char_array = NULL;
1425     {
1426       PreserveReexecuteState preexecs(&kit);
1427       // The original jvms is for an allocation of either a String or
1428       // StringBuffer so no stack adjustment is necessary for proper
1429       // reexecution.  If we deoptimize in the slow path the bytecode
1430       // will be reexecuted and the char[] allocation will be thrown away.
1431       kit.jvms()->set_should_reexecute(true);
1432       char_array = kit.new_array(__ makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_CHAR))),
1433                                  length, 1);
1434     }
1435 
1436     // Mark the allocation so that zeroing is skipped since the code
1437     // below will overwrite the entire array
1438     AllocateArrayNode* char_alloc = AllocateArrayNode::Ideal_array_allocation(char_array, _gvn);
1439     char_alloc->maybe_set_complete(_gvn);
1440 
1441     // Now copy the string representations into the final char[]


1450           start = end;
1451           break;
1452         }
1453         case StringConcat::StringNullCheckMode:
1454         case StringConcat::StringMode: {
1455           start = copy_string(kit, arg, char_array, start);
1456           break;
1457         }
1458         case StringConcat::CharMode: {
1459           __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
1460                              arg, T_CHAR, char_adr_idx);
1461           start = __ AddI(start, __ intcon(1));
1462           break;
1463         }
1464         default:
1465           ShouldNotReachHere();
1466       }
1467     }
1468 
1469     // If we're not reusing an existing String allocation then allocate one here.
1470     result = sc->string_alloc();
1471     if (result == NULL) {
1472       PreserveReexecuteState preexecs(&kit);
1473       // The original jvms is for an allocation of either a String or
1474       // StringBuffer so no stack adjustment is necessary for proper
1475       // reexecution.
1476       kit.jvms()->set_should_reexecute(true);
1477       result = kit.new_instance(__ makecon(TypeKlassPtr::make(C->env()->String_klass())));
1478     }
1479 
1480     // Intialize the string
1481     if (java_lang_String::has_offset_field()) {
1482       kit.store_String_offset(kit.control(), result, __ intcon(0));
1483       kit.store_String_length(kit.control(), result, length);
1484     }
1485     kit.store_String_value(kit.control(), result, char_array);
1486   } else {
1487     result = C->top();
1488   }
1489   // hook up the outgoing control and result
1490   kit.replace_call(sc->end(), result);
1491 
1492   // Unhook any hook nodes
1493   string_sizes->disconnect_inputs(NULL, C);
1494   sc->cleanup();
1495 }