Wed, 29 Jun 2011 20:28:58 -0700
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);