src/share/vm/opto/stringopts.cpp

Print this page
rev 5661 : 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering.


1105   if( bt == T_OBJECT ) {
1106     if (!field->type()->is_loaded()) {
1107       type = TypeInstPtr::BOTTOM;
1108     } else if (field->is_constant()) {
1109       // This can happen if the constant oop is non-perm.
1110       ciObject* con = field->constant_value().as_object();
1111       // Do not "join" in the previous type; it doesn't add value,
1112       // and may yield a vacuous result if the field is of interface type.
1113       type = TypeOopPtr::make_from_constant(con, true)->isa_oopptr();
1114       assert(type != NULL, "field singleton type must be consistent");
1115       return __ makecon(type);
1116     } else {
1117       type = TypeOopPtr::make_from_klass(field_klass->as_klass());
1118     }
1119   } else {
1120     type = Type::get_const_basic_type(bt);
1121   }
1122 
1123   return kit.make_load(NULL, kit.basic_plus_adr(klass_node, field->offset_in_bytes()),
1124                        type, T_OBJECT,
1125                        C->get_alias_index(mirror_type->add_offset(field->offset_in_bytes())));

1126 }
1127 
1128 Node* PhaseStringOpts::int_stringSize(GraphKit& kit, Node* arg) {
1129   RegionNode *final_merge = new (C) RegionNode(3);
1130   kit.gvn().set_type(final_merge, Type::CONTROL);
1131   Node* final_size = new (C) PhiNode(final_merge, TypeInt::INT);
1132   kit.gvn().set_type(final_size, TypeInt::INT);
1133 
1134   IfNode* iff = kit.create_and_map_if(kit.control(),
1135                                       __ Bool(__ CmpI(arg, __ intcon(0x80000000)), BoolTest::ne),
1136                                       PROB_FAIR, COUNT_UNKNOWN);
1137   Node* is_min = __ IfFalse(iff);
1138   final_merge->init_req(1, is_min);
1139   final_size->init_req(1, __ intcon(11));
1140 
1141   kit.set_control(__ IfTrue(iff));
1142   if (kit.stopped()) {
1143     final_merge->init_req(2, C->top());
1144     final_size->init_req(2, C->top());
1145   } else {


1297     RegionNode *head = new (C) RegionNode(3);
1298     head->init_req(1, kit.control());
1299     kit.gvn().set_type(head, Type::CONTROL);
1300     Node *i_phi = new (C) PhiNode(head, TypeInt::INT);
1301     i_phi->init_req(1, i);
1302     kit.gvn().set_type(i_phi, TypeInt::INT);
1303     charPos = PhiNode::make(head, charPos);
1304     kit.gvn().set_type(charPos, TypeInt::INT);
1305     Node *mem = PhiNode::make(head, kit.memory(char_adr_idx), Type::MEMORY, TypeAryPtr::CHARS);
1306     kit.gvn().set_type(mem, Type::MEMORY);
1307     kit.set_control(head);
1308     kit.set_memory(mem, char_adr_idx);
1309 
1310     Node* q = __ DivI(NULL, i_phi, __ intcon(10));
1311     Node* r = __ SubI(i_phi, __ AddI(__ LShiftI(q, __ intcon(3)),
1312                                      __ LShiftI(q, __ intcon(1))));
1313     Node* m1 = __ SubI(charPos, __ intcon(1));
1314     Node* ch = __ AddI(r, __ intcon('0'));
1315 
1316     Node* st = __ store_to_memory(kit.control(), kit.array_element_address(char_array, m1, T_CHAR),
1317                                   ch, T_CHAR, char_adr_idx);
1318 
1319 
1320     IfNode* iff = kit.create_and_map_if(head, __ Bool(__ CmpI(q, __ intcon(0)), BoolTest::ne),
1321                                         PROB_FAIR, COUNT_UNKNOWN);
1322     Node* ne = __ IfTrue(iff);
1323     Node* eq = __ IfFalse(iff);
1324 
1325     head->init_req(2, ne);
1326     mem->init_req(2, st);
1327     i_phi->init_req(2, q);
1328     charPos->init_req(2, m1);
1329 
1330     charPos = m1;
1331 
1332     kit.set_control(eq);
1333     kit.set_memory(st, char_adr_idx);
1334 
1335     C->record_for_igvn(head);
1336     C->record_for_igvn(mem);
1337     C->record_for_igvn(i_phi);


1339   }
1340 
1341   {
1342     // if (sign != 0) {
1343     //     buf [--charPos] = sign;
1344     // }
1345     IfNode* iff = kit.create_and_map_if(kit.control(),
1346                                         __ Bool(__ CmpI(sign, __ intcon(0)), BoolTest::ne),
1347                                         PROB_FAIR, COUNT_UNKNOWN);
1348 
1349     final_merge->init_req(2, __ IfFalse(iff));
1350     final_mem->init_req(2, kit.memory(char_adr_idx));
1351 
1352     kit.set_control(__ IfTrue(iff));
1353     if (kit.stopped()) {
1354       final_merge->init_req(1, C->top());
1355       final_mem->init_req(1, C->top());
1356     } else {
1357       Node* m1 = __ SubI(charPos, __ intcon(1));
1358       Node* st = __ store_to_memory(kit.control(), kit.array_element_address(char_array, m1, T_CHAR),
1359                                     sign, T_CHAR, char_adr_idx);
1360 
1361       final_merge->init_req(1, kit.control());
1362       final_mem->init_req(1, st);
1363     }
1364 
1365     kit.set_control(final_merge);
1366     kit.set_memory(final_mem, char_adr_idx);
1367 
1368     C->record_for_igvn(final_merge);
1369     C->record_for_igvn(final_mem);
1370   }
1371 }
1372 
1373 
1374 Node* PhaseStringOpts::copy_string(GraphKit& kit, Node* str, Node* char_array, Node* start) {
1375   Node* string = str;
1376   Node* offset = kit.load_String_offset(kit.control(), string);
1377   Node* count  = kit.load_String_length(kit.control(), string);
1378   Node* value  = kit.load_String_value (kit.control(), string);
1379 
1380   // copy the contents
1381   if (offset->is_Con() && count->is_Con() && value->is_Con() && count->get_int() < unroll_string_copy_length) {
1382     // For small constant strings just emit individual stores.
1383     // A length of 6 seems like a good space/speed tradeof.
1384     int c = count->get_int();
1385     int o = offset->get_int();
1386     const TypeOopPtr* t = kit.gvn().type(value)->isa_oopptr();
1387     ciTypeArray* value_array = t->const_oop()->as_type_array();
1388     for (int e = 0; e < c; e++) {
1389       __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
1390                          __ intcon(value_array->char_at(o + e)), T_CHAR, char_adr_idx);

1391       start = __ AddI(start, __ intcon(1));
1392     }
1393   } else {
1394     Node* src_ptr = kit.array_element_address(value, offset, T_CHAR);
1395     Node* dst_ptr = kit.array_element_address(char_array, start, T_CHAR);
1396     Node* c = count;
1397     Node* extra = NULL;
1398 #ifdef _LP64
1399     c = __ ConvI2L(c);
1400     extra = C->top();
1401 #endif
1402     Node* call = kit.make_runtime_call(GraphKit::RC_LEAF|GraphKit::RC_NO_FP,
1403                                        OptoRuntime::fast_arraycopy_Type(),
1404                                        CAST_FROM_FN_PTR(address, StubRoutines::jshort_disjoint_arraycopy()),
1405                                        "jshort_disjoint_arraycopy", TypeAryPtr::CHARS,
1406                                        src_ptr, dst_ptr, c, extra);
1407     start = __ AddI(start, count);
1408   }
1409   return start;
1410 }


1590 
1591     // Now copy the string representations into the final char[]
1592     Node* start = __ intcon(0);
1593     for (int argi = 0; argi < sc->num_arguments(); argi++) {
1594       Node* arg = sc->argument(argi);
1595       switch (sc->mode(argi)) {
1596         case StringConcat::IntMode: {
1597           Node* end = __ AddI(start, string_sizes->in(argi));
1598           // getChars words backwards so pass the ending point as well as the start
1599           int_getChars(kit, arg, char_array, start, end);
1600           start = end;
1601           break;
1602         }
1603         case StringConcat::StringNullCheckMode:
1604         case StringConcat::StringMode: {
1605           start = copy_string(kit, arg, char_array, start);
1606           break;
1607         }
1608         case StringConcat::CharMode: {
1609           __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
1610                              arg, T_CHAR, char_adr_idx);
1611           start = __ AddI(start, __ intcon(1));
1612           break;
1613         }
1614         default:
1615           ShouldNotReachHere();
1616       }
1617     }
1618 
1619     // If we're not reusing an existing String allocation then allocate one here.
1620     result = sc->string_alloc();
1621     if (result == NULL) {
1622       PreserveReexecuteState preexecs(&kit);
1623       // The original jvms is for an allocation of either a String or
1624       // StringBuffer so no stack adjustment is necessary for proper
1625       // reexecution.
1626       kit.jvms()->set_should_reexecute(true);
1627       result = kit.new_instance(__ makecon(TypeKlassPtr::make(C->env()->String_klass())));
1628     }
1629 
1630     // Intialize the string


1105   if( bt == T_OBJECT ) {
1106     if (!field->type()->is_loaded()) {
1107       type = TypeInstPtr::BOTTOM;
1108     } else if (field->is_constant()) {
1109       // This can happen if the constant oop is non-perm.
1110       ciObject* con = field->constant_value().as_object();
1111       // Do not "join" in the previous type; it doesn't add value,
1112       // and may yield a vacuous result if the field is of interface type.
1113       type = TypeOopPtr::make_from_constant(con, true)->isa_oopptr();
1114       assert(type != NULL, "field singleton type must be consistent");
1115       return __ makecon(type);
1116     } else {
1117       type = TypeOopPtr::make_from_klass(field_klass->as_klass());
1118     }
1119   } else {
1120     type = Type::get_const_basic_type(bt);
1121   }
1122 
1123   return kit.make_load(NULL, kit.basic_plus_adr(klass_node, field->offset_in_bytes()),
1124                        type, T_OBJECT,
1125                        C->get_alias_index(mirror_type->add_offset(field->offset_in_bytes())),
1126                        false, LoadNode::unordered);
1127 }
1128 
1129 Node* PhaseStringOpts::int_stringSize(GraphKit& kit, Node* arg) {
1130   RegionNode *final_merge = new (C) RegionNode(3);
1131   kit.gvn().set_type(final_merge, Type::CONTROL);
1132   Node* final_size = new (C) PhiNode(final_merge, TypeInt::INT);
1133   kit.gvn().set_type(final_size, TypeInt::INT);
1134 
1135   IfNode* iff = kit.create_and_map_if(kit.control(),
1136                                       __ Bool(__ CmpI(arg, __ intcon(0x80000000)), BoolTest::ne),
1137                                       PROB_FAIR, COUNT_UNKNOWN);
1138   Node* is_min = __ IfFalse(iff);
1139   final_merge->init_req(1, is_min);
1140   final_size->init_req(1, __ intcon(11));
1141 
1142   kit.set_control(__ IfTrue(iff));
1143   if (kit.stopped()) {
1144     final_merge->init_req(2, C->top());
1145     final_size->init_req(2, C->top());
1146   } else {


1298     RegionNode *head = new (C) RegionNode(3);
1299     head->init_req(1, kit.control());
1300     kit.gvn().set_type(head, Type::CONTROL);
1301     Node *i_phi = new (C) PhiNode(head, TypeInt::INT);
1302     i_phi->init_req(1, i);
1303     kit.gvn().set_type(i_phi, TypeInt::INT);
1304     charPos = PhiNode::make(head, charPos);
1305     kit.gvn().set_type(charPos, TypeInt::INT);
1306     Node *mem = PhiNode::make(head, kit.memory(char_adr_idx), Type::MEMORY, TypeAryPtr::CHARS);
1307     kit.gvn().set_type(mem, Type::MEMORY);
1308     kit.set_control(head);
1309     kit.set_memory(mem, char_adr_idx);
1310 
1311     Node* q = __ DivI(NULL, i_phi, __ intcon(10));
1312     Node* r = __ SubI(i_phi, __ AddI(__ LShiftI(q, __ intcon(3)),
1313                                      __ LShiftI(q, __ intcon(1))));
1314     Node* m1 = __ SubI(charPos, __ intcon(1));
1315     Node* ch = __ AddI(r, __ intcon('0'));
1316 
1317     Node* st = __ store_to_memory(kit.control(), kit.array_element_address(char_array, m1, T_CHAR),
1318                                   ch, T_CHAR, char_adr_idx, false, StoreNode::unordered);
1319 
1320 
1321     IfNode* iff = kit.create_and_map_if(head, __ Bool(__ CmpI(q, __ intcon(0)), BoolTest::ne),
1322                                         PROB_FAIR, COUNT_UNKNOWN);
1323     Node* ne = __ IfTrue(iff);
1324     Node* eq = __ IfFalse(iff);
1325 
1326     head->init_req(2, ne);
1327     mem->init_req(2, st);
1328     i_phi->init_req(2, q);
1329     charPos->init_req(2, m1);
1330 
1331     charPos = m1;
1332 
1333     kit.set_control(eq);
1334     kit.set_memory(st, char_adr_idx);
1335 
1336     C->record_for_igvn(head);
1337     C->record_for_igvn(mem);
1338     C->record_for_igvn(i_phi);


1340   }
1341 
1342   {
1343     // if (sign != 0) {
1344     //     buf [--charPos] = sign;
1345     // }
1346     IfNode* iff = kit.create_and_map_if(kit.control(),
1347                                         __ Bool(__ CmpI(sign, __ intcon(0)), BoolTest::ne),
1348                                         PROB_FAIR, COUNT_UNKNOWN);
1349 
1350     final_merge->init_req(2, __ IfFalse(iff));
1351     final_mem->init_req(2, kit.memory(char_adr_idx));
1352 
1353     kit.set_control(__ IfTrue(iff));
1354     if (kit.stopped()) {
1355       final_merge->init_req(1, C->top());
1356       final_mem->init_req(1, C->top());
1357     } else {
1358       Node* m1 = __ SubI(charPos, __ intcon(1));
1359       Node* st = __ store_to_memory(kit.control(), kit.array_element_address(char_array, m1, T_CHAR),
1360                                     sign, T_CHAR, char_adr_idx, false, StoreNode::unordered);
1361 
1362       final_merge->init_req(1, kit.control());
1363       final_mem->init_req(1, st);
1364     }
1365 
1366     kit.set_control(final_merge);
1367     kit.set_memory(final_mem, char_adr_idx);
1368 
1369     C->record_for_igvn(final_merge);
1370     C->record_for_igvn(final_mem);
1371   }
1372 }
1373 
1374 
1375 Node* PhaseStringOpts::copy_string(GraphKit& kit, Node* str, Node* char_array, Node* start) {
1376   Node* string = str;
1377   Node* offset = kit.load_String_offset(kit.control(), string);
1378   Node* count  = kit.load_String_length(kit.control(), string);
1379   Node* value  = kit.load_String_value (kit.control(), string);
1380 
1381   // copy the contents
1382   if (offset->is_Con() && count->is_Con() && value->is_Con() && count->get_int() < unroll_string_copy_length) {
1383     // For small constant strings just emit individual stores.
1384     // A length of 6 seems like a good space/speed tradeof.
1385     int c = count->get_int();
1386     int o = offset->get_int();
1387     const TypeOopPtr* t = kit.gvn().type(value)->isa_oopptr();
1388     ciTypeArray* value_array = t->const_oop()->as_type_array();
1389     for (int e = 0; e < c; e++) {
1390       __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
1391                          __ intcon(value_array->char_at(o + e)), T_CHAR, char_adr_idx,
1392                          false, StoreNode::unordered);
1393       start = __ AddI(start, __ intcon(1));
1394     }
1395   } else {
1396     Node* src_ptr = kit.array_element_address(value, offset, T_CHAR);
1397     Node* dst_ptr = kit.array_element_address(char_array, start, T_CHAR);
1398     Node* c = count;
1399     Node* extra = NULL;
1400 #ifdef _LP64
1401     c = __ ConvI2L(c);
1402     extra = C->top();
1403 #endif
1404     Node* call = kit.make_runtime_call(GraphKit::RC_LEAF|GraphKit::RC_NO_FP,
1405                                        OptoRuntime::fast_arraycopy_Type(),
1406                                        CAST_FROM_FN_PTR(address, StubRoutines::jshort_disjoint_arraycopy()),
1407                                        "jshort_disjoint_arraycopy", TypeAryPtr::CHARS,
1408                                        src_ptr, dst_ptr, c, extra);
1409     start = __ AddI(start, count);
1410   }
1411   return start;
1412 }


1592 
1593     // Now copy the string representations into the final char[]
1594     Node* start = __ intcon(0);
1595     for (int argi = 0; argi < sc->num_arguments(); argi++) {
1596       Node* arg = sc->argument(argi);
1597       switch (sc->mode(argi)) {
1598         case StringConcat::IntMode: {
1599           Node* end = __ AddI(start, string_sizes->in(argi));
1600           // getChars words backwards so pass the ending point as well as the start
1601           int_getChars(kit, arg, char_array, start, end);
1602           start = end;
1603           break;
1604         }
1605         case StringConcat::StringNullCheckMode:
1606         case StringConcat::StringMode: {
1607           start = copy_string(kit, arg, char_array, start);
1608           break;
1609         }
1610         case StringConcat::CharMode: {
1611           __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
1612                              arg, T_CHAR, char_adr_idx, false, StoreNode::unordered);
1613           start = __ AddI(start, __ intcon(1));
1614           break;
1615         }
1616         default:
1617           ShouldNotReachHere();
1618       }
1619     }
1620 
1621     // If we're not reusing an existing String allocation then allocate one here.
1622     result = sc->string_alloc();
1623     if (result == NULL) {
1624       PreserveReexecuteState preexecs(&kit);
1625       // The original jvms is for an allocation of either a String or
1626       // StringBuffer so no stack adjustment is necessary for proper
1627       // reexecution.
1628       kit.jvms()->set_should_reexecute(true);
1629       result = kit.new_instance(__ makecon(TypeKlassPtr::make(C->env()->String_klass())));
1630     }
1631 
1632     // Intialize the string