1542 if (shift == 0) {
1543 return;
1544 }
1545 if (!reset) {
1546 // Move all cells of trap entry at dp left by "shift" cells
1547 intptr_t* start = (intptr_t*)dp;
1548 intptr_t* end = (intptr_t*)next_extra(dp);
1549 for (intptr_t* ptr = start; ptr < end; ptr++) {
1550 *(ptr-shift) = *ptr;
1551 }
1552 } else {
1553 // Reset "shift" cells stopping at dp
1554 intptr_t* start = ((intptr_t*)dp) - shift;
1555 intptr_t* end = (intptr_t*)dp;
1556 for (intptr_t* ptr = start; ptr < end; ptr++) {
1557 *ptr = 0;
1558 }
1559 }
1560 }
1561
1562 // Remove SpeculativeTrapData entries that reference an unloaded
1563 // method
1564 void MethodData::clean_extra_data(BoolObjectClosure* is_alive) {
1565 DataLayout* dp = extra_data_base();
1566 DataLayout* end = extra_data_limit();
1567
1568 int shift = 0;
1569 for (; dp < end; dp = next_extra(dp)) {
1570 switch(dp->tag()) {
1571 case DataLayout::speculative_trap_data_tag: {
1572 SpeculativeTrapData* data = new SpeculativeTrapData(dp);
1573 Method* m = data->method();
1574 assert(m != NULL, "should have a method");
1575 if (!m->method_holder()->is_loader_alive(is_alive)) {
1576 // "shift" accumulates the number of cells for dead
1577 // SpeculativeTrapData entries that have been seen so
1578 // far. Following entries must be shifted left by that many
1579 // cells to remove the dead SpeculativeTrapData entries.
1580 shift += (int)((intptr_t*)next_extra(dp) - (intptr_t*)dp);
1581 } else {
1582 // Shift this entry left if it follows dead
1583 // SpeculativeTrapData entries
1584 clean_extra_data_helper(dp, shift);
1585 }
1586 break;
1587 }
1588 case DataLayout::bit_data_tag:
1589 // Shift this entry left if it follows dead SpeculativeTrapData
1590 // entries
1591 clean_extra_data_helper(dp, shift);
1592 continue;
1593 case DataLayout::no_tag:
1594 case DataLayout::arg_info_data_tag:
1595 // We are at end of the live trap entries. The previous "shift"
1596 // cells contain entries that are either dead or were shifted
1597 // left. They need to be reset to no_tag
1598 clean_extra_data_helper(dp, shift, true);
1599 return;
1600 default:
1601 fatal(err_msg("unexpected tag %d", dp->tag()));
1602 }
1603 }
1604 }
1605
1606 // Verify there's no unloaded method referenced by a
1607 // SpeculativeTrapData entry
1608 void MethodData::verify_extra_data_clean(BoolObjectClosure* is_alive) {
1609 #ifdef ASSERT
1610 DataLayout* dp = extra_data_base();
1611 DataLayout* end = extra_data_limit();
1612
1613 for (; dp < end; dp = next_extra(dp)) {
1614 switch(dp->tag()) {
1615 case DataLayout::speculative_trap_data_tag: {
1616 SpeculativeTrapData* data = new SpeculativeTrapData(dp);
1617 Method* m = data->method();
1618 assert(m != NULL && m->method_holder()->is_loader_alive(is_alive), "Method should exist");
1619 break;
1620 }
1621 case DataLayout::bit_data_tag:
1622 continue;
1623 case DataLayout::no_tag:
1624 case DataLayout::arg_info_data_tag:
1625 return;
1626 default:
1627 fatal(err_msg("unexpected tag %d", dp->tag()));
1628 }
1629 }
1630 #endif
1631 }
1632
1633 void MethodData::clean_method_data(BoolObjectClosure* is_alive) {
1634 for (ProfileData* data = first_data();
1635 is_valid(data);
1636 data = next_data(data)) {
1637 data->clean_weak_klass_links(is_alive);
1638 }
1639 ParametersTypeData* parameters = parameters_type_data();
1640 if (parameters != NULL) {
1641 parameters->clean_weak_klass_links(is_alive);
1642 }
1643
1644 clean_extra_data(is_alive);
1645 verify_extra_data_clean(is_alive);
1646 }
|
1542 if (shift == 0) {
1543 return;
1544 }
1545 if (!reset) {
1546 // Move all cells of trap entry at dp left by "shift" cells
1547 intptr_t* start = (intptr_t*)dp;
1548 intptr_t* end = (intptr_t*)next_extra(dp);
1549 for (intptr_t* ptr = start; ptr < end; ptr++) {
1550 *(ptr-shift) = *ptr;
1551 }
1552 } else {
1553 // Reset "shift" cells stopping at dp
1554 intptr_t* start = ((intptr_t*)dp) - shift;
1555 intptr_t* end = (intptr_t*)dp;
1556 for (intptr_t* ptr = start; ptr < end; ptr++) {
1557 *ptr = 0;
1558 }
1559 }
1560 }
1561
1562 class CleanExtraDataClosure : public StackObj {
1563 public:
1564 virtual bool is_live(Method* m) = 0;
1565 };
1566
1567 // Check for entries that reference an unloaded method
1568 class CleanExtraDataKlassClosure : public CleanExtraDataClosure {
1569 private:
1570 BoolObjectClosure* _is_alive;
1571 public:
1572 CleanExtraDataKlassClosure(BoolObjectClosure* is_alive) : _is_alive(is_alive) {}
1573 bool is_live(Method* m) {
1574 return m->method_holder()->is_loader_alive(_is_alive);
1575 }
1576 };
1577
1578 // Check for entries that reference a redefined method
1579 class CleanExtraDataMethodClosure : public CleanExtraDataClosure {
1580 public:
1581 CleanExtraDataMethodClosure() {}
1582 bool is_live(Method* m) {
1583 return m->on_stack();
1584 }
1585 };
1586
1587
1588 // Remove SpeculativeTrapData entries that reference an unloaded or
1589 // redefined method
1590 void MethodData::clean_extra_data(CleanExtraDataClosure* cl) {
1591 DataLayout* dp = extra_data_base();
1592 DataLayout* end = extra_data_limit();
1593
1594 int shift = 0;
1595 for (; dp < end; dp = next_extra(dp)) {
1596 switch(dp->tag()) {
1597 case DataLayout::speculative_trap_data_tag: {
1598 SpeculativeTrapData* data = new SpeculativeTrapData(dp);
1599 Method* m = data->method();
1600 assert(m != NULL, "should have a method");
1601 if (!cl->is_live(m)) {
1602 // "shift" accumulates the number of cells for dead
1603 // SpeculativeTrapData entries that have been seen so
1604 // far. Following entries must be shifted left by that many
1605 // cells to remove the dead SpeculativeTrapData entries.
1606 shift += (int)((intptr_t*)next_extra(dp) - (intptr_t*)dp);
1607 } else {
1608 // Shift this entry left if it follows dead
1609 // SpeculativeTrapData entries
1610 clean_extra_data_helper(dp, shift);
1611 }
1612 break;
1613 }
1614 case DataLayout::bit_data_tag:
1615 // Shift this entry left if it follows dead SpeculativeTrapData
1616 // entries
1617 clean_extra_data_helper(dp, shift);
1618 continue;
1619 case DataLayout::no_tag:
1620 case DataLayout::arg_info_data_tag:
1621 // We are at end of the live trap entries. The previous "shift"
1622 // cells contain entries that are either dead or were shifted
1623 // left. They need to be reset to no_tag
1624 clean_extra_data_helper(dp, shift, true);
1625 return;
1626 default:
1627 fatal(err_msg("unexpected tag %d", dp->tag()));
1628 }
1629 }
1630 }
1631
1632 // Verify there's no unloaded or redefined method referenced by a
1633 // SpeculativeTrapData entry
1634 void MethodData::verify_extra_data_clean(CleanExtraDataClosure* cl) {
1635 #ifdef ASSERT
1636 DataLayout* dp = extra_data_base();
1637 DataLayout* end = extra_data_limit();
1638
1639 for (; dp < end; dp = next_extra(dp)) {
1640 switch(dp->tag()) {
1641 case DataLayout::speculative_trap_data_tag: {
1642 SpeculativeTrapData* data = new SpeculativeTrapData(dp);
1643 Method* m = data->method();
1644 assert(m != NULL && cl->is_live(m), "Method should exist");
1645 break;
1646 }
1647 case DataLayout::bit_data_tag:
1648 continue;
1649 case DataLayout::no_tag:
1650 case DataLayout::arg_info_data_tag:
1651 return;
1652 default:
1653 fatal(err_msg("unexpected tag %d", dp->tag()));
1654 }
1655 }
1656 #endif
1657 }
1658
1659 void MethodData::clean_method_data(BoolObjectClosure* is_alive) {
1660 for (ProfileData* data = first_data();
1661 is_valid(data);
1662 data = next_data(data)) {
1663 data->clean_weak_klass_links(is_alive);
1664 }
1665 ParametersTypeData* parameters = parameters_type_data();
1666 if (parameters != NULL) {
1667 parameters->clean_weak_klass_links(is_alive);
1668 }
1669
1670 CleanExtraDataKlassClosure cl(is_alive);
1671 clean_extra_data(&cl);
1672 verify_extra_data_clean(&cl);
1673 }
1674
1675 void MethodData::clean_weak_method_links() {
1676 for (ProfileData* data = first_data();
1677 is_valid(data);
1678 data = next_data(data)) {
1679 data->clean_weak_method_links();
1680 }
1681
1682 CleanExtraDataMethodClosure cl;
1683 clean_extra_data(&cl);
1684 verify_extra_data_clean(&cl);
1685 }
|