1557 *ptr = 0; |
1557 *ptr = 0; |
1558 } |
1558 } |
1559 } |
1559 } |
1560 } |
1560 } |
1561 |
1561 |
1562 // Remove SpeculativeTrapData entries that reference an unloaded |
1562 class CleanExtraDataClosure : public StackObj { |
1563 // method |
1563 public: |
1564 void MethodData::clean_extra_data(BoolObjectClosure* is_alive) { |
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) { |
1565 DataLayout* dp = extra_data_base(); |
1591 DataLayout* dp = extra_data_base(); |
1566 DataLayout* end = extra_data_limit(); |
1592 DataLayout* end = extra_data_limit(); |
1567 |
1593 |
1568 int shift = 0; |
1594 int shift = 0; |
1569 for (; dp < end; dp = next_extra(dp)) { |
1595 for (; dp < end; dp = next_extra(dp)) { |
1570 switch(dp->tag()) { |
1596 switch(dp->tag()) { |
1571 case DataLayout::speculative_trap_data_tag: { |
1597 case DataLayout::speculative_trap_data_tag: { |
1572 SpeculativeTrapData* data = new SpeculativeTrapData(dp); |
1598 SpeculativeTrapData* data = new SpeculativeTrapData(dp); |
1573 Method* m = data->method(); |
1599 Method* m = data->method(); |
1574 assert(m != NULL, "should have a method"); |
1600 assert(m != NULL, "should have a method"); |
1575 if (!m->method_holder()->is_loader_alive(is_alive)) { |
1601 if (!cl->is_live(m)) { |
1576 // "shift" accumulates the number of cells for dead |
1602 // "shift" accumulates the number of cells for dead |
1577 // SpeculativeTrapData entries that have been seen so |
1603 // SpeculativeTrapData entries that have been seen so |
1578 // far. Following entries must be shifted left by that many |
1604 // far. Following entries must be shifted left by that many |
1579 // cells to remove the dead SpeculativeTrapData entries. |
1605 // cells to remove the dead SpeculativeTrapData entries. |
1580 shift += (int)((intptr_t*)next_extra(dp) - (intptr_t*)dp); |
1606 shift += (int)((intptr_t*)next_extra(dp) - (intptr_t*)dp); |
1601 fatal(err_msg("unexpected tag %d", dp->tag())); |
1627 fatal(err_msg("unexpected tag %d", dp->tag())); |
1602 } |
1628 } |
1603 } |
1629 } |
1604 } |
1630 } |
1605 |
1631 |
1606 // Verify there's no unloaded method referenced by a |
1632 // Verify there's no unloaded or redefined method referenced by a |
1607 // SpeculativeTrapData entry |
1633 // SpeculativeTrapData entry |
1608 void MethodData::verify_extra_data_clean(BoolObjectClosure* is_alive) { |
1634 void MethodData::verify_extra_data_clean(CleanExtraDataClosure* cl) { |
1609 #ifdef ASSERT |
1635 #ifdef ASSERT |
1610 DataLayout* dp = extra_data_base(); |
1636 DataLayout* dp = extra_data_base(); |
1611 DataLayout* end = extra_data_limit(); |
1637 DataLayout* end = extra_data_limit(); |
1612 |
1638 |
1613 for (; dp < end; dp = next_extra(dp)) { |
1639 for (; dp < end; dp = next_extra(dp)) { |
1614 switch(dp->tag()) { |
1640 switch(dp->tag()) { |
1615 case DataLayout::speculative_trap_data_tag: { |
1641 case DataLayout::speculative_trap_data_tag: { |
1616 SpeculativeTrapData* data = new SpeculativeTrapData(dp); |
1642 SpeculativeTrapData* data = new SpeculativeTrapData(dp); |
1617 Method* m = data->method(); |
1643 Method* m = data->method(); |
1618 assert(m != NULL && m->method_holder()->is_loader_alive(is_alive), "Method should exist"); |
1644 assert(m != NULL && cl->is_live(m), "Method should exist"); |
1619 break; |
1645 break; |
1620 } |
1646 } |
1621 case DataLayout::bit_data_tag: |
1647 case DataLayout::bit_data_tag: |
1622 continue; |
1648 continue; |
1623 case DataLayout::no_tag: |
1649 case DataLayout::no_tag: |
1639 ParametersTypeData* parameters = parameters_type_data(); |
1665 ParametersTypeData* parameters = parameters_type_data(); |
1640 if (parameters != NULL) { |
1666 if (parameters != NULL) { |
1641 parameters->clean_weak_klass_links(is_alive); |
1667 parameters->clean_weak_klass_links(is_alive); |
1642 } |
1668 } |
1643 |
1669 |
1644 clean_extra_data(is_alive); |
1670 CleanExtraDataKlassClosure cl(is_alive); |
1645 verify_extra_data_clean(is_alive); |
1671 clean_extra_data(&cl); |
1646 } |
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 } |