1529 *ptr = 0; |
1529 *ptr = 0; |
1530 } |
1530 } |
1531 } |
1531 } |
1532 } |
1532 } |
1533 |
1533 |
1534 // Remove SpeculativeTrapData entries that reference an unloaded |
1534 class CleanExtraDataClosure : public StackObj { |
1535 // method |
1535 public: |
1536 void MethodData::clean_extra_data(BoolObjectClosure* is_alive) { |
1536 virtual bool is_live(Method* m) = 0; |
|
1537 }; |
|
1538 |
|
1539 // Check for entries that reference an unloaded method |
|
1540 class CleanExtraDataKlassClosure : public CleanExtraDataClosure { |
|
1541 private: |
|
1542 BoolObjectClosure* _is_alive; |
|
1543 public: |
|
1544 CleanExtraDataKlassClosure(BoolObjectClosure* is_alive) : _is_alive(is_alive) {} |
|
1545 bool is_live(Method* m) { |
|
1546 return m->method_holder()->is_loader_alive(_is_alive); |
|
1547 } |
|
1548 }; |
|
1549 |
|
1550 // Check for entries that reference a redefined method |
|
1551 class CleanExtraDataMethodClosure : public CleanExtraDataClosure { |
|
1552 public: |
|
1553 CleanExtraDataMethodClosure() {} |
|
1554 bool is_live(Method* m) { |
|
1555 return m->on_stack(); |
|
1556 } |
|
1557 }; |
|
1558 |
|
1559 |
|
1560 // Remove SpeculativeTrapData entries that reference an unloaded or |
|
1561 // redefined method |
|
1562 void MethodData::clean_extra_data(CleanExtraDataClosure* cl) { |
1537 DataLayout* dp = extra_data_base(); |
1563 DataLayout* dp = extra_data_base(); |
1538 DataLayout* end = extra_data_limit(); |
1564 DataLayout* end = extra_data_limit(); |
1539 |
1565 |
1540 int shift = 0; |
1566 int shift = 0; |
1541 for (; dp < end; dp = next_extra(dp)) { |
1567 for (; dp < end; dp = next_extra(dp)) { |
1542 switch(dp->tag()) { |
1568 switch(dp->tag()) { |
1543 case DataLayout::speculative_trap_data_tag: { |
1569 case DataLayout::speculative_trap_data_tag: { |
1544 SpeculativeTrapData* data = new SpeculativeTrapData(dp); |
1570 SpeculativeTrapData* data = new SpeculativeTrapData(dp); |
1545 Method* m = data->method(); |
1571 Method* m = data->method(); |
1546 assert(m != NULL, "should have a method"); |
1572 assert(m != NULL, "should have a method"); |
1547 if (!m->method_holder()->is_loader_alive(is_alive)) { |
1573 if (!cl->is_live(m)) { |
1548 // "shift" accumulates the number of cells for dead |
1574 // "shift" accumulates the number of cells for dead |
1549 // SpeculativeTrapData entries that have been seen so |
1575 // SpeculativeTrapData entries that have been seen so |
1550 // far. Following entries must be shifted left by that many |
1576 // far. Following entries must be shifted left by that many |
1551 // cells to remove the dead SpeculativeTrapData entries. |
1577 // cells to remove the dead SpeculativeTrapData entries. |
1552 shift += (int)((intptr_t*)next_extra(dp) - (intptr_t*)dp); |
1578 shift += (int)((intptr_t*)next_extra(dp) - (intptr_t*)dp); |
1573 fatal(err_msg("unexpected tag %d", dp->tag())); |
1599 fatal(err_msg("unexpected tag %d", dp->tag())); |
1574 } |
1600 } |
1575 } |
1601 } |
1576 } |
1602 } |
1577 |
1603 |
1578 // Verify there's no unloaded method referenced by a |
1604 // Verify there's no unloaded or redefined method referenced by a |
1579 // SpeculativeTrapData entry |
1605 // SpeculativeTrapData entry |
1580 void MethodData::verify_extra_data_clean(BoolObjectClosure* is_alive) { |
1606 void MethodData::verify_extra_data_clean(CleanExtraDataClosure* cl) { |
1581 #ifdef ASSERT |
1607 #ifdef ASSERT |
1582 DataLayout* dp = extra_data_base(); |
1608 DataLayout* dp = extra_data_base(); |
1583 DataLayout* end = extra_data_limit(); |
1609 DataLayout* end = extra_data_limit(); |
1584 |
1610 |
1585 for (; dp < end; dp = next_extra(dp)) { |
1611 for (; dp < end; dp = next_extra(dp)) { |
1586 switch(dp->tag()) { |
1612 switch(dp->tag()) { |
1587 case DataLayout::speculative_trap_data_tag: { |
1613 case DataLayout::speculative_trap_data_tag: { |
1588 SpeculativeTrapData* data = new SpeculativeTrapData(dp); |
1614 SpeculativeTrapData* data = new SpeculativeTrapData(dp); |
1589 Method* m = data->method(); |
1615 Method* m = data->method(); |
1590 assert(m != NULL && m->method_holder()->is_loader_alive(is_alive), "Method should exist"); |
1616 assert(m != NULL && cl->is_live(m), "Method should exist"); |
1591 break; |
1617 break; |
1592 } |
1618 } |
1593 case DataLayout::bit_data_tag: |
1619 case DataLayout::bit_data_tag: |
1594 continue; |
1620 continue; |
1595 case DataLayout::no_tag: |
1621 case DataLayout::no_tag: |
1611 ParametersTypeData* parameters = parameters_type_data(); |
1637 ParametersTypeData* parameters = parameters_type_data(); |
1612 if (parameters != NULL) { |
1638 if (parameters != NULL) { |
1613 parameters->clean_weak_klass_links(is_alive); |
1639 parameters->clean_weak_klass_links(is_alive); |
1614 } |
1640 } |
1615 |
1641 |
1616 clean_extra_data(is_alive); |
1642 CleanExtraDataKlassClosure cl(is_alive); |
1617 verify_extra_data_clean(is_alive); |
1643 clean_extra_data(&cl); |
1618 } |
1644 verify_extra_data_clean(&cl); |
|
1645 } |
|
1646 |
|
1647 void MethodData::clean_weak_method_links() { |
|
1648 for (ProfileData* data = first_data(); |
|
1649 is_valid(data); |
|
1650 data = next_data(data)) { |
|
1651 data->clean_weak_method_links(); |
|
1652 } |
|
1653 |
|
1654 CleanExtraDataMethodClosure cl; |
|
1655 clean_extra_data(&cl); |
|
1656 verify_extra_data_clean(&cl); |
|
1657 } |