comparison src/share/vm/opto/stringopts.cpp @ 2090:2ddb2fab82cb

7009359: HS with -XX:+AggressiveOpts optimize new StringBuffer(null) so it does not throw NPE as expected Summary: Bailout StringConcat optimization if null is passed to StringBuffer constructor. Reviewed-by: iveresov
author kvn
date Tue, 28 Dec 2010 17:34:02 -0800
parents f95d63e2154a
children b099aaf51bf8 9dc311b8473e
comparison
equal deleted inserted replaced
2089:037c727f35fb 2090:2ddb2fab82cb
57 public: 57 public:
58 // Mode for converting arguments to Strings 58 // Mode for converting arguments to Strings
59 enum { 59 enum {
60 StringMode, 60 StringMode,
61 IntMode, 61 IntMode,
62 CharMode 62 CharMode,
63 StringNullCheckMode
63 }; 64 };
64 65
65 StringConcat(PhaseStringOpts* stringopts, CallStaticJavaNode* end): 66 StringConcat(PhaseStringOpts* stringopts, CallStaticJavaNode* end):
66 _end(end), 67 _end(end),
67 _begin(NULL), 68 _begin(NULL),
112 _mode.insert_before(0, mode); 113 _mode.insert_before(0, mode);
113 } 114 }
114 void push_string(Node* value) { 115 void push_string(Node* value) {
115 push(value, StringMode); 116 push(value, StringMode);
116 } 117 }
118 void push_string_null_check(Node* value) {
119 push(value, StringNullCheckMode);
120 }
117 void push_int(Node* value) { 121 void push_int(Node* value) {
118 push(value, IntMode); 122 push(value, IntMode);
119 } 123 }
120 void push_char(Node* value) { 124 void push_char(Node* value) {
121 push(value, CharMode); 125 push(value, CharMode);
414 sig == ciSymbol::int_void_signature() || 418 sig == ciSymbol::int_void_signature() ||
415 sig == ciSymbol::string_void_signature()) { 419 sig == ciSymbol::string_void_signature()) {
416 if (sig == ciSymbol::string_void_signature()) { 420 if (sig == ciSymbol::string_void_signature()) {
417 // StringBuilder(String) so pick this up as the first argument 421 // StringBuilder(String) so pick this up as the first argument
418 assert(use->in(TypeFunc::Parms + 1) != NULL, "what?"); 422 assert(use->in(TypeFunc::Parms + 1) != NULL, "what?");
419 sc->push_string(use->in(TypeFunc::Parms + 1)); 423 const Type* type = _gvn->type(use->in(TypeFunc::Parms + 1));
424 if (type == TypePtr::NULL_PTR) {
425 // StringBuilder(null) throws exception.
426 #ifndef PRODUCT
427 if (PrintOptimizeStringConcat) {
428 tty->print("giving up because StringBuilder(null) throws exception");
429 alloc->jvms()->dump_spec(tty); tty->cr();
430 }
431 #endif
432 return NULL;
433 }
434 // StringBuilder(str) argument needs null check.
435 sc->push_string_null_check(use->in(TypeFunc::Parms + 1));
420 } 436 }
421 // The int variant takes an initial size for the backing 437 // The int variant takes an initial size for the backing
422 // array so just treat it like the void version. 438 // array so just treat it like the void version.
423 constructor = use; 439 constructor = use;
424 } else { 440 } else {
434 if (constructor == NULL) { 450 if (constructor == NULL) {
435 // couldn't find constructor 451 // couldn't find constructor
436 #ifndef PRODUCT 452 #ifndef PRODUCT
437 if (PrintOptimizeStringConcat) { 453 if (PrintOptimizeStringConcat) {
438 tty->print("giving up because couldn't find constructor "); 454 tty->print("giving up because couldn't find constructor ");
439 alloc->jvms()->dump_spec(tty); 455 alloc->jvms()->dump_spec(tty); tty->cr();
440 } 456 }
441 #endif 457 #endif
442 break; 458 break;
443 } 459 }
444 460
1266 length = __ AddI(length, string_size); 1282 length = __ AddI(length, string_size);
1267 1283
1268 // Cache this value for the use by int_toString 1284 // Cache this value for the use by int_toString
1269 string_sizes->init_req(argi, string_size); 1285 string_sizes->init_req(argi, string_size);
1270 break; 1286 break;
1287 }
1288 case StringConcat::StringNullCheckMode: {
1289 const Type* type = kit.gvn().type(arg);
1290 assert(type != TypePtr::NULL_PTR, "missing check");
1291 if (!type->higher_equal(TypeInstPtr::NOTNULL)) {
1292 // Null check with uncommont trap since
1293 // StringBuilder(null) throws exception.
1294 // Use special uncommon trap instead of
1295 // calling normal do_null_check().
1296 Node* p = __ Bool(__ CmpP(arg, kit.null()), BoolTest::ne);
1297 IfNode* iff = kit.create_and_map_if(kit.control(), p, PROB_MIN, COUNT_UNKNOWN);
1298 overflow->add_req(__ IfFalse(iff));
1299 Node* notnull = __ IfTrue(iff);
1300 kit.set_control(notnull); // set control for the cast_not_null
1301 arg = kit.cast_not_null(arg, false);
1302 sc->set_argument(argi, arg);
1303 }
1304 assert(kit.gvn().type(arg)->higher_equal(TypeInstPtr::NOTNULL), "sanity");
1305 // Fallthrough to add string length.
1271 } 1306 }
1272 case StringConcat::StringMode: { 1307 case StringConcat::StringMode: {
1273 const Type* type = kit.gvn().type(arg); 1308 const Type* type = kit.gvn().type(arg);
1274 if (type == TypePtr::NULL_PTR) { 1309 if (type == TypePtr::NULL_PTR) {
1275 // replace the argument with the null checked version 1310 // replace the argument with the null checked version
1326 1361
1327 { 1362 {
1328 // Hook 1363 // Hook
1329 PreserveJVMState pjvms(&kit); 1364 PreserveJVMState pjvms(&kit);
1330 kit.set_control(overflow); 1365 kit.set_control(overflow);
1366 C->record_for_igvn(overflow);
1331 kit.uncommon_trap(Deoptimization::Reason_intrinsic, 1367 kit.uncommon_trap(Deoptimization::Reason_intrinsic,
1332 Deoptimization::Action_make_not_entrant); 1368 Deoptimization::Action_make_not_entrant);
1333 } 1369 }
1334 1370
1335 // length now contains the number of characters needed for the 1371 // length now contains the number of characters needed for the
1361 // getChars words backwards so pass the ending point as well as the start 1397 // getChars words backwards so pass the ending point as well as the start
1362 int_getChars(kit, arg, char_array, start, end); 1398 int_getChars(kit, arg, char_array, start, end);
1363 start = end; 1399 start = end;
1364 break; 1400 break;
1365 } 1401 }
1402 case StringConcat::StringNullCheckMode:
1366 case StringConcat::StringMode: { 1403 case StringConcat::StringMode: {
1367 start = copy_string(kit, arg, char_array, start); 1404 start = copy_string(kit, arg, char_array, start);
1368 break; 1405 break;
1369 } 1406 }
1370 case StringConcat::CharMode: { 1407 case StringConcat::CharMode: {