61 #include "runtime/vmOperations.hpp" |
61 #include "runtime/vmOperations.hpp" |
62 #include "utilities/macros.hpp" |
62 #include "utilities/macros.hpp" |
63 #if INCLUDE_ZGC |
63 #if INCLUDE_ZGC |
64 #include "gc/z/zGlobals.hpp" |
64 #include "gc/z/zGlobals.hpp" |
65 #endif |
65 #endif |
66 #if INCLUDE_JVMCI |
|
67 #include "jvmci/jvmci.hpp" |
|
68 #endif |
|
69 |
66 |
70 // JvmtiTagHashmapEntry |
67 // JvmtiTagHashmapEntry |
71 // |
68 // |
72 // Each entry encapsulates a reference to the tagged object |
69 // Each entry encapsulates a reference to the tagged object |
73 // and the tag value. In addition an entry includes a next pointer which |
70 // and the tag value. In addition an entry includes a next pointer which |
106 assert(tag != 0, "can't be zero"); |
103 assert(tag != 0, "can't be zero"); |
107 _tag = tag; |
104 _tag = tag; |
108 } |
105 } |
109 |
106 |
110 inline bool equals(oop object) { |
107 inline bool equals(oop object) { |
111 return oopDesc::equals(object, object_peek()); |
108 return object == object_peek(); |
112 } |
109 } |
113 |
110 |
114 inline JvmtiTagHashmapEntry* next() const { return _next; } |
111 inline JvmtiTagHashmapEntry* next() const { return _next; } |
115 inline void set_next(JvmtiTagHashmapEntry* next) { _next = next; } |
112 inline void set_next(JvmtiTagHashmapEntry* next) { _next = next; } |
116 }; |
113 }; |
521 tag_map = ((JvmtiEnvBase*)env)->tag_map(); |
518 tag_map = ((JvmtiEnvBase*)env)->tag_map(); |
522 if (tag_map == NULL) { |
519 if (tag_map == NULL) { |
523 tag_map = new JvmtiTagMap(env); |
520 tag_map = new JvmtiTagMap(env); |
524 } |
521 } |
525 } else { |
522 } else { |
526 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); |
523 DEBUG_ONLY(Thread::current()->check_possible_safepoint()); |
527 } |
524 } |
528 return tag_map; |
525 return tag_map; |
529 } |
526 } |
530 |
527 |
531 // iterate over all entries in the tag map. |
528 // iterate over all entries in the tag map. |
1546 // The reference in this tag map could be the only (implicitly weak) |
1543 // The reference in this tag map could be the only (implicitly weak) |
1547 // reference to that object. If we hand it out, we need to keep it live wrt |
1544 // reference to that object. If we hand it out, we need to keep it live wrt |
1548 // SATB marking similar to other j.l.ref.Reference referents. This is |
1545 // SATB marking similar to other j.l.ref.Reference referents. This is |
1549 // achieved by using a phantom load in the object() accessor. |
1546 // achieved by using a phantom load in the object() accessor. |
1550 oop o = entry->object(); |
1547 oop o = entry->object(); |
1551 assert(o != NULL && Universe::heap()->is_in_reserved(o), "sanity check"); |
1548 assert(o != NULL && Universe::heap()->is_in(o), "sanity check"); |
1552 jobject ref = JNIHandles::make_local(JavaThread::current(), o); |
1549 jobject ref = JNIHandles::make_local(JavaThread::current(), o); |
1553 _object_results->append(ref); |
1550 _object_results->append(ref); |
1554 _tag_results->append((uint64_t)entry->tag()); |
1551 _tag_results->append((uint64_t)entry->tag()); |
1555 } |
1552 } |
1556 } |
1553 } |
1629 // An ObjectClosure used to restore the mark bits of an object |
1626 // An ObjectClosure used to restore the mark bits of an object |
1630 class RestoreMarksClosure : public ObjectClosure { |
1627 class RestoreMarksClosure : public ObjectClosure { |
1631 public: |
1628 public: |
1632 void do_object(oop o) { |
1629 void do_object(oop o) { |
1633 if (o != NULL) { |
1630 if (o != NULL) { |
1634 markOop mark = o->mark(); |
1631 markWord mark = o->mark(); |
1635 if (mark->is_marked()) { |
1632 if (mark.is_marked()) { |
1636 o->init_mark(); |
1633 o->init_mark(); |
1637 } |
1634 } |
1638 } |
1635 } |
1639 } |
1636 } |
1640 }; |
1637 }; |
1642 // ObjectMarker provides the mark and visited functions |
1639 // ObjectMarker provides the mark and visited functions |
1643 class ObjectMarker : AllStatic { |
1640 class ObjectMarker : AllStatic { |
1644 private: |
1641 private: |
1645 // saved headers |
1642 // saved headers |
1646 static GrowableArray<oop>* _saved_oop_stack; |
1643 static GrowableArray<oop>* _saved_oop_stack; |
1647 static GrowableArray<markOop>* _saved_mark_stack; |
1644 static GrowableArray<markWord>* _saved_mark_stack; |
1648 static bool _needs_reset; // do we need to reset mark bits? |
1645 static bool _needs_reset; // do we need to reset mark bits? |
1649 |
1646 |
1650 public: |
1647 public: |
1651 static void init(); // initialize |
1648 static void init(); // initialize |
1652 static void done(); // clean-up |
1649 static void done(); // clean-up |
1657 static inline bool needs_reset() { return _needs_reset; } |
1654 static inline bool needs_reset() { return _needs_reset; } |
1658 static inline void set_needs_reset(bool v) { _needs_reset = v; } |
1655 static inline void set_needs_reset(bool v) { _needs_reset = v; } |
1659 }; |
1656 }; |
1660 |
1657 |
1661 GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL; |
1658 GrowableArray<oop>* ObjectMarker::_saved_oop_stack = NULL; |
1662 GrowableArray<markOop>* ObjectMarker::_saved_mark_stack = NULL; |
1659 GrowableArray<markWord>* ObjectMarker::_saved_mark_stack = NULL; |
1663 bool ObjectMarker::_needs_reset = true; // need to reset mark bits by default |
1660 bool ObjectMarker::_needs_reset = true; // need to reset mark bits by default |
1664 |
1661 |
1665 // initialize ObjectMarker - prepares for object marking |
1662 // initialize ObjectMarker - prepares for object marking |
1666 void ObjectMarker::init() { |
1663 void ObjectMarker::init() { |
1667 assert(Thread::current()->is_VM_thread(), "must be VMThread"); |
1664 assert(Thread::current()->is_VM_thread(), "must be VMThread"); |
1668 |
1665 |
1669 // prepare heap for iteration |
1666 // prepare heap for iteration |
1670 Universe::heap()->ensure_parsability(false); // no need to retire TLABs |
1667 Universe::heap()->ensure_parsability(false); // no need to retire TLABs |
1671 |
1668 |
1672 // create stacks for interesting headers |
1669 // create stacks for interesting headers |
1673 _saved_mark_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<markOop>(4000, true); |
1670 _saved_mark_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<markWord>(4000, true); |
1674 _saved_oop_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(4000, true); |
1671 _saved_oop_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(4000, true); |
1675 |
1672 |
1676 if (UseBiasedLocking) { |
1673 if (UseBiasedLocking) { |
1677 BiasedLocking::preserve_marks(); |
1674 BiasedLocking::preserve_marks(); |
1678 } |
1675 } |
1692 } |
1689 } |
1693 |
1690 |
1694 // now restore the interesting headers |
1691 // now restore the interesting headers |
1695 for (int i = 0; i < _saved_oop_stack->length(); i++) { |
1692 for (int i = 0; i < _saved_oop_stack->length(); i++) { |
1696 oop o = _saved_oop_stack->at(i); |
1693 oop o = _saved_oop_stack->at(i); |
1697 markOop mark = _saved_mark_stack->at(i); |
1694 markWord mark = _saved_mark_stack->at(i); |
1698 o->set_mark(mark); |
1695 o->set_mark(mark); |
1699 } |
1696 } |
1700 |
1697 |
1701 if (UseBiasedLocking) { |
1698 if (UseBiasedLocking) { |
1702 BiasedLocking::restore_marks(); |
1699 BiasedLocking::restore_marks(); |
1708 } |
1705 } |
1709 |
1706 |
1710 // mark an object |
1707 // mark an object |
1711 inline void ObjectMarker::mark(oop o) { |
1708 inline void ObjectMarker::mark(oop o) { |
1712 assert(Universe::heap()->is_in(o), "sanity check"); |
1709 assert(Universe::heap()->is_in(o), "sanity check"); |
1713 assert(!o->mark()->is_marked(), "should only mark an object once"); |
1710 assert(!o->mark().is_marked(), "should only mark an object once"); |
1714 |
1711 |
1715 // object's mark word |
1712 // object's mark word |
1716 markOop mark = o->mark(); |
1713 markWord mark = o->mark(); |
1717 |
1714 |
1718 if (mark->must_be_preserved(o)) { |
1715 if (o->mark_must_be_preserved(mark)) { |
1719 _saved_mark_stack->push(mark); |
1716 _saved_mark_stack->push(mark); |
1720 _saved_oop_stack->push(o); |
1717 _saved_oop_stack->push(o); |
1721 } |
1718 } |
1722 |
1719 |
1723 // mark the object |
1720 // mark the object |
1724 o->set_mark(markOopDesc::prototype()->set_marked()); |
1721 o->set_mark(markWord::prototype().set_marked()); |
1725 } |
1722 } |
1726 |
1723 |
1727 // return true if object is marked |
1724 // return true if object is marked |
1728 inline bool ObjectMarker::visited(oop o) { |
1725 inline bool ObjectMarker::visited(oop o) { |
1729 return o->mark()->is_marked(); |
1726 return o->mark().is_marked(); |
1730 } |
1727 } |
1731 |
1728 |
1732 // Stack allocated class to help ensure that ObjectMarker is used |
1729 // Stack allocated class to help ensure that ObjectMarker is used |
1733 // correctly. Constructor initializes ObjectMarker, destructor calls |
1730 // correctly. Constructor initializes ObjectMarker, destructor calls |
1734 // ObjectMarker's done() function to restore object headers. |
1731 // ObjectMarker's done() function to restore object headers. |
2573 // ignore null |
2570 // ignore null |
2574 if (o == NULL) { |
2571 if (o == NULL) { |
2575 return; |
2572 return; |
2576 } |
2573 } |
2577 |
2574 |
2578 assert(Universe::heap()->is_in_reserved(o), "should be impossible"); |
2575 assert(Universe::heap()->is_in(o), "should be impossible"); |
2579 |
2576 |
2580 jvmtiHeapReferenceKind kind = root_kind(); |
2577 jvmtiHeapReferenceKind kind = root_kind(); |
2581 if (kind == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) { |
2578 if (kind == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) { |
2582 // SystemDictionary::oops_do reports the application |
2579 // SystemDictionary::oops_do reports the application |
2583 // class loader as a root. We want this root to be reported as |
2580 // class loader as a root. We want this root to be reported as |
2965 char type = field->field_type(); |
2962 char type = field->field_type(); |
2966 if (!is_primitive_field_type(type)) { |
2963 if (!is_primitive_field_type(type)) { |
2967 oop fld_o = o->obj_field(field->field_offset()); |
2964 oop fld_o = o->obj_field(field->field_offset()); |
2968 // ignore any objects that aren't visible to profiler |
2965 // ignore any objects that aren't visible to profiler |
2969 if (fld_o != NULL) { |
2966 if (fld_o != NULL) { |
2970 assert(Universe::heap()->is_in_reserved(fld_o), "unsafe code should not " |
2967 assert(Universe::heap()->is_in(fld_o), "unsafe code should not " |
2971 "have references to Klass* anymore"); |
2968 "have references to Klass* anymore"); |
2972 int slot = field->field_index(); |
2969 int slot = field->field_index(); |
2973 if (!CallbackInvoker::report_field_reference(o, fld_o, slot)) { |
2970 if (!CallbackInvoker::report_field_reference(o, fld_o, slot)) { |
2974 return false; |
2971 return false; |
2975 } |
2972 } |
3039 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER); |
3036 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER); |
3040 Universe::oops_do(&blk); |
3037 Universe::oops_do(&blk); |
3041 if (blk.stopped()) { |
3038 if (blk.stopped()) { |
3042 return false; |
3039 return false; |
3043 } |
3040 } |
3044 |
|
3045 #if INCLUDE_JVMCI |
|
3046 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER); |
|
3047 JVMCI::oops_do(&blk); |
|
3048 if (blk.stopped()) { |
|
3049 return false; |
|
3050 } |
|
3051 #endif |
|
3052 |
3041 |
3053 return true; |
3042 return true; |
3054 } |
3043 } |
3055 |
3044 |
3056 // Walk the stack of a given thread and find all references (locals |
3045 // Walk the stack of a given thread and find all references (locals |