Mercurial > hg > graal-compiler
comparison src/share/vm/opto/macro.cpp @ 460:424f9bfe6b96
6775880: EA +DeoptimizeALot: assert(mon_info->owner()->is_locked(),"object must be locked now")
Summary: Create new "eliminated" BoxLock node for monitor debug info when corresponding locks are eliminated.
Reviewed-by: never
author | kvn |
---|---|
date | Wed, 03 Dec 2008 13:41:37 -0800 |
parents | 87559db65269 |
children | dd70dd4c91de |
comparison
equal
deleted
inserted
replaced
459:3a86a8dcf27c | 460:424f9bfe6b96 |
---|---|
57 | 57 |
58 Dict* sosn_map = new Dict(cmpkey,hashkey); | 58 Dict* sosn_map = new Dict(cmpkey,hashkey); |
59 for (uint i = old_dbg_start; i < oldcall->req(); i++) { | 59 for (uint i = old_dbg_start; i < oldcall->req(); i++) { |
60 Node* old_in = oldcall->in(i); | 60 Node* old_in = oldcall->in(i); |
61 // Clone old SafePointScalarObjectNodes, adjusting their field contents. | 61 // Clone old SafePointScalarObjectNodes, adjusting their field contents. |
62 if (old_in->is_SafePointScalarObject()) { | 62 if (old_in != NULL && old_in->is_SafePointScalarObject()) { |
63 SafePointScalarObjectNode* old_sosn = old_in->as_SafePointScalarObject(); | 63 SafePointScalarObjectNode* old_sosn = old_in->as_SafePointScalarObject(); |
64 uint old_unique = C->unique(); | 64 uint old_unique = C->unique(); |
65 Node* new_in = old_sosn->clone(jvms_adj, sosn_map); | 65 Node* new_in = old_sosn->clone(jvms_adj, sosn_map); |
66 if (old_unique != C->unique()) { | 66 if (old_unique != C->unique()) { |
67 new_in = transform_later(new_in); // Register new node. | 67 new_in = transform_later(new_in); // Register new node. |
1507 bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) { | 1507 bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) { |
1508 | 1508 |
1509 if (!alock->is_eliminated()) { | 1509 if (!alock->is_eliminated()) { |
1510 return false; | 1510 return false; |
1511 } | 1511 } |
1512 // Mark the box lock as eliminated if all correspondent locks are eliminated | 1512 if (alock->is_Lock() && !alock->is_coarsened()) { |
1513 // to construct correct debug info. | 1513 // Create new "eliminated" BoxLock node and use it |
1514 BoxLockNode* box = alock->box_node()->as_BoxLock(); | 1514 // in monitor debug info for the same object. |
1515 if (!box->is_eliminated()) { | 1515 BoxLockNode* oldbox = alock->box_node()->as_BoxLock(); |
1516 bool eliminate = true; | 1516 Node* obj = alock->obj_node(); |
1517 for (DUIterator_Fast imax, i = box->fast_outs(imax); i < imax; i++) { | 1517 if (!oldbox->is_eliminated()) { |
1518 Node *lck = box->fast_out(i); | 1518 BoxLockNode* newbox = oldbox->clone()->as_BoxLock(); |
1519 if (lck->is_Lock() && !lck->as_AbstractLock()->is_eliminated()) { | 1519 newbox->set_eliminated(); |
1520 eliminate = false; | 1520 transform_later(newbox); |
1521 break; | 1521 // Replace old box node with new box for all users |
1522 } | 1522 // of the same object. |
1523 } | 1523 for (uint i = 0; i < oldbox->outcnt();) { |
1524 if (eliminate) | 1524 |
1525 box->set_eliminated(); | 1525 bool next_edge = true; |
1526 } | 1526 Node* u = oldbox->raw_out(i); |
1527 if (u == alock) { | |
1528 i++; | |
1529 continue; // It will be removed below | |
1530 } | |
1531 if (u->is_Lock() && | |
1532 u->as_Lock()->obj_node() == obj && | |
1533 // oldbox could be referenced in debug info also | |
1534 u->as_Lock()->box_node() == oldbox) { | |
1535 assert(u->as_Lock()->is_eliminated(), "sanity"); | |
1536 _igvn.hash_delete(u); | |
1537 u->set_req(TypeFunc::Parms + 1, newbox); | |
1538 next_edge = false; | |
1539 #ifdef ASSERT | |
1540 } else if (u->is_Unlock() && u->as_Unlock()->obj_node() == obj) { | |
1541 assert(u->as_Unlock()->is_eliminated(), "sanity"); | |
1542 #endif | |
1543 } | |
1544 // Replace old box in monitor debug info. | |
1545 if (u->is_SafePoint() && u->as_SafePoint()->jvms()) { | |
1546 SafePointNode* sfn = u->as_SafePoint(); | |
1547 JVMState* youngest_jvms = sfn->jvms(); | |
1548 int max_depth = youngest_jvms->depth(); | |
1549 for (int depth = 1; depth <= max_depth; depth++) { | |
1550 JVMState* jvms = youngest_jvms->of_depth(depth); | |
1551 int num_mon = jvms->nof_monitors(); | |
1552 // Loop over monitors | |
1553 for (int idx = 0; idx < num_mon; idx++) { | |
1554 Node* obj_node = sfn->monitor_obj(jvms, idx); | |
1555 Node* box_node = sfn->monitor_box(jvms, idx); | |
1556 if (box_node == oldbox && obj_node == obj) { | |
1557 int j = jvms->monitor_box_offset(idx); | |
1558 _igvn.hash_delete(u); | |
1559 u->set_req(j, newbox); | |
1560 next_edge = false; | |
1561 } | |
1562 } // for (int idx = 0; | |
1563 } // for (int depth = 1; | |
1564 } // if (u->is_SafePoint() | |
1565 if (next_edge) i++; | |
1566 } // for (uint i = 0; i < oldbox->outcnt();) | |
1567 } // if (!oldbox->is_eliminated()) | |
1568 } // if (alock->is_Lock() && !lock->is_coarsened()) | |
1527 | 1569 |
1528 #ifndef PRODUCT | 1570 #ifndef PRODUCT |
1529 if (PrintEliminateLocks) { | 1571 if (PrintEliminateLocks) { |
1530 if (alock->is_Lock()) { | 1572 if (alock->is_Lock()) { |
1531 tty->print_cr("++++ Eliminating: %d Lock", alock->_idx); | 1573 tty->print_cr("++++ Eliminating: %d Lock", alock->_idx); |
1560 Node* memproj = membar->proj_out(TypeFunc::Memory); | 1602 Node* memproj = membar->proj_out(TypeFunc::Memory); |
1561 _igvn.hash_delete(ctrlproj); | 1603 _igvn.hash_delete(ctrlproj); |
1562 _igvn.subsume_node(ctrlproj, fallthroughproj); | 1604 _igvn.subsume_node(ctrlproj, fallthroughproj); |
1563 _igvn.hash_delete(memproj); | 1605 _igvn.hash_delete(memproj); |
1564 _igvn.subsume_node(memproj, memproj_fallthrough); | 1606 _igvn.subsume_node(memproj, memproj_fallthrough); |
1607 | |
1608 // Delete FastLock node also if this Lock node is unique user | |
1609 // (a loop peeling may clone a Lock node). | |
1610 Node* flock = alock->as_Lock()->fastlock_node(); | |
1611 if (flock->outcnt() == 1) { | |
1612 assert(flock->unique_out() == alock, "sanity"); | |
1613 _igvn.hash_delete(flock); | |
1614 _igvn.subsume_node(flock, top()); | |
1615 } | |
1565 } | 1616 } |
1566 | 1617 |
1567 // Seach for MemBarRelease node and delete it also. | 1618 // Seach for MemBarRelease node and delete it also. |
1568 if (alock->is_Unlock() && ctrl != NULL && ctrl->is_Proj() && | 1619 if (alock->is_Unlock() && ctrl != NULL && ctrl->is_Proj() && |
1569 ctrl->in(0)->is_MemBar()) { | 1620 ctrl->in(0)->is_MemBar()) { |
1885 //------------------------------expand_macro_nodes---------------------- | 1936 //------------------------------expand_macro_nodes---------------------- |
1886 // Returns true if a failure occurred. | 1937 // Returns true if a failure occurred. |
1887 bool PhaseMacroExpand::expand_macro_nodes() { | 1938 bool PhaseMacroExpand::expand_macro_nodes() { |
1888 if (C->macro_count() == 0) | 1939 if (C->macro_count() == 0) |
1889 return false; | 1940 return false; |
1890 // attempt to eliminate allocations | 1941 // First, attempt to eliminate locks |
1891 bool progress = true; | 1942 bool progress = true; |
1943 while (progress) { | |
1944 progress = false; | |
1945 for (int i = C->macro_count(); i > 0; i--) { | |
1946 Node * n = C->macro_node(i-1); | |
1947 bool success = false; | |
1948 debug_only(int old_macro_count = C->macro_count();); | |
1949 if (n->is_AbstractLock()) { | |
1950 success = eliminate_locking_node(n->as_AbstractLock()); | |
1951 } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) { | |
1952 _igvn.add_users_to_worklist(n); | |
1953 _igvn.hash_delete(n); | |
1954 _igvn.subsume_node(n, n->in(1)); | |
1955 success = true; | |
1956 } | |
1957 assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count"); | |
1958 progress = progress || success; | |
1959 } | |
1960 } | |
1961 // Next, attempt to eliminate allocations | |
1962 progress = true; | |
1892 while (progress) { | 1963 while (progress) { |
1893 progress = false; | 1964 progress = false; |
1894 for (int i = C->macro_count(); i > 0; i--) { | 1965 for (int i = C->macro_count(); i > 0; i--) { |
1895 Node * n = C->macro_node(i-1); | 1966 Node * n = C->macro_node(i-1); |
1896 bool success = false; | 1967 bool success = false; |
1900 case Node::Class_AllocateArray: | 1971 case Node::Class_AllocateArray: |
1901 success = eliminate_allocate_node(n->as_Allocate()); | 1972 success = eliminate_allocate_node(n->as_Allocate()); |
1902 break; | 1973 break; |
1903 case Node::Class_Lock: | 1974 case Node::Class_Lock: |
1904 case Node::Class_Unlock: | 1975 case Node::Class_Unlock: |
1905 success = eliminate_locking_node(n->as_AbstractLock()); | 1976 assert(!n->as_AbstractLock()->is_eliminated(), "sanity"); |
1906 break; | 1977 break; |
1907 default: | 1978 default: |
1908 if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) { | 1979 assert(false, "unknown node type in macro list"); |
1909 _igvn.add_users_to_worklist(n); | |
1910 _igvn.hash_delete(n); | |
1911 _igvn.subsume_node(n, n->in(1)); | |
1912 success = true; | |
1913 } else { | |
1914 assert(false, "unknown node type in macro list"); | |
1915 } | |
1916 } | 1980 } |
1917 assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count"); | 1981 assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count"); |
1918 progress = progress || success; | 1982 progress = progress || success; |
1919 } | 1983 } |
1920 } | 1984 } |