1270 // always just translate the loads and stores to ldr<x> and str<x> |
1257 // always just translate the loads and stores to ldr<x> and str<x> |
1271 // and translate acquire, release and volatile membars to the |
1258 // and translate acquire, release and volatile membars to the |
1272 // relevant dmb instructions. |
1259 // relevant dmb instructions. |
1273 // |
1260 // |
1274 |
1261 |
1275 // graph traversal helpers used for volatile put/get and CAS |
|
1276 // optimization |
|
1277 |
|
1278 // 1) general purpose helpers |
|
1279 |
|
1280 // if node n is linked to a parent MemBarNode by an intervening |
|
1281 // Control and Memory ProjNode return the MemBarNode otherwise return |
|
1282 // NULL. |
|
1283 // |
|
1284 // n may only be a Load or a MemBar. |
|
1285 |
|
1286 MemBarNode *parent_membar(const Node *n) |
|
1287 { |
|
1288 Node *ctl = NULL; |
|
1289 Node *mem = NULL; |
|
1290 Node *membar = NULL; |
|
1291 |
|
1292 if (n->is_Load()) { |
|
1293 ctl = n->lookup(LoadNode::Control); |
|
1294 mem = n->lookup(LoadNode::Memory); |
|
1295 } else if (n->is_MemBar()) { |
|
1296 ctl = n->lookup(TypeFunc::Control); |
|
1297 mem = n->lookup(TypeFunc::Memory); |
|
1298 } else { |
|
1299 return NULL; |
|
1300 } |
|
1301 |
|
1302 if (!ctl || !mem || !ctl->is_Proj() || !mem->is_Proj()) { |
|
1303 return NULL; |
|
1304 } |
|
1305 |
|
1306 membar = ctl->lookup(0); |
|
1307 |
|
1308 if (!membar || !membar->is_MemBar()) { |
|
1309 return NULL; |
|
1310 } |
|
1311 |
|
1312 if (mem->lookup(0) != membar) { |
|
1313 return NULL; |
|
1314 } |
|
1315 |
|
1316 return membar->as_MemBar(); |
|
1317 } |
|
1318 |
|
1319 // if n is linked to a child MemBarNode by intervening Control and |
|
1320 // Memory ProjNodes return the MemBarNode otherwise return NULL. |
|
1321 |
|
1322 MemBarNode *child_membar(const MemBarNode *n) |
|
1323 { |
|
1324 ProjNode *ctl = n->proj_out_or_null(TypeFunc::Control); |
|
1325 ProjNode *mem = n->proj_out_or_null(TypeFunc::Memory); |
|
1326 |
|
1327 // MemBar needs to have both a Ctl and Mem projection |
|
1328 if (! ctl || ! mem) |
|
1329 return NULL; |
|
1330 |
|
1331 MemBarNode *child = NULL; |
|
1332 Node *x; |
|
1333 |
|
1334 for (DUIterator_Fast imax, i = ctl->fast_outs(imax); i < imax; i++) { |
|
1335 x = ctl->fast_out(i); |
|
1336 // if we see a membar we keep hold of it. we may also see a new |
|
1337 // arena copy of the original but it will appear later |
|
1338 if (x->is_MemBar()) { |
|
1339 child = x->as_MemBar(); |
|
1340 break; |
|
1341 } |
|
1342 } |
|
1343 |
|
1344 if (child == NULL) { |
|
1345 return NULL; |
|
1346 } |
|
1347 |
|
1348 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { |
|
1349 x = mem->fast_out(i); |
|
1350 // if we see a membar we keep hold of it. we may also see a new |
|
1351 // arena copy of the original but it will appear later |
|
1352 if (x == child) { |
|
1353 return child; |
|
1354 } |
|
1355 } |
|
1356 return NULL; |
|
1357 } |
|
1358 |
|
1359 // helper predicate use to filter candidates for a leading memory |
|
1360 // barrier |
|
1361 // |
|
1362 // returns true if barrier is a MemBarRelease or a MemBarCPUOrder |
|
1363 // whose Ctl and Mem feeds come from a MemBarRelease otherwise false |
|
1364 |
|
1365 bool leading_membar(const MemBarNode *barrier) |
|
1366 { |
|
1367 int opcode = barrier->Opcode(); |
|
1368 // if this is a release membar we are ok |
|
1369 if (opcode == Op_MemBarRelease) { |
|
1370 return true; |
|
1371 } |
|
1372 // if its a cpuorder membar . . . |
|
1373 if (opcode != Op_MemBarCPUOrder) { |
|
1374 return false; |
|
1375 } |
|
1376 // then the parent has to be a release membar |
|
1377 MemBarNode *parent = parent_membar(barrier); |
|
1378 if (!parent) { |
|
1379 return false; |
|
1380 } |
|
1381 opcode = parent->Opcode(); |
|
1382 return opcode == Op_MemBarRelease; |
|
1383 } |
|
1384 |
|
1385 // 2) card mark detection helper |
|
1386 |
|
1387 // helper predicate which can be used to detect a volatile membar |
|
1388 // introduced as part of a conditional card mark sequence either by |
|
1389 // G1 or by CMS when UseCondCardMark is true. |
|
1390 // |
|
1391 // membar can be definitively determined to be part of a card mark |
|
1392 // sequence if and only if all the following hold |
|
1393 // |
|
1394 // i) it is a MemBarVolatile |
|
1395 // |
|
1396 // ii) either UseG1GC or (UseConcMarkSweepGC && UseCondCardMark) is |
|
1397 // true |
|
1398 // |
|
1399 // iii) the node's Mem projection feeds a StoreCM node. |
|
1400 |
|
1401 bool is_card_mark_membar(const MemBarNode *barrier) |
|
1402 { |
|
1403 if (!UseG1GC && !(UseConcMarkSweepGC && UseCondCardMark)) { |
|
1404 return false; |
|
1405 } |
|
1406 |
|
1407 if (barrier->Opcode() != Op_MemBarVolatile) { |
|
1408 return false; |
|
1409 } |
|
1410 |
|
1411 ProjNode *mem = barrier->proj_out(TypeFunc::Memory); |
|
1412 |
|
1413 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax ; i++) { |
|
1414 Node *y = mem->fast_out(i); |
|
1415 if (y->Opcode() == Op_StoreCM) { |
|
1416 return true; |
|
1417 } |
|
1418 } |
|
1419 |
|
1420 return false; |
|
1421 } |
|
1422 |
|
1423 |
|
1424 // 3) helper predicates to traverse volatile put or CAS graphs which |
|
1425 // may contain GC barrier subgraphs |
|
1426 |
|
1427 // Preamble |
|
1428 // -------- |
|
1429 // |
|
1430 // for volatile writes we can omit generating barriers and employ a |
|
1431 // releasing store when we see a node sequence sequence with a |
|
1432 // leading MemBarRelease and a trailing MemBarVolatile as follows |
|
1433 // |
|
1434 // MemBarRelease |
|
1435 // { || } -- optional |
|
1436 // {MemBarCPUOrder} |
|
1437 // || \\ |
|
1438 // || StoreX[mo_release] |
|
1439 // | \ / |
|
1440 // | MergeMem |
|
1441 // | / |
|
1442 // {MemBarCPUOrder} -- optional |
|
1443 // { || } |
|
1444 // MemBarVolatile |
|
1445 // |
|
1446 // where |
|
1447 // || and \\ represent Ctl and Mem feeds via Proj nodes |
|
1448 // | \ and / indicate further routing of the Ctl and Mem feeds |
|
1449 // |
|
1450 // this is the graph we see for non-object stores. however, for a |
|
1451 // volatile Object store (StoreN/P) we may see other nodes below the |
|
1452 // leading membar because of the need for a GC pre- or post-write |
|
1453 // barrier. |
|
1454 // |
|
1455 // with most GC configurations we with see this simple variant which |
|
1456 // includes a post-write barrier card mark. |
|
1457 // |
|
1458 // MemBarRelease______________________________ |
|
1459 // || \\ Ctl \ \\ |
|
1460 // || StoreN/P[mo_release] CastP2X StoreB/CM |
|
1461 // | \ / . . . / |
|
1462 // | MergeMem |
|
1463 // | / |
|
1464 // || / |
|
1465 // {MemBarCPUOrder} -- optional |
|
1466 // { || } |
|
1467 // MemBarVolatile |
|
1468 // |
|
1469 // i.e. the leading membar feeds Ctl to a CastP2X (which converts |
|
1470 // the object address to an int used to compute the card offset) and |
|
1471 // Ctl+Mem to a StoreB node (which does the actual card mark). |
|
1472 // |
|
1473 // n.b. a StoreCM node will only appear in this configuration when |
|
1474 // using CMS or G1. StoreCM differs from a normal card mark write (StoreB) |
|
1475 // because it implies a requirement to order visibility of the card |
|
1476 // mark (StoreCM) relative to the object put (StoreP/N) using a |
|
1477 // StoreStore memory barrier (arguably this ought to be represented |
|
1478 // explicitly in the ideal graph but that is not how it works). This |
|
1479 // ordering is required for both non-volatile and volatile |
|
1480 // puts. Normally that means we need to translate a StoreCM using |
|
1481 // the sequence |
|
1482 // |
|
1483 // dmb ishst |
|
1484 // strb |
|
1485 // |
|
1486 // However, when using G1 or CMS with conditional card marking (as |
|
1487 // we shall see) we don't need to insert the dmb when translating |
|
1488 // StoreCM because there is already an intervening StoreLoad barrier |
|
1489 // between it and the StoreP/N. |
|
1490 // |
|
1491 // It is also possible to perform the card mark conditionally on it |
|
1492 // currently being unmarked in which case the volatile put graph |
|
1493 // will look slightly different |
|
1494 // |
|
1495 // MemBarRelease____________________________________________ |
|
1496 // || \\ Ctl \ Ctl \ \\ Mem \ |
|
1497 // || StoreN/P[mo_release] CastP2X If LoadB | |
|
1498 // | \ / \ | |
|
1499 // | MergeMem . . . StoreB |
|
1500 // | / / |
|
1501 // || / |
|
1502 // MemBarVolatile |
|
1503 // |
|
1504 // It is worth noting at this stage that both the above |
|
1505 // configurations can be uniquely identified by checking that the |
|
1506 // memory flow includes the following subgraph: |
|
1507 // |
|
1508 // MemBarRelease |
|
1509 // {MemBarCPUOrder} |
|
1510 // | \ . . . |
|
1511 // | StoreX[mo_release] . . . |
|
1512 // | / |
|
1513 // MergeMem |
|
1514 // | |
|
1515 // {MemBarCPUOrder} |
|
1516 // MemBarVolatile |
|
1517 // |
|
1518 // This is referred to as a *normal* subgraph. It can easily be |
|
1519 // detected starting from any candidate MemBarRelease, |
|
1520 // StoreX[mo_release] or MemBarVolatile. |
|
1521 // |
|
1522 // A simple variation on this normal case occurs for an unsafe CAS |
|
1523 // operation. The basic graph for a non-object CAS is |
|
1524 // |
|
1525 // MemBarRelease |
|
1526 // || |
|
1527 // MemBarCPUOrder |
|
1528 // || \\ . . . |
|
1529 // || CompareAndSwapX |
|
1530 // || | |
|
1531 // || SCMemProj |
|
1532 // | \ / |
|
1533 // | MergeMem |
|
1534 // | / |
|
1535 // MemBarCPUOrder |
|
1536 // || |
|
1537 // MemBarAcquire |
|
1538 // |
|
1539 // The same basic variations on this arrangement (mutatis mutandis) |
|
1540 // occur when a card mark is introduced. i.e. we se the same basic |
|
1541 // shape but the StoreP/N is replaced with CompareAndSawpP/N and the |
|
1542 // tail of the graph is a pair comprising a MemBarCPUOrder + |
|
1543 // MemBarAcquire. |
|
1544 // |
|
1545 // So, in the case of a CAS the normal graph has the variant form |
|
1546 // |
|
1547 // MemBarRelease |
|
1548 // MemBarCPUOrder |
|
1549 // | \ . . . |
|
1550 // | CompareAndSwapX . . . |
|
1551 // | | |
|
1552 // | SCMemProj |
|
1553 // | / . . . |
|
1554 // MergeMem |
|
1555 // | |
|
1556 // MemBarCPUOrder |
|
1557 // MemBarAcquire |
|
1558 // |
|
1559 // This graph can also easily be detected starting from any |
|
1560 // candidate MemBarRelease, CompareAndSwapX or MemBarAcquire. |
|
1561 // |
|
1562 // the code below uses two helper predicates, leading_to_normal and |
|
1563 // normal_to_leading to identify these normal graphs, one validating |
|
1564 // the layout starting from the top membar and searching down and |
|
1565 // the other validating the layout starting from the lower membar |
|
1566 // and searching up. |
|
1567 // |
|
1568 // There are two special case GC configurations when a normal graph |
|
1569 // may not be generated: when using G1 (which always employs a |
|
1570 // conditional card mark); and when using CMS with conditional card |
|
1571 // marking configured. These GCs are both concurrent rather than |
|
1572 // stop-the world GCs. So they introduce extra Ctl+Mem flow into the |
|
1573 // graph between the leading and trailing membar nodes, in |
|
1574 // particular enforcing stronger memory serialisation beween the |
|
1575 // object put and the corresponding conditional card mark. CMS |
|
1576 // employs a post-write GC barrier while G1 employs both a pre- and |
|
1577 // post-write GC barrier. Of course the extra nodes may be absent -- |
|
1578 // they are only inserted for object puts/swaps. This significantly |
|
1579 // complicates the task of identifying whether a MemBarRelease, |
|
1580 // StoreX[mo_release] or MemBarVolatile forms part of a volatile put |
|
1581 // when using these GC configurations (see below). It adds similar |
|
1582 // complexity to the task of identifying whether a MemBarRelease, |
|
1583 // CompareAndSwapX or MemBarAcquire forms part of a CAS. |
|
1584 // |
|
1585 // In both cases the post-write subtree includes an auxiliary |
|
1586 // MemBarVolatile (StoreLoad barrier) separating the object put/swap |
|
1587 // and the read of the corresponding card. This poses two additional |
|
1588 // problems. |
|
1589 // |
|
1590 // Firstly, a card mark MemBarVolatile needs to be distinguished |
|
1591 // from a normal trailing MemBarVolatile. Resolving this first |
|
1592 // problem is straightforward: a card mark MemBarVolatile always |
|
1593 // projects a Mem feed to a StoreCM node and that is a unique marker |
|
1594 // |
|
1595 // MemBarVolatile (card mark) |
|
1596 // C | \ . . . |
|
1597 // | StoreCM . . . |
|
1598 // . . . |
|
1599 // |
|
1600 // The second problem is how the code generator is to translate the |
|
1601 // card mark barrier? It always needs to be translated to a "dmb |
|
1602 // ish" instruction whether or not it occurs as part of a volatile |
|
1603 // put. A StoreLoad barrier is needed after the object put to ensure |
|
1604 // i) visibility to GC threads of the object put and ii) visibility |
|
1605 // to the mutator thread of any card clearing write by a GC |
|
1606 // thread. Clearly a normal store (str) will not guarantee this |
|
1607 // ordering but neither will a releasing store (stlr). The latter |
|
1608 // guarantees that the object put is visible but does not guarantee |
|
1609 // that writes by other threads have also been observed. |
|
1610 // |
|
1611 // So, returning to the task of translating the object put and the |
|
1612 // leading/trailing membar nodes: what do the non-normal node graph |
|
1613 // look like for these 2 special cases? and how can we determine the |
|
1614 // status of a MemBarRelease, StoreX[mo_release] or MemBarVolatile |
|
1615 // in both normal and non-normal cases? |
|
1616 // |
|
1617 // A CMS GC post-barrier wraps its card write (StoreCM) inside an If |
|
1618 // which selects conditonal execution based on the value loaded |
|
1619 // (LoadB) from the card. Ctl and Mem are fed to the If via an |
|
1620 // intervening StoreLoad barrier (MemBarVolatile). |
|
1621 // |
|
1622 // So, with CMS we may see a node graph for a volatile object store |
|
1623 // which looks like this |
|
1624 // |
|
1625 // MemBarRelease |
|
1626 // {MemBarCPUOrder}_(leading)_________________ |
|
1627 // C | M \ \\ C \ |
|
1628 // | \ StoreN/P[mo_release] CastP2X |
|
1629 // | Bot \ / |
|
1630 // | MergeMem |
|
1631 // | / |
|
1632 // MemBarVolatile (card mark) |
|
1633 // C | || M | |
|
1634 // | LoadB | |
|
1635 // | | | |
|
1636 // | Cmp |\ |
|
1637 // | / | \ |
|
1638 // If | \ |
|
1639 // | \ | \ |
|
1640 // IfFalse IfTrue | \ |
|
1641 // \ / \ | \ |
|
1642 // \ / StoreCM | |
|
1643 // \ / | | |
|
1644 // Region . . . | |
|
1645 // | \ / |
|
1646 // | . . . \ / Bot |
|
1647 // | MergeMem |
|
1648 // | | |
|
1649 // {MemBarCPUOrder} |
|
1650 // MemBarVolatile (trailing) |
|
1651 // |
|
1652 // The first MergeMem merges the AliasIdxBot Mem slice from the |
|
1653 // leading membar and the oopptr Mem slice from the Store into the |
|
1654 // card mark membar. The trailing MergeMem merges the AliasIdxBot |
|
1655 // Mem slice from the card mark membar and the AliasIdxRaw slice |
|
1656 // from the StoreCM into the trailing membar (n.b. the latter |
|
1657 // proceeds via a Phi associated with the If region). |
|
1658 // |
|
1659 // The graph for a CAS varies slightly, the difference being |
|
1660 // that the StoreN/P node is replaced by a CompareAndSwapP/N node |
|
1661 // and the trailing MemBarVolatile by a MemBarCPUOrder + |
|
1662 // MemBarAcquire pair (also the MemBarCPUOrder nodes are not optional). |
|
1663 // |
|
1664 // MemBarRelease |
|
1665 // MemBarCPUOrder_(leading)_______________ |
|
1666 // C | M \ \\ C \ |
|
1667 // | \ CompareAndSwapN/P CastP2X |
|
1668 // | \ | |
|
1669 // | \ SCMemProj |
|
1670 // | Bot \ / |
|
1671 // | MergeMem |
|
1672 // | / |
|
1673 // MemBarVolatile (card mark) |
|
1674 // C | || M | |
|
1675 // | LoadB | |
|
1676 // | | | |
|
1677 // | Cmp |\ |
|
1678 // | / | \ |
|
1679 // If | \ |
|
1680 // | \ | \ |
|
1681 // IfFalse IfTrue | \ |
|
1682 // \ / \ | \ |
|
1683 // \ / StoreCM | |
|
1684 // \ / | | |
|
1685 // Region . . . | |
|
1686 // | \ / |
|
1687 // | . . . \ / Bot |
|
1688 // | MergeMem |
|
1689 // | | |
|
1690 // MemBarCPUOrder |
|
1691 // MemBarVolatile (trailing) |
|
1692 // |
|
1693 // |
|
1694 // G1 is quite a lot more complicated. The nodes inserted on behalf |
|
1695 // of G1 may comprise: a pre-write graph which adds the old value to |
|
1696 // the SATB queue; the releasing store itself; and, finally, a |
|
1697 // post-write graph which performs a card mark. |
|
1698 // |
|
1699 // The pre-write graph may be omitted, but only when the put is |
|
1700 // writing to a newly allocated (young gen) object and then only if |
|
1701 // there is a direct memory chain to the Initialize node for the |
|
1702 // object allocation. This will not happen for a volatile put since |
|
1703 // any memory chain passes through the leading membar. |
|
1704 // |
|
1705 // The pre-write graph includes a series of 3 If tests. The outermost |
|
1706 // If tests whether SATB is enabled (no else case). The next If tests |
|
1707 // whether the old value is non-NULL (no else case). The third tests |
|
1708 // whether the SATB queue index is > 0, if so updating the queue. The |
|
1709 // else case for this third If calls out to the runtime to allocate a |
|
1710 // new queue buffer. |
|
1711 // |
|
1712 // So with G1 the pre-write and releasing store subgraph looks like |
|
1713 // this (the nested Ifs are omitted). |
|
1714 // |
|
1715 // MemBarRelease |
|
1716 // {MemBarCPUOrder}_(leading)___________ |
|
1717 // C | || M \ M \ M \ M \ . . . |
|
1718 // | LoadB \ LoadL LoadN \ |
|
1719 // | / \ \ |
|
1720 // If |\ \ |
|
1721 // | \ | \ \ |
|
1722 // IfFalse IfTrue | \ \ |
|
1723 // | | | \ | |
|
1724 // | If | /\ | |
|
1725 // | | \ | |
|
1726 // | \ | |
|
1727 // | . . . \ | |
|
1728 // | / | / | | |
|
1729 // Region Phi[M] | | |
|
1730 // | \ | | | |
|
1731 // | \_____ | ___ | | |
|
1732 // C | C \ | C \ M | | |
|
1733 // | CastP2X | StoreN/P[mo_release] | |
|
1734 // | | | | |
|
1735 // C | M | M | M | |
|
1736 // \ | | / |
|
1737 // . . . |
|
1738 // (post write subtree elided) |
|
1739 // . . . |
|
1740 // C \ M / |
|
1741 // \ / |
|
1742 // {MemBarCPUOrder} |
|
1743 // MemBarVolatile (trailing) |
|
1744 // |
|
1745 // n.b. the LoadB in this subgraph is not the card read -- it's a |
|
1746 // read of the SATB queue active flag. |
|
1747 // |
|
1748 // The G1 post-write subtree is also optional, this time when the |
|
1749 // new value being written is either null or can be identified as a |
|
1750 // newly allocated (young gen) object with no intervening control |
|
1751 // flow. The latter cannot happen but the former may, in which case |
|
1752 // the card mark membar is omitted and the memory feeds form the |
|
1753 // leading membar and the SToreN/P are merged direct into the |
|
1754 // trailing membar as per the normal subgraph. So, the only special |
|
1755 // case which arises is when the post-write subgraph is generated. |
|
1756 // |
|
1757 // The kernel of the post-write G1 subgraph is the card mark itself |
|
1758 // which includes a card mark memory barrier (MemBarVolatile), a |
|
1759 // card test (LoadB), and a conditional update (If feeding a |
|
1760 // StoreCM). These nodes are surrounded by a series of nested Ifs |
|
1761 // which try to avoid doing the card mark. The top level If skips if |
|
1762 // the object reference does not cross regions (i.e. it tests if |
|
1763 // (adr ^ val) >> log2(regsize) != 0) -- intra-region references |
|
1764 // need not be recorded. The next If, which skips on a NULL value, |
|
1765 // may be absent (it is not generated if the type of value is >= |
|
1766 // OopPtr::NotNull). The 3rd If skips writes to young regions (by |
|
1767 // checking if card_val != young). n.b. although this test requires |
|
1768 // a pre-read of the card it can safely be done before the StoreLoad |
|
1769 // barrier. However that does not bypass the need to reread the card |
|
1770 // after the barrier. A final, 4th If tests if the card is already |
|
1771 // marked. |
|
1772 // |
|
1773 // (pre-write subtree elided) |
|
1774 // . . . . . . . . . . . . |
|
1775 // C | M | M | M | |
|
1776 // Region Phi[M] StoreN | |
|
1777 // | / \ | | |
|
1778 // / \_______ / \ | | |
|
1779 // C / C \ . . . \ | | |
|
1780 // If CastP2X . . . | | | |
|
1781 // / \ | | | |
|
1782 // / \ | | | |
|
1783 // IfFalse IfTrue | | | |
|
1784 // | | | | /| |
|
1785 // | If | | / | |
|
1786 // | / \ | | / | |
|
1787 // | / \ \ | / | |
|
1788 // | IfFalse IfTrue MergeMem | |
|
1789 // | . . . / \ / | |
|
1790 // | / \ / | |
|
1791 // | IfFalse IfTrue / | |
|
1792 // | . . . | / | |
|
1793 // | If / | |
|
1794 // | / \ / | |
|
1795 // | / \ / | |
|
1796 // | IfFalse IfTrue / | |
|
1797 // | . . . | / | |
|
1798 // | \ / | |
|
1799 // | \ / | |
|
1800 // | MemBarVolatile__(card mark) | |
|
1801 // | || C | M \ M \ | |
|
1802 // | LoadB If | | | |
|
1803 // | / \ | | | |
|
1804 // | . . . | | | |
|
1805 // | \ | | / |
|
1806 // | StoreCM | / |
|
1807 // | . . . | / |
|
1808 // | _________/ / |
|
1809 // | / _____________/ |
|
1810 // | . . . . . . | / / |
|
1811 // | | | / _________/ |
|
1812 // | | Phi[M] / / |
|
1813 // | | | / / |
|
1814 // | | | / / |
|
1815 // | Region . . . Phi[M] _____/ |
|
1816 // | / | / |
|
1817 // | | / |
|
1818 // | . . . . . . | / |
|
1819 // | / | / |
|
1820 // Region | | Phi[M] |
|
1821 // | | | / Bot |
|
1822 // \ MergeMem |
|
1823 // \ / |
|
1824 // {MemBarCPUOrder} |
|
1825 // MemBarVolatile |
|
1826 // |
|
1827 // As with CMS the initial MergeMem merges the AliasIdxBot Mem slice |
|
1828 // from the leading membar and the oopptr Mem slice from the Store |
|
1829 // into the card mark membar i.e. the memory flow to the card mark |
|
1830 // membar still looks like a normal graph. |
|
1831 // |
|
1832 // The trailing MergeMem merges an AliasIdxBot Mem slice with other |
|
1833 // Mem slices (from the StoreCM and other card mark queue stores). |
|
1834 // However in this case the AliasIdxBot Mem slice does not come |
|
1835 // direct from the card mark membar. It is merged through a series |
|
1836 // of Phi nodes. These are needed to merge the AliasIdxBot Mem flow |
|
1837 // from the leading membar with the Mem feed from the card mark |
|
1838 // membar. Each Phi corresponds to one of the Ifs which may skip |
|
1839 // around the card mark membar. So when the If implementing the NULL |
|
1840 // value check has been elided the total number of Phis is 2 |
|
1841 // otherwise it is 3. |
|
1842 // |
|
1843 // The CAS graph when using G1GC also includes a pre-write subgraph |
|
1844 // and an optional post-write subgraph. The same variations are |
|
1845 // introduced as for CMS with conditional card marking i.e. the |
|
1846 // StoreP/N is swapped for a CompareAndSwapP/N with a following |
|
1847 // SCMemProj, the trailing MemBarVolatile for a MemBarCPUOrder + |
|
1848 // MemBarAcquire pair. There may be an extra If test introduced in |
|
1849 // the CAS case, when the boolean result of the CAS is tested by the |
|
1850 // caller. In that case an extra Region and AliasIdxBot Phi may be |
|
1851 // introduced before the MergeMem |
|
1852 // |
|
1853 // So, the upshot is that in all cases the subgraph will include a |
|
1854 // *normal* memory subgraph betwen the leading membar and its child |
|
1855 // membar: either a normal volatile put graph including a releasing |
|
1856 // StoreX and terminating with a trailing volatile membar or card |
|
1857 // mark volatile membar; or a normal CAS graph including a |
|
1858 // CompareAndSwapX + SCMemProj pair and terminating with a card mark |
|
1859 // volatile membar or a trailing cpu order and acquire membar |
|
1860 // pair. If the child membar is not a (volatile) card mark membar |
|
1861 // then it marks the end of the volatile put or CAS subgraph. If the |
|
1862 // child is a card mark membar then the normal subgraph will form |
|
1863 // part of a larger volatile put or CAS subgraph if and only if the |
|
1864 // child feeds an AliasIdxBot Mem feed to a trailing barrier via a |
|
1865 // MergeMem. That feed is either direct (for CMS) or via 2, 3 or 4 |
|
1866 // Phi nodes merging the leading barrier memory flow (for G1). |
|
1867 // |
|
1868 // The predicates controlling generation of instructions for store |
|
1869 // and barrier nodes employ a few simple helper functions (described |
|
1870 // below) which identify the presence or absence of all these |
|
1871 // subgraph configurations and provide a means of traversing from |
|
1872 // one node in the subgraph to another. |
|
1873 |
|
1874 // is_CAS(int opcode) |
1262 // is_CAS(int opcode) |
1875 // |
1263 // |
1876 // return true if opcode is one of the possible CompareAndSwapX |
1264 // return true if opcode is one of the possible CompareAndSwapX |
1877 // values otherwise false. |
1265 // values otherwise false. |
1878 |
1266 |
1908 |
1296 |
1909 // helper to determine the maximum number of Phi nodes we may need to |
1297 // helper to determine the maximum number of Phi nodes we may need to |
1910 // traverse when searching from a card mark membar for the merge mem |
1298 // traverse when searching from a card mark membar for the merge mem |
1911 // feeding a trailing membar or vice versa |
1299 // feeding a trailing membar or vice versa |
1912 |
1300 |
1913 int max_phis() |
1301 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb |
1914 { |
|
1915 if (UseG1GC) { |
|
1916 return 4; |
|
1917 } else if (UseConcMarkSweepGC && UseCondCardMark) { |
|
1918 return 1; |
|
1919 } else { |
|
1920 return 0; |
|
1921 } |
|
1922 } |
|
1923 |
|
1924 // leading_to_normal |
|
1925 // |
|
1926 // graph traversal helper which detects the normal case Mem feed |
|
1927 // from a release membar (or, optionally, its cpuorder child) to a |
|
1928 // dependent volatile or acquire membar i.e. it ensures that one of |
|
1929 // the following 3 Mem flow subgraphs is present. |
|
1930 // |
|
1931 // MemBarRelease |
|
1932 // {MemBarCPUOrder} {leading} |
|
1933 // | \ . . . |
|
1934 // | StoreN/P[mo_release] . . . |
|
1935 // | / |
|
1936 // MergeMem |
|
1937 // | |
|
1938 // {MemBarCPUOrder} |
|
1939 // MemBarVolatile {trailing or card mark} |
|
1940 // |
|
1941 // MemBarRelease |
|
1942 // MemBarCPUOrder {leading} |
|
1943 // | \ . . . |
|
1944 // | CompareAndSwapX . . . |
|
1945 // | / |
|
1946 // MergeMem |
|
1947 // | |
|
1948 // MemBarVolatile {card mark} |
|
1949 // |
|
1950 // MemBarRelease |
|
1951 // MemBarCPUOrder {leading} |
|
1952 // | \ . . . |
|
1953 // | CompareAndSwapX . . . |
|
1954 // | / |
|
1955 // MergeMem |
|
1956 // | |
|
1957 // MemBarCPUOrder |
|
1958 // MemBarAcquire {trailing} |
|
1959 // |
|
1960 // if the correct configuration is present returns the trailing |
|
1961 // or cardmark membar otherwise NULL. |
|
1962 // |
|
1963 // the input membar is expected to be either a cpuorder membar or a |
|
1964 // release membar. in the latter case it should not have a cpu membar |
|
1965 // child. |
|
1966 // |
|
1967 // the returned value may be a card mark or trailing membar |
|
1968 // |
|
1969 |
|
1970 MemBarNode *leading_to_normal(MemBarNode *leading) |
|
1971 { |
|
1972 assert((leading->Opcode() == Op_MemBarRelease || |
|
1973 leading->Opcode() == Op_MemBarCPUOrder), |
|
1974 "expecting a volatile or cpuroder membar!"); |
|
1975 |
|
1976 // check the mem flow |
|
1977 ProjNode *mem = leading->proj_out(TypeFunc::Memory); |
|
1978 |
|
1979 if (!mem) { |
|
1980 return NULL; |
|
1981 } |
|
1982 |
|
1983 Node *x = NULL; |
|
1984 StoreNode * st = NULL; |
|
1985 LoadStoreNode *cas = NULL; |
|
1986 MergeMemNode *mm = NULL; |
|
1987 |
|
1988 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { |
|
1989 x = mem->fast_out(i); |
|
1990 if (x->is_MergeMem()) { |
|
1991 if (mm != NULL) { |
|
1992 return NULL; |
|
1993 } |
|
1994 // two merge mems is one too many |
|
1995 mm = x->as_MergeMem(); |
|
1996 } else if (x->is_Store() && x->as_Store()->is_release() && x->Opcode() != Op_StoreCM) { |
|
1997 // two releasing stores/CAS nodes is one too many |
|
1998 if (st != NULL || cas != NULL) { |
|
1999 return NULL; |
|
2000 } |
|
2001 st = x->as_Store(); |
|
2002 } else if (is_CAS(x->Opcode())) { |
|
2003 if (st != NULL || cas != NULL) { |
|
2004 return NULL; |
|
2005 } |
|
2006 cas = x->as_LoadStore(); |
|
2007 } |
|
2008 } |
|
2009 |
|
2010 // must have a store or a cas |
|
2011 if (!st && !cas) { |
|
2012 return NULL; |
|
2013 } |
|
2014 |
|
2015 // must have a merge |
|
2016 if (!mm) { |
|
2017 return NULL; |
|
2018 } |
|
2019 |
|
2020 Node *feed = NULL; |
|
2021 if (cas) { |
|
2022 // look for an SCMemProj |
|
2023 for (DUIterator_Fast imax, i = cas->fast_outs(imax); i < imax; i++) { |
|
2024 x = cas->fast_out(i); |
|
2025 if (x->Opcode() == Op_SCMemProj) { |
|
2026 feed = x; |
|
2027 break; |
|
2028 } |
|
2029 } |
|
2030 if (feed == NULL) { |
|
2031 return NULL; |
|
2032 } |
|
2033 } else { |
|
2034 feed = st; |
|
2035 } |
|
2036 // ensure the feed node feeds the existing mergemem; |
|
2037 for (DUIterator_Fast imax, i = feed->fast_outs(imax); i < imax; i++) { |
|
2038 x = feed->fast_out(i); |
|
2039 if (x == mm) { |
|
2040 break; |
|
2041 } |
|
2042 } |
|
2043 if (x != mm) { |
|
2044 return NULL; |
|
2045 } |
|
2046 |
|
2047 MemBarNode *mbar = NULL; |
|
2048 // ensure the merge feeds to the expected type of membar |
|
2049 for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) { |
|
2050 x = mm->fast_out(i); |
|
2051 if (x->is_MemBar()) { |
|
2052 if (x->Opcode() == Op_MemBarCPUOrder) { |
|
2053 // with a store any cpu order membar should precede a |
|
2054 // trailing volatile membar. with a cas it should precede a |
|
2055 // trailing acquire membar. in either case try to skip to |
|
2056 // that next membar |
|
2057 MemBarNode *y = x->as_MemBar(); |
|
2058 y = child_membar(y); |
|
2059 if (y != NULL) { |
|
2060 // skip to this new membar to do the check |
|
2061 x = y; |
|
2062 } |
|
2063 |
|
2064 } |
|
2065 if (x->Opcode() == Op_MemBarVolatile) { |
|
2066 mbar = x->as_MemBar(); |
|
2067 // for a volatile store this can be either a trailing membar |
|
2068 // or a card mark membar. for a cas it must be a card mark |
|
2069 // membar |
|
2070 guarantee(cas == NULL || is_card_mark_membar(mbar), |
|
2071 "in CAS graph volatile membar must be a card mark"); |
|
2072 } else if (cas != NULL && x->Opcode() == Op_MemBarAcquire) { |
|
2073 mbar = x->as_MemBar(); |
|
2074 } |
|
2075 break; |
|
2076 } |
|
2077 } |
|
2078 |
|
2079 return mbar; |
|
2080 } |
|
2081 |
|
2082 // normal_to_leading |
|
2083 // |
|
2084 // graph traversal helper which detects the normal case Mem feed |
|
2085 // from either a card mark or a trailing membar to a preceding |
|
2086 // release membar (optionally its cpuorder child) i.e. it ensures |
|
2087 // that one of the following 3 Mem flow subgraphs is present. |
|
2088 // |
|
2089 // MemBarRelease |
|
2090 // {MemBarCPUOrder} {leading} |
|
2091 // | \ . . . |
|
2092 // | StoreN/P[mo_release] . . . |
|
2093 // | / |
|
2094 // MergeMem |
|
2095 // | |
|
2096 // {MemBarCPUOrder} |
|
2097 // MemBarVolatile {trailing or card mark} |
|
2098 // |
|
2099 // MemBarRelease |
|
2100 // MemBarCPUOrder {leading} |
|
2101 // | \ . . . |
|
2102 // | CompareAndSwapX . . . |
|
2103 // | / |
|
2104 // MergeMem |
|
2105 // | |
|
2106 // MemBarVolatile {card mark} |
|
2107 // |
|
2108 // MemBarRelease |
|
2109 // MemBarCPUOrder {leading} |
|
2110 // | \ . . . |
|
2111 // | CompareAndSwapX . . . |
|
2112 // | / |
|
2113 // MergeMem |
|
2114 // | |
|
2115 // MemBarCPUOrder |
|
2116 // MemBarAcquire {trailing} |
|
2117 // |
|
2118 // this predicate checks for the same flow as the previous predicate |
|
2119 // but starting from the bottom rather than the top. |
|
2120 // |
|
2121 // if the configuration is present returns the cpuorder member for |
|
2122 // preference or when absent the release membar otherwise NULL. |
|
2123 // |
|
2124 // n.b. the input membar is expected to be a MemBarVolatile but |
|
2125 // need not be a card mark membar. |
|
2126 |
|
2127 MemBarNode *normal_to_leading(const MemBarNode *barrier) |
|
2128 { |
|
2129 // input must be a volatile membar |
|
2130 assert((barrier->Opcode() == Op_MemBarVolatile || |
|
2131 barrier->Opcode() == Op_MemBarAcquire), |
|
2132 "expecting a volatile or an acquire membar"); |
|
2133 bool barrier_is_acquire = barrier->Opcode() == Op_MemBarAcquire; |
|
2134 |
|
2135 // if we have an intervening cpu order membar then start the |
|
2136 // search from it |
|
2137 |
|
2138 Node *x = parent_membar(barrier); |
|
2139 |
|
2140 if (x == NULL) { |
|
2141 // stick with the original barrier |
|
2142 x = (Node *)barrier; |
|
2143 } else if (x->Opcode() != Op_MemBarCPUOrder) { |
|
2144 // any other barrier means this is not the graph we want |
|
2145 return NULL; |
|
2146 } |
|
2147 |
|
2148 // the Mem feed to the membar should be a merge |
|
2149 x = x ->in(TypeFunc::Memory); |
|
2150 if (!x->is_MergeMem()) |
|
2151 return NULL; |
|
2152 |
|
2153 MergeMemNode *mm = x->as_MergeMem(); |
|
2154 |
|
2155 // the merge should get its Bottom mem feed from the leading membar |
|
2156 x = mm->in(Compile::AliasIdxBot); |
|
2157 |
|
2158 // ensure this is a non control projection |
|
2159 if (!x->is_Proj() || x->is_CFG()) { |
|
2160 return NULL; |
|
2161 } |
|
2162 // if it is fed by a membar that's the one we want |
|
2163 x = x->in(0); |
|
2164 |
|
2165 if (!x->is_MemBar()) { |
|
2166 return NULL; |
|
2167 } |
|
2168 |
|
2169 MemBarNode *leading = x->as_MemBar(); |
|
2170 // reject invalid candidates |
|
2171 if (!leading_membar(leading)) { |
|
2172 return NULL; |
|
2173 } |
|
2174 |
|
2175 // ok, we have a leading membar, now for the sanity clauses |
|
2176 |
|
2177 // the leading membar must feed Mem to a releasing store or CAS |
|
2178 ProjNode *mem = leading->proj_out(TypeFunc::Memory); |
|
2179 StoreNode *st = NULL; |
|
2180 LoadStoreNode *cas = NULL; |
|
2181 for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) { |
|
2182 x = mem->fast_out(i); |
|
2183 if (x->is_Store() && x->as_Store()->is_release() && x->Opcode() != Op_StoreCM) { |
|
2184 // two stores or CASes is one too many |
|
2185 if (st != NULL || cas != NULL) { |
|
2186 return NULL; |
|
2187 } |
|
2188 st = x->as_Store(); |
|
2189 } else if (is_CAS(x->Opcode())) { |
|
2190 if (st != NULL || cas != NULL) { |
|
2191 return NULL; |
|
2192 } |
|
2193 cas = x->as_LoadStore(); |
|
2194 } |
|
2195 } |
|
2196 |
|
2197 // we cannot have both a store and a cas |
|
2198 if (st == NULL && cas == NULL) { |
|
2199 // we have neither -- this is not a normal graph |
|
2200 return NULL; |
|
2201 } |
|
2202 if (st == NULL) { |
|
2203 // if we started from a volatile membar and found a CAS then the |
|
2204 // original membar ought to be for a card mark |
|
2205 guarantee((barrier_is_acquire || is_card_mark_membar(barrier)), |
|
2206 "unexpected volatile barrier (i.e. not card mark) in CAS graph"); |
|
2207 // check that the CAS feeds the merge we used to get here via an |
|
2208 // intermediary SCMemProj |
|
2209 Node *scmemproj = NULL; |
|
2210 for (DUIterator_Fast imax, i = cas->fast_outs(imax); i < imax; i++) { |
|
2211 x = cas->fast_out(i); |
|
2212 if (x->Opcode() == Op_SCMemProj) { |
|
2213 scmemproj = x; |
|
2214 break; |
|
2215 } |
|
2216 } |
|
2217 if (scmemproj == NULL) { |
|
2218 return NULL; |
|
2219 } |
|
2220 for (DUIterator_Fast imax, i = scmemproj->fast_outs(imax); i < imax; i++) { |
|
2221 x = scmemproj->fast_out(i); |
|
2222 if (x == mm) { |
|
2223 return leading; |
|
2224 } |
|
2225 } |
|
2226 } else { |
|
2227 // we should not have found a store if we started from an acquire |
|
2228 guarantee(!barrier_is_acquire, |
|
2229 "unexpected trailing acquire barrier in volatile store graph"); |
|
2230 |
|
2231 // the store should feed the merge we used to get here |
|
2232 for (DUIterator_Fast imax, i = st->fast_outs(imax); i < imax; i++) { |
|
2233 if (st->fast_out(i) == mm) { |
|
2234 return leading; |
|
2235 } |
|
2236 } |
|
2237 } |
|
2238 |
|
2239 return NULL; |
|
2240 } |
|
2241 |
|
2242 // card_mark_to_trailing |
|
2243 // |
|
2244 // graph traversal helper which detects extra, non-normal Mem feed |
|
2245 // from a card mark volatile membar to a trailing membar i.e. it |
|
2246 // ensures that one of the following three GC post-write Mem flow |
|
2247 // subgraphs is present. |
|
2248 // |
|
2249 // 1) |
|
2250 // . . . |
|
2251 // | |
|
2252 // MemBarVolatile (card mark) |
|
2253 // | | |
|
2254 // | StoreCM |
|
2255 // | | |
|
2256 // | . . . |
|
2257 // Bot | / |
|
2258 // MergeMem |
|
2259 // | |
|
2260 // {MemBarCPUOrder} OR MemBarCPUOrder |
|
2261 // MemBarVolatile {trailing} MemBarAcquire {trailing} |
|
2262 // |
|
2263 // |
|
2264 // 2) |
|
2265 // MemBarRelease/CPUOrder (leading) |
|
2266 // | |
|
2267 // | |
|
2268 // |\ . . . |
|
2269 // | \ | |
|
2270 // | \ MemBarVolatile (card mark) |
|
2271 // | \ | | |
|
2272 // \ \ | StoreCM . . . |
|
2273 // \ \ | |
|
2274 // \ Phi |
|
2275 // \ / |
|
2276 // Phi . . . |
|
2277 // Bot | / |
|
2278 // MergeMem |
|
2279 // | |
|
2280 // {MemBarCPUOrder} OR MemBarCPUOrder |
|
2281 // MemBarVolatile {trailing} MemBarAcquire {trailing} |
|
2282 // |
|
2283 // 3) |
|
2284 // MemBarRelease/CPUOrder (leading) |
|
2285 // | |
|
2286 // |\ |
|
2287 // | \ |
|
2288 // | \ . . . |
|
2289 // | \ | |
|
2290 // |\ \ MemBarVolatile (card mark) |
|
2291 // | \ \ | | |
|
2292 // | \ \ | StoreCM . . . |
|
2293 // | \ \ | |
|
2294 // \ \ Phi |
|
2295 // \ \ / |
|
2296 // \ Phi |
|
2297 // \ / |
|
2298 // Phi . . . |
|
2299 // Bot | / |
|
2300 // MergeMem |
|
2301 // | |
|
2302 // | |
|
2303 // {MemBarCPUOrder} OR MemBarCPUOrder |
|
2304 // MemBarVolatile {trailing} MemBarAcquire {trailing} |
|
2305 // |
|
2306 // 4) |
|
2307 // MemBarRelease/CPUOrder (leading) |
|
2308 // | |
|
2309 // |\ |
|
2310 // | \ |
|
2311 // | \ |
|
2312 // | \ |
|
2313 // |\ \ |
|
2314 // | \ \ |
|
2315 // | \ \ . . . |
|
2316 // | \ \ | |
|
2317 // |\ \ \ MemBarVolatile (card mark) |
|
2318 // | \ \ \ / | |
|
2319 // | \ \ \ / StoreCM . . . |
|
2320 // | \ \ Phi |
|
2321 // \ \ \ / |
|
2322 // \ \ Phi |
|
2323 // \ \ / |
|
2324 // \ Phi |
|
2325 // \ / |
|
2326 // Phi . . . |
|
2327 // Bot | / |
|
2328 // MergeMem |
|
2329 // | |
|
2330 // | |
|
2331 // MemBarCPUOrder |
|
2332 // MemBarAcquire {trailing} |
|
2333 // |
|
2334 // configuration 1 is only valid if UseConcMarkSweepGC && |
|
2335 // UseCondCardMark |
|
2336 // |
|
2337 // configuration 2, is only valid if UseConcMarkSweepGC && |
|
2338 // UseCondCardMark or if UseG1GC |
|
2339 // |
|
2340 // configurations 3 and 4 are only valid if UseG1GC. |
|
2341 // |
|
2342 // if a valid configuration is present returns the trailing membar |
|
2343 // otherwise NULL. |
|
2344 // |
|
2345 // n.b. the supplied membar is expected to be a card mark |
|
2346 // MemBarVolatile i.e. the caller must ensure the input node has the |
|
2347 // correct operand and feeds Mem to a StoreCM node |
|
2348 |
|
2349 MemBarNode *card_mark_to_trailing(const MemBarNode *barrier) |
|
2350 { |
|
2351 // input must be a card mark volatile membar |
|
2352 assert(is_card_mark_membar(barrier), "expecting a card mark membar"); |
|
2353 |
|
2354 Node *feed = barrier->proj_out(TypeFunc::Memory); |
|
2355 Node *x; |
|
2356 MergeMemNode *mm = NULL; |
|
2357 |
|
2358 const int MAX_PHIS = max_phis(); // max phis we will search through |
|
2359 int phicount = 0; // current search count |
|
2360 |
|
2361 bool retry_feed = true; |
|
2362 while (retry_feed) { |
|
2363 // see if we have a direct MergeMem feed |
|
2364 for (DUIterator_Fast imax, i = feed->fast_outs(imax); i < imax; i++) { |
|
2365 x = feed->fast_out(i); |
|
2366 // the correct Phi will be merging a Bot memory slice |
|
2367 if (x->is_MergeMem()) { |
|
2368 mm = x->as_MergeMem(); |
|
2369 break; |
|
2370 } |
|
2371 } |
|
2372 if (mm) { |
|
2373 retry_feed = false; |
|
2374 } else if (phicount++ < MAX_PHIS) { |
|
2375 // the barrier may feed indirectly via one or two Phi nodes |
|
2376 PhiNode *phi = NULL; |
|
2377 for (DUIterator_Fast imax, i = feed->fast_outs(imax); i < imax; i++) { |
|
2378 x = feed->fast_out(i); |
|
2379 // the correct Phi will be merging a Bot memory slice |
|
2380 if (x->is_Phi() && x->adr_type() == TypePtr::BOTTOM) { |
|
2381 phi = x->as_Phi(); |
|
2382 break; |
|
2383 } |
|
2384 } |
|
2385 if (!phi) { |
|
2386 return NULL; |
|
2387 } |
|
2388 // look for another merge below this phi |
|
2389 feed = phi; |
|
2390 } else { |
|
2391 // couldn't find a merge |
|
2392 return NULL; |
|
2393 } |
|
2394 } |
|
2395 |
|
2396 // sanity check this feed turns up as the expected slice |
|
2397 guarantee(mm->as_MergeMem()->in(Compile::AliasIdxBot) == feed, "expecting membar to feed AliasIdxBot slice to Merge"); |
|
2398 |
|
2399 MemBarNode *trailing = NULL; |
|
2400 // be sure we have a trailing membar fed by the merge |
|
2401 for (DUIterator_Fast imax, i = mm->fast_outs(imax); i < imax; i++) { |
|
2402 x = mm->fast_out(i); |
|
2403 if (x->is_MemBar()) { |
|
2404 // if this is an intervening cpu order membar skip to the |
|
2405 // following membar |
|
2406 if (x->Opcode() == Op_MemBarCPUOrder) { |
|
2407 MemBarNode *y = x->as_MemBar(); |
|
2408 y = child_membar(y); |
|
2409 if (y != NULL) { |
|
2410 x = y; |
|
2411 } |
|
2412 } |
|
2413 if (x->Opcode() == Op_MemBarVolatile || |
|
2414 x->Opcode() == Op_MemBarAcquire) { |
|
2415 trailing = x->as_MemBar(); |
|
2416 } |
|
2417 break; |
|
2418 } |
|
2419 } |
|
2420 |
|
2421 return trailing; |
|
2422 } |
|
2423 |
|
2424 // trailing_to_card_mark |
|
2425 // |
|
2426 // graph traversal helper which detects extra, non-normal Mem feed |
|
2427 // from a trailing volatile membar to a preceding card mark volatile |
|
2428 // membar i.e. it identifies whether one of the three possible extra |
|
2429 // GC post-write Mem flow subgraphs is present |
|
2430 // |
|
2431 // this predicate checks for the same flow as the previous predicate |
|
2432 // but starting from the bottom rather than the top. |
|
2433 // |
|
2434 // if the configuration is present returns the card mark membar |
|
2435 // otherwise NULL |
|
2436 // |
|
2437 // n.b. the supplied membar is expected to be a trailing |
|
2438 // MemBarVolatile or MemBarAcquire i.e. the caller must ensure the |
|
2439 // input node has the correct opcode |
|
2440 |
|
2441 MemBarNode *trailing_to_card_mark(const MemBarNode *trailing) |
|
2442 { |
|
2443 assert(trailing->Opcode() == Op_MemBarVolatile || |
|
2444 trailing->Opcode() == Op_MemBarAcquire, |
|
2445 "expecting a volatile or acquire membar"); |
|
2446 assert(!is_card_mark_membar(trailing), |
|
2447 "not expecting a card mark membar"); |
|
2448 |
|
2449 Node *x = (Node *)trailing; |
|
2450 |
|
2451 // look for a preceding cpu order membar |
|
2452 MemBarNode *y = parent_membar(x->as_MemBar()); |
|
2453 if (y != NULL) { |
|
2454 // make sure it is a cpu order membar |
|
2455 if (y->Opcode() != Op_MemBarCPUOrder) { |
|
2456 // this is nto the graph we were looking for |
|
2457 return NULL; |
|
2458 } |
|
2459 // start the search from here |
|
2460 x = y; |
|
2461 } |
|
2462 |
|
2463 // the Mem feed to the membar should be a merge |
|
2464 x = x->in(TypeFunc::Memory); |
|
2465 if (!x->is_MergeMem()) { |
|
2466 return NULL; |
|
2467 } |
|
2468 |
|
2469 MergeMemNode *mm = x->as_MergeMem(); |
|
2470 |
|
2471 x = mm->in(Compile::AliasIdxBot); |
|
2472 // with G1 we may possibly see a Phi or two before we see a Memory |
|
2473 // Proj from the card mark membar |
|
2474 |
|
2475 const int MAX_PHIS = max_phis(); // max phis we will search through |
|
2476 int phicount = 0; // current search count |
|
2477 |
|
2478 bool retry_feed = !x->is_Proj(); |
|
2479 |
|
2480 while (retry_feed) { |
|
2481 if (x->is_Phi() && phicount++ < MAX_PHIS) { |
|
2482 PhiNode *phi = x->as_Phi(); |
|
2483 ProjNode *proj = NULL; |
|
2484 PhiNode *nextphi = NULL; |
|
2485 bool found_leading = false; |
|
2486 for (uint i = 1; i < phi->req(); i++) { |
|
2487 x = phi->in(i); |
|
2488 if (x->is_Phi() && x->adr_type() == TypePtr::BOTTOM) { |
|
2489 nextphi = x->as_Phi(); |
|
2490 } else if (x->is_Proj()) { |
|
2491 int opcode = x->in(0)->Opcode(); |
|
2492 if (opcode == Op_MemBarVolatile) { |
|
2493 proj = x->as_Proj(); |
|
2494 } else if (opcode == Op_MemBarRelease || |
|
2495 opcode == Op_MemBarCPUOrder) { |
|
2496 // probably a leading membar |
|
2497 found_leading = true; |
|
2498 } |
|
2499 } |
|
2500 } |
|
2501 // if we found a correct looking proj then retry from there |
|
2502 // otherwise we must see a leading and a phi or this the |
|
2503 // wrong config |
|
2504 if (proj != NULL) { |
|
2505 x = proj; |
|
2506 retry_feed = false; |
|
2507 } else if (found_leading && nextphi != NULL) { |
|
2508 // retry from this phi to check phi2 |
|
2509 x = nextphi; |
|
2510 } else { |
|
2511 // not what we were looking for |
|
2512 return NULL; |
|
2513 } |
|
2514 } else { |
|
2515 return NULL; |
|
2516 } |
|
2517 } |
|
2518 // the proj has to come from the card mark membar |
|
2519 x = x->in(0); |
|
2520 if (!x->is_MemBar()) { |
|
2521 return NULL; |
|
2522 } |
|
2523 |
|
2524 MemBarNode *card_mark_membar = x->as_MemBar(); |
|
2525 |
|
2526 if (!is_card_mark_membar(card_mark_membar)) { |
|
2527 return NULL; |
|
2528 } |
|
2529 |
|
2530 return card_mark_membar; |
|
2531 } |
|
2532 |
|
2533 // trailing_to_leading |
|
2534 // |
|
2535 // graph traversal helper which checks the Mem flow up the graph |
|
2536 // from a (non-card mark) trailing membar attempting to locate and |
|
2537 // return an associated leading membar. it first looks for a |
|
2538 // subgraph in the normal configuration (relying on helper |
|
2539 // normal_to_leading). failing that it then looks for one of the |
|
2540 // possible post-write card mark subgraphs linking the trailing node |
|
2541 // to a the card mark membar (relying on helper |
|
2542 // trailing_to_card_mark), and then checks that the card mark membar |
|
2543 // is fed by a leading membar (once again relying on auxiliary |
|
2544 // predicate normal_to_leading). |
|
2545 // |
|
2546 // if the configuration is valid returns the cpuorder member for |
|
2547 // preference or when absent the release membar otherwise NULL. |
|
2548 // |
|
2549 // n.b. the input membar is expected to be either a volatile or |
|
2550 // acquire membar but in the former case must *not* be a card mark |
|
2551 // membar. |
|
2552 |
|
2553 MemBarNode *trailing_to_leading(const MemBarNode *trailing) |
|
2554 { |
|
2555 assert((trailing->Opcode() == Op_MemBarAcquire || |
|
2556 trailing->Opcode() == Op_MemBarVolatile), |
|
2557 "expecting an acquire or volatile membar"); |
|
2558 assert((trailing->Opcode() != Op_MemBarVolatile || |
|
2559 !is_card_mark_membar(trailing)), |
|
2560 "not expecting a card mark membar"); |
|
2561 |
|
2562 MemBarNode *leading = normal_to_leading(trailing); |
|
2563 |
|
2564 if (leading) { |
|
2565 return leading; |
|
2566 } |
|
2567 |
|
2568 // there is no normal path from trailing to leading membar. see if |
|
2569 // we can arrive via a card mark membar |
|
2570 |
|
2571 MemBarNode *card_mark_membar = trailing_to_card_mark(trailing); |
|
2572 |
|
2573 if (!card_mark_membar) { |
|
2574 return NULL; |
|
2575 } |
|
2576 |
|
2577 return normal_to_leading(card_mark_membar); |
|
2578 } |
|
2579 |
|
2580 // predicates controlling emit of ldr<x>/ldar<x> and associated dmb |
|
2581 |
1302 |
2582 bool unnecessary_acquire(const Node *barrier) |
1303 bool unnecessary_acquire(const Node *barrier) |
2583 { |
1304 { |
2584 assert(barrier->is_MemBar(), "expecting a membar"); |
1305 assert(barrier->is_MemBar(), "expecting a membar"); |
2585 |
1306 |
2586 if (UseBarriersForVolatile) { |
1307 if (UseBarriersForVolatile) { |
2587 // we need to plant a dmb |
1308 // we need to plant a dmb |
2588 return false; |
1309 return false; |
2589 } |
1310 } |
2590 |
1311 |
2591 // a volatile read derived from bytecode (or also from an inlined |
1312 MemBarNode* mb = barrier->as_MemBar(); |
2592 // SHA field read via LibraryCallKit::load_field_from_object) |
1313 |
2593 // manifests as a LoadX[mo_acquire] followed by an acquire membar |
1314 if (mb->trailing_load()) { |
2594 // with a bogus read dependency on it's preceding load. so in those |
1315 return true; |
2595 // cases we will find the load node at the PARMS offset of the |
|
2596 // acquire membar. n.b. there may be an intervening DecodeN node. |
|
2597 |
|
2598 Node *x = barrier->lookup(TypeFunc::Parms); |
|
2599 if (x) { |
|
2600 // we are starting from an acquire and it has a fake dependency |
|
2601 // |
|
2602 // need to check for |
|
2603 // |
|
2604 // LoadX[mo_acquire] |
|
2605 // { |1 } |
|
2606 // {DecodeN} |
|
2607 // |Parms |
|
2608 // MemBarAcquire* |
|
2609 // |
|
2610 // where * tags node we were passed |
|
2611 // and |k means input k |
|
2612 if (x->is_DecodeNarrowPtr()) { |
|
2613 x = x->in(1); |
|
2614 } |
|
2615 |
|
2616 return (x->is_Load() && x->as_Load()->is_acquire()); |
|
2617 } |
1316 } |
2618 |
1317 |
2619 // other option for unnecessary membar is that it is a trailing node |
1318 if (mb->trailing_load_store()) { |
2620 // belonging to a CAS |
1319 Node* load_store = mb->in(MemBarNode::Precedent); |
2621 |
1320 assert(load_store->is_LoadStore(), "unexpected graph shape"); |
2622 MemBarNode *leading = trailing_to_leading(barrier->as_MemBar()); |
1321 return is_CAS(load_store->Opcode()); |
2623 |
1322 } |
2624 return leading != NULL; |
1323 |
|
1324 return false; |
2625 } |
1325 } |
2626 |
1326 |
2627 bool needs_acquiring_load(const Node *n) |
1327 bool needs_acquiring_load(const Node *n) |
2628 { |
1328 { |
2629 assert(n->is_Load(), "expecting a load"); |
1329 assert(n->is_Load(), "expecting a load"); |