Mercurial > hg > truffle
comparison src/share/vm/opto/macro.cpp @ 4767:d12a66fa3820
7123954: Some CTW test crash with SIGSEGV
Summary: Correct Allocate expansion code to preserve i_o when only slow call is generated.
Reviewed-by: iveresov
author | kvn |
---|---|
date | Tue, 27 Dec 2011 15:08:43 -0800 |
parents | 1dc233a8c7fe |
children | 9c87bcb3b4dd |
comparison
equal
deleted
inserted
replaced
4766:40c2484c09e1 | 4767:d12a66fa3820 |
---|---|
1386 result_phi_rawoop->init_req(fast_result_path, fast_oop); | 1386 result_phi_rawoop->init_req(fast_result_path, fast_oop); |
1387 result_phi_i_o ->init_req(fast_result_path, i_o); | 1387 result_phi_i_o ->init_req(fast_result_path, i_o); |
1388 result_phi_rawmem->init_req(fast_result_path, fast_oop_rawmem); | 1388 result_phi_rawmem->init_req(fast_result_path, fast_oop_rawmem); |
1389 } else { | 1389 } else { |
1390 slow_region = ctrl; | 1390 slow_region = ctrl; |
1391 result_phi_i_o = i_o; // Rename it to use in the following code. | |
1391 } | 1392 } |
1392 | 1393 |
1393 // Generate slow-path call | 1394 // Generate slow-path call |
1394 CallNode *call = new (C, slow_call_type->domain()->cnt()) | 1395 CallNode *call = new (C, slow_call_type->domain()->cnt()) |
1395 CallStaticJavaNode(slow_call_type, slow_call_address, | 1396 CallStaticJavaNode(slow_call_type, slow_call_address, |
1410 // Copy debug information and adjust JVMState information, then replace | 1411 // Copy debug information and adjust JVMState information, then replace |
1411 // allocate node with the call | 1412 // allocate node with the call |
1412 copy_call_debug_info((CallNode *) alloc, call); | 1413 copy_call_debug_info((CallNode *) alloc, call); |
1413 if (!always_slow) { | 1414 if (!always_slow) { |
1414 call->set_cnt(PROB_UNLIKELY_MAG(4)); // Same effect as RC_UNCOMMON. | 1415 call->set_cnt(PROB_UNLIKELY_MAG(4)); // Same effect as RC_UNCOMMON. |
1416 } else { | |
1417 // Hook i_o projection to avoid its elimination during allocation | |
1418 // replacement (when only a slow call is generated). | |
1419 call->set_req(TypeFunc::I_O, result_phi_i_o); | |
1415 } | 1420 } |
1416 _igvn.replace_node(alloc, call); | 1421 _igvn.replace_node(alloc, call); |
1417 transform_later(call); | 1422 transform_later(call); |
1418 | 1423 |
1419 // Identify the output projections from the allocate node and | 1424 // Identify the output projections from the allocate node and |
1426 // | 1431 // |
1427 // We are interested in the CatchProj nodes. | 1432 // We are interested in the CatchProj nodes. |
1428 // | 1433 // |
1429 extract_call_projections(call); | 1434 extract_call_projections(call); |
1430 | 1435 |
1431 // An allocate node has separate memory projections for the uses on the control and i_o paths | 1436 // An allocate node has separate memory projections for the uses on |
1432 // Replace uses of the control memory projection with result_phi_rawmem (unless we are only generating a slow call) | 1437 // the control and i_o paths. Replace the control memory projection with |
1438 // result_phi_rawmem (unless we are only generating a slow call when | |
1439 // both memory projections are combined) | |
1433 if (!always_slow && _memproj_fallthrough != NULL) { | 1440 if (!always_slow && _memproj_fallthrough != NULL) { |
1434 for (DUIterator_Fast imax, i = _memproj_fallthrough->fast_outs(imax); i < imax; i++) { | 1441 for (DUIterator_Fast imax, i = _memproj_fallthrough->fast_outs(imax); i < imax; i++) { |
1435 Node *use = _memproj_fallthrough->fast_out(i); | 1442 Node *use = _memproj_fallthrough->fast_out(i); |
1436 _igvn.hash_delete(use); | 1443 _igvn.hash_delete(use); |
1437 imax -= replace_input(use, _memproj_fallthrough, result_phi_rawmem); | 1444 imax -= replace_input(use, _memproj_fallthrough, result_phi_rawmem); |
1438 _igvn._worklist.push(use); | 1445 _igvn._worklist.push(use); |
1439 // back up iterator | 1446 // back up iterator |
1440 --i; | 1447 --i; |
1441 } | 1448 } |
1442 } | 1449 } |
1443 // Now change uses of _memproj_catchall to use _memproj_fallthrough and delete _memproj_catchall so | 1450 // Now change uses of _memproj_catchall to use _memproj_fallthrough and delete |
1444 // we end up with a call that has only 1 memory projection | 1451 // _memproj_catchall so we end up with a call that has only 1 memory projection. |
1445 if (_memproj_catchall != NULL ) { | 1452 if (_memproj_catchall != NULL ) { |
1446 if (_memproj_fallthrough == NULL) { | 1453 if (_memproj_fallthrough == NULL) { |
1447 _memproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::Memory); | 1454 _memproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::Memory); |
1448 transform_later(_memproj_fallthrough); | 1455 transform_later(_memproj_fallthrough); |
1449 } | 1456 } |
1453 imax -= replace_input(use, _memproj_catchall, _memproj_fallthrough); | 1460 imax -= replace_input(use, _memproj_catchall, _memproj_fallthrough); |
1454 _igvn._worklist.push(use); | 1461 _igvn._worklist.push(use); |
1455 // back up iterator | 1462 // back up iterator |
1456 --i; | 1463 --i; |
1457 } | 1464 } |
1458 } | 1465 assert(_memproj_catchall->outcnt() == 0, "all uses must be deleted"); |
1459 | 1466 _igvn.remove_dead_node(_memproj_catchall); |
1460 // An allocate node has separate i_o projections for the uses on the control and i_o paths | 1467 } |
1461 // Replace uses of the control i_o projection with result_phi_i_o (unless we are only generating a slow call) | 1468 |
1462 if (_ioproj_fallthrough == NULL) { | 1469 // An allocate node has separate i_o projections for the uses on the control |
1463 _ioproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::I_O); | 1470 // and i_o paths. Always replace the control i_o projection with result i_o |
1464 transform_later(_ioproj_fallthrough); | 1471 // otherwise incoming i_o become dead when only a slow call is generated |
1465 } else if (!always_slow) { | 1472 // (it is different from memory projections where both projections are |
1473 // combined in such case). | |
1474 if (_ioproj_fallthrough != NULL) { | |
1466 for (DUIterator_Fast imax, i = _ioproj_fallthrough->fast_outs(imax); i < imax; i++) { | 1475 for (DUIterator_Fast imax, i = _ioproj_fallthrough->fast_outs(imax); i < imax; i++) { |
1467 Node *use = _ioproj_fallthrough->fast_out(i); | 1476 Node *use = _ioproj_fallthrough->fast_out(i); |
1468 | |
1469 _igvn.hash_delete(use); | 1477 _igvn.hash_delete(use); |
1470 imax -= replace_input(use, _ioproj_fallthrough, result_phi_i_o); | 1478 imax -= replace_input(use, _ioproj_fallthrough, result_phi_i_o); |
1471 _igvn._worklist.push(use); | 1479 _igvn._worklist.push(use); |
1472 // back up iterator | 1480 // back up iterator |
1473 --i; | 1481 --i; |
1474 } | 1482 } |
1475 } | 1483 } |
1476 // Now change uses of _ioproj_catchall to use _ioproj_fallthrough and delete _ioproj_catchall so | 1484 // Now change uses of _ioproj_catchall to use _ioproj_fallthrough and delete |
1477 // we end up with a call that has only 1 control projection | 1485 // _ioproj_catchall so we end up with a call that has only 1 i_o projection. |
1478 if (_ioproj_catchall != NULL ) { | 1486 if (_ioproj_catchall != NULL ) { |
1487 if (_ioproj_fallthrough == NULL) { | |
1488 _ioproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::I_O); | |
1489 transform_later(_ioproj_fallthrough); | |
1490 } | |
1479 for (DUIterator_Fast imax, i = _ioproj_catchall->fast_outs(imax); i < imax; i++) { | 1491 for (DUIterator_Fast imax, i = _ioproj_catchall->fast_outs(imax); i < imax; i++) { |
1480 Node *use = _ioproj_catchall->fast_out(i); | 1492 Node *use = _ioproj_catchall->fast_out(i); |
1481 _igvn.hash_delete(use); | 1493 _igvn.hash_delete(use); |
1482 imax -= replace_input(use, _ioproj_catchall, _ioproj_fallthrough); | 1494 imax -= replace_input(use, _ioproj_catchall, _ioproj_fallthrough); |
1483 _igvn._worklist.push(use); | 1495 _igvn._worklist.push(use); |
1484 // back up iterator | 1496 // back up iterator |
1485 --i; | 1497 --i; |
1486 } | 1498 } |
1499 assert(_ioproj_catchall->outcnt() == 0, "all uses must be deleted"); | |
1500 _igvn.remove_dead_node(_ioproj_catchall); | |
1487 } | 1501 } |
1488 | 1502 |
1489 // if we generated only a slow call, we are done | 1503 // if we generated only a slow call, we are done |
1490 if (always_slow) | 1504 if (always_slow) { |
1505 // Now we can unhook i_o. | |
1506 call->set_req(TypeFunc::I_O, top()); | |
1507 if (result_phi_i_o->outcnt() == 0) | |
1508 _igvn.remove_dead_node(result_phi_i_o); | |
1491 return; | 1509 return; |
1510 } | |
1492 | 1511 |
1493 | 1512 |
1494 if (_fallthroughcatchproj != NULL) { | 1513 if (_fallthroughcatchproj != NULL) { |
1495 ctrl = _fallthroughcatchproj->clone(); | 1514 ctrl = _fallthroughcatchproj->clone(); |
1496 transform_later(ctrl); | 1515 transform_later(ctrl); |