< prev index next >

src/hotspot/share/prims/jvmtiTagMap.cpp

Print this page
rev 60137 : 8227745: Enable Escape Analysis for Better Performance in the Presence of JVMTI Agents
Reviewed-by: mdoerr, goetz


  30 #include "classfile/vmSymbols.hpp"
  31 #include "jvmtifiles/jvmtiEnv.hpp"
  32 #include "logging/log.hpp"
  33 #include "memory/allocation.inline.hpp"
  34 #include "memory/resourceArea.hpp"
  35 #include "memory/universe.hpp"
  36 #include "oops/access.inline.hpp"
  37 #include "oops/arrayOop.inline.hpp"
  38 #include "oops/constantPool.inline.hpp"
  39 #include "oops/instanceMirrorKlass.hpp"
  40 #include "oops/objArrayKlass.hpp"
  41 #include "oops/objArrayOop.inline.hpp"
  42 #include "oops/oop.inline.hpp"
  43 #include "oops/typeArrayOop.inline.hpp"
  44 #include "prims/jvmtiEventController.hpp"
  45 #include "prims/jvmtiEventController.inline.hpp"
  46 #include "prims/jvmtiExport.hpp"
  47 #include "prims/jvmtiImpl.hpp"
  48 #include "prims/jvmtiTagMap.hpp"
  49 #include "runtime/biasedLocking.hpp"

  50 #include "runtime/frame.inline.hpp"
  51 #include "runtime/handles.inline.hpp"
  52 #include "runtime/javaCalls.hpp"
  53 #include "runtime/jniHandles.inline.hpp"
  54 #include "runtime/mutex.hpp"
  55 #include "runtime/mutexLocker.hpp"
  56 #include "runtime/reflectionUtils.hpp"
  57 #include "runtime/thread.inline.hpp"
  58 #include "runtime/threadSMR.hpp"
  59 #include "runtime/vframe.hpp"
  60 #include "runtime/vmThread.hpp"
  61 #include "runtime/vmOperations.hpp"
  62 #include "utilities/macros.hpp"
  63 #if INCLUDE_ZGC
  64 #include "gc/z/zGlobals.hpp"
  65 #endif
  66 
  67 // JvmtiTagHashmapEntry
  68 //
  69 // Each entry encapsulates a reference to the tagged object


1471   // array callback
1472   if (is_array &&
1473       callbacks()->array_primitive_value_callback != NULL &&
1474       obj->is_typeArray()) {
1475     jint res = invoke_array_primitive_value_callback(
1476                callbacks()->array_primitive_value_callback,
1477                &wrapper,
1478                obj,
1479                (void*)user_data() );
1480     if (check_flags_for_abort(res)) return;
1481   }
1482 };
1483 
1484 
1485 // Deprecated function to iterate over all objects in the heap
1486 void JvmtiTagMap::iterate_over_heap(jvmtiHeapObjectFilter object_filter,
1487                                     Klass* klass,
1488                                     jvmtiHeapObjectCallback heap_object_callback,
1489                                     const void* user_data)
1490 {




1491   MutexLocker ml(Heap_lock);
1492   IterateOverHeapObjectClosure blk(this,
1493                                    klass,
1494                                    object_filter,
1495                                    heap_object_callback,
1496                                    user_data);
1497   VM_HeapIterateOperation op(&blk);
1498   VMThread::execute(&op);
1499 }
1500 
1501 
1502 // Iterates over all objects in the heap
1503 void JvmtiTagMap::iterate_through_heap(jint heap_filter,
1504                                        Klass* klass,
1505                                        const jvmtiHeapCallbacks* callbacks,
1506                                        const void* user_data)
1507 {



1508   MutexLocker ml(Heap_lock);
1509   IterateThroughHeapObjectClosure blk(this,
1510                                       klass,
1511                                       heap_filter,
1512                                       callbacks,
1513                                       user_data);
1514   VM_HeapIterateOperation op(&blk);
1515   VMThread::execute(&op);
1516 }
1517 
1518 // support class for get_objects_with_tags
1519 
1520 class TagObjectCollector : public JvmtiTagHashmapEntryClosure {
1521  private:
1522   JvmtiEnv* _env;
1523   jlong* _tags;
1524   jint _tag_count;
1525 
1526   GrowableArray<jobject>* _object_results;  // collected objects (JNI weak refs)
1527   GrowableArray<uint64_t>* _tag_results;    // collected tags


3243   if (is_following_references()) {
3244 
3245     // visit each object until all reachable objects have been
3246     // visited or the callback asked to terminate the iteration.
3247     while (!visit_stack()->is_empty()) {
3248       oop o = visit_stack()->pop();
3249       if (!ObjectMarker::visited(o)) {
3250         if (!visit(o)) {
3251           break;
3252         }
3253       }
3254     }
3255   }
3256 }
3257 
3258 // iterate over all objects that are reachable from a set of roots
3259 void JvmtiTagMap::iterate_over_reachable_objects(jvmtiHeapRootCallback heap_root_callback,
3260                                                  jvmtiStackReferenceCallback stack_ref_callback,
3261                                                  jvmtiObjectReferenceCallback object_ref_callback,
3262                                                  const void* user_data) {



3263   MutexLocker ml(Heap_lock);
3264   BasicHeapWalkContext context(heap_root_callback, stack_ref_callback, object_ref_callback);
3265   VM_HeapWalkOperation op(this, Handle(), context, user_data);
3266   VMThread::execute(&op);
3267 }
3268 
3269 // iterate over all objects that are reachable from a given object
3270 void JvmtiTagMap::iterate_over_objects_reachable_from_object(jobject object,
3271                                                              jvmtiObjectReferenceCallback object_ref_callback,
3272                                                              const void* user_data) {
3273   oop obj = JNIHandles::resolve(object);
3274   Handle initial_object(Thread::current(), obj);
3275 
3276   MutexLocker ml(Heap_lock);
3277   BasicHeapWalkContext context(NULL, NULL, object_ref_callback);
3278   VM_HeapWalkOperation op(this, initial_object, context, user_data);
3279   VMThread::execute(&op);
3280 }
3281 
3282 // follow references from an initial object or the GC roots
3283 void JvmtiTagMap::follow_references(jint heap_filter,
3284                                     Klass* klass,
3285                                     jobject object,
3286                                     const jvmtiHeapCallbacks* callbacks,
3287                                     const void* user_data)
3288 {
3289   oop obj = JNIHandles::resolve(object);
3290   Handle initial_object(Thread::current(), obj);
3291 




3292   MutexLocker ml(Heap_lock);
3293   AdvancedHeapWalkContext context(heap_filter, klass, callbacks);
3294   VM_HeapWalkOperation op(this, initial_object, context, user_data);
3295   VMThread::execute(&op);
3296 }
3297 
3298 
3299 void JvmtiTagMap::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
3300   // No locks during VM bring-up (0 threads) and no safepoints after main
3301   // thread creation and before VMThread creation (1 thread); initial GC
3302   // verification can happen in that window which gets to here.
3303   assert(Threads::number_of_threads() <= 1 ||
3304          SafepointSynchronize::is_at_safepoint(),
3305          "must be executed at a safepoint");
3306   if (JvmtiEnv::environments_might_exist()) {
3307     JvmtiEnvIterator it;
3308     for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) {
3309       JvmtiTagMap* tag_map = env->tag_map_acquire();
3310       if (tag_map != NULL && !tag_map->is_empty()) {
3311         tag_map->do_weak_oops(is_alive, f);




  30 #include "classfile/vmSymbols.hpp"
  31 #include "jvmtifiles/jvmtiEnv.hpp"
  32 #include "logging/log.hpp"
  33 #include "memory/allocation.inline.hpp"
  34 #include "memory/resourceArea.hpp"
  35 #include "memory/universe.hpp"
  36 #include "oops/access.inline.hpp"
  37 #include "oops/arrayOop.inline.hpp"
  38 #include "oops/constantPool.inline.hpp"
  39 #include "oops/instanceMirrorKlass.hpp"
  40 #include "oops/objArrayKlass.hpp"
  41 #include "oops/objArrayOop.inline.hpp"
  42 #include "oops/oop.inline.hpp"
  43 #include "oops/typeArrayOop.inline.hpp"
  44 #include "prims/jvmtiEventController.hpp"
  45 #include "prims/jvmtiEventController.inline.hpp"
  46 #include "prims/jvmtiExport.hpp"
  47 #include "prims/jvmtiImpl.hpp"
  48 #include "prims/jvmtiTagMap.hpp"
  49 #include "runtime/biasedLocking.hpp"
  50 #include "runtime/deoptimization.hpp"
  51 #include "runtime/frame.inline.hpp"
  52 #include "runtime/handles.inline.hpp"
  53 #include "runtime/javaCalls.hpp"
  54 #include "runtime/jniHandles.inline.hpp"
  55 #include "runtime/mutex.hpp"
  56 #include "runtime/mutexLocker.hpp"
  57 #include "runtime/reflectionUtils.hpp"
  58 #include "runtime/thread.inline.hpp"
  59 #include "runtime/threadSMR.hpp"
  60 #include "runtime/vframe.hpp"
  61 #include "runtime/vmThread.hpp"
  62 #include "runtime/vmOperations.hpp"
  63 #include "utilities/macros.hpp"
  64 #if INCLUDE_ZGC
  65 #include "gc/z/zGlobals.hpp"
  66 #endif
  67 
  68 // JvmtiTagHashmapEntry
  69 //
  70 // Each entry encapsulates a reference to the tagged object


1472   // array callback
1473   if (is_array &&
1474       callbacks()->array_primitive_value_callback != NULL &&
1475       obj->is_typeArray()) {
1476     jint res = invoke_array_primitive_value_callback(
1477                callbacks()->array_primitive_value_callback,
1478                &wrapper,
1479                obj,
1480                (void*)user_data() );
1481     if (check_flags_for_abort(res)) return;
1482   }
1483 };
1484 
1485 
1486 // Deprecated function to iterate over all objects in the heap
1487 void JvmtiTagMap::iterate_over_heap(jvmtiHeapObjectFilter object_filter,
1488                                     Klass* klass,
1489                                     jvmtiHeapObjectCallback heap_object_callback,
1490                                     const void* user_data)
1491 {
1492   // EA based optimizations on tagged objects are already reverted.
1493   EscapeBarrier eb(JavaThread::current(),
1494       object_filter == JVMTI_HEAP_OBJECT_UNTAGGED || object_filter == JVMTI_HEAP_OBJECT_EITHER);
1495   eb.deoptimize_objects_all_threads();
1496   MutexLocker ml(Heap_lock);
1497   IterateOverHeapObjectClosure blk(this,
1498                                    klass,
1499                                    object_filter,
1500                                    heap_object_callback,
1501                                    user_data);
1502   VM_HeapIterateOperation op(&blk);
1503   VMThread::execute(&op);
1504 }
1505 
1506 
1507 // Iterates over all objects in the heap
1508 void JvmtiTagMap::iterate_through_heap(jint heap_filter,
1509                                        Klass* klass,
1510                                        const jvmtiHeapCallbacks* callbacks,
1511                                        const void* user_data)
1512 {
1513   // EA based optimizations on tagged objects are already reverted.
1514   EscapeBarrier eb(JavaThread::current(), !(heap_filter & JVMTI_HEAP_FILTER_UNTAGGED));
1515   eb.deoptimize_objects_all_threads();
1516   MutexLocker ml(Heap_lock);
1517   IterateThroughHeapObjectClosure blk(this,
1518                                       klass,
1519                                       heap_filter,
1520                                       callbacks,
1521                                       user_data);
1522   VM_HeapIterateOperation op(&blk);
1523   VMThread::execute(&op);
1524 }
1525 
1526 // support class for get_objects_with_tags
1527 
1528 class TagObjectCollector : public JvmtiTagHashmapEntryClosure {
1529  private:
1530   JvmtiEnv* _env;
1531   jlong* _tags;
1532   jint _tag_count;
1533 
1534   GrowableArray<jobject>* _object_results;  // collected objects (JNI weak refs)
1535   GrowableArray<uint64_t>* _tag_results;    // collected tags


3251   if (is_following_references()) {
3252 
3253     // visit each object until all reachable objects have been
3254     // visited or the callback asked to terminate the iteration.
3255     while (!visit_stack()->is_empty()) {
3256       oop o = visit_stack()->pop();
3257       if (!ObjectMarker::visited(o)) {
3258         if (!visit(o)) {
3259           break;
3260         }
3261       }
3262     }
3263   }
3264 }
3265 
3266 // iterate over all objects that are reachable from a set of roots
3267 void JvmtiTagMap::iterate_over_reachable_objects(jvmtiHeapRootCallback heap_root_callback,
3268                                                  jvmtiStackReferenceCallback stack_ref_callback,
3269                                                  jvmtiObjectReferenceCallback object_ref_callback,
3270                                                  const void* user_data) {
3271   JavaThread* jt = JavaThread::current();
3272   EscapeBarrier eb(jt, true);
3273   eb.deoptimize_objects_all_threads();
3274   MutexLocker ml(Heap_lock);
3275   BasicHeapWalkContext context(heap_root_callback, stack_ref_callback, object_ref_callback);
3276   VM_HeapWalkOperation op(this, Handle(), context, user_data);
3277   VMThread::execute(&op);
3278 }
3279 
3280 // iterate over all objects that are reachable from a given object
3281 void JvmtiTagMap::iterate_over_objects_reachable_from_object(jobject object,
3282                                                              jvmtiObjectReferenceCallback object_ref_callback,
3283                                                              const void* user_data) {
3284   oop obj = JNIHandles::resolve(object);
3285   Handle initial_object(Thread::current(), obj);
3286 
3287   MutexLocker ml(Heap_lock);
3288   BasicHeapWalkContext context(NULL, NULL, object_ref_callback);
3289   VM_HeapWalkOperation op(this, initial_object, context, user_data);
3290   VMThread::execute(&op);
3291 }
3292 
3293 // follow references from an initial object or the GC roots
3294 void JvmtiTagMap::follow_references(jint heap_filter,
3295                                     Klass* klass,
3296                                     jobject object,
3297                                     const jvmtiHeapCallbacks* callbacks,
3298                                     const void* user_data)
3299 {
3300   oop obj = JNIHandles::resolve(object);
3301   JavaThread* jt = JavaThread::current();
3302   Handle initial_object(jt, obj);
3303   // EA based optimizations that are tagged or reachable from initial_object are already reverted.
3304   EscapeBarrier eb(jt,
3305       initial_object.is_null() && !(heap_filter & JVMTI_HEAP_FILTER_UNTAGGED));
3306   eb.deoptimize_objects_all_threads();
3307   MutexLocker ml(Heap_lock);
3308   AdvancedHeapWalkContext context(heap_filter, klass, callbacks);
3309   VM_HeapWalkOperation op(this, initial_object, context, user_data);
3310   VMThread::execute(&op);
3311 }
3312 
3313 
3314 void JvmtiTagMap::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
3315   // No locks during VM bring-up (0 threads) and no safepoints after main
3316   // thread creation and before VMThread creation (1 thread); initial GC
3317   // verification can happen in that window which gets to here.
3318   assert(Threads::number_of_threads() <= 1 ||
3319          SafepointSynchronize::is_at_safepoint(),
3320          "must be executed at a safepoint");
3321   if (JvmtiEnv::environments_might_exist()) {
3322     JvmtiEnvIterator it;
3323     for (JvmtiEnvBase* env = it.first(); env != NULL; env = it.next(env)) {
3324       JvmtiTagMap* tag_map = env->tag_map_acquire();
3325       if (tag_map != NULL && !tag_map->is_empty()) {
3326         tag_map->do_weak_oops(is_alive, f);


< prev index next >