comparison src/share/vm/prims/jvmtiTagMap.cpp @ 3816:88dce6a60ac8

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
author dcubed
date Wed, 29 Jun 2011 20:28:58 -0700
parents d425748f2203
children 2b150750d53d
comparison
equal deleted inserted replaced
3815:d425748f2203 3816:88dce6a60ac8
3032 } 3032 }
3033 return true; 3033 return true;
3034 } 3034 }
3035 3035
3036 3036
3037 // collects all simple (non-stack) roots. 3037 // Collects all simple (non-stack) roots except for threads;
3038 // threads are handled in collect_stack_roots() as an optimization.
3038 // if there's a heap root callback provided then the callback is 3039 // if there's a heap root callback provided then the callback is
3039 // invoked for each simple root. 3040 // invoked for each simple root.
3040 // if an object reference callback is provided then all simple 3041 // if an object reference callback is provided then all simple
3041 // roots are pushed onto the marking stack so that they can be 3042 // roots are pushed onto the marking stack so that they can be
3042 // processed later 3043 // processed later
3063 ObjectSynchronizer::oops_do(&blk); 3064 ObjectSynchronizer::oops_do(&blk);
3064 if (blk.stopped()) { 3065 if (blk.stopped()) {
3065 return false; 3066 return false;
3066 } 3067 }
3067 3068
3068 // Threads 3069 // threads are now handled in collect_stack_roots()
3069 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
3070 oop threadObj = thread->threadObj();
3071 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
3072 bool cont = CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD, threadObj);
3073 if (!cont) {
3074 return false;
3075 }
3076 }
3077 }
3078 3070
3079 // Other kinds of roots maintained by HotSpot 3071 // Other kinds of roots maintained by HotSpot
3080 // Many of these won't be visible but others (such as instances of important 3072 // Many of these won't be visible but others (such as instances of important
3081 // exceptions) will be visible. 3073 // exceptions) will be visible.
3082 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER); 3074 blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
3184 } 3176 }
3185 return true; 3177 return true;
3186 } 3178 }
3187 3179
3188 3180
3189 // collects all stack roots - for each thread it walks the execution 3181 // Collects the simple roots for all threads and collects all
3182 // stack roots - for each thread it walks the execution
3190 // stack to find all references and local JNI refs. 3183 // stack to find all references and local JNI refs.
3191 inline bool VM_HeapWalkOperation::collect_stack_roots() { 3184 inline bool VM_HeapWalkOperation::collect_stack_roots() {
3192 JNILocalRootsClosure blk; 3185 JNILocalRootsClosure blk;
3193 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) { 3186 for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
3194 oop threadObj = thread->threadObj(); 3187 oop threadObj = thread->threadObj();
3195 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) { 3188 if (threadObj != NULL && !thread->is_exiting() && !thread->is_hidden_from_external_view()) {
3189 // Collect the simple root for this thread before we
3190 // collect its stack roots
3191 if (!CallbackInvoker::report_simple_root(JVMTI_HEAP_REFERENCE_THREAD,
3192 threadObj)) {
3193 return false;
3194 }
3196 if (!collect_stack_roots(thread, &blk)) { 3195 if (!collect_stack_roots(thread, &blk)) {
3197 return false; 3196 return false;
3198 } 3197 }
3199 } 3198 }
3200 } 3199 }
3249 // If either collect_stack_roots() or collect_simple_roots() 3248 // If either collect_stack_roots() or collect_simple_roots()
3250 // returns false at this point, then there are no mark bits 3249 // returns false at this point, then there are no mark bits
3251 // to reset. 3250 // to reset.
3252 ObjectMarker::set_needs_reset(false); 3251 ObjectMarker::set_needs_reset(false);
3253 3252
3253 // Calling collect_stack_roots() before collect_simple_roots()
3254 // can result in a big performance boost for an agent that is
3255 // focused on analyzing references in the thread stacks.
3256 if (!collect_stack_roots()) return;
3257
3254 if (!collect_simple_roots()) return; 3258 if (!collect_simple_roots()) return;
3255 if (!collect_stack_roots()) return;
3256 3259
3257 // no early return so enable heap traversal to reset the mark bits 3260 // no early return so enable heap traversal to reset the mark bits
3258 ObjectMarker::set_needs_reset(true); 3261 ObjectMarker::set_needs_reset(true);
3259 } else { 3262 } else {
3260 visit_stack()->push(initial_object()()); 3263 visit_stack()->push(initial_object()());