6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()

Wed, 29 Jun 2011 20:28:58 -0700

author
dcubed
date
Wed, 29 Jun 2011 20:28:58 -0700
changeset 3014
88dce6a60ac8
parent 3013
d425748f2203
child 3015
109d1d265924

6951623: 3/3 possible performance problems in FollowReferences() and GetObjectsWithTags()
Summary: Call collect_stack_roots() before collect_simple_roots() as an optimization.
Reviewed-by: ysr, dsamersoff, dcubed
Contributed-by: ashok.srinivasa.murthy@oracle.com

src/share/vm/prims/jvmtiTagMap.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/prims/jvmtiTagMap.cpp	Thu Jun 23 20:31:43 2011 -0700
     1.2 +++ b/src/share/vm/prims/jvmtiTagMap.cpp	Wed Jun 29 20:28:58 2011 -0700
     1.3 @@ -3034,7 +3034,8 @@
     1.4  }
     1.5  
     1.6  
     1.7 -// collects all simple (non-stack) roots.
     1.8 +// Collects all simple (non-stack) roots except for threads;
     1.9 +// threads are handled in collect_stack_roots() as an optimization.
    1.10  // if there's a heap root callback provided then the callback is
    1.11  // invoked for each simple root.
    1.12  // if an object reference callback is provided then all simple
    1.13 @@ -3065,16 +3066,7 @@
    1.14      return false;
    1.15    }
    1.16  
    1.17 -  // Threads
    1.18 -  for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
    1.19 -    oop threadObj = thread->threadObj();
    1.20 -    if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
    1.21 -      bool cont = CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD, threadObj);
    1.22 -      if (!cont) {
    1.23 -        return false;
    1.24 -      }
    1.25 -    }
    1.26 -  }
    1.27 +  // threads are now handled in collect_stack_roots()
    1.28  
    1.29    // Other kinds of roots maintained by HotSpot
    1.30    // Many of these won't be visible but others (such as instances of important
    1.31 @@ -3186,13 +3178,20 @@
    1.32  }
    1.33  
    1.34  
    1.35 -// collects all stack roots - for each thread it walks the execution
    1.36 +// Collects the simple roots for all threads and collects all
    1.37 +// stack roots - for each thread it walks the execution
    1.38  // stack to find all references and local JNI refs.
    1.39  inline bool VM_HeapWalkOperation::collect_stack_roots() {
    1.40    JNILocalRootsClosure blk;
    1.41    for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
    1.42      oop threadObj = thread->threadObj();
    1.43      if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
    1.44 +      // Collect the simple root for this thread before we
    1.45 +      // collect its stack roots
    1.46 +      if (!CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD,
    1.47 +                                               threadObj)) {
    1.48 +        return false;
    1.49 +      }
    1.50        if (!collect_stack_roots(thread, &blk)) {
    1.51          return false;
    1.52        }
    1.53 @@ -3251,8 +3250,12 @@
    1.54      // to reset.
    1.55      ObjectMarker::set_needs_reset(false);
    1.56  
    1.57 +    // Calling collect_stack_roots() before collect_simple_roots()
    1.58 +    // can result in a big performance boost for an agent that is
    1.59 +    // focused on analyzing references in the thread stacks.
    1.60 +    if (!collect_stack_roots()) return;
    1.61 +
    1.62      if (!collect_simple_roots()) return;
    1.63 -    if (!collect_stack_roots()) return;
    1.64  
    1.65      // no early return so enable heap traversal to reset the mark bits
    1.66      ObjectMarker::set_needs_reset(true);

mercurial