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 }
|